cogl-texture: Replace the ensure_mipmaps virtual with pre_paint

Instead of the ensure_mipmaps virtual that is only called whenever the
texture is about to be rendered with a min filter that needs the
mipmap, there is now a pre_paint virtual that is always called when
the texture is about to be painted in any way. It has a flags
parameter which is used to specify whether the mipmap will be needed.

This is useful for CoglTexturePixmapX11 because it needs to do stuff
before painting that is unrelated to mipmapping.
This commit is contained in:
Neil Roberts 2010-06-09 17:39:59 +01:00
parent ebb05bcb64
commit 82e63a4753
10 changed files with 67 additions and 51 deletions

View File

@ -407,16 +407,17 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
} }
static void static void
_cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex) _cogl_atlas_texture_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
{ {
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Mipmaps do not work well with the current atlas so instead we'll if ((flags & COGL_TEXTURE_NEEDS_MIPMAP))
just migrate the texture out and use a regular texture */ /* Mipmaps do not work well with the current atlas so instead
we'll just migrate the texture out and use a regular texture */
_cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex);
/* Forward on to the sub texture */ /* Forward on to the sub texture */
_cogl_texture_ensure_mipmaps (atlas_tex->sub_texture); _cogl_texture_pre_paint (atlas_tex->sub_texture, flags);
} }
static void static void
@ -1081,7 +1082,7 @@ cogl_atlas_texture_vtable =
_cogl_atlas_texture_transform_quad_coords_to_gl, _cogl_atlas_texture_transform_quad_coords_to_gl,
_cogl_atlas_texture_get_gl_texture, _cogl_atlas_texture_get_gl_texture,
_cogl_atlas_texture_set_filters, _cogl_atlas_texture_set_filters,
_cogl_atlas_texture_ensure_mipmaps, _cogl_atlas_texture_pre_paint,
_cogl_atlas_texture_ensure_non_quad_rendering, _cogl_atlas_texture_ensure_non_quad_rendering,
_cogl_atlas_texture_set_wrap_mode_parameters, _cogl_atlas_texture_set_wrap_mode_parameters,
_cogl_atlas_texture_get_format, _cogl_atlas_texture_get_format,

View File

