gpu: Add scissor operation

Nothing is using it yet (we don't do clipping) apart from initializing
the scissor rect at startup.
This commit is contained in:
Benjamin Otte 2023-08-28 10:42:04 +02:00
parent 77e05a4240
commit e2b5e0d17d
5 changed files with 121 additions and 6 deletions

View File

@ -76,6 +76,8 @@ gsk_gl_frame_submit (GskGpuFrame *frame,
{
GskGLFrame *self = GSK_GL_FRAME (frame);
glEnable (GL_SCISSOR_TEST);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LEQUAL);

View File

@ -6,6 +6,7 @@
#include "gskgpuframeprivate.h"
#include "gskgpuglobalsopprivate.h"
#include "gskgpuimageprivate.h"
#include "gskgpuscissoropprivate.h"
#include "gskgputextureopprivate.h"
#include "gskgpuuploadopprivate.h"
@ -62,9 +63,10 @@
typedef struct _GskGpuNodeProcessor GskGpuNodeProcessor;
typedef enum {
GSK_GPU_GLOBAL_MATRIX = (1 << 0),
GSK_GPU_GLOBAL_SCALE = (1 << 1),
GSK_GPU_GLOBAL_CLIP = (1 << 2)
GSK_GPU_GLOBAL_MATRIX = (1 << 0),
GSK_GPU_GLOBAL_SCALE = (1 << 1),
GSK_GPU_GLOBAL_CLIP = (1 << 2),
GSK_GPU_GLOBAL_SCISSOR = (1 << 3),
} GskGpuGlobals;
struct _GskGpuNodeProcessor
@ -108,7 +110,7 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
gsk_gpu_image_get_height (target) / viewport->size.height);
self->offset = GRAPHENE_POINT_INIT (-viewport->origin.x,
-viewport->origin.y);
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP;
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR;
}
static void
@ -132,6 +134,14 @@ gsk_gpu_node_processor_emit_globals_op (GskGpuNodeProcessor *self)
self->pending_globals &= ~(GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP);
}
static void
gsk_gpu_node_processor_emit_scissor_op (GskGpuNodeProcessor *self)
{
gsk_gpu_scissor_op (self->frame,
&self->scissor);
self->pending_globals &= ~GSK_GPU_GLOBAL_SCISSOR;
}
void
gsk_gpu_node_processor_process (GskGpuFrame *frame,
GskGpuImage *target,
@ -373,7 +383,7 @@ static const struct
NULL,
},
[GSK_CONTAINER_NODE] = {
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP,
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
gsk_gpu_node_processor_add_container_node,
},
[GSK_CAIRO_NODE] = {
@ -421,7 +431,7 @@ static const struct
NULL,
},
[GSK_TRANSFORM_NODE] = {
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP,
GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR,
gsk_gpu_node_processor_add_transform_node,
},
[GSK_OPACITY_NODE] = {
@ -519,6 +529,8 @@ gsk_gpu_node_processor_add_node (GskGpuNodeProcessor *self,
required_globals = self->pending_globals & ~nodes_vtable[node_type].ignored_globals;
if (required_globals & (GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP))
gsk_gpu_node_processor_emit_globals_op (self);
if (required_globals & GSK_GPU_GLOBAL_SCISSOR)
gsk_gpu_node_processor_emit_scissor_op (self);
g_assert ((self->pending_globals & ~nodes_vtable[node_type].ignored_globals) == 0);
if (nodes_vtable[node_type].process_node)

88
gsk/gpu/gskgpuscissorop.c Normal file
View File

@ -0,0 +1,88 @@
#include "config.h"
#include "gskgpuscissoropprivate.h"
#include "gskgpuopprivate.h"
#include "gskgpuprintprivate.h"
typedef struct _GskGpuScissorOp GskGpuScissorOp;
struct _GskGpuScissorOp
{
GskGpuOp op;
cairo_rectangle_int_t rect;
};
static void
gsk_gpu_scissor_op_finish (GskGpuOp *op)
{
}
static void
gsk_gpu_scissor_op_print (GskGpuOp *op,
GskGpuFrame *frame,
GString *string,
guint indent)
{
GskGpuScissorOp *self = (GskGpuScissorOp *) op;
gsk_gpu_print_op (string, indent, "scissor");
gsk_gpu_print_int_rect (string, &self->rect);
gsk_gpu_print_newline (string);
}
#ifdef GDK_RENDERING_VULKAN
static GskGpuOp *
gsk_gpu_scissor_op_vk_command (GskGpuOp *op,
GskGpuFrame *frame,
VkRenderPass render_pass,
VkFormat format,
VkCommandBuffer command_buffer)
{
GskGpuScissorOp *self = (GskGpuScissorOp *) op;
vkCmdSetScissor (command_buffer,
0,
1,
&(VkRect2D) {
{ self->rect.x, self->rect.y },
{ self->rect.width, self->rect.height },
});
return op->next;
}
#endif
static GskGpuOp *
gsk_gpu_scissor_op_gl_command (GskGpuOp *op,
GskGpuFrame *frame)
{
GskGpuScissorOp *self = (GskGpuScissorOp *) op;
glScissor (self->rect.x, self->rect.y, self->rect.width, self->rect.height);
return op->next;
}
static const GskGpuOpClass GSK_GPU_SCISSOR_OP_CLASS = {
GSK_GPU_OP_SIZE (GskGpuScissorOp),
GSK_GPU_STAGE_COMMAND,
gsk_gpu_scissor_op_finish,
gsk_gpu_scissor_op_print,
#ifdef GDK_RENDERING_VULKAN
gsk_gpu_scissor_op_vk_command,
#endif
gsk_gpu_scissor_op_gl_command
};
void
gsk_gpu_scissor_op (GskGpuFrame *frame,
const cairo_rectangle_int_t *rect)
{
GskGpuScissorOp *self;
self = (GskGpuScissorOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_SCISSOR_OP_CLASS);
self->rect = *rect;
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "gskgputypesprivate.h"
G_BEGIN_DECLS
void gsk_gpu_scissor_op (GskGpuFrame *frame,
const cairo_rectangle_int_t *rect);
G_END_DECLS

View File

@ -85,6 +85,7 @@ gsk_private_sources = files([
'gpu/gskgpurenderer.c',
'gpu/gskgpurenderpassop.c',
'gpu/gskgpushaderop.c',
'gpu/gskgpuscissorop.c',
'gpu/gskgputextureop.c',
'gpu/gskgpuuploadop.c',
'gpu/gsknglrenderer.c',