gpu: Make patterns do opacity nodes

Of course, for now this only works for opacity nodes that contain color
nodes, but we're still building up to ore useful stuff here.
This commit is contained in:
Benjamin Otte
2023-08-31 13:27:25 +02:00
parent ee3367697d
commit ffc117564b
5 changed files with 116 additions and 23 deletions

View File

@@ -601,6 +601,32 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
pattern_id);
}
static void
gsk_gpu_node_processor_add_opacity_node (GskGpuNodeProcessor *self,
GskRenderNode *node)
{
GskGpuBufferWriter writer;
guint32 pattern_id;
gsk_gpu_frame_write_buffer_memory (self->frame, &writer);
if (!gsk_gpu_pattern_create_for_node (&writer, node))
{
gsk_gpu_buffer_writer_abort (&writer);
GSK_DEBUG (FALLBACK, "Color node children can't be turned into pattern");
gsk_gpu_node_processor_add_fallback_node (self, node);
return;
}
pattern_id = gsk_gpu_buffer_writer_commit (&writer) / sizeof (float);
gsk_gpu_uber_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
&node->bounds,
&self->offset,
pattern_id);
}
static void
gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self,
GskRenderNode *node)
@@ -673,7 +699,7 @@ static const struct
},
[GSK_OPACITY_NODE] = {
0,
NULL,
gsk_gpu_node_processor_add_opacity_node,
},
[GSK_COLOR_MATRIX_NODE] = {
0,

View File

@@ -4,6 +4,10 @@
#include "gskrendernode.h"
static gboolean
gsk_gpu_pattern_create_internal (GskGpuBufferWriter *writer,
GskRenderNode *node);
static gboolean
gsk_gpu_pattern_create_for_color_node (GskGpuBufferWriter *writer,
GskRenderNode *node)
@@ -21,6 +25,19 @@ gsk_gpu_pattern_create_for_color_node (GskGpuBufferWriter *writer,
return TRUE;
}
static gboolean
gsk_gpu_pattern_create_for_opacity_node (GskGpuBufferWriter *writer,
GskRenderNode *node)
{
if (!gsk_gpu_pattern_create_internal (writer, gsk_opacity_node_get_child (node)))
return FALSE;
gsk_gpu_buffer_writer_append_uint (writer, GSK_GPU_PATTERN_OPACITY);
gsk_gpu_buffer_writer_append_float (writer, gsk_opacity_node_get_opacity (node));
return TRUE;
}
static const struct
{
gboolean (* create_for_node) (GskGpuBufferWriter *writer,
@@ -69,7 +86,7 @@ static const struct
NULL,
},
[GSK_OPACITY_NODE] = {
NULL,
gsk_gpu_pattern_create_for_opacity_node,
},
[GSK_COLOR_MATRIX_NODE] = {
NULL,
@@ -118,8 +135,8 @@ static const struct
},
};
gboolean
gsk_gpu_pattern_create_for_node (GskGpuBufferWriter *writer,
static gboolean
gsk_gpu_pattern_create_internal (GskGpuBufferWriter *writer,
GskRenderNode *node)
{
GskRenderNodeType node_type;
@@ -134,5 +151,19 @@ gsk_gpu_pattern_create_for_node (GskGpuBufferWriter *writer,
if (nodes_vtable[node_type].create_for_node == NULL)
return FALSE;
return nodes_vtable[node_type].create_for_node (writer, node);
if (!nodes_vtable[node_type].create_for_node (writer, node))
return FALSE;
return TRUE;
}
gboolean
gsk_gpu_pattern_create_for_node (GskGpuBufferWriter *writer,
GskRenderNode *node)
{
if (!gsk_gpu_pattern_create_internal (writer, node))
return FALSE;
gsk_gpu_buffer_writer_append_uint (writer, GSK_GPU_PATTERN_DONE);
return TRUE;
}

View File

@@ -7,7 +7,9 @@
G_BEGIN_DECLS
typedef enum {
GSK_GPU_PATTERN_DONE,
GSK_GPU_PATTERN_COLOR,
GSK_GPU_PATTERN_OPACITY,
} GskGpuPatternType;
gboolean gsk_gpu_pattern_create_for_node (GskGpuBufferWriter *writer,

View File

@@ -5,6 +5,8 @@
#define GSK_GPU_SHADER_CLIP_RECT 1u
#define GSK_GPU_SHADER_CLIP_ROUNDED 2u
#define GSK_GPU_PATTERN_COLOR 0
#define GSK_GPU_PATTERN_DONE 0u
#define GSK_GPU_PATTERN_COLOR 1u
#define GSK_GPU_PATTERN_OPACITY 2u
#endif

View File

@@ -5,36 +5,68 @@
#ifdef GSK_FRAGMENT_SHADER
vec4
gsk_get_vec4 (uint id)
uint
read_uint (inout uint reader)
{
return vec4 (gsk_get_float (id),
gsk_get_float (id + 1),
gsk_get_float (id + 2),
gsk_get_float (id + 3));
uint result = gsk_get_uint (reader);
reader++;
return result;
}
float
read_float (inout uint reader)
{
float result = gsk_get_float (reader);
reader++;
return result;
}
vec4
color_pattern (uint pattern)
read_vec4 (inout uint reader)
{
vec4 color = gsk_get_vec4 (pattern);
return vec4 (read_float (reader), read_float (reader), read_float (reader), read_float (reader));
}
void
opacity_pattern (inout uint reader,
inout vec4 color,
vec2 pos)
{
float opacity = read_float (reader);
color *= opacity;
}
vec4
color_pattern (inout uint reader)
{
vec4 color = read_vec4 (reader);
return color_premultiply (color);
}
vec4
pattern (uint pattern,
pattern (uint reader,
vec2 pos)
{
uint type = gsk_get_uint (pattern);
vec4 color = vec4 (1.0, 0.0, 0.8, 1.0); /* pink */
switch (type)
{
case GSK_GPU_PATTERN_COLOR:
return color_pattern (pattern + 1);
default:
return vec4 (1.0, 0.0, 0.8, 1.0); /* pink */
}
for(;;)
{
uint type = read_uint (reader);
switch (type)
{
default:
case GSK_GPU_PATTERN_DONE:
return color;
case GSK_GPU_PATTERN_COLOR:
color = color_pattern (reader);
break;
case GSK_GPU_PATTERN_OPACITY:
opacity_pattern (reader, color, pos);
break;
}
}
}
#endif