From 82e63a47536e6151e3678df8ac4e47935683b7c8 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Wed, 9 Jun 2010 17:39:59 +0100 Subject: [PATCH] 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. --- cogl/cogl-atlas-texture.c | 13 +++++++------ cogl/cogl-material-private.h | 7 ++++--- cogl/cogl-material.c | 33 ++++++++++++++++----------------- cogl/cogl-primitives.c | 4 ++-- cogl/cogl-sub-texture.c | 7 ++++--- cogl/cogl-texture-2d-sliced.c | 9 +++++++-- cogl/cogl-texture-2d.c | 27 ++++++++++++++------------- cogl/cogl-texture-private.h | 12 ++++++++++-- cogl/cogl-texture.c | 4 ++-- cogl/cogl-vertex-buffer.c | 2 +- 10 files changed, 67 insertions(+), 51 deletions(-) diff --git a/cogl/cogl-atlas-texture.c b/cogl/cogl-atlas-texture.c index 5f2d1b373..1f32a04bc 100644 --- a/cogl/cogl-atlas-texture.c +++ b/cogl/cogl-atlas-texture.c @@ -407,16 +407,17 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex) } 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); - /* 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); + if ((flags & COGL_TEXTURE_NEEDS_MIPMAP)) + /* 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); /* 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 @@ -1081,7 +1082,7 @@ cogl_atlas_texture_vtable = _cogl_atlas_texture_transform_quad_coords_to_gl, _cogl_atlas_texture_get_gl_texture, _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_set_wrap_mode_parameters, _cogl_atlas_texture_get_format, diff --git a/cogl/cogl-material-private.h b/cogl/cogl-material-private.h index 2a33e1a22..78c26b68c 100644 --- a/cogl/cogl-material-private.h +++ b/cogl/cogl-material-private.h @@ -629,11 +629,12 @@ gboolean _cogl_material_layer_has_user_matrix (CoglHandle layer_handle); /* - * Ensures the mipmaps are available for the texture in the layer if - * the filter settings would require it + * Calls the pre_paint method on the layer texture if there is + * one. This will determine whether mipmaps are needed based on the + * filter settings. */ void -_cogl_material_layer_ensure_mipmaps (CoglHandle layer_handler); +_cogl_material_layer_pre_paint (CoglHandle layer_handler); /* * CoglMaterialFlushFlag: diff --git a/cogl/cogl-material.c b/cogl/cogl-material.c index 99e09a293..12afde74c 100644 --- a/cogl/cogl-material.c +++ b/cogl/cogl-material.c @@ -4877,15 +4877,6 @@ _cogl_material_layer_has_user_matrix (CoglHandle handle) 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 _cogl_material_layer_get_filters (CoglMaterialLayer *layer, CoglMaterialFilter *min_filter, @@ -4900,23 +4891,31 @@ _cogl_material_layer_get_filters (CoglMaterialLayer *layer, } void -_cogl_material_layer_ensure_mipmaps (CoglHandle handle) +_cogl_material_layer_pre_paint (CoglHandle handle) { CoglMaterialLayer *layer = COGL_MATERIAL_LAYER (handle); CoglMaterialLayer *texture_authority; - CoglMaterialFilter min_filter; - CoglMaterialFilter mag_filter; texture_authority = _cogl_material_layer_get_authority (layer, COGL_MATERIAL_LAYER_STATE_TEXTURE); - _cogl_material_layer_get_filters (layer, &min_filter, &mag_filter); + if (texture_authority->texture != COGL_INVALID_HANDLE) + { + CoglTexturePrePaintFlags flags = 0; + CoglMaterialFilter min_filter; + CoglMaterialFilter mag_filter; - if (texture_authority->texture != COGL_INVALID_HANDLE && - (is_mipmap_filter (min_filter) || - is_mipmap_filter (mag_filter))) - _cogl_texture_ensure_mipmaps (texture_authority->texture); + _cogl_material_layer_get_filters (layer, &min_filter, &mag_filter); + + if (min_filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST + || min_filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST + || min_filter == COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR + || min_filter == COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR) + flags |= COGL_TEXTURE_NEEDS_MIPMAP; + + _cogl_texture_pre_paint (layer->texture, flags); + } } CoglMaterialFilter diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c index cae19e5e9..708130a95 100644 --- a/cogl/cogl-primitives.c +++ b/cogl/cogl-primitives.c @@ -561,7 +561,7 @@ _cogl_rectangles_with_multitexture_coords ( * sure the referenced texture is migrated out of the atlas and * mipmaps are generated.) */ - _cogl_material_layer_ensure_mipmaps (layer); + _cogl_material_layer_pre_paint (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 * 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)) { diff --git a/cogl/cogl-sub-texture.c b/cogl/cogl-sub-texture.c index fd6346d9a..8fbcc4dca 100644 --- a/cogl/cogl-sub-texture.c +++ b/cogl/cogl-sub-texture.c @@ -385,11 +385,12 @@ _cogl_sub_texture_set_filters (CoglTexture *tex, } 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); - _cogl_texture_ensure_mipmaps (sub_tex->full_texture); + _cogl_texture_pre_paint (sub_tex->full_texture, flags); } static void @@ -551,7 +552,7 @@ cogl_sub_texture_vtable = _cogl_sub_texture_transform_quad_coords_to_gl, _cogl_sub_texture_get_gl_texture, _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_set_wrap_mode_parameters, _cogl_sub_texture_get_format, diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c index 9049db5d8..2a41721ba 100644 --- a/cogl/cogl-texture-2d-sliced.c +++ b/cogl/cogl-texture-2d-sliced.c @@ -1400,13 +1400,18 @@ _cogl_texture_2d_sliced_set_filters (CoglTexture *tex, } 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); int i; _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 */ if (!tex_2ds->auto_mipmap || !tex_2ds->mipmaps_dirty) return; @@ -1757,7 +1762,7 @@ cogl_texture_2d_sliced_vtable = _cogl_texture_2d_sliced_transform_quad_coords_to_gl, _cogl_texture_2d_sliced_get_gl_texture, _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_set_wrap_mode_parameters, _cogl_texture_2d_sliced_get_format, diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c index b3296419e..d4d6c8aa2 100644 --- a/cogl/cogl-texture-2d.c +++ b/cogl/cogl-texture-2d.c @@ -414,25 +414,26 @@ _cogl_texture_2d_set_filters (CoglTexture *tex, } 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); _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* Only update if the mipmaps are dirty */ - if (!tex_2d->auto_mipmap || !tex_2d->mipmaps_dirty) - return; + if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && + tex_2d->auto_mipmap && tex_2d->mipmaps_dirty) + { + _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, + tex_2d->gl_texture, + FALSE); + /* glGenerateMipmap is defined in the FBO extension. We only allow + CoglTexture2D instances to be created if this feature is + available so we don't need to check for the extension */ + _cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D); - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - FALSE); - /* glGenerateMipmap is defined in the FBO extension. We only allow - CoglTexture2D instances to be created if this feature is - available so we don't need to check for the extension */ - _cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D); - - tex_2d->mipmaps_dirty = FALSE; + tex_2d->mipmaps_dirty = FALSE; + } } static void @@ -656,7 +657,7 @@ cogl_texture_2d_vtable = _cogl_texture_2d_transform_quad_coords_to_gl, _cogl_texture_2d_get_gl_texture, _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_set_wrap_mode_parameters, _cogl_texture_2d_get_format, diff --git a/cogl/cogl-texture-private.h b/cogl/cogl-texture-private.h index a8b4cc079..56b109951 100644 --- a/cogl/cogl-texture-private.h +++ b/cogl/cogl-texture-private.h @@ -55,6 +55,14 @@ typedef enum { COGL_TRANSFORM_SOFTWARE_REPEAT, } 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 { /* Virtual functions that must be implemented for a texture @@ -106,7 +114,7 @@ struct _CoglTextureVtable GLenum min_filter, GLenum mag_filter); - void (* ensure_mipmaps) (CoglTexture *tex); + void (* pre_paint) (CoglTexture *tex, CoglTexturePrePaintFlags flags); void (* ensure_non_quad_rendering) (CoglTexture *tex); void (* set_wrap_mode_parameters) (CoglTexture *tex, @@ -189,7 +197,7 @@ _cogl_texture_set_filters (CoglHandle handle, GLenum mag_filter); void -_cogl_texture_ensure_mipmaps (CoglHandle handle); +_cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags); void _cogl_texture_ensure_non_quad_rendering (CoglHandle handle); diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c index 64f7c54eb..9dea40e64 100644 --- a/cogl/cogl-texture.c +++ b/cogl/cogl-texture.c @@ -785,7 +785,7 @@ _cogl_texture_set_filters (CoglHandle handle, } void -_cogl_texture_ensure_mipmaps (CoglHandle handle) +_cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags) { CoglTexture *tex; @@ -794,7 +794,7 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle) tex = COGL_TEXTURE (handle); - tex->vtable->ensure_mipmaps (tex); + tex->vtable->pre_paint (tex, flags); } void diff --git a/cogl/cogl-vertex-buffer.c b/cogl/cogl-vertex-buffer.c index fbbc2febc..a25c26bbd 100644 --- a/cogl/cogl-vertex-buffer.c +++ b/cogl/cogl-vertex-buffer.c @@ -1669,7 +1669,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) * could completely change if it needs to be migrated out of the * 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)) {