cogl-material: Use CLAMP_TO_EDGE for WRAP_AUTOMATIC unless overriden
CoglMaterial now sets GL_CLAMP_TO_EDGE if WRAP_MODE_AUTOMATIC is used unless it is overridden when the material is flushed. The primitives are still expected to expose repeat semantics so no user visible changes are made. The idea is that drawing non-repeated textures is the most common case so if we make clamp_to_ege the default then we will reduce the number of times we have to override the material. Avoiding overrides will become important if the overriding mechanism is replaced with one where the primitive is expected to copy the material and change that instead.
This commit is contained in:
parent
e007bc5358
commit
3769862323
@ -1372,7 +1372,7 @@ _cogl_material_set_wrap_modes_for_layer (CoglMaterialLayer *layer,
|
|||||||
GL_CLAMP_TO_EDGE :
|
GL_CLAMP_TO_EDGE :
|
||||||
GL_CLAMP_TO_BORDER);
|
GL_CLAMP_TO_BORDER);
|
||||||
else if (layer->wrap_mode_s == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
else if (layer->wrap_mode_s == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
wrap_mode_s = GL_REPEAT;
|
wrap_mode_s = GL_CLAMP_TO_EDGE;
|
||||||
else
|
else
|
||||||
wrap_mode_s = layer->wrap_mode_s;
|
wrap_mode_s = layer->wrap_mode_s;
|
||||||
|
|
||||||
@ -1385,7 +1385,7 @@ _cogl_material_set_wrap_modes_for_layer (CoglMaterialLayer *layer,
|
|||||||
GL_CLAMP_TO_EDGE :
|
GL_CLAMP_TO_EDGE :
|
||||||
GL_CLAMP_TO_BORDER);
|
GL_CLAMP_TO_BORDER);
|
||||||
else if (layer->wrap_mode_t == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
else if (layer->wrap_mode_t == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
wrap_mode_t = GL_REPEAT;
|
wrap_mode_t = GL_CLAMP_TO_EDGE;
|
||||||
else
|
else
|
||||||
wrap_mode_t = layer->wrap_mode_t;
|
wrap_mode_t = layer->wrap_mode_t;
|
||||||
|
|
||||||
@ -1398,7 +1398,7 @@ _cogl_material_set_wrap_modes_for_layer (CoglMaterialLayer *layer,
|
|||||||
GL_CLAMP_TO_EDGE :
|
GL_CLAMP_TO_EDGE :
|
||||||
GL_CLAMP_TO_BORDER);
|
GL_CLAMP_TO_BORDER);
|
||||||
else if (layer->wrap_mode_r == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
else if (layer->wrap_mode_r == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
wrap_mode_r = GL_REPEAT;
|
wrap_mode_r = GL_CLAMP_TO_EDGE;
|
||||||
else
|
else
|
||||||
wrap_mode_r = layer->wrap_mode_r;
|
wrap_mode_r = layer->wrap_mode_r;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ typedef struct _TextureSlicedQuadState
|
|||||||
float quad_len_y;
|
float quad_len_y;
|
||||||
gboolean flipped_x;
|
gboolean flipped_x;
|
||||||
gboolean flipped_y;
|
gboolean flipped_y;
|
||||||
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
CoglMaterialWrapModeOverrides *wrap_mode_overrides;
|
||||||
} TextureSlicedQuadState;
|
} TextureSlicedQuadState;
|
||||||
|
|
||||||
typedef struct _TextureSlicedPolygonState
|
typedef struct _TextureSlicedPolygonState
|
||||||
@ -117,7 +117,7 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
|
|||||||
1, /* one layer */
|
1, /* one layer */
|
||||||
0, /* don't need to use fallbacks */
|
0, /* don't need to use fallbacks */
|
||||||
gl_handle, /* replace the layer0 texture */
|
gl_handle, /* replace the layer0 texture */
|
||||||
&state->wrap_mode_overrides, /* use CLAMP_TO_EDGE */
|
state->wrap_mode_overrides, /* use GL_CLAMP_TO_EDGE */
|
||||||
subtexture_coords,
|
subtexture_coords,
|
||||||
4);
|
4);
|
||||||
}
|
}
|
||||||
@ -148,10 +148,12 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
|
|||||||
float ty_2)
|
float ty_2)
|
||||||
{
|
{
|
||||||
TextureSlicedQuadState state;
|
TextureSlicedQuadState state;
|
||||||
|
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
||||||
gboolean tex_virtual_flipped_x;
|
gboolean tex_virtual_flipped_x;
|
||||||
gboolean tex_virtual_flipped_y;
|
gboolean tex_virtual_flipped_y;
|
||||||
gboolean quad_flipped_x;
|
gboolean quad_flipped_x;
|
||||||
gboolean quad_flipped_y;
|
gboolean quad_flipped_y;
|
||||||
|
CoglHandle first_layer;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -253,14 +255,28 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
|
|||||||
position = replacement_position;
|
position = replacement_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.wrap_mode_overrides = NULL;
|
||||||
memset (&state.wrap_mode_overrides, 0, sizeof (state.wrap_mode_overrides));
|
memset (&state.wrap_mode_overrides, 0, sizeof (state.wrap_mode_overrides));
|
||||||
|
|
||||||
/* We can't use hardware repeat so we need to set 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 */
|
otherwise it might pull in edge pixels from the other side. By
|
||||||
state.wrap_mode_overrides.values[0].s =
|
default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need
|
||||||
|
to override if the wrap mode is repeat */
|
||||||
|
first_layer = cogl_material_get_layers (material)->data;
|
||||||
|
if (cogl_material_layer_get_wrap_mode_s (first_layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_REPEAT)
|
||||||
|
{
|
||||||
|
state.wrap_mode_overrides = &wrap_mode_overrides;
|
||||||
|
wrap_mode_overrides.values[0].s =
|
||||||
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
|
||||||
state.wrap_mode_overrides.values[0].t =
|
}
|
||||||
|
if (cogl_material_layer_get_wrap_mode_t (first_layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_REPEAT)
|
||||||
|
{
|
||||||
|
state.wrap_mode_overrides = &wrap_mode_overrides;
|
||||||
|
wrap_mode_overrides.values[0].t =
|
||||||
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
|
||||||
|
}
|
||||||
|
|
||||||
state.material = material;
|
state.material = material;
|
||||||
|
|
||||||
@ -340,6 +356,9 @@ _cogl_multitexture_quad_single_primitive (const float *position,
|
|||||||
GList *tmp;
|
GList *tmp;
|
||||||
int i;
|
int i;
|
||||||
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
||||||
|
/* This will be set to point to wrap_mode_overrides when an override
|
||||||
|
is needed */
|
||||||
|
CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||||
|
|
||||||
@ -357,7 +376,6 @@ _cogl_multitexture_quad_single_primitive (const float *position,
|
|||||||
float *out_tex_coords;
|
float *out_tex_coords;
|
||||||
float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
|
float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
|
||||||
CoglTransformResult transform_result;
|
CoglTransformResult transform_result;
|
||||||
unsigned long auto_wrap_mode;
|
|
||||||
|
|
||||||
tex_handle = cogl_material_layer_get_texture (layer);
|
tex_handle = cogl_material_layer_get_texture (layer);
|
||||||
|
|
||||||
@ -427,20 +445,28 @@ _cogl_multitexture_quad_single_primitive (const float *position,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not repeating then we want to clamp the coords
|
/* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If
|
||||||
to the edge otherwise it can pull in edge pixels from the
|
the texture coordinates need repeating then we'll override
|
||||||
wrong side when scaled */
|
this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE
|
||||||
|
so that it won't blend in pixels from the opposite side when
|
||||||
|
the full texture is drawn with GL_LINEAR filter mode */
|
||||||
if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
|
if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
|
||||||
auto_wrap_mode = COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
{
|
||||||
else
|
|
||||||
auto_wrap_mode = COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
|
|
||||||
|
|
||||||
if (cogl_material_layer_get_wrap_mode_s (layer) ==
|
if (cogl_material_layer_get_wrap_mode_s (layer) ==
|
||||||
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
wrap_mode_overrides.values[i].s = auto_wrap_mode;
|
{
|
||||||
|
wrap_mode_overrides.values[i].s
|
||||||
|
= COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
wrap_mode_overrides_p = &wrap_mode_overrides;
|
||||||
|
}
|
||||||
if (cogl_material_layer_get_wrap_mode_t (layer) ==
|
if (cogl_material_layer_get_wrap_mode_t (layer) ==
|
||||||
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
wrap_mode_overrides.values[i].t = auto_wrap_mode;
|
{
|
||||||
|
wrap_mode_overrides.values[i].t
|
||||||
|
= COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
wrap_mode_overrides_p = &wrap_mode_overrides;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_journal_log_quad (position,
|
_cogl_journal_log_quad (position,
|
||||||
@ -448,7 +474,7 @@ _cogl_multitexture_quad_single_primitive (const float *position,
|
|||||||
n_layers,
|
n_layers,
|
||||||
fallback_layers,
|
fallback_layers,
|
||||||
0, /* don't replace the layer0 texture */
|
0, /* don't replace the layer0 texture */
|
||||||
&wrap_mode_overrides,
|
wrap_mode_overrides_p,
|
||||||
final_tex_coords,
|
final_tex_coords,
|
||||||
n_layers * 4);
|
n_layers * 4);
|
||||||
|
|
||||||
@ -891,7 +917,9 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
|||||||
unsigned int n_layers,
|
unsigned int n_layers,
|
||||||
unsigned int stride,
|
unsigned int stride,
|
||||||
gboolean use_color,
|
gboolean use_color,
|
||||||
guint32 fallback_layers)
|
guint32 fallback_layers,
|
||||||
|
CoglMaterialWrapModeOverrides *
|
||||||
|
wrap_mode_overrides)
|
||||||
{
|
{
|
||||||
CoglHandle material;
|
CoglHandle material;
|
||||||
const GList *layers;
|
const GList *layers;
|
||||||
@ -959,6 +987,11 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
|||||||
if (use_color)
|
if (use_color)
|
||||||
options.flags |= COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
options.flags |= COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
||||||
options.fallback_layers = fallback_layers;
|
options.fallback_layers = fallback_layers;
|
||||||
|
if (wrap_mode_overrides)
|
||||||
|
{
|
||||||
|
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||||
|
options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||||
|
}
|
||||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||||
|
|
||||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
||||||
@ -980,6 +1013,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
|||||||
gsize stride_bytes;
|
gsize stride_bytes;
|
||||||
GLfloat *v;
|
GLfloat *v;
|
||||||
int prev_n_texcoord_arrays_enabled;
|
int prev_n_texcoord_arrays_enabled;
|
||||||
|
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
||||||
|
CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -994,6 +1029,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
|||||||
layers = cogl_material_get_layers (ctx->source_material);
|
layers = cogl_material_get_layers (ctx->source_material);
|
||||||
n_layers = g_list_length ((GList *)layers);
|
n_layers = g_list_length ((GList *)layers);
|
||||||
|
|
||||||
|
memset (&wrap_mode_overrides, 0, sizeof (wrap_mode_overrides));
|
||||||
|
|
||||||
for (tmp = layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
|
for (tmp = layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
|
||||||
{
|
{
|
||||||
CoglHandle layer = tmp->data;
|
CoglHandle layer = tmp->data;
|
||||||
@ -1066,6 +1103,24 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
|||||||
fallback_layers |= (1 << i);
|
fallback_layers |= (1 << i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* By default COGL_MATERIAL_WRAP_MODE_AUTOMATIC becomes
|
||||||
|
GL_CLAMP_TO_EDGE but we want the polygon API to use GL_REPEAT
|
||||||
|
to maintain compatibility with previous releases */
|
||||||
|
if (cogl_material_layer_get_wrap_mode_s (layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
|
{
|
||||||
|
wrap_mode_overrides.values[i].s =
|
||||||
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
wrap_mode_overrides_p = &wrap_mode_overrides;
|
||||||
|
}
|
||||||
|
if (cogl_material_layer_get_wrap_mode_t (layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
|
{
|
||||||
|
wrap_mode_overrides.values[i].t =
|
||||||
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
wrap_mode_overrides_p = &wrap_mode_overrides;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Our data is arranged like:
|
/* Our data is arranged like:
|
||||||
@ -1130,7 +1185,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
|||||||
n_layers,
|
n_layers,
|
||||||
stride,
|
stride,
|
||||||
use_color,
|
use_color,
|
||||||
fallback_layers);
|
fallback_layers,
|
||||||
|
wrap_mode_overrides_p);
|
||||||
|
|
||||||
/* Reset the size of the logged vertex array because rendering
|
/* Reset the size of the logged vertex array because rendering
|
||||||
rectangles expects it to start at 0 */
|
rectangles expects it to start at 0 */
|
||||||
|
@ -1530,6 +1530,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||||||
if (buffer->new_attributes)
|
if (buffer->new_attributes)
|
||||||
cogl_vertex_buffer_submit_real (buffer);
|
cogl_vertex_buffer_submit_real (buffer);
|
||||||
|
|
||||||
|
options.flags =
|
||||||
|
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
|
||||||
|
COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||||
|
memset (&options.wrap_mode_overrides, 0,
|
||||||
|
sizeof (options.wrap_mode_overrides));
|
||||||
|
|
||||||
for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
|
for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
|
||||||
{
|
{
|
||||||
CoglVertexBufferVBO *cogl_vbo = tmp->data;
|
CoglVertexBufferVBO *cogl_vbo = tmp->data;
|
||||||
@ -1668,6 +1674,32 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||||||
*/
|
*/
|
||||||
fallback_layers |= (1 << i);
|
fallback_layers |= (1 << i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* By default COGL_MATERIAL_WRAP_MODE_AUTOMATIC becomes
|
||||||
|
GL_CLAMP_TO_EDGE but we want GL_REPEAT to maintain
|
||||||
|
compatibility with older versions of Cogl so we'll override
|
||||||
|
it */
|
||||||
|
if (cogl_material_layer_get_wrap_mode_s (layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
|
{
|
||||||
|
options.wrap_mode_overrides.values[i].s =
|
||||||
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||||
|
}
|
||||||
|
if (cogl_material_layer_get_wrap_mode_t (layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
|
{
|
||||||
|
options.wrap_mode_overrides.values[i].t =
|
||||||
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||||
|
}
|
||||||
|
if (_cogl_material_layer_get_wrap_mode_r (layer) ==
|
||||||
|
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||||
|
{
|
||||||
|
options.wrap_mode_overrides.values[i].r =
|
||||||
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
|
||||||
|
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = max_texcoord_attrib_unit + 1; i < ctx->n_texcoord_arrays_enabled; i++)
|
for (i = max_texcoord_attrib_unit + 1; i < ctx->n_texcoord_arrays_enabled; i++)
|
||||||
@ -1682,9 +1714,6 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||||||
* always be done first when preparing to draw. */
|
* always be done first when preparing to draw. */
|
||||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||||
|
|
||||||
options.flags =
|
|
||||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
|
|
||||||
COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
|
||||||
options.fallback_layers = fallback_layers;
|
options.fallback_layers = fallback_layers;
|
||||||
options.disable_layers = disable_layers;
|
options.disable_layers = disable_layers;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user