diff --git a/ChangeLog b/ChangeLog index febaa2134..f5972f1eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-11-07 Matthew Allum + + * clutter/clutter-actor.c: + * clutter/clutter-actor.h: + * clutter/clutter-clone-texture.c: + * clutter/clutter-private.h: + * clutter/clutter-texture.c: + * clutter/x11/clutter-x11-texture-pixmap.c: + + Attempt to lower overhead of updating TFP's (particularly mipmaped). + Compresses mipmap updates only for visible TFPs. + Avoiding updates for non visible TFP's whilst keeping visible + clones working ok. + 2008-11-06 Neil Roberts Bug 1230 - Pick fails on low precision color buffers diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index d2a78da89..75147fcef 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -5686,6 +5686,30 @@ clutter_actor_get_parent (ClutterActor *self) return self->priv->parent_actor; } +/** + * clutter_actor_get_paint_visibility: + * @self: A #ClutterActor + * + * Retrieves the 'paint' visibility of an actor recursively checking for non + * visible parents. + * + * Return Value: TRUE if the actor is visibile and will be painted. + * + * Since: 0.8.4 + */ +gboolean +clutter_actor_get_paint_visibility (ClutterActor *actor) +{ + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); + + while (actor + && !(CLUTTER_PRIVATE_FLAGS (actor) & CLUTTER_ACTOR_IS_TOPLEVEL) + && CLUTTER_ACTOR_IS_VISIBLE (actor)) + actor = clutter_actor_get_parent (actor); + + return (CLUTTER_PRIVATE_FLAGS (actor) & CLUTTER_ACTOR_IS_TOPLEVEL); +} + /** * clutter_actor_unparent: * @self: a #ClutterActor diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 371ce20cc..5b25de576 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -553,6 +553,8 @@ void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, ClutterVertex *point, ClutterVertex *vertex); +gboolean clutter_actor_get_paint_visibility (ClutterActor *self); + G_END_DECLS #endif /* _HAVE_CLUTTER_ACTOR_H */ diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c index b5081a4bf..9b299e7b0 100644 --- a/clutter/clutter-clone-texture.c +++ b/clutter/clutter-clone-texture.c @@ -165,6 +165,19 @@ clutter_clone_texture_paint (ClutterActor *self) if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) clutter_actor_realize (parent_texture); + /* If 'parent' texture isn't visible we run its paint to be sure it + * updates. Needed for TFP and likely FBOs. + * Potentially could cause issues + */ + if (!clutter_actor_get_paint_visibility(parent_texture)) + { + CLUTTER_SET_PRIVATE_FLAGS(parent_texture, + CLUTTER_TEXTURE_IN_CLONE_PAINT); + g_signal_emit_by_name (priv->parent_texture, "paint", NULL); + CLUTTER_UNSET_PRIVATE_FLAGS(parent_texture, + CLUTTER_TEXTURE_IN_CLONE_PAINT); + } + cogl_color_set_from_4ub (&col, 255, 255, 255, clutter_actor_get_paint_opacity (self)); cogl_color (&col); diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 74aac64aa..81e030adf 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -59,8 +59,9 @@ typedef enum { * viewport / perspective etc * needs (re)setting. */ - CLUTTER_ACTOR_IN_PAINT = 1 << 4, /* Used to avoid recursion */ - CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5 /* Used to avoid recursion */ + CLUTTER_ACTOR_IN_PAINT = 1 << 4, /* Used to avoid recursion */ + CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5, /* Used to avoid recursion */ + CLUTTER_TEXTURE_IN_CLONE_PAINT = 1 << 6 /* Used for safety in clones */ } ClutterPrivateFlags; typedef enum { diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 5182142aa..b790358b6 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -572,6 +572,13 @@ clutter_texture_paint (ClutterActor *self) clutter_shader_set_is_enabled (shader, TRUE); } + /* A clone may need to fire above if were a TFP/FBO but not visible. + * Ultimatly needs some reworking with maybe an extra prepare_paint + * method or some such. + */ + if (CLUTTER_PRIVATE_FLAGS(self) & CLUTTER_TEXTURE_IN_CLONE_PAINT) + return; + CLUTTER_NOTE (PAINT, "painting texture '%s'", clutter_actor_get_name (self) ? clutter_actor_get_name (self) diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index 3ae6f54f8..a76ff30d9 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -85,6 +85,7 @@ struct _ClutterGLXTexturePixmapPrivate gboolean bound; gint can_mipmap; + gint mipmap_generate_queued; }; static void @@ -130,6 +131,29 @@ texture_bind (ClutterGLXTexturePixmap *tex) return TRUE; } +static void +on_glx_texture_pixmap_pre_paint (ClutterGLXTexturePixmap *texture, + gpointer user_data) +{ + if (texture->priv->mipmap_generate_queued) + { + GLuint handle = 0; + GLenum target = 0; + CoglHandle cogl_tex; + cogl_tex = clutter_texture_get_cogl_texture + (CLUTTER_TEXTURE(texture)); + + texture_bind (texture); + + cogl_texture_get_gl_texture (cogl_tex, &handle, &target); + + _gl_generate_mipmap (target); + + texture->priv->mipmap_generate_queued = 0; + } + +} + static void clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self) { @@ -140,6 +164,10 @@ clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self) CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, ClutterGLXTexturePixmapPrivate); + g_signal_connect (CLUTTER_ACTOR(self), + "paint", G_CALLBACK (on_glx_texture_pixmap_pre_paint), + NULL); + if (_ext_check_done == FALSE) { const gchar *glx_extensions = NULL; @@ -580,6 +608,15 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) CLUTTER_NOTE (TEXTURE, "Created GLXPixmap"); + /* Get ready to queue initial mipmap generation */ + if (_gl_generate_mipmap + && priv->can_mipmap + && clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)) + == CLUTTER_TEXTURE_QUALITY_HIGH) + { + priv->mipmap_generate_queued++; + } + return; } else @@ -656,15 +693,7 @@ clutter_glx_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, * to call generate mipmap * May break clones however.. */ - GLuint handle = 0; - GLenum target = 0; - CoglHandle cogl_tex; - cogl_tex = clutter_texture_get_cogl_texture - (CLUTTER_TEXTURE(texture)); - - cogl_texture_get_gl_texture (cogl_tex, &handle, &target); - - _gl_generate_mipmap (target); + priv->mipmap_generate_queued++; } } diff --git a/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/x11/clutter-x11-texture-pixmap.c index 1bfa9aff2..29f9d6798 100644 --- a/clutter/x11/clutter-x11-texture-pixmap.c +++ b/clutter/x11/clutter-x11-texture-pixmap.c @@ -1304,6 +1304,9 @@ clutter_x11_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, { g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); + if (!CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(texture))) + return; /* No need to update when not visible */ + g_signal_emit (texture, signals[UPDATE_AREA], 0, x, y, width, height); }