shaped-texture: Put actual texture painting in helper
This is so that it can be reused later by meta_shaped_texture_get_image() for drawing via an offscreen framebuffer. https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
This commit is contained in:
parent
37e36e8208
commit
e1370ee209
@ -490,9 +490,11 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_shaped_texture_paint (ClutterActor *actor)
|
do_paint (MetaShapedTexture *stex,
|
||||||
|
CoglFramebuffer *fb,
|
||||||
|
CoglTexture *paint_tex,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
|
||||||
double tex_scale;
|
double tex_scale;
|
||||||
int dst_width, dst_height;
|
int dst_width, dst_height;
|
||||||
cairo_rectangle_int_t tex_rect;
|
cairo_rectangle_int_t tex_rect;
|
||||||
@ -502,63 +504,10 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
cairo_region_t *opaque_tex_region;
|
cairo_region_t *opaque_tex_region;
|
||||||
cairo_region_t *blended_tex_region;
|
cairo_region_t *blended_tex_region;
|
||||||
CoglContext *ctx;
|
CoglContext *ctx;
|
||||||
CoglFramebuffer *fb;
|
|
||||||
CoglTexture *paint_tex = NULL;
|
|
||||||
ClutterActorBox alloc;
|
ClutterActorBox alloc;
|
||||||
CoglPipelineFilter filter;
|
CoglPipelineFilter filter;
|
||||||
gint64 now = g_get_monotonic_time ();
|
|
||||||
|
|
||||||
if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
|
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
|
||||||
return;
|
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
|
||||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
|
||||||
|
|
||||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
|
||||||
* used together with SGIS_generate_mipmap, however this is very
|
|
||||||
* rarely supported. Also, even when it is supported there
|
|
||||||
* are distinct performance implications from:
|
|
||||||
*
|
|
||||||
* - Updating mipmaps that we don't need
|
|
||||||
* - Having to reallocate pixmaps on the server into larger buffers
|
|
||||||
*
|
|
||||||
* So, we just unconditionally use our mipmap emulation code. If we
|
|
||||||
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
|
||||||
* see if it was supported (no API currently), and then if and only
|
|
||||||
* if that was the case, set the clutter texture quality to HIGH.
|
|
||||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
|
||||||
* support for TFP textures will result in fallbacks to XGetImage.
|
|
||||||
*/
|
|
||||||
if (stex->create_mipmaps && stex->last_invalidation)
|
|
||||||
{
|
|
||||||
gint64 age = now - stex->last_invalidation;
|
|
||||||
|
|
||||||
if (age >= MIN_MIPMAP_AGE_USEC ||
|
|
||||||
stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
|
||||||
paint_tex = meta_texture_tower_get_paint_texture (stex->paint_tower);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paint_tex == NULL)
|
|
||||||
{
|
|
||||||
paint_tex = COGL_TEXTURE (stex->texture);
|
|
||||||
|
|
||||||
if (paint_tex == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (stex->create_mipmaps)
|
|
||||||
{
|
|
||||||
/* Minus 1000 to ensure we don't fail the age test in timeout */
|
|
||||||
stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
|
|
||||||
|
|
||||||
if (!stex->remipmap_timeout_id)
|
|
||||||
stex->remipmap_timeout_id =
|
|
||||||
g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
|
|
||||||
texture_is_idle_and_not_mipmapped,
|
|
||||||
stex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_actor_get_scale (actor, &tex_scale, NULL);
|
|
||||||
ensure_size_valid (stex);
|
ensure_size_valid (stex);
|
||||||
dst_width = stex->dst_width;
|
dst_width = stex->dst_width;
|
||||||
|
|
||||||
@ -568,8 +517,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
tex_rect = (cairo_rectangle_int_t) { 0, 0, dst_width, dst_height };
|
tex_rect = (cairo_rectangle_int_t) { 0, 0, dst_width, dst_height };
|
||||||
|
|
||||||
fb = cogl_get_draw_framebuffer ();
|
|
||||||
|
|
||||||
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
||||||
* improves performance, especially with software rendering.
|
* improves performance, especially with software rendering.
|
||||||
*/
|
*/
|
||||||
@ -583,8 +530,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
|
|
||||||
opacity = clutter_actor_get_paint_opacity (actor);
|
opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (stex));
|
||||||
clutter_actor_get_allocation_box (actor, &alloc);
|
clutter_actor_get_allocation_box (CLUTTER_ACTOR (stex), &alloc);
|
||||||
|
|
||||||
if (stex->opaque_region && opacity == 255)
|
if (stex->opaque_region && opacity == 255)
|
||||||
{
|
{
|
||||||
@ -600,10 +547,10 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
use_opaque_region = FALSE;
|
use_opaque_region = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stex->clip_region)
|
if (clip_region)
|
||||||
{
|
{
|
||||||
clip_tex_region =
|
clip_tex_region =
|
||||||
meta_region_scale_double (stex->clip_region,
|
meta_region_scale_double (clip_region,
|
||||||
1.0 / tex_scale,
|
1.0 / tex_scale,
|
||||||
META_ROUNDING_STRATEGY_GROW);
|
META_ROUNDING_STRATEGY_GROW);
|
||||||
}
|
}
|
||||||
@ -745,6 +692,74 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
|
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_shaped_texture_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
|
||||||
|
CoglTexture *paint_tex;
|
||||||
|
CoglFramebuffer *fb;
|
||||||
|
|
||||||
|
if (!stex->texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||||
|
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||||
|
|
||||||
|
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||||
|
* used together with SGIS_generate_mipmap, however this is very
|
||||||
|
* rarely supported. Also, even when it is supported there
|
||||||
|
* are distinct performance implications from:
|
||||||
|
*
|
||||||
|
* - Updating mipmaps that we don't need
|
||||||
|
* - Having to reallocate pixmaps on the server into larger buffers
|
||||||
|
*
|
||||||
|
* So, we just unconditionally use our mipmap emulation code. If we
|
||||||
|
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
||||||
|
* see if it was supported (no API currently), and then if and only
|
||||||
|
* if that was the case, set the clutter texture quality to HIGH.
|
||||||
|
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||||
|
* support for TFP textures will result in fallbacks to XGetImage.
|
||||||
|
*/
|
||||||
|
if (stex->create_mipmaps)
|
||||||
|
{
|
||||||
|
int64_t now = g_get_monotonic_time ();
|
||||||
|
int64_t age = now - stex->last_invalidation;
|
||||||
|
|
||||||
|
if (age >= MIN_MIPMAP_AGE_USEC ||
|
||||||
|
stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
||||||
|
{
|
||||||
|
paint_tex = meta_texture_tower_get_paint_texture (stex->paint_tower);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paint_tex = stex->texture;
|
||||||
|
|
||||||
|
/* Minus 1000 to ensure we don't fail the age test in timeout */
|
||||||
|
stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
|
||||||
|
|
||||||
|
if (!stex->remipmap_timeout_id)
|
||||||
|
stex->remipmap_timeout_id =
|
||||||
|
g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
|
||||||
|
texture_is_idle_and_not_mipmapped,
|
||||||
|
stex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paint_tex = COGL_TEXTURE (stex->texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cogl_texture_get_width (paint_tex) == 0 ||
|
||||||
|
cogl_texture_get_height (paint_tex) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fb = cogl_get_draw_framebuffer ();
|
||||||
|
do_paint (META_SHAPED_TEXTURE (actor), fb, paint_tex, stex->clip_region);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_shaped_texture_get_preferred_width (ClutterActor *self,
|
meta_shaped_texture_get_preferred_width (ClutterActor *self,
|
||||||
gfloat for_height,
|
gfloat for_height,
|
||||||
|
Loading…
Reference in New Issue
Block a user