Compare commits
3 Commits
macos-ci
...
wip/matthi
Author | SHA1 | Date | |
---|---|---|---|
|
51ad547995 | ||
|
df48be7c4c | ||
|
f64e86ebcd |
@@ -2716,6 +2716,48 @@ render_cross_fade_node (GskGLRenderer *self,
|
|||||||
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
render_mask_node (GskGLRenderer *self,
|
||||||
|
GskRenderNode *node,
|
||||||
|
RenderOpBuilder *builder)
|
||||||
|
{
|
||||||
|
GskRenderNode *source = gsk_mask_node_get_source (node);
|
||||||
|
GskRenderNode *mask = gsk_mask_node_get_mask (node);
|
||||||
|
TextureRegion source_region;
|
||||||
|
TextureRegion mask_region;
|
||||||
|
gboolean is_offscreen1, is_offscreen2;
|
||||||
|
OpMask *op;
|
||||||
|
|
||||||
|
if (!add_offscreen_ops (self, builder,
|
||||||
|
&node->bounds,
|
||||||
|
source,
|
||||||
|
&source_region, &is_offscreen1,
|
||||||
|
FORCE_OFFSCREEN | RESET_CLIP))
|
||||||
|
{
|
||||||
|
gsk_gl_renderer_add_render_ops (self, source, builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!add_offscreen_ops (self, builder,
|
||||||
|
&node->bounds,
|
||||||
|
mask,
|
||||||
|
&mask_region, &is_offscreen2,
|
||||||
|
FORCE_OFFSCREEN | RESET_CLIP))
|
||||||
|
{
|
||||||
|
gsk_gl_renderer_add_render_ops (self, source, builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ops_set_program (builder, &self->programs->mask_program);
|
||||||
|
|
||||||
|
op = ops_begin (builder, OP_CHANGE_MASK);
|
||||||
|
op->mask = mask_region.texture_id;
|
||||||
|
|
||||||
|
ops_set_texture (builder, source_region.texture_id);
|
||||||
|
|
||||||
|
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
render_blend_node (GskGLRenderer *self,
|
render_blend_node (GskGLRenderer *self,
|
||||||
GskRenderNode *node,
|
GskRenderNode *node,
|
||||||
@@ -3203,6 +3245,17 @@ apply_repeat_op (const Program *program,
|
|||||||
glUniform4fv (program->repeat.texture_rect_location, 1, op->texture_rect);
|
glUniform4fv (program->repeat.texture_rect_location, 1, op->texture_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
apply_mask_op (const Program *program,
|
||||||
|
const OpMask *op)
|
||||||
|
{
|
||||||
|
OP_PRINT (" -> Mask ");
|
||||||
|
/* Mask texture id */
|
||||||
|
glUniform1i (program->mask.mask_location, 1);
|
||||||
|
glActiveTexture (GL_TEXTURE0 + 1);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, op->mask);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_gl_renderer_dispose (GObject *gobject)
|
gsk_gl_renderer_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
@@ -3326,6 +3379,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
|||||||
{ "/org/gtk/libgsk/glsl/outset_shadow.glsl", "outset shadow" },
|
{ "/org/gtk/libgsk/glsl/outset_shadow.glsl", "outset shadow" },
|
||||||
{ "/org/gtk/libgsk/glsl/repeat.glsl", "repeat" },
|
{ "/org/gtk/libgsk/glsl/repeat.glsl", "repeat" },
|
||||||
{ "/org/gtk/libgsk/glsl/unblurred_outset_shadow.glsl", "unblurred_outset shadow" },
|
{ "/org/gtk/libgsk/glsl/unblurred_outset_shadow.glsl", "unblurred_outset shadow" },
|
||||||
|
{ "/org/gtk/libgsk/glsl/mask.glsl", "mask" },
|
||||||
};
|
};
|
||||||
|
|
||||||
gsk_gl_shader_builder_init (&shader_builder,
|
gsk_gl_shader_builder_init (&shader_builder,
|
||||||
@@ -3421,6 +3475,9 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
|
|||||||
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
|
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
|
||||||
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
|
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
|
||||||
|
|
||||||
|
/* mask */
|
||||||
|
INIT_PROGRAM_UNIFORM_LOCATION (mask, mask);
|
||||||
|
|
||||||
/* blend */
|
/* blend */
|
||||||
INIT_PROGRAM_UNIFORM_LOCATION (blend, source2);
|
INIT_PROGRAM_UNIFORM_LOCATION (blend, source2);
|
||||||
INIT_PROGRAM_UNIFORM_LOCATION (blend, mode);
|
INIT_PROGRAM_UNIFORM_LOCATION (blend, mode);
|
||||||
@@ -3805,6 +3862,10 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
|
|||||||
render_gl_shader_node (self, node, builder);
|
render_gl_shader_node (self, node, builder);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
render_mask_node (self, node, builder);
|
||||||
|
break;
|
||||||
|
|
||||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||||
case GSK_CAIRO_NODE:
|
case GSK_CAIRO_NODE:
|
||||||
@@ -4110,6 +4171,11 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self)
|
|||||||
apply_blend_op (program, ptr);
|
apply_blend_op (program, ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_CHANGE_MASK:
|
||||||
|
g_assert (program == &self->programs->mask_program);
|
||||||
|
apply_mask_op (program, ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_CHANGE_LINEAR_GRADIENT:
|
case OP_CHANGE_LINEAR_GRADIENT:
|
||||||
apply_linear_gradient_op (program, ptr);
|
apply_linear_gradient_op (program, ptr);
|
||||||
break;
|
break;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include "opbuffer.h"
|
#include "opbuffer.h"
|
||||||
|
|
||||||
#define GL_N_VERTICES 6
|
#define GL_N_VERTICES 6
|
||||||
#define GL_N_PROGRAMS 15
|
#define GL_N_PROGRAMS 16
|
||||||
#define GL_MAX_GRADIENT_STOPS 6
|
#define GL_MAX_GRADIENT_STOPS 6
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -179,6 +179,9 @@ struct _Program
|
|||||||
int texture_locations[4];
|
int texture_locations[4];
|
||||||
GError *compile_error;
|
GError *compile_error;
|
||||||
} glshader;
|
} glshader;
|
||||||
|
struct {
|
||||||
|
int mask_location;
|
||||||
|
} mask;
|
||||||
};
|
};
|
||||||
ProgramState state;
|
ProgramState state;
|
||||||
};
|
};
|
||||||
@@ -203,6 +206,7 @@ typedef struct {
|
|||||||
Program outset_shadow_program;
|
Program outset_shadow_program;
|
||||||
Program repeat_program;
|
Program repeat_program;
|
||||||
Program unblurred_outset_shadow_program;
|
Program unblurred_outset_shadow_program;
|
||||||
|
Program mask_program;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
GHashTable *custom_programs; /* GskGLShader -> Program* */
|
GHashTable *custom_programs; /* GskGLShader -> Program* */
|
||||||
|
@@ -34,6 +34,7 @@ static guint op_sizes[OP_LAST] = {
|
|||||||
sizeof (OpGLShader),
|
sizeof (OpGLShader),
|
||||||
sizeof (OpExtraTexture),
|
sizeof (OpExtraTexture),
|
||||||
sizeof (OpConicGradient),
|
sizeof (OpConicGradient),
|
||||||
|
sizeof (OpMask),
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -42,6 +42,7 @@ typedef enum
|
|||||||
OP_CHANGE_GL_SHADER_ARGS = 28,
|
OP_CHANGE_GL_SHADER_ARGS = 28,
|
||||||
OP_CHANGE_EXTRA_SOURCE_TEXTURE = 29,
|
OP_CHANGE_EXTRA_SOURCE_TEXTURE = 29,
|
||||||
OP_CHANGE_CONIC_GRADIENT = 30,
|
OP_CHANGE_CONIC_GRADIENT = 30,
|
||||||
|
OP_CHANGE_MASK = 31,
|
||||||
OP_LAST
|
OP_LAST
|
||||||
} OpKind;
|
} OpKind;
|
||||||
|
|
||||||
@@ -222,6 +223,11 @@ typedef struct
|
|||||||
const guchar *uniform_data;
|
const guchar *uniform_data;
|
||||||
} OpGLShader;
|
} OpGLShader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int mask;
|
||||||
|
} OpMask;
|
||||||
|
|
||||||
void op_buffer_init (OpBuffer *buffer);
|
void op_buffer_init (OpBuffer *buffer);
|
||||||
void op_buffer_destroy (OpBuffer *buffer);
|
void op_buffer_destroy (OpBuffer *buffer);
|
||||||
void op_buffer_clear (OpBuffer *buffer);
|
void op_buffer_clear (OpBuffer *buffer);
|
||||||
|
@@ -79,7 +79,8 @@ typedef enum {
|
|||||||
GSK_TEXT_NODE,
|
GSK_TEXT_NODE,
|
||||||
GSK_BLUR_NODE,
|
GSK_BLUR_NODE,
|
||||||
GSK_DEBUG_NODE,
|
GSK_DEBUG_NODE,
|
||||||
GSK_GL_SHADER_NODE
|
GSK_GL_SHADER_NODE,
|
||||||
|
GSK_MASK_NODE,
|
||||||
} GskRenderNodeType;
|
} GskRenderNodeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -164,6 +164,7 @@ GskRenderNode * gsk_render_node_deserialize (GBytes
|
|||||||
#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_GL_SHADER_NODE (gsk_gl_shader_node_get_type())
|
#define GSK_TYPE_GL_SHADER_NODE (gsk_gl_shader_node_get_type())
|
||||||
|
#define GSK_TYPE_MASK_NODE (gsk_mask_node_get_type())
|
||||||
|
|
||||||
typedef struct _GskDebugNode GskDebugNode;
|
typedef struct _GskDebugNode GskDebugNode;
|
||||||
typedef struct _GskColorNode GskColorNode;
|
typedef struct _GskColorNode GskColorNode;
|
||||||
@@ -190,6 +191,7 @@ typedef struct _GskCrossFadeNode GskCrossFadeNode;
|
|||||||
typedef struct _GskTextNode GskTextNode;
|
typedef struct _GskTextNode GskTextNode;
|
||||||
typedef struct _GskBlurNode GskBlurNode;
|
typedef struct _GskBlurNode GskBlurNode;
|
||||||
typedef struct _GskGLShaderNode GskGLShaderNode;
|
typedef struct _GskGLShaderNode GskGLShaderNode;
|
||||||
|
typedef struct _GskMaskNode GskMaskNode;
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType gsk_debug_node_get_type (void) G_GNUC_CONST;
|
GType gsk_debug_node_get_type (void) G_GNUC_CONST;
|
||||||
@@ -531,6 +533,16 @@ GBytes * gsk_gl_shader_node_get_args (GskRenderNode
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GskGLShader * gsk_gl_shader_node_get_shader (GskRenderNode *node);
|
GskGLShader * gsk_gl_shader_node_get_shader (GskRenderNode *node);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GType gsk_mask_node_get_type (void) G_GNUC_CONST;
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GskRenderNode * gsk_mask_node_new (GskRenderNode *source_child,
|
||||||
|
GskRenderNode *mask_child);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GskRenderNode * gsk_mask_node_get_source (GskRenderNode *node);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GskRenderNode * gsk_mask_node_get_mask (GskRenderNode *node);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GSK_RENDER_NODE_H__ */
|
#endif /* __GSK_RENDER_NODE_H__ */
|
||||||
|
@@ -5175,6 +5175,83 @@ gsk_gl_shader_node_get_args (GskRenderNode *node)
|
|||||||
return self->args;
|
return self->args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** GSK_MASK_NODE ***/
|
||||||
|
|
||||||
|
typedef struct _GskMaskNode GskMaskNode;
|
||||||
|
|
||||||
|
struct _GskMaskNode
|
||||||
|
{
|
||||||
|
GskRenderNode render_node;
|
||||||
|
|
||||||
|
GskRenderNode *mask_child;
|
||||||
|
GskRenderNode *source_child;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_mask_node_finalize (GskRenderNode *node)
|
||||||
|
{
|
||||||
|
GskMaskNode *self = (GskMaskNode *) node;
|
||||||
|
|
||||||
|
gsk_render_node_unref (self->source_child);
|
||||||
|
gsk_render_node_unref (self->mask_child);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_child, cr);
|
||||||
|
cairo_pop_group_to_source (cr);
|
||||||
|
|
||||||
|
cairo_push_group (cr);
|
||||||
|
gsk_render_node_draw (self->mask_child, cr);
|
||||||
|
mask_pattern = cairo_pop_group (cr);
|
||||||
|
|
||||||
|
cairo_mask (cr, mask_pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_new (GskRenderNode *source_child,
|
||||||
|
GskRenderNode *mask_child)
|
||||||
|
{
|
||||||
|
GskMaskNode *self;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (source_child), NULL);
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE (mask_child), NULL);
|
||||||
|
|
||||||
|
self = gsk_render_node_alloc (GSK_MASK_NODE);
|
||||||
|
self->source_child = gsk_render_node_ref (source_child);
|
||||||
|
self->mask_child = gsk_render_node_ref (mask_child);
|
||||||
|
|
||||||
|
graphene_rect_union (&source_child->bounds, &mask_child->bounds, &self->render_node.bounds);
|
||||||
|
|
||||||
|
return &self->render_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_get_source (GskRenderNode *node)
|
||||||
|
{
|
||||||
|
GskMaskNode *self = (GskMaskNode *) node;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_MASK_NODE), NULL);
|
||||||
|
|
||||||
|
return self->source_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
GskRenderNode *
|
||||||
|
gsk_mask_node_get_mask (GskRenderNode *node)
|
||||||
|
{
|
||||||
|
GskMaskNode *self = (GskMaskNode *) node;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_MASK_NODE), NULL);
|
||||||
|
|
||||||
|
return self->mask_child;
|
||||||
|
}
|
||||||
|
|
||||||
GType gsk_render_node_types[GSK_RENDER_NODE_TYPE_N_TYPES];
|
GType gsk_render_node_types[GSK_RENDER_NODE_TYPE_N_TYPES];
|
||||||
|
|
||||||
#ifndef I_
|
#ifndef I_
|
||||||
@@ -5214,6 +5291,7 @@ 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_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)
|
||||||
|
GSK_DEFINE_RENDER_NODE_TYPE (gsk_mask_node, GSK_MASK_NODE)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_render_node_init_types_once (void)
|
gsk_render_node_init_types_once (void)
|
||||||
@@ -5617,6 +5695,22 @@ gsk_render_node_init_types_once (void)
|
|||||||
GType node_type = gsk_render_node_type_register_static (I_("GskDebugNode"), &node_info);
|
GType node_type = gsk_render_node_type_register_static (I_("GskDebugNode"), &node_info);
|
||||||
gsk_render_node_types[GSK_DEBUG_NODE] = node_type;
|
gsk_render_node_types[GSK_DEBUG_NODE] = node_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const GskRenderNodeTypeInfo node_info =
|
||||||
|
{
|
||||||
|
GSK_MASK_NODE,
|
||||||
|
sizeof (GskMaskNode),
|
||||||
|
NULL,
|
||||||
|
gsk_mask_node_finalize,
|
||||||
|
gsk_mask_node_draw,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
GType node_type = gsk_render_node_type_register_static (I_("GskMaskNode"), &node_info);
|
||||||
|
gsk_render_node_types[GSK_MASK_NODE] = node_type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*< private >
|
/*< private >
|
||||||
* gsk_render_node_init_types:
|
* gsk_render_node_init_types:
|
||||||
|
@@ -1565,6 +1565,31 @@ parse_blend_node (GtkCssParser *parser)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_repeat_node (GtkCssParser *parser)
|
parse_repeat_node (GtkCssParser *parser)
|
||||||
{
|
{
|
||||||
@@ -1843,6 +1868,7 @@ parse_node (GtkCssParser *parser,
|
|||||||
{ "texture", parse_texture_node },
|
{ "texture", parse_texture_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;
|
||||||
@@ -2911,6 +2937,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;
|
||||||
|
@@ -13,7 +13,7 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass;
|
|||||||
* We don't add an "n-types" value to avoid having to handle
|
* We don't add an "n-types" value to avoid having to handle
|
||||||
* it in every single switch.
|
* it in every single switch.
|
||||||
*/
|
*/
|
||||||
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_GL_SHADER_NODE + 1)
|
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_MASK_NODE + 1)
|
||||||
|
|
||||||
extern GType gsk_render_node_types[];
|
extern GType gsk_render_node_types[];
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ gsk_private_gl_shaders = [
|
|||||||
'resources/glsl/blend.glsl',
|
'resources/glsl/blend.glsl',
|
||||||
'resources/glsl/repeat.glsl',
|
'resources/glsl/repeat.glsl',
|
||||||
'resources/glsl/custom.glsl',
|
'resources/glsl/custom.glsl',
|
||||||
|
'resources/glsl/mask.glsl',
|
||||||
]
|
]
|
||||||
|
|
||||||
gsk_public_sources = files([
|
gsk_public_sources = files([
|
||||||
|
15
gsk/resources/glsl/mask.glsl
Normal file
15
gsk/resources/glsl/mask.glsl
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// VERTEX_SHADER:
|
||||||
|
void main() {
|
||||||
|
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||||
|
|
||||||
|
vUv = vec2(aUv.x, aUv.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FRAGMENT_SHADER:
|
||||||
|
uniform sampler2D u_mask;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 source = GskTexture(u_source, vUv);
|
||||||
|
vec4 mask = GskTexture(u_mask, vUv);
|
||||||
|
gskSetOutputColor(source * mask.a);
|
||||||
|
}
|
@@ -260,6 +260,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
case GSK_RADIAL_GRADIENT_NODE:
|
case GSK_RADIAL_GRADIENT_NODE:
|
||||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||||
case GSK_CONIC_GRADIENT_NODE:
|
case GSK_CONIC_GRADIENT_NODE:
|
||||||
|
case GSK_MASK_NODE:
|
||||||
default:
|
default:
|
||||||
FALLBACK ("Unsupported node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
|
FALLBACK ("Unsupported node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
|
||||||
|
|
||||||
|
@@ -191,19 +191,23 @@ gtk_application_load_resources (GtkApplication *application)
|
|||||||
{
|
{
|
||||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
||||||
const char *base_path;
|
const char *base_path;
|
||||||
|
const char *optional_slash = "/";
|
||||||
|
|
||||||
base_path = g_application_get_resource_base_path (G_APPLICATION (application));
|
base_path = g_application_get_resource_base_path (G_APPLICATION (application));
|
||||||
|
|
||||||
if (base_path == NULL)
|
if (base_path == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (base_path[strlen (base_path) - 1] == '/')
|
||||||
|
optional_slash = "";
|
||||||
|
|
||||||
/* Expand the icon search path */
|
/* Expand the icon search path */
|
||||||
{
|
{
|
||||||
GtkIconTheme *default_theme;
|
GtkIconTheme *default_theme;
|
||||||
char *iconspath;
|
char *iconspath;
|
||||||
|
|
||||||
default_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
default_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
||||||
iconspath = g_strconcat (base_path, "/icons/", NULL);
|
iconspath = g_strconcat (base_path, optional_slash, "icons/", NULL);
|
||||||
gtk_icon_theme_add_resource_path (default_theme, iconspath);
|
gtk_icon_theme_add_resource_path (default_theme, iconspath);
|
||||||
g_free (iconspath);
|
g_free (iconspath);
|
||||||
}
|
}
|
||||||
@@ -212,7 +216,7 @@ gtk_application_load_resources (GtkApplication *application)
|
|||||||
{
|
{
|
||||||
char *menuspath;
|
char *menuspath;
|
||||||
|
|
||||||
menuspath = g_strconcat (base_path, "/gtk/menus.ui", NULL);
|
menuspath = g_strconcat (base_path, optional_slash, "gtk/menus.ui", NULL);
|
||||||
if (g_resources_get_info (menuspath, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
if (g_resources_get_info (menuspath, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
||||||
priv->menus_builder = gtk_builder_new_from_resource (menuspath);
|
priv->menus_builder = gtk_builder_new_from_resource (menuspath);
|
||||||
g_free (menuspath);
|
g_free (menuspath);
|
||||||
@@ -231,7 +235,7 @@ gtk_application_load_resources (GtkApplication *application)
|
|||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
path = g_strconcat (base_path, "/gtk/help-overlay.ui", NULL);
|
path = g_strconcat (base_path, optional_slash, "gtk/help-overlay.ui", NULL);
|
||||||
if (g_resources_get_info (path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
if (g_resources_get_info (path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
||||||
{
|
{
|
||||||
const char * const accels[] = { "<Control>question", NULL };
|
const char * const accels[] = { "<Control>question", NULL };
|
||||||
|
@@ -124,6 +124,9 @@ struct _GtkSnapshotState {
|
|||||||
struct {
|
struct {
|
||||||
char *message;
|
char *message;
|
||||||
} debug;
|
} debug;
|
||||||
|
struct {
|
||||||
|
GskRenderNode *source_node;
|
||||||
|
} mask;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1251,6 +1254,73 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GskRenderNode *
|
||||||
|
gtk_snapshot_collect_mask_mask (GtkSnapshot *snapshot,
|
||||||
|
GtkSnapshotState *state,
|
||||||
|
GskRenderNode **nodes,
|
||||||
|
guint n_nodes)
|
||||||
|
{
|
||||||
|
GskRenderNode *source_child, *mask_child, *mask_node;
|
||||||
|
|
||||||
|
mask_child = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes);
|
||||||
|
source_child = state->data.mask.source_node;
|
||||||
|
|
||||||
|
if (source_child == NULL ||
|
||||||
|
mask_child == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mask_node = gsk_mask_node_new (source_child, mask_child);
|
||||||
|
|
||||||
|
gsk_render_node_unref (source_child);
|
||||||
|
gsk_render_node_unref (mask_child);
|
||||||
|
|
||||||
|
return mask_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GskRenderNode *
|
||||||
|
gtk_snapshot_collect_mask_source (GtkSnapshot *snapshot,
|
||||||
|
GtkSnapshotState *state,
|
||||||
|
GskRenderNode **nodes,
|
||||||
|
guint n_nodes)
|
||||||
|
{
|
||||||
|
GtkSnapshotState *prev_state = gtk_snapshot_get_previous_state (snapshot);
|
||||||
|
|
||||||
|
g_assert (prev_state->collect_func == gtk_snapshot_collect_mask_mask);
|
||||||
|
|
||||||
|
prev_state->data.mask.source_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_snapshot_clear_mask_source (GtkSnapshotState *state)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&(state->data.mask.source_node), gsk_render_node_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_snapshot_push_mask:
|
||||||
|
* @snapshot: a #GtkSnapshot
|
||||||
|
*
|
||||||
|
* Calling this function requires 2 subsequent calls to gtk_snapshot_pop().
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_snapshot_push_mask (GtkSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
|
||||||
|
GtkSnapshotState *source_state;
|
||||||
|
|
||||||
|
source_state = gtk_snapshot_push_state (snapshot,
|
||||||
|
current_state->transform,
|
||||||
|
gtk_snapshot_collect_mask_source,
|
||||||
|
gtk_snapshot_clear_mask_source);
|
||||||
|
|
||||||
|
gtk_snapshot_push_state (snapshot,
|
||||||
|
source_state->transform,
|
||||||
|
gtk_snapshot_collect_mask_mask,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static GskRenderNode *
|
static GskRenderNode *
|
||||||
gtk_snapshot_collect_cross_fade_end (GtkSnapshot *snapshot,
|
gtk_snapshot_collect_cross_fade_end (GtkSnapshot *snapshot,
|
||||||
GtkSnapshotState *state,
|
GtkSnapshotState *state,
|
||||||
|
@@ -96,6 +96,8 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
void gtk_snapshot_push_blend (GtkSnapshot *snapshot,
|
void gtk_snapshot_push_blend (GtkSnapshot *snapshot,
|
||||||
GskBlendMode blend_mode);
|
GskBlendMode blend_mode);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
void gtk_snapshot_push_mask (GtkSnapshot *snapshot);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
|
void gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
|
||||||
double progress);
|
double progress);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
@@ -168,6 +168,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);
|
||||||
@@ -294,6 +298,8 @@ node_type_name (GskRenderNodeType type)
|
|||||||
return "Blur";
|
return "Blur";
|
||||||
case GSK_GL_SHADER_NODE:
|
case GSK_GL_SHADER_NODE:
|
||||||
return "GL Shader";
|
return "GL Shader";
|
||||||
|
case GSK_MASK_NODE:
|
||||||
|
return "Mask";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +329,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:
|
||||||
@@ -1136,6 +1143,7 @@ populate_render_node_properties (GtkListStore *store,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GSK_NOT_A_RENDER_NODE:
|
case GSK_NOT_A_RENDER_NODE:
|
||||||
|
case GSK_MASK_NODE:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user