2008-11-07 Matthew Allum <mallum@linux.intel.com>

* 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.
This commit is contained in:
Matthew Allum 2008-11-07 16:31:56 +00:00
parent b6cc701930
commit c7c5cf9bd4
8 changed files with 104 additions and 11 deletions

View File

@ -1,3 +1,17 @@
2008-11-07 Matthew Allum <mallum@linux.intel.com>
* 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 <neil@linux.intel.com>
Bug 1230 - Pick fails on low precision color buffers

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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++;
}
}

View File

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