From c51c3b2660ce32ec859cb83df03a50e088e70b32 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 4 Nov 2023 04:13:57 +0100 Subject: [PATCH] gpu: Cache GL state That way we don't need to setup the textures and program for every command. --- gsk/gpu/gskgpumipmapop.c | 4 ++-- gsk/gpu/gskgpuopprivate.h | 6 ++++++ gsk/gpu/gskgpushaderop.c | 30 +++++++++++++++++++++++------- gsk/gpu/gskgputypesprivate.h | 1 + 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gsk/gpu/gskgpumipmapop.c b/gsk/gpu/gskgpumipmapop.c index 991b532d76..374e6ae199 100644 --- a/gsk/gpu/gskgpumipmapop.c +++ b/gsk/gpu/gskgpumipmapop.c @@ -155,10 +155,10 @@ gsk_gpu_mipmap_op_gl_command (GskGpuOp *op, { GskGpuMipmapOp *self = (GskGpuMipmapOp *) op; - /* not sure the ActiveTexture call is needed, but better not - * use any random texturing instance */ glActiveTexture (GL_TEXTURE0); gsk_gl_image_bind_texture (GSK_GL_IMAGE (self->image)); + /* need to reset the images again */ + state->desc = NULL; glGenerateMipmap (GL_TEXTURE_2D); diff --git a/gsk/gpu/gskgpuopprivate.h b/gsk/gpu/gskgpuopprivate.h index 064a592cd7..3bf98710ad 100644 --- a/gsk/gpu/gskgpuopprivate.h +++ b/gsk/gpu/gskgpuopprivate.h @@ -23,6 +23,12 @@ typedef struct _GskVulkanCommandState GskVulkanCommandState; struct _GskGLCommandState { gsize flip_y; + struct { + const GskGpuOpClass *op_class; + GskGpuShaderClip clip; + gsize n_external; + } current_program; + GskGLDescriptors *desc; }; #ifdef GDK_RENDERING_VULKAN diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index 0ed5a0264c..18a69fb379 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -84,16 +84,32 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, GskGpuShaderOpClass *shader_op_class = (GskGpuShaderOpClass *) op->op_class; GskGLDescriptors *desc; GskGpuOp *next; - gsize i; + gsize i, n_external; desc = GSK_GL_DESCRIPTORS (self->desc); - gsk_gl_frame_use_program (GSK_GL_FRAME (frame), - shader_op_class, - self->clip, - desc ? gsk_gl_descriptors_get_n_external (desc) : 0); - if (desc) - gsk_gl_descriptors_use (GSK_GL_DESCRIPTORS (desc)); + n_external = gsk_gl_descriptors_get_n_external (desc); + else + n_external = 0; + + if (state->current_program.op_class != op->op_class || + state->current_program.clip != self->clip || + state->current_program.n_external != n_external) + { + state->current_program.op_class = op->op_class; + state->current_program.clip = self->clip; + state->current_program.n_external = n_external; + gsk_gl_frame_use_program (GSK_GL_FRAME (frame), + shader_op_class, + self->clip, + n_external); + } + + if (desc != state->desc && desc) + { + gsk_gl_descriptors_use (desc); + state->desc = desc; + } i = 1; for (next = op->next; next && i < 10 * 1000; next = next->next) diff --git a/gsk/gpu/gskgputypesprivate.h b/gsk/gpu/gskgputypesprivate.h index 67a1d1bb8e..286b4f2056 100644 --- a/gsk/gpu/gskgputypesprivate.h +++ b/gsk/gpu/gskgputypesprivate.h @@ -6,6 +6,7 @@ #define GSK_GPU_PATTERN_STACK_SIZE 16 +typedef struct _GskGLDescriptors GskGLDescriptors; typedef struct _GskGpuBuffer GskGpuBuffer; typedef struct _GskGpuDescriptors GskGpuDescriptors; typedef struct _GskGpuDevice GskGpuDevice;