forked from AuroraMiddleware/gtk
gsk: Introduce mask nodes
Add GskMaskNode, and support it in the render node parser, in the inspector and in GtkSnapshot. The rendering is just fallback for now. Based on old work by Timm Bäder.
This commit is contained in:
parent
d00d4c4475
commit
0d58e5365d
@ -270,6 +270,7 @@ collect_reused_child_nodes (GskRenderer *renderer,
|
|||||||
case GSK_BLEND_NODE:
|
case GSK_BLEND_NODE:
|
||||||
case GSK_CROSS_FADE_NODE:
|
case GSK_CROSS_FADE_NODE:
|
||||||
case GSK_BLUR_NODE:
|
case GSK_BLUR_NODE:
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
@ -846,6 +847,7 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
|
|||||||
}
|
}
|
||||||
break; /* Fallback */
|
break; /* Fallback */
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
case GSK_TEXTURE_SCALE_NODE:
|
case GSK_TEXTURE_SCALE_NODE:
|
||||||
case GSK_TEXT_NODE:
|
case GSK_TEXT_NODE:
|
||||||
case GSK_RADIAL_GRADIENT_NODE:
|
case GSK_RADIAL_GRADIENT_NODE:
|
||||||
|
@ -3869,6 +3869,10 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
|||||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||||
|
break;
|
||||||
|
|
||||||
case GSK_OPACITY_NODE:
|
case GSK_OPACITY_NODE:
|
||||||
gsk_gl_render_job_visit_opacity_node (job, node);
|
gsk_gl_render_job_visit_opacity_node (job, node);
|
||||||
break;
|
break;
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
* @GSK_ROUNDED_CLIP_NODE: A node that clips its child to a rounded rectangle
|
* @GSK_ROUNDED_CLIP_NODE: A node that clips its child to a rounded rectangle
|
||||||
* @GSK_SHADOW_NODE: A node that draws a shadow below its child
|
* @GSK_SHADOW_NODE: A node that draws a shadow below its child
|
||||||
* @GSK_BLEND_NODE: A node that blends two children together
|
* @GSK_BLEND_NODE: A node that blends two children together
|
||||||
|
* @GSK_MASK_NODE: A node that masks one child with another
|
||||||
* @GSK_CROSS_FADE_NODE: A node that cross-fades between two children
|
* @GSK_CROSS_FADE_NODE: A node that cross-fades between two children
|
||||||
* @GSK_TEXT_NODE: A node containing a glyph string
|
* @GSK_TEXT_NODE: A node containing a glyph string
|
||||||
* @GSK_BLUR_NODE: A node that applies a blur
|
* @GSK_BLUR_NODE: A node that applies a blur
|
||||||
@ -77,6 +78,7 @@ typedef enum {
|
|||||||
GSK_ROUNDED_CLIP_NODE,
|
GSK_ROUNDED_CLIP_NODE,
|
||||||
GSK_SHADOW_NODE,
|
GSK_SHADOW_NODE,
|
||||||
GSK_BLEND_NODE,
|
GSK_BLEND_NODE,
|
||||||
|
GSK_MASK_NODE,
|
||||||
GSK_CROSS_FADE_NODE,
|
GSK_CROSS_FADE_NODE,
|
||||||
GSK_TEXT_NODE,
|
GSK_TEXT_NODE,
|
||||||
GSK_BLUR_NODE,
|
GSK_BLUR_NODE,
|
||||||
|
@ -164,6 +164,7 @@ GskRenderNode * gsk_render_node_deserialize (GBytes
|
|||||||
#define GSK_TYPE_CROSS_FADE_NODE (gsk_cross_fade_node_get_type())
|
#define GSK_TYPE_CROSS_FADE_NODE (gsk_cross_fade_node_get_type())
|
||||||
#define GSK_TYPE_TEXT_NODE (gsk_text_node_get_type())
|
#define GSK_TYPE_TEXT_NODE (gsk_text_node_get_type())
|
||||||
#define GSK_TYPE_BLUR_NODE (gsk_blur_node_get_type())
|
#define GSK_TYPE_BLUR_NODE (gsk_blur_node_get_type())
|
||||||
|
#define GSK_TYPE_MASK_NODE (gsk_mask_node_get_type())
|
||||||
#define GSK_TYPE_GL_SHADER_NODE (gsk_gl_shader_node_get_type())
|
#define GSK_TYPE_GL_SHADER_NODE (gsk_gl_shader_node_get_type())
|
||||||
|
|
||||||
typedef struct _GskDebugNode GskDebugNode;
|
typedef struct _GskDebugNode GskDebugNode;
|
||||||
@ -191,6 +192,7 @@ typedef struct _GskBlendNode GskBlendNode;
|
|||||||
typedef struct _GskCrossFadeNode GskCrossFadeNode;
|
typedef struct _GskCrossFadeNode GskCrossFadeNode;
|
||||||
typedef struct _GskTextNode GskTextNode;
|
typedef struct _GskTextNode GskTextNode;
|
||||||
typedef struct _GskBlurNode GskBlurNode;
|
typedef struct _GskBlurNode GskBlurNode;
|
||||||
|
typedef struct _GskMaskNode GskMaskNode;
|
||||||
typedef struct _GskGLShaderNode GskGLShaderNode;
|
typedef struct _GskGLShaderNode GskGLShaderNode;
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
@ -529,8 +531,18 @@ GskRenderNode * gsk_blur_node_get_child (const GskRender
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
float gsk_blur_node_get_radius (const GskRenderNode *node) G_GNUC_PURE;
|
float gsk_blur_node_get_radius (const GskRenderNode *node) G_GNUC_PURE;
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_10
|
||||||
|
GType gsk_mask_node_get_type (void) G_GNUC_CONST;
|
||||||
|
GDK_AVAILABLE_IN_4_10
|
||||||
|
GskRenderNode * gsk_mask_node_new (GskRenderNode *source,
|
||||||
|
GskRenderNode *mask);
|
||||||
|
GDK_AVAILABLE_IN_4_10
|
||||||
|
GskRenderNode * gsk_mask_node_get_source (const GskRenderNode *node);
|
||||||
|
GDK_AVAILABLE_IN_4_10
|
||||||
|
GskRenderNode * gsk_mask_node_get_mask (const GskRenderNode *node);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType gsk_gl_shader_node_get_type (void) G_GNUC_CONST;
|
GType gsk_gl_shader_node_get_type (void) G_GNUC_CONST;
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GskRenderNode * gsk_gl_shader_node_new (GskGLShader *shader,
|
GskRenderNode * gsk_gl_shader_node_new (GskGLShader *shader,
|
||||||
const graphene_rect_t *bounds,
|
const graphene_rect_t *bounds,
|
||||||
|
@ -5184,6 +5184,135 @@ gsk_blur_node_get_radius (const GskRenderNode *node)
|
|||||||
return self->radius;
|
return self->radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }}} */
|
||||||
|
/* {{{ GSK_MASK_NODE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GskMaskNode:
|
||||||
|
*
|
||||||
|
* A render node masking one child node with another.
|
||||||
|
*
|
||||||
|
* Since: 4.10
|
||||||
|
*/
|
||||||
|
typedef struct _GskMaskNode GskMaskNode;
|
||||||
|
|
||||||
|
struct _GskMaskNode
|
||||||
|
{
|
||||||
|
GskRenderNode render_node;
|
||||||
|
|
||||||
|
GskRenderNode *mask;
|
||||||
|
GskRenderNode *source;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_mask_node_finalize (GskRenderNode *node)
|
||||||
|
{
|
||||||
|
GskMaskNode *self = (GskMaskNode *) node;
|
||||||
|
|
||||||
|
gsk_render_node_unref (self->source);
|
||||||
|
gsk_render_node_unref (self->mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_mask_node_draw (GskRenderNode *node,
|
||||||
|
cairo_t *cr)
|
||||||
|
{
|
||||||
|
GskMaskNode *self = (GskMaskNode *) node;
|
||||||
|
cairo_pattern_t *mask_pattern;
|
||||||
|
|
||||||
|
cairo_push_group (cr);
|
||||||
|
gsk_render_node_draw (self->source, cr);
|
||||||
|
cairo_pop_group_to_source (cr);
|
||||||
|
|
||||||
|
cairo_push_group (cr);
|
||||||
|
gsk_render_node_draw (self->mask, cr);
|
||||||
|
mask_pattern = cairo_pop_group (cr);
|
||||||
|
|
||||||
|
cairo_mask (cr, mask_pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_mask_node_diff (GskRenderNode *node1,
|
||||||
|
GskRenderNode *node2,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GskMaskNode *self1 = (GskMaskNode *) node1;
|
||||||
|
GskMaskNode *self2 = (GskMaskNode *) node2;
|
||||||
|
|
||||||
|
gsk_render_node_diff (self1->source, self2->source, region);
|
||||||
|
gsk_render_node_diff (self1->mask, self2->mask, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_mask_node_new:
|
||||||
|
* @source: The bottom node to be drawn
|
||||||
|
* @mask: The node to be blended onto the @bottom node
|
||||||
|
*
|
||||||
|
* Creates a `GskRenderNode` that will use @blend_mode to blend the @top
|
||||||
|
* node onto the @bottom node.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full) (type GskMaskNode): A new `GskRenderNode`
|
||||||
|
*
|
||||||
|
* Since: 4.10
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_new (GskRenderNode *source,
|
||||||
|
GskRenderNode *mask)
|
||||||
|
{
|
||||||
|
GskMaskNode *self;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (source), NULL);
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (mask), NULL);
|
||||||
|
|
||||||
|
self = gsk_render_node_alloc (GSK_MASK_NODE);
|
||||||
|
self->source = gsk_render_node_ref (source);
|
||||||
|
self->mask = gsk_render_node_ref (mask);
|
||||||
|
|
||||||
|
graphene_rect_union (&source->bounds, &mask->bounds, &self->render_node.bounds);
|
||||||
|
|
||||||
|
return &self->render_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_mask_node_get_source:
|
||||||
|
* @node: (type GskBlendNode): a mask `GskRenderNode`
|
||||||
|
*
|
||||||
|
* Retrieves the source `GskRenderNode` child of the @node.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the source child node
|
||||||
|
*
|
||||||
|
* Since: 4.10
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_get_source (const GskRenderNode *node)
|
||||||
|
{
|
||||||
|
const GskMaskNode *self = (const GskMaskNode *) node;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_MASK_NODE), NULL);
|
||||||
|
|
||||||
|
return self->source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_mask_node_get_mask:
|
||||||
|
* @node: (type GskBlendNode): a mask `GskRenderNode`
|
||||||
|
*
|
||||||
|
* Retrieves the mask `GskRenderNode` child of the @node.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the mask child node
|
||||||
|
*
|
||||||
|
* Since: 4.10
|
||||||
|
*/
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_get_mask (const GskRenderNode *node)
|
||||||
|
{
|
||||||
|
const GskMaskNode *self = (const GskMaskNode *) node;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_MASK_NODE), NULL);
|
||||||
|
|
||||||
|
return self->mask;
|
||||||
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
/* {{{ GSK_DEBUG_NODE */
|
/* {{{ GSK_DEBUG_NODE */
|
||||||
|
|
||||||
@ -5556,6 +5685,7 @@ GSK_DEFINE_RENDER_NODE_TYPE (gsk_blend_node, GSK_BLEND_NODE)
|
|||||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_cross_fade_node, GSK_CROSS_FADE_NODE)
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_cross_fade_node, GSK_CROSS_FADE_NODE)
|
||||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_text_node, GSK_TEXT_NODE)
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_text_node, GSK_TEXT_NODE)
|
||||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_blur_node, GSK_BLUR_NODE)
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_blur_node, GSK_BLUR_NODE)
|
||||||
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_mask_node, GSK_MASK_NODE)
|
||||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_gl_shader_node, GSK_GL_SHADER_NODE)
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_gl_shader_node, GSK_GL_SHADER_NODE)
|
||||||
GSK_DEFINE_RENDER_NODE_TYPE (gsk_debug_node, GSK_DEBUG_NODE)
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_debug_node, GSK_DEBUG_NODE)
|
||||||
|
|
||||||
@ -5946,6 +6076,22 @@ gsk_render_node_init_types_once (void)
|
|||||||
gsk_render_node_types[GSK_BLUR_NODE] = node_type;
|
gsk_render_node_types[GSK_BLUR_NODE] = node_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const GskRenderNodeTypeInfo node_info =
|
||||||
|
{
|
||||||
|
GSK_MASK_NODE,
|
||||||
|
sizeof (GskMaskNode),
|
||||||
|
NULL,
|
||||||
|
gsk_mask_node_finalize,
|
||||||
|
gsk_mask_node_draw,
|
||||||
|
NULL,
|
||||||
|
gsk_mask_node_diff,
|
||||||
|
};
|
||||||
|
|
||||||
|
GType node_type = gsk_render_node_type_register_static (I_("GskMaskNode"), &node_info);
|
||||||
|
gsk_render_node_types[GSK_MASK_NODE] = node_type;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const GskRenderNodeTypeInfo node_info =
|
const GskRenderNodeTypeInfo node_info =
|
||||||
{
|
{
|
||||||
|
@ -1376,6 +1376,31 @@ parse_glshader_node (GtkCssParser *parser)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GskRenderNode *
|
||||||
|
parse_mask_node (GtkCssParser *parser)
|
||||||
|
{
|
||||||
|
GskRenderNode *source = NULL;
|
||||||
|
GskRenderNode *mask = NULL;
|
||||||
|
const Declaration declarations[] = {
|
||||||
|
{ "source", parse_node, clear_node, &source },
|
||||||
|
{ "mask", parse_node, clear_node, &mask },
|
||||||
|
};
|
||||||
|
GskRenderNode *result;
|
||||||
|
|
||||||
|
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
|
||||||
|
if (source == NULL)
|
||||||
|
source = create_default_render_node ();
|
||||||
|
if (mask == NULL)
|
||||||
|
mask = gsk_color_node_new (&GDK_RGBA("AAFF00"), &GRAPHENE_RECT_INIT (0, 0, 50, 50));
|
||||||
|
|
||||||
|
result = gsk_mask_node_new (source, mask);
|
||||||
|
|
||||||
|
gsk_render_node_unref (source);
|
||||||
|
gsk_render_node_unref (mask);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static GskRenderNode *
|
static GskRenderNode *
|
||||||
parse_border_node (GtkCssParser *parser)
|
parse_border_node (GtkCssParser *parser)
|
||||||
{
|
{
|
||||||
@ -1914,6 +1939,7 @@ parse_node (GtkCssParser *parser,
|
|||||||
{ "texture-scale", parse_texture_scale_node },
|
{ "texture-scale", parse_texture_scale_node },
|
||||||
{ "transform", parse_transform_node },
|
{ "transform", parse_transform_node },
|
||||||
{ "glshader", parse_glshader_node },
|
{ "glshader", parse_glshader_node },
|
||||||
|
{ "mask", parse_mask_node },
|
||||||
};
|
};
|
||||||
GskRenderNode **node_p = out_node;
|
GskRenderNode **node_p = out_node;
|
||||||
guint i;
|
guint i;
|
||||||
@ -3100,6 +3126,17 @@ render_node_print (Printer *p,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
{
|
||||||
|
start_node (p, "mask");
|
||||||
|
|
||||||
|
append_node_param (p, "source", gsk_mask_node_get_source (node));
|
||||||
|
append_node_param (p, "mask", gsk_mask_node_get_mask (node));
|
||||||
|
|
||||||
|
end_node (p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GSK_NOT_A_RENDER_NODE:
|
case GSK_NOT_A_RENDER_NODE:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
|
@ -504,6 +504,9 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
case GSK_COLOR_MATRIX_NODE:
|
case GSK_COLOR_MATRIX_NODE:
|
||||||
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||||
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
|
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
|
||||||
|
@ -305,6 +305,10 @@ create_list_model_for_render_node (GskRenderNode *node)
|
|||||||
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_blend_node_get_bottom_child (node),
|
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_blend_node_get_bottom_child (node),
|
||||||
gsk_blend_node_get_top_child (node) }, 2);
|
gsk_blend_node_get_top_child (node) }, 2);
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_mask_node_get_source (node),
|
||||||
|
gsk_mask_node_get_mask (node) }, 2);
|
||||||
|
|
||||||
case GSK_CROSS_FADE_NODE:
|
case GSK_CROSS_FADE_NODE:
|
||||||
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_cross_fade_node_get_start_child (node),
|
return create_render_node_list_model ((GskRenderNode *[2]) { gsk_cross_fade_node_get_start_child (node),
|
||||||
gsk_cross_fade_node_get_end_child (node) }, 2);
|
gsk_cross_fade_node_get_end_child (node) }, 2);
|
||||||
@ -425,6 +429,8 @@ node_type_name (GskRenderNodeType type)
|
|||||||
return "Shadow";
|
return "Shadow";
|
||||||
case GSK_BLEND_NODE:
|
case GSK_BLEND_NODE:
|
||||||
return "Blend";
|
return "Blend";
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
return "Mask";
|
||||||
case GSK_CROSS_FADE_NODE:
|
case GSK_CROSS_FADE_NODE:
|
||||||
return "CrossFade";
|
return "CrossFade";
|
||||||
case GSK_TEXT_NODE:
|
case GSK_TEXT_NODE:
|
||||||
@ -462,6 +468,7 @@ node_name (GskRenderNode *node)
|
|||||||
case GSK_ROUNDED_CLIP_NODE:
|
case GSK_ROUNDED_CLIP_NODE:
|
||||||
case GSK_SHADOW_NODE:
|
case GSK_SHADOW_NODE:
|
||||||
case GSK_BLEND_NODE:
|
case GSK_BLEND_NODE:
|
||||||
|
case GSK_MASK_NODE:
|
||||||
case GSK_CROSS_FADE_NODE:
|
case GSK_CROSS_FADE_NODE:
|
||||||
case GSK_TEXT_NODE:
|
case GSK_TEXT_NODE:
|
||||||
case GSK_BLUR_NODE:
|
case GSK_BLUR_NODE:
|
||||||
@ -1132,6 +1139,9 @@ populate_render_node_properties (GListStore *store,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
break;
|
||||||
|
|
||||||
case GSK_BLUR_NODE:
|
case GSK_BLUR_NODE:
|
||||||
add_float_row (store, "Radius", gsk_blur_node_get_radius (node));
|
add_float_row (store, "Radius", gsk_blur_node_get_radius (node));
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user