mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-24 20:51:10 +00:00
gpu: Add repeat nodes
They're done using the pattern shader. The pattern shader now gained a stack where vec4's can be pushed and popped back later, which allows storing the position before computing the new position inside the repeat node's child.
This commit is contained in:
parent
b7a8c2207e
commit
0876089f8f
@ -17,7 +17,7 @@
|
||||
#define DEFAULT_VERTEX_BUFFER_SIZE 128 * 1024
|
||||
|
||||
/* GL_MAX_UNIFORM_BLOCK_SIZE is at 16384 */
|
||||
#define DEFAULT_STORAGE_BUFFER_SIZE 16 * 1024
|
||||
#define DEFAULT_STORAGE_BUFFER_SIZE 16 * 1024 * 64
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_gpu_ops
|
||||
#define GDK_ARRAY_TYPE_NAME GskGpuOps
|
||||
|
@ -111,6 +111,7 @@ struct _GskGpuPatternWriter
|
||||
graphene_rect_t bounds;
|
||||
graphene_point_t offset;
|
||||
graphene_vec2_t scale;
|
||||
guint stack;
|
||||
|
||||
GskGpuBufferWriter writer;
|
||||
GskGpuPatternImages images;
|
||||
@ -246,14 +247,33 @@ gsk_gpu_pattern_writer_init (GskGpuPatternWriter *self,
|
||||
bounds->size.height);
|
||||
self->offset = *offset;
|
||||
self->scale = *scale;
|
||||
self->stack = 0;
|
||||
|
||||
gsk_gpu_frame_write_buffer_memory (frame, &self->writer);
|
||||
gsk_gpu_pattern_images_init (&self->images);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_pattern_writer_push_stack (GskGpuPatternWriter *self)
|
||||
{
|
||||
if (self->stack >= GSK_GPU_PATTERN_STACK_SIZE)
|
||||
return FALSE;
|
||||
|
||||
self->stack++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_pattern_writer_pop_stack (GskGpuPatternWriter *self)
|
||||
{
|
||||
g_assert (self->stack > 0);
|
||||
self->stack--;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_pattern_writer_finish (GskGpuPatternWriter *self)
|
||||
{
|
||||
g_assert (self->stack == 0);
|
||||
gsk_gpu_pattern_images_clear (&self->images);
|
||||
}
|
||||
|
||||
@ -1164,12 +1184,60 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_node_processor_add_node (self, gsk_subsurface_node_get_child (node));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_create_repeat_pattern (GskGpuPatternWriter *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child;
|
||||
const graphene_rect_t *child_bounds;
|
||||
graphene_rect_t old_bounds;
|
||||
|
||||
child = gsk_repeat_node_get_child (node);
|
||||
child_bounds = gsk_repeat_node_get_child_bounds (node);
|
||||
|
||||
if (gsk_rect_is_empty (child_bounds))
|
||||
{
|
||||
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_COLOR);
|
||||
gsk_gpu_buffer_writer_append_rgba (&self->writer, &(GdkRGBA) { 0, 0, 0, 0 });
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gsk_gpu_pattern_writer_push_stack (self))
|
||||
return FALSE;
|
||||
|
||||
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_REPEAT_PUSH);
|
||||
gsk_gpu_buffer_writer_append_rect (&self->writer, child_bounds, &self->offset);
|
||||
|
||||
old_bounds = self->bounds;
|
||||
self->bounds = GRAPHENE_RECT_INIT (child_bounds->origin.x + self->offset.x,
|
||||
child_bounds->origin.y + self->offset.y,
|
||||
child_bounds->size.width,
|
||||
child_bounds->size.height);
|
||||
|
||||
if (!gsk_gpu_node_processor_create_node_pattern (self, child))
|
||||
{
|
||||
gsk_gpu_pattern_writer_pop_stack (self);
|
||||
return FALSE;
|
||||
}
|
||||
self->bounds = old_bounds;
|
||||
|
||||
if (!gsk_rect_contains_rect (&child->bounds, child_bounds))
|
||||
{
|
||||
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_CLIP);
|
||||
gsk_gpu_buffer_writer_append_rect (&self->writer, &child->bounds, &self->offset);
|
||||
}
|
||||
|
||||
gsk_gpu_buffer_writer_append_uint (&self->writer, GSK_GPU_PATTERN_POSITION_POP);
|
||||
gsk_gpu_pattern_writer_pop_stack (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_create_subsurface_pattern (GskGpuPatternWriter *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
return gsk_gpu_node_processor_create_node_pattern (self,
|
||||
gsk_subsurface_node_get_child (node));
|
||||
return gsk_gpu_node_processor_create_node_pattern (self, gsk_subsurface_node_get_child (node));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1284,8 +1352,8 @@ static const struct
|
||||
},
|
||||
[GSK_REPEAT_NODE] = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_gpu_node_processor_add_node_as_pattern,
|
||||
gsk_gpu_node_processor_create_repeat_pattern
|
||||
},
|
||||
[GSK_CLIP_NODE] = {
|
||||
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
|
||||
#define GSK_GPU_PATTERN_STACK_SIZE 16
|
||||
|
||||
typedef struct _GskGpuBuffer GskGpuBuffer;
|
||||
typedef struct _GskGpuDevice GskGpuDevice;
|
||||
typedef struct _GskGpuFrame GskGpuFrame;
|
||||
@ -41,5 +43,7 @@ typedef enum {
|
||||
GSK_GPU_PATTERN_CONIC_GRADIENT,
|
||||
GSK_GPU_PATTERN_CLIP,
|
||||
GSK_GPU_PATTERN_ROUNDED_CLIP,
|
||||
GSK_GPU_PATTERN_REPEAT_PUSH,
|
||||
GSK_GPU_PATTERN_POSITION_POP,
|
||||
} GskGpuPatternType;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef _ENUMS_
|
||||
#define _ENUMS_
|
||||
|
||||
#define GSK_GPU_PATTERN_STACK_SIZE 16
|
||||
|
||||
#define GSK_GPU_SHADER_CLIP_NONE 0u
|
||||
#define GSK_GPU_SHADER_CLIP_RECT 1u
|
||||
#define GSK_GPU_SHADER_CLIP_ROUNDED 2u
|
||||
@ -18,6 +20,8 @@
|
||||
#define GSK_GPU_PATTERN_CONIC_GRADIENT 10u
|
||||
#define GSK_GPU_PATTERN_CLIP 11u
|
||||
#define GSK_GPU_PATTERN_ROUNDED_CLIP 12u
|
||||
#define GSK_GPU_PATTERN_REPEAT_PUSH 13u
|
||||
#define GSK_GPU_PATTERN_POSITION_POP 14u
|
||||
|
||||
#define TOP 0u
|
||||
#define RIGHT 1u
|
||||
|
@ -7,6 +7,23 @@
|
||||
|
||||
#ifdef GSK_FRAGMENT_SHADER
|
||||
|
||||
vec4 stack[GSK_GPU_PATTERN_STACK_SIZE];
|
||||
uint stack_size = 0u;
|
||||
|
||||
void
|
||||
stack_push (vec4 data)
|
||||
{
|
||||
stack[stack_size] = data;
|
||||
stack_size++;
|
||||
}
|
||||
|
||||
vec4
|
||||
stack_pop (void)
|
||||
{
|
||||
stack_size--;
|
||||
return stack[stack_size];
|
||||
}
|
||||
|
||||
uint
|
||||
read_uint (inout uint reader)
|
||||
{
|
||||
@ -102,6 +119,27 @@ color_matrix_pattern (inout uint reader,
|
||||
color = color_premultiply (color);
|
||||
}
|
||||
|
||||
void
|
||||
repeat_push_pattern (inout uint reader,
|
||||
inout vec2 pos)
|
||||
{
|
||||
stack_push (vec4 (pos, 0.0, 0.0));
|
||||
Rect bounds = read_rect (reader);
|
||||
|
||||
vec2 size = rect_size (bounds);
|
||||
pos = mod (pos - bounds.bounds.xy, size);
|
||||
/* make sure we have a positive result */
|
||||
pos = mix (pos, pos + size, lessThan (pos, vec2 (0.0)));
|
||||
pos += bounds.bounds.xy;
|
||||
}
|
||||
|
||||
void
|
||||
position_pop_pattern (inout uint reader,
|
||||
inout vec2 pos)
|
||||
{
|
||||
pos = stack_pop ().xy;
|
||||
}
|
||||
|
||||
vec4
|
||||
glyphs_pattern (inout uint reader,
|
||||
vec2 pos)
|
||||
@ -250,6 +288,12 @@ pattern (uint reader,
|
||||
case GSK_GPU_PATTERN_CLIP:
|
||||
clip_pattern (reader, color, pos);
|
||||
break;
|
||||
case GSK_GPU_PATTERN_REPEAT_PUSH:
|
||||
repeat_push_pattern (reader, pos);
|
||||
break;
|
||||
case GSK_GPU_PATTERN_POSITION_POP:
|
||||
position_pop_pattern (reader, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ gsk_rect_intersection (const graphene_rect_t *r1,
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
gsk_rect_is_empty (const graphene_rect_t *rect)
|
||||
{
|
||||
return rect->size.width == 0 || rect->size.height == 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_rect_to_float (const graphene_rect_t *rect,
|
||||
float values[4])
|
||||
|
Loading…
Reference in New Issue
Block a user