@ -629,11 +629,12 @@ gboolean
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle); _cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
/* /*
* Ensures the mipmaps are available for the texture in the layer if * Calls the pre_paint method on the layer texture if there is
* the filter settings would require it * one. This will determine whether mipmaps are needed based on the
* filter settings.
*/ */
void void
_cogl_material_layer_ensure_mipmaps (CoglHandle layer_handler); _cogl_material_layer_pre_paint (CoglHandle layer_handler);
/* /*
* CoglMaterialFlushFlag: * CoglMaterialFlushFlag:

View File

@ -4877,15 +4877,6 @@ _cogl_material_layer_has_user_matrix (CoglHandle handle)
return authority->parent ? TRUE : FALSE; return authority->parent ? TRUE : FALSE;
} }
static gboolean
is_mipmap_filter (CoglMaterialFilter filter)
{
return (filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST
|| filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST
|| filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR
|| filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR);
}
static void static void
_cogl_material_layer_get_filters (CoglMaterialLayer *layer, _cogl_material_layer_get_filters (CoglMaterialLayer *layer,
CoglMaterialFilter *min_filter, CoglMaterialFilter *min_filter,
@ -4900,23 +4891,31 @@ _cogl_material_layer_get_filters (CoglMaterialLayer *layer,
} }
void void
_cogl_material_layer_ensure_mipmaps (CoglHandle handle) _cogl_material_layer_pre_paint (CoglHandle handle)
{ {
CoglMaterialLayer *layer = COGL_MATERIAL_LAYER (handle); CoglMaterialLayer *layer = COGL_MATERIAL_LAYER (handle);
CoglMaterialLayer *texture_authority; CoglMaterialLayer *texture_authority;
CoglMaterialFilter min_filter;
CoglMaterialFilter mag_filter;
texture_authority = texture_authority =
_cogl_material_layer_get_authority (layer, _cogl_material_layer_get_authority (layer,
COGL_MATERIAL_LAYER_STATE_TEXTURE); COGL_MATERIAL_LAYER_STATE_TEXTURE);
if (texture_authority->texture != COGL_INVALID_HANDLE)
{
CoglTexturePrePaintFlags flags = 0;
CoglMaterialFilter min_filter;
CoglMaterialFilter mag_filter;
_cogl_material_layer_get_filters (layer, &min_filter, &mag_filter); _cogl_material_layer_get_filters (layer, &min_filter, &mag_filter);
if (texture_authority->texture != COGL_INVALID_HANDLE && if (min_filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST
(is_mipmap_filter (min_filter) || || min_filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST
is_mipmap_filter (mag_filter))) || min_filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR
_cogl_texture_ensure_mipmaps (texture_authority->texture); || min_filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR)
flags |= COGL_TEXTURE_NEEDS_MIPMAP;
_cogl_texture_pre_paint (layer->texture, flags);
}
} }
CoglMaterialFilter CoglMaterialFilter

View File

@ -561,7 +561,7 @@ _cogl_rectangles_with_multitexture_coords (
* sure the referenced texture is migrated out of the atlas and * sure the referenced texture is migrated out of the atlas and
* mipmaps are generated.) * mipmaps are generated.)
*/ */
_cogl_material_layer_ensure_mipmaps (layer); _cogl_material_layer_pre_paint (layer);
tex_handle = cogl_material_layer_get_texture (layer); tex_handle = cogl_material_layer_get_texture (layer);
@ -1137,7 +1137,7 @@ cogl_polygon (const CoglTextureVertex *vertices,
* could completely change if it needs to be migrated out of the * could completely change if it needs to be migrated out of the
* atlas and will affect how we validate the layer. * atlas and will affect how we validate the layer.
*/ */
_cogl_material_layer_ensure_mipmaps (layer); _cogl_material_layer_pre_paint (layer);
if (i == 0 && cogl_texture_is_sliced (tex_handle)) if (i == 0 && cogl_texture_is_sliced (tex_handle))
{ {

View File

@ -385,11 +385,12 @@ _cogl_sub_texture_set_filters (CoglTexture *tex,
} }
static void static void
_cogl_sub_texture_ensure_mipmaps (CoglTexture *tex) _cogl_sub_texture_pre_paint (CoglTexture *tex,
CoglTexturePrePaintFlags flags)
{ {
CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
_cogl_texture_ensure_mipmaps (sub_tex->full_texture); _cogl_texture_pre_paint (sub_tex->full_texture, flags);
} }
static void static void
@ -551,7 +552,7 @@ cogl_sub_texture_vtable =
_cogl_sub_texture_transform_quad_coords_to_gl, _cogl_sub_texture_transform_quad_coords_to_gl,
_cogl_sub_texture_get_gl_texture, _cogl_sub_texture_get_gl_texture,
_cogl_sub_texture_set_filters, _cogl_sub_texture_set_filters,
_cogl_sub_texture_ensure_mipmaps, _cogl_sub_texture_pre_paint,
_cogl_sub_texture_ensure_non_quad_rendering, _cogl_sub_texture_ensure_non_quad_rendering,
_cogl_sub_texture_set_wrap_mode_parameters, _cogl_sub_texture_set_wrap_mode_parameters,
_cogl_sub_texture_get_format, _cogl_sub_texture_get_format,

View File

@ -1400,13 +1400,18 @@ _cogl_texture_2d_sliced_set_filters (CoglTexture *tex,
} }
static void static void
_cogl_texture_2d_sliced_ensure_mipmaps (CoglTexture *tex) _cogl_texture_2d_sliced_pre_paint (CoglTexture *tex,
CoglTexturePrePaintFlags flags)
{ {
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
int i; int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* We only care about the mipmap flag */
if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) == 0)
return;
/* Only update if the mipmaps are dirty */ /* Only update if the mipmaps are dirty */
if (!tex_2ds->auto_mipmap || !tex_2ds->mipmaps_dirty) if (!tex_2ds->auto_mipmap || !tex_2ds->mipmaps_dirty)
return; return;
@ -1757,7 +1762,7 @@ cogl_texture_2d_sliced_vtable =
_cogl_texture_2d_sliced_transform_quad_coords_to_gl, _cogl_texture_2d_sliced_transform_quad_coords_to_gl,
_cogl_texture_2d_sliced_get_gl_texture, _cogl_texture_2d_sliced_get_gl_texture,
_cogl_texture_2d_sliced_set_filters, _cogl_texture_2d_sliced_set_filters,
_cogl_texture_2d_sliced_ensure_mipmaps, _cogl_texture_2d_sliced_pre_paint,
_cogl_texture_2d_sliced_ensure_non_quad_rendering, _cogl_texture_2d_sliced_ensure_non_quad_rendering,
_cogl_texture_2d_sliced_set_wrap_mode_parameters, _cogl_texture_2d_sliced_set_wrap_mode_parameters,
_cogl_texture_2d_sliced_get_format, _cogl_texture_2d_sliced_get_format,

View File

@ -414,16 +414,16 @@ _cogl_texture_2d_set_filters (CoglTexture *tex,
} }
static void static void
_cogl_texture_2d_ensure_mipmaps (CoglTexture *tex) _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
{ {
CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Only update if the mipmaps are dirty */ /* Only update if the mipmaps are dirty */
if (!tex_2d->auto_mipmap || !tex_2d->mipmaps_dirty) if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) &&
return; tex_2d->auto_mipmap && tex_2d->mipmaps_dirty)
{
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D, _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture, tex_2d->gl_texture,
FALSE); FALSE);
@ -433,6 +433,7 @@ _cogl_texture_2d_ensure_mipmaps (CoglTexture *tex)
_cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D); _cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D);
tex_2d->mipmaps_dirty = FALSE; tex_2d->mipmaps_dirty = FALSE;
}
} }
static void static void
@ -656,7 +657,7 @@ cogl_texture_2d_vtable =
_cogl_texture_2d_transform_quad_coords_to_gl, _cogl_texture_2d_transform_quad_coords_to_gl,
_cogl_texture_2d_get_gl_texture, _cogl_texture_2d_get_gl_texture,
_cogl_texture_2d_set_filters, _cogl_texture_2d_set_filters,
_cogl_texture_2d_ensure_mipmaps, _cogl_texture_2d_pre_paint,
_cogl_texture_2d_ensure_non_quad_rendering, _cogl_texture_2d_ensure_non_quad_rendering,
_cogl_texture_2d_set_wrap_mode_parameters, _cogl_texture_2d_set_wrap_mode_parameters,
_cogl_texture_2d_get_format, _cogl_texture_2d_get_format,

