texture_quad_multiple_primitives: rework wrap mode overrides

This reworks _cogl_texture_quad_multiple_primitives so instead of using
the CoglPipelineWrapModeOverrides mechanism to force the clamp to edge
repeat mode we now derive an override pipeline using cogl_pipeline_copy
instead. This avoids a relatively large, unconditional, memset.
This commit is contained in:
Robert Bragg 2010-11-01 18:55:48 +00:00
parent 636310a81e
commit 4bd64b6ba6

View File

@ -60,7 +60,6 @@ typedef struct _TextureSlicedQuadState
float quad_len_y;
gboolean flipped_x;
gboolean flipped_y;
CoglPipelineWrapModeOverrides *wrap_mode_overrides;
} TextureSlicedQuadState;
typedef struct _TextureSlicedPolygonState
@ -114,18 +113,55 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
subtexture_coords[0], subtexture_coords[1],
subtexture_coords[2], subtexture_coords[3]);
/* FIXME: when the wrap mode becomes part of the pipeline we need to
* be able to override the wrap mode when logging a quad. */
_cogl_journal_log_quad (quad_coords,
state->pipeline,
1, /* one layer */
0, /* don't need to use fallbacks */
gl_handle, /* replace the layer0 texture */
state->wrap_mode_overrides, /* use GL_CLAMP_TO_EDGE */
NULL, /* we never use wrap mode overrides */
subtexture_coords,
4);
}
typedef struct _ValidateFirstLayerState
{
CoglPipeline *override_pipeline;
} ValidateFirstLayerState;
static gboolean
validate_first_layer_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
ValidateFirstLayerState *state = user_data;
CoglPipelineWrapMode clamp_to_edge =
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE;
/* We can't use hardware repeat so we need to set clamp to edge
* otherwise it might pull in edge pixels from the other side. By
* default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need
* to override if the wrap mode is repeat.
*/
if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
if (!state->override_pipeline)
state->override_pipeline = cogl_pipeline_copy (pipeline);
cogl_pipeline_set_layer_wrap_mode_s (pipeline, layer_index,
clamp_to_edge);
}
if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
if (!state->override_pipeline)
state->override_pipeline = cogl_pipeline_copy (pipeline);
cogl_pipeline_set_layer_wrap_mode_t (pipeline, layer_index,
clamp_to_edge);
}
return FALSE;
}
/* This path doesn't currently support multitexturing but is used for
* CoglTextures that don't support repeating using the GPU so we need to
* manually emit extra geometry to fake the repeating. This includes:
@ -152,12 +188,11 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
float ty_2)
{
TextureSlicedQuadState state;
CoglPipelineWrapModeOverrides wrap_mode_overrides;
gboolean tex_virtual_flipped_x;
gboolean tex_virtual_flipped_y;
gboolean quad_flipped_x;
gboolean quad_flipped_y;
CoglHandle first_layer;
ValidateFirstLayerState validate_first_layer_state;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -259,29 +294,14 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
position = replacement_position;
}
state.wrap_mode_overrides = NULL;
memset (&wrap_mode_overrides, 0, sizeof (wrap_mode_overrides));
/* We can't use hardware repeat so we need to set clamp to edge
otherwise it might pull in edge pixels from the other side. By
default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need
to override if the wrap mode is repeat */
first_layer = _cogl_pipeline_get_layers (pipeline)->data;
if (_cogl_pipeline_layer_get_wrap_mode_s (first_layer) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
state.wrap_mode_overrides = &wrap_mode_overrides;
wrap_mode_overrides.values[0].s =
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
}
if (_cogl_pipeline_layer_get_wrap_mode_t (first_layer) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
state.wrap_mode_overrides = &wrap_mode_overrides;
wrap_mode_overrides.values[0].t =
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
}
validate_first_layer_state.override_pipeline = NULL;
cogl_pipeline_foreach_layer (pipeline,
validate_first_layer_cb,
&validate_first_layer_state);
if (validate_first_layer_state.override_pipeline)
state.pipeline = validate_first_layer_state.override_pipeline;
else
state.pipeline = pipeline;
/* Get together the data we need to transform the virtual texture
@ -329,6 +349,9 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
tx_1, ty_1, tx_2, ty_2,
log_quad_sub_textures_cb,
&state);
if (validate_first_layer_state.override_pipeline)
cogl_object_unref (validate_first_layer_state.override_pipeline);
}
typedef struct _ValidateTexCoordsState
@ -519,6 +542,9 @@ _cogl_multitexture_quad_single_primitive (const float *position,
final_tex_coords,
n_layers * 4);
if (state.override_pipeline)
cogl_object_unref (state.override_pipeline);
return TRUE;
}