clutter/paint-context: Add content and target color state tracking
The initial target color state is the color state of the stage view being painted to. If we're painting to an arbitrary framebuffer, it's currently hard coded to sRGB/electrical. The content color state is not set on construction, but when starting to paint, it's set to the color state of the stage itself. Whenever an actor is painted, it'll set the color state to the color state of itself. The intention is that offscreen rendering pushes a target color state that causes painting to it to not necessarily be in the stage view color state. Pass color state with offscreen framebuffer, as this avoids hard coding sRGB in the lower level bits of paint contexts. It's still practically hard coded, only that it's derived from somewhere else (e.g. the stage or window actor). Nothing is actually using this yet, but will eventually. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3433>
This commit is contained in:
parent
1a52108c17
commit
b275af95b7
6 changed files with 131 additions and 10 deletions
|
@ -3460,6 +3460,8 @@ clutter_actor_paint (ClutterActor *self,
|
|||
}
|
||||
#endif
|
||||
|
||||
clutter_paint_context_push_color_state (paint_context, priv->color_state);
|
||||
|
||||
actor_node = clutter_actor_node_new (self, -1);
|
||||
root_node = clutter_paint_node_ref (actor_node);
|
||||
|
||||
|
@ -3574,7 +3576,7 @@ clutter_actor_paint (ClutterActor *self,
|
|||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS))
|
||||
_clutter_actor_paint_cull_result (self, success, result, actor_node);
|
||||
else if (result == CLUTTER_CULL_RESULT_OUT && success)
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (priv->effects == NULL)
|
||||
|
@ -3593,6 +3595,9 @@ clutter_actor_paint (ClutterActor *self,
|
|||
* unless a new redraw was queued up.
|
||||
*/
|
||||
priv->is_dirty = priv->propagated_one_redraw;
|
||||
|
||||
out:
|
||||
clutter_paint_context_pop_color_state (paint_context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,3 +34,8 @@ clutter_paint_context_get_clip_frusta (ClutterPaintContext *paint_context);
|
|||
|
||||
void clutter_paint_context_assign_frame (ClutterPaintContext *paint_context,
|
||||
ClutterFrame *frame);
|
||||
|
||||
void clutter_paint_context_push_target_color_state (ClutterPaintContext *paint_context,
|
||||
ClutterColorState *color_state);
|
||||
|
||||
void clutter_paint_context_pop_target_color_state (ClutterPaintContext *paint_context);
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-paint-context-private.h"
|
||||
|
||||
#include "clutter/clutter-color-state.h"
|
||||
#include "clutter/clutter-frame.h"
|
||||
#include "clutter/clutter-stage-view-private.h"
|
||||
|
||||
struct _ClutterPaintContext
|
||||
{
|
||||
|
@ -33,6 +36,11 @@ struct _ClutterPaintContext
|
|||
|
||||
MtkRegion *redraw_clip;
|
||||
GArray *clip_frusta;
|
||||
|
||||
GList *target_color_states;
|
||||
GList *color_states;
|
||||
|
||||
ClutterColorState *framebuffer_color_state;
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
|
||||
|
@ -46,6 +54,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
|||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
ClutterColorState *target_color_state;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
paint_context = g_new0 (ClutterPaintContext, 1);
|
||||
|
@ -54,6 +63,12 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
|||
paint_context->redraw_clip = mtk_region_copy (redraw_clip);
|
||||
paint_context->clip_frusta = g_array_ref (clip_frusta);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
g_set_object (&paint_context->framebuffer_color_state,
|
||||
clutter_stage_view_get_color_state (view));
|
||||
|
||||
target_color_state = paint_context->framebuffer_color_state;
|
||||
clutter_paint_context_push_target_color_state (paint_context,
|
||||
target_color_state);
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
|
@ -65,15 +80,22 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
|||
* clutter_paint_context_new_for_framebuffer: (skip)
|
||||
*/
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const MtkRegion *redraw_clip,
|
||||
ClutterPaintFlag paint_flags)
|
||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const MtkRegion *redraw_clip,
|
||||
ClutterPaintFlag paint_flags,
|
||||
ClutterColorState *color_state)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
ClutterColorState *target_color_state;
|
||||
|
||||
paint_context = g_new0 (ClutterPaintContext, 1);
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
g_set_object (&paint_context->framebuffer_color_state, color_state);
|
||||
|
||||
target_color_state = paint_context->framebuffer_color_state;
|
||||
clutter_paint_context_push_target_color_state (paint_context,
|
||||
target_color_state);
|
||||
|
||||
if (redraw_clip)
|
||||
paint_context->redraw_clip = mtk_region_copy (redraw_clip);
|
||||
|
@ -93,6 +115,14 @@ clutter_paint_context_ref (ClutterPaintContext *paint_context)
|
|||
static void
|
||||
clutter_paint_context_dispose (ClutterPaintContext *paint_context)
|
||||
{
|
||||
if (paint_context->framebuffer_color_state)
|
||||
{
|
||||
clutter_paint_context_pop_target_color_state (paint_context);
|
||||
g_clear_object (&paint_context->framebuffer_color_state);
|
||||
}
|
||||
|
||||
g_warn_if_fail (!paint_context->color_states);
|
||||
g_warn_if_fail (!paint_context->target_color_states);
|
||||
g_list_free_full (paint_context->framebuffers, g_object_unref);
|
||||
paint_context->framebuffers = NULL;
|
||||
g_clear_pointer (&paint_context->redraw_clip, mtk_region_unref);
|
||||
|
@ -229,3 +259,59 @@ clutter_paint_context_get_frame (ClutterPaintContext *paint_context)
|
|||
{
|
||||
return paint_context->frame;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_paint_context_push_target_color_state (ClutterPaintContext *paint_context,
|
||||
ClutterColorState *color_state)
|
||||
{
|
||||
paint_context->target_color_states =
|
||||
g_list_prepend (paint_context->target_color_states, color_state);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_paint_context_pop_target_color_state (ClutterPaintContext *paint_context)
|
||||
{
|
||||
g_return_if_fail (paint_context->target_color_states);
|
||||
|
||||
paint_context->target_color_states =
|
||||
g_list_delete_link (paint_context->target_color_states,
|
||||
paint_context->target_color_states);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_paint_context_push_color_state (ClutterPaintContext *paint_context,
|
||||
ClutterColorState *color_state)
|
||||
{
|
||||
paint_context->color_states = g_list_prepend (paint_context->color_states,
|
||||
color_state);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_paint_context_pop_color_state (ClutterPaintContext *paint_context)
|
||||
{
|
||||
g_return_if_fail (paint_context->color_states);
|
||||
|
||||
paint_context->color_states =
|
||||
g_list_delete_link (paint_context->color_states,
|
||||
paint_context->color_states);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_context_get_target_color_state: (skip)
|
||||
*/
|
||||
ClutterColorState *
|
||||
clutter_paint_context_get_target_color_state (ClutterPaintContext *paint_context)
|
||||
{
|
||||
return CLUTTER_COLOR_STATE (paint_context->target_color_states->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_context_get_color_state: (skip)
|
||||
*/
|
||||
ClutterColorState *
|
||||
clutter_paint_context_get_color_state (ClutterPaintContext *paint_context)
|
||||
{
|
||||
g_return_val_if_fail (paint_context->color_states, NULL);
|
||||
|
||||
return CLUTTER_COLOR_STATE (paint_context->color_states->data);
|
||||
}
|
||||
|
|
|
@ -42,9 +42,10 @@ CLUTTER_EXPORT
|
|||
GType clutter_paint_context_get_type (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const MtkRegion *redraw_clip,
|
||||
ClutterPaintFlag paint_flags);
|
||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const MtkRegion *redraw_clip,
|
||||
ClutterPaintFlag paint_flags,
|
||||
ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context);
|
||||
|
@ -77,4 +78,17 @@ ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *pai
|
|||
CLUTTER_EXPORT
|
||||
ClutterFrame * clutter_paint_context_get_frame (ClutterPaintContext *paint_context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_paint_context_push_color_state (ClutterPaintContext *paint_context,
|
||||
ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_paint_context_pop_color_state (ClutterPaintContext *paint_context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_paint_context_get_target_color_state (ClutterPaintContext *paint_context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_paint_context_get_color_state (ClutterPaintContext *paint_context);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref)
|
||||
|
|
|
@ -455,11 +455,16 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
|||
|
||||
fb = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
clutter_paint_context_push_color_state (paint_context,
|
||||
clutter_actor_get_color_state (CLUTTER_ACTOR (stage)));
|
||||
|
||||
root_node = clutter_root_node_new (fb, &bg_color, COGL_BUFFER_BIT_DEPTH);
|
||||
clutter_paint_node_set_static_name (root_node, "Stage (root)");
|
||||
clutter_paint_node_paint (root_node, paint_context);
|
||||
clutter_paint_node_unref (root_node);
|
||||
|
||||
clutter_paint_context_pop_color_state (paint_context);
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
}
|
||||
|
@ -2668,6 +2673,7 @@ clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
|||
ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage);
|
||||
ClutterPaintContext *paint_context;
|
||||
g_autoptr (MtkRegion) redraw_clip = NULL;
|
||||
ClutterColorState *color_state;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (PaintToFramebuffer,
|
||||
"Clutter::Stage::paint_to_framebuffer()");
|
||||
|
@ -2681,10 +2687,13 @@ clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
|||
}
|
||||
|
||||
redraw_clip = mtk_region_create_rectangle (rect);
|
||||
color_state =
|
||||
clutter_actor_get_color_state (CLUTTER_ACTOR (stage));
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer,
|
||||
redraw_clip,
|
||||
paint_flags);
|
||||
paint_flags,
|
||||
color_state);
|
||||
|
||||
cogl_framebuffer_push_matrix (framebuffer);
|
||||
cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
|
||||
|
|
|
@ -1481,7 +1481,8 @@ meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
|||
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
CLUTTER_PAINT_FLAG_NONE,
|
||||
clutter_actor_get_color_state (actor));
|
||||
clutter_actor_paint (actor, paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
|
||||
|
@ -1614,7 +1615,8 @@ create_framebuffer_from_window_actor (MetaWindowActor *self,
|
|||
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
CLUTTER_PAINT_FLAG_NONE,
|
||||
clutter_actor_get_color_state (actor));
|
||||
clutter_actor_paint (actor, paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
|
||||
|
|
Loading…
Reference in a new issue