View File

@ -55,6 +55,14 @@ typedef enum {
COGL_TRANSFORM_SOFTWARE_REPEAT, COGL_TRANSFORM_SOFTWARE_REPEAT,
} CoglTransformResult; } CoglTransformResult;
/* Flags given to the pre_paint method */
typedef enum {
/* The texture is going to be used with filters that require
mipmapping. This gives the texture the opportunity to
automatically update the mipmap tree */
COGL_TEXTURE_NEEDS_MIPMAP = 1
} CoglTexturePrePaintFlags;
struct _CoglTextureVtable struct _CoglTextureVtable
{ {
/* Virtual functions that must be implemented for a texture /* Virtual functions that must be implemented for a texture
@ -106,7 +114,7 @@ struct _CoglTextureVtable
GLenum min_filter, GLenum min_filter,
GLenum mag_filter); GLenum mag_filter);
void (* ensure_mipmaps) (CoglTexture *tex); void (* pre_paint) (CoglTexture *tex, CoglTexturePrePaintFlags flags);
void (* ensure_non_quad_rendering) (CoglTexture *tex); void (* ensure_non_quad_rendering) (CoglTexture *tex);
void (* set_wrap_mode_parameters) (CoglTexture *tex, void (* set_wrap_mode_parameters) (CoglTexture *tex,
@ -189,7 +197,7 @@ _cogl_texture_set_filters (CoglHandle handle,
GLenum mag_filter); GLenum mag_filter);
void void
_cogl_texture_ensure_mipmaps (CoglHandle handle); _cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags);
void void
_cogl_texture_ensure_non_quad_rendering (CoglHandle handle); _cogl_texture_ensure_non_quad_rendering (CoglHandle handle);

View File

@ -785,7 +785,7 @@ _cogl_texture_set_filters (CoglHandle handle,
} }
void void
_cogl_texture_ensure_mipmaps (CoglHandle handle) _cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags)
{ {
CoglTexture *tex; CoglTexture *tex;
@ -794,7 +794,7 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle)
tex = COGL_TEXTURE (handle); tex = COGL_TEXTURE (handle);
tex->vtable->ensure_mipmaps (tex); tex->vtable->pre_paint (tex, flags);
} }
void void

View File

@ -1669,7 +1669,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
* could completely change if it needs to be migrated out of the * could completely change if it needs to be migrated out of the
* atlas and will affect how we validate the layer. * atlas and will affect how we validate the layer.
*/ */
_cogl_material_layer_ensure_mipmaps (layer); _cogl_material_layer_pre_paint (layer);
if (!_cogl_texture_can_hardware_repeat (tex_handle)) if (!_cogl_texture_can_hardware_repeat (tex_handle))
{ {