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 87240cd764
commit fd3a3e93bf
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
_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,

View File

@ -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:

View File

@ -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

View File

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

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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

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