cogl: Separate out state flags for the alpha test func and ref

Previously the flag to mark the differences for the alpha test
function and reference value were conflated into one. However this is
awkward when generating shader code to simulate the alpha testing for
GLES 2 because in that case changing the function would need a
different program but changing the reference value just requires
updating a uniform. This patch makes the function and reference have
their own state flags.
This commit is contained in:
Neil Roberts 2010-11-22 18:29:50 +00:00
parent 38ad560b19
commit 60000690e1
3 changed files with 102 additions and 36 deletions

View File

@ -521,7 +521,8 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
blend_state->blend_dst_factor_rgb));
}
if (pipelines_difference & COGL_PIPELINE_STATE_ALPHA_FUNC)
if (pipelines_difference & (COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE))
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC);

View File

@ -273,19 +273,20 @@ struct _CoglPipelineLayer
* state changes... */
typedef enum _CoglPipelineState
{
COGL_PIPELINE_STATE_COLOR = 1L<<0,
COGL_PIPELINE_STATE_BLEND_ENABLE = 1L<<1,
COGL_PIPELINE_STATE_LAYERS = 1L<<2,
COGL_PIPELINE_STATE_COLOR = 1L<<0,
COGL_PIPELINE_STATE_BLEND_ENABLE = 1L<<1,
COGL_PIPELINE_STATE_LAYERS = 1L<<2,
COGL_PIPELINE_STATE_LIGHTING = 1L<<3,
COGL_PIPELINE_STATE_ALPHA_FUNC = 1L<<4,
COGL_PIPELINE_STATE_BLEND = 1L<<5,
COGL_PIPELINE_STATE_USER_SHADER = 1L<<6,
COGL_PIPELINE_STATE_DEPTH = 1L<<7,
COGL_PIPELINE_STATE_FOG = 1L<<8,
COGL_PIPELINE_STATE_POINT_SIZE = 1L<<9,
COGL_PIPELINE_STATE_LIGHTING = 1L<<3,
COGL_PIPELINE_STATE_ALPHA_FUNC = 1L<<4,
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE = 1L<<5,
COGL_PIPELINE_STATE_BLEND = 1L<<6,
COGL_PIPELINE_STATE_USER_SHADER = 1L<<7,
COGL_PIPELINE_STATE_DEPTH = 1L<<8,
COGL_PIPELINE_STATE_FOG = 1L<<9,
COGL_PIPELINE_STATE_POINT_SIZE = 1L<<10,
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE = 1L<<10,
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE = 1L<<11,
COGL_PIPELINE_STATE_ALL_SPARSE =
COGL_PIPELINE_STATE_COLOR |
@ -293,6 +294,7 @@ typedef enum _CoglPipelineState
COGL_PIPELINE_STATE_LAYERS |
COGL_PIPELINE_STATE_LIGHTING |
COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE |
COGL_PIPELINE_STATE_BLEND |
COGL_PIPELINE_STATE_USER_SHADER |
COGL_PIPELINE_STATE_DEPTH |
@ -310,6 +312,7 @@ typedef enum _CoglPipelineState
COGL_PIPELINE_STATE_NEEDS_BIG_STATE =
COGL_PIPELINE_STATE_LIGHTING |
COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE |
COGL_PIPELINE_STATE_BLEND |
COGL_PIPELINE_STATE_USER_SHADER |
COGL_PIPELINE_STATE_DEPTH |

View File

@ -1010,11 +1010,12 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
}
if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC)
{
memcpy (&big_state->alpha_state,
&src->big_state->alpha_state,
sizeof (CoglPipelineAlphaFuncState));
}
big_state->alpha_state.alpha_func =
src->big_state->alpha_state.alpha_func;
if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE)
big_state->alpha_state.alpha_func_reference =
src->big_state->alpha_state.alpha_func_reference;
if (differences & COGL_PIPELINE_STATE_BLEND)
{
@ -3014,19 +3015,28 @@ _cogl_pipeline_lighting_state_equal (CoglPipeline *authority0,
}
static gboolean
_cogl_pipeline_alpha_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
{
CoglPipelineAlphaFuncState *alpha_state0 =
&authority0->big_state->alpha_state;
CoglPipelineAlphaFuncState *alpha_state1 =
&authority1->big_state->alpha_state;
if (alpha_state0->alpha_func != alpha_state1->alpha_func ||
alpha_state0->alpha_func_reference != alpha_state1->alpha_func_reference)
return FALSE;
else
return TRUE;
return alpha_state0->alpha_func == alpha_state1->alpha_func;
}
static gboolean
_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
{
CoglPipelineAlphaFuncState *alpha_state0 =
&authority0->big_state->alpha_state;
CoglPipelineAlphaFuncState *alpha_state1 =
&authority1->big_state->alpha_state;
return (alpha_state0->alpha_func_reference ==
alpha_state1->alpha_func_reference);
}
static gboolean
@ -3315,7 +3325,13 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
if (!simple_property_equal (pipeline0, pipeline1,
pipelines_difference,
COGL_PIPELINE_STATE_ALPHA_FUNC,
_cogl_pipeline_alpha_state_equal))
_cogl_pipeline_alpha_func_state_equal))
goto done;
if (!simple_property_equal (pipeline0, pipeline1,
pipelines_difference,
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE,
_cogl_pipeline_alpha_func_reference_state_equal))
goto done;
/* We don't need to compare the detailed blending state if we know
@ -3834,10 +3850,9 @@ cogl_pipeline_set_emission (CoglPipeline *pipeline, const CoglColor *emission)
handle_automatic_blend_enable (pipeline, state);
}
void
cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline,
CoglPipelineAlphaFunc alpha_func,
float alpha_reference)
static void
_cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline,
CoglPipelineAlphaFunc alpha_func)
{
CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC;
CoglPipeline *authority;
@ -3848,8 +3863,7 @@ cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline,
authority = _cogl_pipeline_get_authority (pipeline, state);
alpha_state = &authority->big_state->alpha_state;
if (alpha_state->alpha_func == alpha_func &&
alpha_state->alpha_func_reference == alpha_reference)
if (alpha_state->alpha_func == alpha_func)
return;
/* - Flush journal primitives referencing the current state.
@ -3861,10 +3875,51 @@ cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline,
alpha_state = &pipeline->big_state->alpha_state;
alpha_state->alpha_func = alpha_func;
alpha_state->alpha_func_reference = alpha_reference;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_alpha_state_equal);
_cogl_pipeline_alpha_func_state_equal);
}
static void
_cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline,
float alpha_reference)
{
CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE;
CoglPipeline *authority;
CoglPipelineAlphaFuncState *alpha_state;
g_return_if_fail (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, state);
alpha_state = &authority->big_state->alpha_state;
if (alpha_state->alpha_func_reference == alpha_reference)
return;
/* - Flush journal primitives referencing the current state.
* - Make sure the pipeline has no dependants so it may be modified.
* - If the pipeline isn't currently an authority for the state being
* changed, then initialize that state from the current authority.
*/
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
alpha_state = &pipeline->big_state->alpha_state;
alpha_state->alpha_func_reference = alpha_reference;
_cogl_pipeline_update_authority
(pipeline, authority, state,
_cogl_pipeline_alpha_func_reference_state_equal);
}
void
cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline,
CoglPipelineAlphaFunc alpha_func,
float alpha_reference)
{
_cogl_pipeline_set_alpha_test_function (pipeline, alpha_func);
_cogl_pipeline_set_alpha_test_function_reference (pipeline, alpha_reference);
}
}
GLenum
@ -5743,6 +5798,13 @@ _cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
int n_layers;
CoglPipelineLayer **authority0_layers;
CoglPipelineLayer **authority1_layers;
/* Under GLES2 the alpha func becomes part of the fragment program
so we can't share programs there */
const int codegen_state = (COGL_PIPELINE_STATE_LAYERS
#ifdef HAVE_COGL_GLES2
| COGL_PIPELINE_STATE_ALPHA_FUNC
#endif
);
/* XXX: we'll need to update this when we add fog support to the
* codegen */
@ -5753,7 +5815,7 @@ _cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
/* Find the first pipeline that modifies state that affects the
* codegen... */
authority0 = _cogl_pipeline_get_authority (pipeline,
COGL_PIPELINE_STATE_LAYERS);
codegen_state);
/* Find the next ancestor after that, that also modifies state
* affecting codegen... */
@ -5761,7 +5823,7 @@ _cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
{
authority1 =
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0),
COGL_PIPELINE_STATE_LAYERS);
codegen_state);
}
else
return authority0;
@ -5804,7 +5866,7 @@ _cogl_pipeline_find_codegen_authority (CoglPipeline *pipeline,
authority0 = authority1;
authority1 =
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1),
COGL_PIPELINE_STATE_LAYERS);
codegen_state);
if (authority1 == authority0)
break;
}