clutter/offscreen-effect: Use paint nodes to paint target
Add a new ClutterPaintNode parameter to the paint_target() vfunc. For now, create a temporary ClutterEffectNode that is passed to paint_target() and immediately painted; next commits will move this to upper layers. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
This commit is contained in:
parent
691d31748a
commit
26c1a5eedf
@ -58,9 +58,12 @@
|
|||||||
|
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
|
|
||||||
|
#include "clutter-color.h"
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
#include "clutter-enum-types.h"
|
#include "clutter-enum-types.h"
|
||||||
#include "clutter-offscreen-effect-private.h"
|
#include "clutter-offscreen-effect-private.h"
|
||||||
|
#include "clutter-paint-node.h"
|
||||||
|
#include "clutter-paint-nodes.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
|
|
||||||
#define DEFAULT_N_TILES 32
|
#define DEFAULT_N_TILES 32
|
||||||
@ -166,14 +169,13 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
|
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
|
||||||
ClutterDeformEffectPrivate *priv = self->priv;
|
ClutterDeformEffectPrivate *priv = self->priv;
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
CoglDepthState depth_state;
|
CoglDepthState depth_state;
|
||||||
CoglFramebuffer *fb =
|
|
||||||
clutter_paint_context_get_framebuffer (paint_context);
|
|
||||||
|
|
||||||
if (priv->is_dirty)
|
if (priv->is_dirty)
|
||||||
{
|
{
|
||||||
@ -285,11 +287,21 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
|
|
||||||
/* draw the front */
|
/* draw the front */
|
||||||
if (pipeline != NULL)
|
if (pipeline != NULL)
|
||||||
cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);
|
{
|
||||||
|
ClutterPaintNode *front_node;
|
||||||
|
|
||||||
|
front_node = clutter_pipeline_node_new (pipeline);
|
||||||
|
clutter_paint_node_set_static_name (front_node,
|
||||||
|
"ClutterDeformEffect (front)");
|
||||||
|
clutter_paint_node_add_child (node, front_node);
|
||||||
|
clutter_paint_node_add_primitive (front_node, priv->primitive);
|
||||||
|
clutter_paint_node_unref (front_node);
|
||||||
|
}
|
||||||
|
|
||||||
/* draw the back */
|
/* draw the back */
|
||||||
if (priv->back_pipeline != NULL)
|
if (priv->back_pipeline != NULL)
|
||||||
{
|
{
|
||||||
|
ClutterPaintNode *back_node;
|
||||||
CoglPipeline *back_pipeline;
|
CoglPipeline *back_pipeline;
|
||||||
|
|
||||||
/* We probably shouldn't be modifying the user's material so
|
/* We probably shouldn't be modifying the user's material so
|
||||||
@ -299,20 +311,30 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
cogl_pipeline_set_cull_face_mode (back_pipeline,
|
cogl_pipeline_set_cull_face_mode (back_pipeline,
|
||||||
COGL_PIPELINE_CULL_FACE_MODE_FRONT);
|
COGL_PIPELINE_CULL_FACE_MODE_FRONT);
|
||||||
|
|
||||||
cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);
|
|
||||||
|
|
||||||
|
back_node = clutter_pipeline_node_new (back_pipeline);
|
||||||
|
clutter_paint_node_set_static_name (back_node,
|
||||||
|
"ClutterDeformEffect (back)");
|
||||||
|
clutter_paint_node_add_child (node, back_node);
|
||||||
|
clutter_paint_node_add_primitive (back_node, priv->primitive);
|
||||||
|
|
||||||
|
clutter_paint_node_unref (back_node);
|
||||||
cogl_object_unref (back_pipeline);
|
cogl_object_unref (back_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (priv->lines_primitive != NULL))
|
if (G_UNLIKELY (priv->lines_primitive != NULL))
|
||||||
{
|
{
|
||||||
CoglContext *ctx =
|
const ClutterColor *red;
|
||||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
ClutterPaintNode *lines_node;
|
||||||
CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
|
|
||||||
cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
|
red = clutter_color_get_static (CLUTTER_COLOR_RED);
|
||||||
cogl_framebuffer_draw_primitive (fb, lines_pipeline,
|
|
||||||
priv->lines_primitive);
|
lines_node = clutter_color_node_new (red);
|
||||||
cogl_object_unref (lines_pipeline);
|
clutter_paint_node_set_static_name (lines_node,
|
||||||
|
"ClutterDeformEffect (lines)");
|
||||||
|
clutter_paint_node_add_child (node, lines_node);
|
||||||
|
clutter_paint_node_add_primitive (lines_node, priv->lines_primitive);
|
||||||
|
clutter_paint_node_unref (lines_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@
|
|||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-stage-private.h"
|
#include "clutter-stage-private.h"
|
||||||
#include "clutter-paint-context-private.h"
|
#include "clutter-paint-context-private.h"
|
||||||
|
#include "clutter-paint-node-private.h"
|
||||||
|
#include "clutter-paint-nodes.h"
|
||||||
#include "clutter-paint-volume-private.h"
|
#include "clutter-paint-volume-private.h"
|
||||||
#include "clutter-actor-box-private.h"
|
#include "clutter-actor-box-private.h"
|
||||||
|
|
||||||
@ -386,11 +388,11 @@ disable_effect:
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
|
clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
ClutterOffscreenEffectPrivate *priv = effect->priv;
|
ClutterOffscreenEffectPrivate *priv = effect->priv;
|
||||||
CoglFramebuffer *framebuffer =
|
ClutterPaintNode *pipeline_node;
|
||||||
clutter_paint_context_get_framebuffer (paint_context);
|
|
||||||
guint8 paint_opacity;
|
guint8 paint_opacity;
|
||||||
|
|
||||||
paint_opacity = clutter_actor_get_paint_opacity (priv->actor);
|
paint_opacity = clutter_actor_get_paint_opacity (priv->actor);
|
||||||
@ -401,18 +403,24 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
paint_opacity,
|
paint_opacity,
|
||||||
paint_opacity);
|
paint_opacity);
|
||||||
|
|
||||||
|
pipeline_node = clutter_pipeline_node_new (priv->pipeline);
|
||||||
|
clutter_paint_node_set_static_name (pipeline_node,
|
||||||
|
"ClutterOffscreenEffect (pipeline)");
|
||||||
|
clutter_paint_node_add_child (node, pipeline_node);
|
||||||
|
|
||||||
/* At this point we are in stage coordinates translated so if
|
/* At this point we are in stage coordinates translated so if
|
||||||
* we draw our texture using a textured quad the size of the paint
|
* we draw our texture using a textured quad the size of the paint
|
||||||
* box then we will overlay where the actor would have drawn if it
|
* box then we will overlay where the actor would have drawn if it
|
||||||
* hadn't been redirected offscreen.
|
* hadn't been redirected offscreen.
|
||||||
*/
|
*/
|
||||||
cogl_framebuffer_draw_textured_rectangle (framebuffer,
|
clutter_paint_node_add_rectangle (pipeline_node,
|
||||||
priv->pipeline,
|
&(ClutterActorBox) {
|
||||||
0, 0,
|
0.f, 0.f,
|
||||||
cogl_texture_get_width (priv->texture),
|
cogl_texture_get_width (priv->texture),
|
||||||
cogl_texture_get_height (priv->texture),
|
cogl_texture_get_height (priv->texture),
|
||||||
0.0, 0.0,
|
});
|
||||||
1.0, 1.0);
|
|
||||||
|
clutter_paint_node_unref (pipeline_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -626,10 +634,17 @@ void
|
|||||||
clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
|
clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
|
ClutterPaintNode *node;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect));
|
g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect));
|
||||||
|
|
||||||
|
node = clutter_effect_node_new (CLUTTER_EFFECT (effect));
|
||||||
|
|
||||||
CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect,
|
CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect,
|
||||||
|
node,
|
||||||
paint_context);
|
paint_context);
|
||||||
|
clutter_paint_node_paint (node, paint_context);
|
||||||
|
clutter_paint_node_unref (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +82,7 @@ struct _ClutterOffscreenEffectClass
|
|||||||
CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect,
|
CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect,
|
||||||
CoglTexture *texture);
|
CoglTexture *texture);
|
||||||
void (* paint_target) (ClutterOffscreenEffect *effect,
|
void (* paint_target) (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context);
|
ClutterPaintContext *paint_context);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
@ -384,6 +384,7 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect);
|
ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect);
|
||||||
@ -414,7 +415,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
out:
|
out:
|
||||||
/* paint the offscreen buffer */
|
/* paint the offscreen buffer */
|
||||||
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class);
|
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class);
|
||||||
parent->paint_target (effect, paint_context);
|
parent->paint_target (effect, node, paint_context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ G_DEFINE_TYPE (FooOldShaderEffect,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
|
clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
|
||||||
@ -47,7 +48,7 @@ foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
1.0f, 0.0f, 0.0f);
|
1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
|
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
|
||||||
paint_target (effect, paint_context);
|
paint_target (effect, node, paint_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -112,6 +113,7 @@ foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||||
|
ClutterPaintNode *node,
|
||||||
ClutterPaintContext *paint_context)
|
ClutterPaintContext *paint_context)
|
||||||
{
|
{
|
||||||
clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
|
clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
|
||||||
@ -120,7 +122,7 @@ foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect,
|
|||||||
0.0f, 1.0f, 0.0f);
|
0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
|
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
|
||||||
paint_target (effect, paint_context);
|
paint_target (effect, node, paint_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user