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)) {