From de2b10e46c6dad5e02d7046655db1eb57450bb63 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 19:37:51 +0100 Subject: [PATCH 1/7] gpu: Set variable to NULL after freeing Saw this while reviewing code. --- gsk/gpu/gskglframe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsk/gpu/gskglframe.c b/gsk/gpu/gskglframe.c index 6e96e0dfc3..ecc7da5f96 100644 --- a/gsk/gpu/gskglframe.c +++ b/gsk/gpu/gskglframe.c @@ -70,7 +70,7 @@ gsk_gl_frame_cleanup (GskGpuFrame *frame) if (self->sync) { glClientWaitSync (self->sync, 0, -1); - glDeleteSync (self->sync); + g_clear_pointer (&self->sync, glDeleteSync); } self->next_texture_slot = 0; From 153b78e2bc577b0276f6fa35803fa1e44759cdf8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 13:37:31 +0100 Subject: [PATCH 2/7] gpu: Add a ShaderOp.print_instance vfunc ... and add gsk_shader_op_print() to do the generic stuff. --- gsk/gpu/gskgpublendmodeop.c | 18 ++++++------------ gsk/gpu/gskgpublurop.c | 18 ++++++------------ gsk/gpu/gskgpuborderop.c | 19 ++++++------------- gsk/gpu/gskgpuboxshadowop.c | 18 ++++++------------ gsk/gpu/gskgpucolorizeop.c | 18 ++++++------------ gsk/gpu/gskgpucolormatrixop.c | 18 ++++++------------ gsk/gpu/gskgpucolorop.c | 18 ++++++------------ gsk/gpu/gskgpuconicgradientop.c | 18 ++++++------------ gsk/gpu/gskgpucrossfadeop.c | 18 ++++++------------ gsk/gpu/gskgpulineargradientop.c | 21 +++++++-------------- gsk/gpu/gskgpumaskop.c | 18 ++++++------------ gsk/gpu/gskgpuradialgradientop.c | 21 +++++++-------------- gsk/gpu/gskgpuroundedcolorop.c | 18 ++++++------------ gsk/gpu/gskgpushaderop.c | 22 ++++++++++++++++++++++ gsk/gpu/gskgpushaderopprivate.h | 7 +++++++ gsk/gpu/gskgpustraightalphaop.c | 18 ++++++------------ gsk/gpu/gskgputextureop.c | 18 ++++++------------ gsk/gpu/gskgpuuberop.c | 20 +++++++------------- 18 files changed, 128 insertions(+), 198 deletions(-) diff --git a/gsk/gpu/gskgpublendmodeop.c b/gsk/gpu/gskgpublendmodeop.c index cfd51c9136..83d0fbed69 100644 --- a/gsk/gpu/gskgpublendmodeop.c +++ b/gsk/gpu/gskgpublendmodeop.c @@ -17,23 +17,16 @@ struct _GskGpuBlendModeOp }; static void -gsk_gpu_blend_mode_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_blend_mode_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuBlendmodeInstance *instance; + GskGpuBlendmodeInstance *instance = (GskGpuBlendmodeInstance *) instance_; - instance = (GskGpuBlendmodeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "blend-mode"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->bottom_id); gsk_gpu_print_enum (string, GSK_TYPE_BLEND_MODE, shader->variation); gsk_gpu_print_image_descriptor (string, shader->desc, instance->top_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS = { @@ -41,7 +34,7 @@ static const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuBlendModeOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_blend_mode_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -52,6 +45,7 @@ static const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_blendmode_info, #endif + gsk_gpu_blend_mode_op_print_instance, gsk_gpu_blendmode_setup_attrib_locations, gsk_gpu_blendmode_setup_vao }; diff --git a/gsk/gpu/gskgpublurop.c b/gsk/gpu/gskgpublurop.c index fd26bf927e..7b657a1b2d 100644 --- a/gsk/gpu/gskgpublurop.c +++ b/gsk/gpu/gskgpublurop.c @@ -20,22 +20,15 @@ struct _GskGpuBlurOp }; static void -gsk_gpu_blur_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_blur_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuBlurInstance *instance; + GskGpuBlurInstance *instance = (GskGpuBlurInstance *) instance_; - instance = (GskGpuBlurInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "blur"); - gsk_gpu_print_shader_info (string, shader->clip); g_string_append_printf (string, "%g,%g ", instance->blur_direction[0], instance->blur_direction[1]); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = { @@ -43,7 +36,7 @@ static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuBlurOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_blur_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -54,6 +47,7 @@ static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_blur_info, #endif + gsk_gpu_blur_op_print_instance, gsk_gpu_blur_setup_attrib_locations, gsk_gpu_blur_setup_vao }; diff --git a/gsk/gpu/gskgpuborderop.c b/gsk/gpu/gskgpuborderop.c index fb414f53cb..c623b7d7c7 100644 --- a/gsk/gpu/gskgpuborderop.c +++ b/gsk/gpu/gskgpuborderop.c @@ -25,18 +25,12 @@ color_equal (const float *color1, } static void -gsk_gpu_border_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_border_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuBorderInstance *instance; + GskGpuBorderInstance *instance = (GskGpuBorderInstance *) instance_; - instance = (GskGpuBorderInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "border"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rounded_rect (string, instance->outline); gsk_gpu_print_rgba (string, (const float *) &instance->border_colors[0]); @@ -58,8 +52,6 @@ gsk_gpu_border_op_print (GskGpuOp *op, instance->border_widths[2], instance->border_widths[3]); } - - gsk_gpu_print_newline (string); } #ifdef GDK_RENDERING_VULKAN @@ -85,7 +77,7 @@ static const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuBorderOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_border_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_border_op_vk_command, #endif @@ -96,6 +88,7 @@ static const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_border_info, #endif + gsk_gpu_border_op_print_instance, gsk_gpu_border_setup_attrib_locations, gsk_gpu_border_setup_vao }; diff --git a/gsk/gpu/gskgpuboxshadowop.c b/gsk/gpu/gskgpuboxshadowop.c index 399c43b212..1b8d1df3e3 100644 --- a/gsk/gpu/gskgpuboxshadowop.c +++ b/gsk/gpu/gskgpuboxshadowop.c @@ -20,24 +20,17 @@ struct _GskGpuBoxShadowOp }; static void -gsk_gpu_box_shadow_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_box_shadow_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuBoxshadowInstance *instance; + GskGpuBoxshadowInstance *instance = (GskGpuBoxshadowInstance *) instance_; - instance = (GskGpuBoxshadowInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, shader->variation & VARIATION_INSET ? "inset-shadow" : "outset-shadow"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rounded_rect (string, instance->outline); gsk_gpu_print_rgba (string, instance->color); g_string_append_printf (string, "%g %g %g %g ", instance->shadow_offset[0], instance->shadow_offset[1], instance->blur_radius, instance->shadow_spread); - gsk_gpu_print_newline (string); } #ifdef GDK_RENDERING_VULKAN @@ -63,7 +56,7 @@ static const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuBoxShadowOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_box_shadow_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_box_shadow_op_vk_command, #endif @@ -74,6 +67,7 @@ static const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_boxshadow_info, #endif + gsk_gpu_box_shadow_op_print_instance, gsk_gpu_boxshadow_setup_attrib_locations, gsk_gpu_boxshadow_setup_vao }; diff --git a/gsk/gpu/gskgpucolorizeop.c b/gsk/gpu/gskgpucolorizeop.c index 9c3d948e8c..98d03eb9e0 100644 --- a/gsk/gpu/gskgpucolorizeop.c +++ b/gsk/gpu/gskgpucolorizeop.c @@ -16,22 +16,15 @@ struct _GskGpuColorizeOp }; static void -gsk_gpu_colorize_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_colorize_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuColorizeInstance *instance; + GskGpuColorizeInstance *instance = (GskGpuColorizeInstance *) instance_; - instance = (GskGpuColorizeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "colorize"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id); gsk_gpu_print_rgba (string, instance->color); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = { @@ -39,7 +32,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuColorizeOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_colorize_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -50,6 +43,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_colorize_info, #endif + gsk_gpu_colorize_op_print_instance, gsk_gpu_colorize_setup_attrib_locations, gsk_gpu_colorize_setup_vao }; diff --git a/gsk/gpu/gskgpucolormatrixop.c b/gsk/gpu/gskgpucolormatrixop.c index 337be07b7a..e3eb1c8d5a 100644 --- a/gsk/gpu/gskgpucolormatrixop.c +++ b/gsk/gpu/gskgpucolormatrixop.c @@ -16,21 +16,14 @@ struct _GskGpuColorMatrixOp }; static void -gsk_gpu_color_matrix_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_color_matrix_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuColormatrixInstance *instance; + GskGpuColormatrixInstance *instance = (GskGpuColormatrixInstance *) instance_; - instance = (GskGpuColormatrixInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "color-matrix"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS = { @@ -38,7 +31,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuColorMatrixOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_color_matrix_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -49,6 +42,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_colormatrix_info, #endif + gsk_gpu_color_matrix_op_print_instance, gsk_gpu_colormatrix_setup_attrib_locations, gsk_gpu_colormatrix_setup_vao }; diff --git a/gsk/gpu/gskgpucolorop.c b/gsk/gpu/gskgpucolorop.c index 219343988c..0d8cf77c42 100644 --- a/gsk/gpu/gskgpucolorop.c +++ b/gsk/gpu/gskgpucolorop.c @@ -17,21 +17,14 @@ struct _GskGpuColorOp }; static void -gsk_gpu_color_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_color_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuColorInstance *instance; + GskGpuColorInstance *instance = (GskGpuColorInstance *) instance_; - instance = (GskGpuColorInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "color"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_rgba (string, instance->color); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = { @@ -39,7 +32,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuColorOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_color_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -50,6 +43,7 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_color_info, #endif + gsk_gpu_color_op_print_instance, gsk_gpu_color_setup_attrib_locations, gsk_gpu_color_setup_vao }; diff --git a/gsk/gpu/gskgpuconicgradientop.c b/gsk/gpu/gskgpuconicgradientop.c index 1f14fbdbbc..a9a8c85cfe 100644 --- a/gsk/gpu/gskgpuconicgradientop.c +++ b/gsk/gpu/gskgpuconicgradientop.c @@ -18,20 +18,13 @@ struct _GskGpuConicGradientOp }; static void -gsk_gpu_conic_gradient_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_conic_gradient_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuConicgradientInstance *instance; + GskGpuConicgradientInstance *instance = (GskGpuConicgradientInstance *) instance_; - instance = (GskGpuConicgradientInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "conic-gradient"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = { @@ -39,7 +32,7 @@ static const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuConicGradientOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_conic_gradient_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -50,6 +43,7 @@ static const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_conicgradient_info, #endif + gsk_gpu_conic_gradient_op_print_instance, gsk_gpu_conicgradient_setup_attrib_locations, gsk_gpu_conicgradient_setup_vao }; diff --git a/gsk/gpu/gskgpucrossfadeop.c b/gsk/gpu/gskgpucrossfadeop.c index a40f91a92c..37f32b45d3 100644 --- a/gsk/gpu/gskgpucrossfadeop.c +++ b/gsk/gpu/gskgpucrossfadeop.c @@ -16,23 +16,16 @@ struct _GskGpuCrossFadeOp }; static void -gsk_gpu_cross_fade_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_cross_fade_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuCrossfadeInstance *instance; + GskGpuCrossfadeInstance *instance = (GskGpuCrossfadeInstance *) instance_; - instance = (GskGpuCrossfadeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "cross-fade"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->start_id); gsk_gpu_print_image_descriptor (string, shader->desc, instance->end_id); g_string_append_printf (string, "%g%%", 100 * instance->opacity_progress[1]); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = { @@ -40,7 +33,7 @@ static const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuCrossFadeOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_cross_fade_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -51,6 +44,7 @@ static const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_crossfade_info, #endif + gsk_gpu_cross_fade_op_print_instance, gsk_gpu_crossfade_setup_attrib_locations, gsk_gpu_crossfade_setup_vao }; diff --git a/gsk/gpu/gskgpulineargradientop.c b/gsk/gpu/gskgpulineargradientop.c index ae2a0ac626..b616d41457 100644 --- a/gsk/gpu/gskgpulineargradientop.c +++ b/gsk/gpu/gskgpulineargradientop.c @@ -19,23 +19,15 @@ struct _GskGpuLinearGradientOp }; static void -gsk_gpu_linear_gradient_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_linear_gradient_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuLineargradientInstance *instance; - - instance = (GskGpuLineargradientInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); + GskGpuLineargradientInstance *instance = (GskGpuLineargradientInstance *) instance_; if (shader->variation & VARIATION_REPEATING) - gsk_gpu_print_op (string, indent, "repeating-linear-gradient"); - else - gsk_gpu_print_op (string, indent, "linear-gradient"); - gsk_gpu_print_shader_info (string, shader->clip); + gsk_gpu_print_string (string, "repeating"); gsk_gpu_print_rect (string, instance->rect); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = { @@ -43,7 +35,7 @@ static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuLinearGradientOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_linear_gradient_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -54,6 +46,7 @@ static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_lineargradient_info, #endif + gsk_gpu_linear_gradient_op_print_instance, gsk_gpu_lineargradient_setup_attrib_locations, gsk_gpu_lineargradient_setup_vao }; diff --git a/gsk/gpu/gskgpumaskop.c b/gsk/gpu/gskgpumaskop.c index 4f6414d9ec..b57f525049 100644 --- a/gsk/gpu/gskgpumaskop.c +++ b/gsk/gpu/gskgpumaskop.c @@ -16,22 +16,15 @@ struct _GskGpuMaskOp }; static void -gsk_gpu_mask_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_mask_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuMaskInstance *instance; + GskGpuMaskInstance *instance = (GskGpuMaskInstance *) instance_; - instance = (GskGpuMaskInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "mask"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->source_id); gsk_gpu_print_image_descriptor (string, shader->desc, instance->mask_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS = { @@ -39,7 +32,7 @@ static const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuMaskOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_mask_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -50,6 +43,7 @@ static const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_mask_info, #endif + gsk_gpu_mask_op_print_instance, gsk_gpu_mask_setup_attrib_locations, gsk_gpu_mask_setup_vao }; diff --git a/gsk/gpu/gskgpuradialgradientop.c b/gsk/gpu/gskgpuradialgradientop.c index ea75fd56a8..36004c6cfc 100644 --- a/gsk/gpu/gskgpuradialgradientop.c +++ b/gsk/gpu/gskgpuradialgradientop.c @@ -19,23 +19,15 @@ struct _GskGpuRadialGradientOp }; static void -gsk_gpu_radial_gradient_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_radial_gradient_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuRadialgradientInstance *instance; - - instance = (GskGpuRadialgradientInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); + GskGpuRadialgradientInstance *instance = (GskGpuRadialgradientInstance *) instance_; if (shader->variation & VARIATION_REPEATING) - gsk_gpu_print_op (string, indent, "repeating-radial-gradient"); - else - gsk_gpu_print_op (string, indent, "radial-gradient"); - gsk_gpu_print_shader_info (string, shader->clip); + gsk_gpu_print_string (string, "repeating"); gsk_gpu_print_rect (string, instance->rect); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = { @@ -43,7 +35,7 @@ static const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuRadialGradientOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_radial_gradient_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -54,6 +46,7 @@ static const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_radialgradient_info, #endif + gsk_gpu_radial_gradient_op_print_instance, gsk_gpu_radialgradient_setup_attrib_locations, gsk_gpu_radialgradient_setup_vao }; diff --git a/gsk/gpu/gskgpuroundedcolorop.c b/gsk/gpu/gskgpuroundedcolorop.c index e9be14978d..41b898a6cd 100644 --- a/gsk/gpu/gskgpuroundedcolorop.c +++ b/gsk/gpu/gskgpuroundedcolorop.c @@ -17,21 +17,14 @@ struct _GskGpuRoundedColorOp }; static void -gsk_gpu_rounded_color_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_rounded_color_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuRoundedcolorInstance *instance; + GskGpuRoundedcolorInstance *instance = (GskGpuRoundedcolorInstance *) instance_; - instance = (GskGpuRoundedcolorInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "rounded-color"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rounded_rect (string, instance->outline); gsk_gpu_print_rgba (string, instance->color); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = { @@ -39,7 +32,7 @@ static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuRoundedColorOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_rounded_color_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -50,6 +43,7 @@ static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_roundedcolor_info, #endif + gsk_gpu_rounded_color_op_print_instance, gsk_gpu_roundedcolor_setup_attrib_locations, gsk_gpu_roundedcolor_setup_vao }; diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index c6ce9e07bd..177f85beae 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -3,6 +3,7 @@ #include "gskgpushaderopprivate.h" #include "gskgpuframeprivate.h" +#include "gskgpuprintprivate.h" #include "gskgldescriptorsprivate.h" #include "gskgldeviceprivate.h" #include "gskglframeprivate.h" @@ -26,6 +27,27 @@ gsk_gpu_shader_op_finish (GskGpuOp *op) g_clear_object (&self->desc); } +void +gsk_gpu_shader_op_print (GskGpuOp *op, + GskGpuFrame *frame, + GString *string, + guint indent) +{ + GskGpuShaderOp *shader = (GskGpuShaderOp *) op; + const GskGpuShaderOpClass *shader_class = (const GskGpuShaderOpClass *) op->op_class; + gpointer instance; + + instance = gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); + + if (g_str_has_prefix (shader_class->shader_name, "gskgpu")) + gsk_gpu_print_op (string, indent, shader_class->shader_name + 6); + else + gsk_gpu_print_op (string, indent, shader_class->shader_name); + gsk_gpu_print_shader_info (string, shader->clip); + shader_class->print_instance (shader, instance, string); + gsk_gpu_print_newline (string); +} + #ifdef GDK_RENDERING_VULKAN GskGpuOp * gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, diff --git a/gsk/gpu/gskgpushaderopprivate.h b/gsk/gpu/gskgpushaderopprivate.h index f7759a6115..f92c91a54f 100644 --- a/gsk/gpu/gskgpushaderopprivate.h +++ b/gsk/gpu/gskgpushaderopprivate.h @@ -25,6 +25,9 @@ struct _GskGpuShaderOpClass #ifdef GDK_RENDERING_VULKAN const VkPipelineVertexInputStateCreateInfo *vertex_input_state; #endif + void (* print_instance) (GskGpuShaderOp *shader, + gpointer instance, + GString *string); void (* setup_attrib_locations) (GLuint program); void (* setup_vao) (gsize offset); }; @@ -38,6 +41,10 @@ GskGpuShaderOp * gsk_gpu_shader_op_alloc (GskGpuF void gsk_gpu_shader_op_finish (GskGpuOp *op); +void gsk_gpu_shader_op_print (GskGpuOp *op, + GskGpuFrame *frame, + GString *string, + guint indent); #ifdef GDK_RENDERING_VULKAN GskGpuOp * gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, GskGpuFrame *frame, diff --git a/gsk/gpu/gskgpustraightalphaop.c b/gsk/gpu/gskgpustraightalphaop.c index 3a252978c9..1e9b784627 100644 --- a/gsk/gpu/gskgpustraightalphaop.c +++ b/gsk/gpu/gskgpustraightalphaop.c @@ -19,21 +19,14 @@ struct _GskGpuStraightAlphaOp }; static void -gsk_gpu_straight_alpha_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_straight_alpha_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuStraightalphaInstance *instance; + GskGpuStraightalphaInstance *instance = (GskGpuStraightalphaInstance *) instance_; - instance = (GskGpuStraightalphaInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "straight-alpha"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS = { @@ -41,7 +34,7 @@ static const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuStraightAlphaOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_straight_alpha_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -52,6 +45,7 @@ static const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_straightalpha_info, #endif + gsk_gpu_straight_alpha_op_print_instance, gsk_gpu_straightalpha_setup_attrib_locations, gsk_gpu_straightalpha_setup_vao }; diff --git a/gsk/gpu/gskgputextureop.c b/gsk/gpu/gskgputextureop.c index 09c169664f..1856b53685 100644 --- a/gsk/gpu/gskgputextureop.c +++ b/gsk/gpu/gskgputextureop.c @@ -16,21 +16,14 @@ struct _GskGpuTextureOp }; static void -gsk_gpu_texture_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_texture_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuTextureInstance *instance; + GskGpuTextureInstance *instance = (GskGpuTextureInstance *) instance_; - instance = (GskGpuTextureInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "texture"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS = { @@ -38,7 +31,7 @@ static const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuTextureOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_texture_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -49,6 +42,7 @@ static const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_texture_info, #endif + gsk_gpu_texture_op_print_instance, gsk_gpu_texture_setup_attrib_locations, gsk_gpu_texture_setup_vao }; diff --git a/gsk/gpu/gskgpuuberop.c b/gsk/gpu/gskgpuuberop.c index cd5e4f4d22..616b3c499e 100644 --- a/gsk/gpu/gskgpuuberop.c +++ b/gsk/gpu/gskgpuuberop.c @@ -17,20 +17,13 @@ struct _GskGpuUberOp }; static void -gsk_gpu_uber_op_print (GskGpuOp *op, - GskGpuFrame *frame, - GString *string, - guint indent) +gsk_gpu_uber_op_print_instance (GskGpuShaderOp *shader, + gpointer instance_, + GString *string) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; - GskGpuUberInstance *instance; + GskGpuUberInstance *instance = instance_; - instance = (GskGpuUberInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); - - gsk_gpu_print_op (string, indent, "uber"); - gsk_gpu_print_shader_info (string, shader->clip); gsk_gpu_print_rect (string, instance->rect); - gsk_gpu_print_newline (string); } static const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS = { @@ -38,7 +31,7 @@ static const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS = { GSK_GPU_OP_SIZE (GskGpuUberOp), GSK_GPU_STAGE_SHADER, gsk_gpu_shader_op_finish, - gsk_gpu_uber_op_print, + gsk_gpu_shader_op_print, #ifdef GDK_RENDERING_VULKAN gsk_gpu_shader_op_vk_command, #endif @@ -49,8 +42,9 @@ static const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS = { #ifdef GDK_RENDERING_VULKAN &gsk_gpu_uber_info, #endif + gsk_gpu_uber_op_print_instance, gsk_gpu_uber_setup_attrib_locations, - gsk_gpu_uber_setup_vao + gsk_gpu_uber_setup_vao, }; void From 975cdd8c30f3e28d9a9867fa22cb410f4c22921f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 13:42:40 +0100 Subject: [PATCH 3/7] gpu: Remove unused return value from function Technically, an alloc() function should return what it allocated. But the return value is never used. Maybe we should rename the function? --- gsk/gpu/gskgpushaderop.c | 4 +--- gsk/gpu/gskgpushaderopprivate.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index 177f85beae..28c7f5f4f1 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -204,7 +204,7 @@ gsk_gpu_shader_op_gl_command (GskGpuOp *op, return gsk_gpu_shader_op_gl_command_n (op, frame, state, 1); } -GskGpuShaderOp * +void gsk_gpu_shader_op_alloc (GskGpuFrame *frame, const GskGpuShaderOpClass *op_class, guint32 variation, @@ -225,7 +225,5 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, self->vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size); *((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, self->vertex_offset); - - return self; } diff --git a/gsk/gpu/gskgpushaderopprivate.h b/gsk/gpu/gskgpushaderopprivate.h index f92c91a54f..42d8bbc7ba 100644 --- a/gsk/gpu/gskgpushaderopprivate.h +++ b/gsk/gpu/gskgpushaderopprivate.h @@ -32,7 +32,7 @@ struct _GskGpuShaderOpClass void (* setup_vao) (gsize offset); }; -GskGpuShaderOp * gsk_gpu_shader_op_alloc (GskGpuFrame *frame, +void gsk_gpu_shader_op_alloc (GskGpuFrame *frame, const GskGpuShaderOpClass *op_class, guint32 variation, GskGpuShaderClip clip, From 28a8dc5a148a48c6ffb9822af23a3a755e764501 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 18:55:48 +0100 Subject: [PATCH 4/7] gpu: Add GskGpuShaderOp.n_ops This just introduces the variable and sets it to 1 everywhere. The ultimate goal is to allow one ShaderOp to collect multiple ops into one, thereby saving memory in the ops array and leading to faster performance. --- gsk/gpu/gskgpushaderop.c | 36 +++++++++++++++++++++------------ gsk/gpu/gskgpushaderopprivate.h | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index 28c7f5f4f1..aa9d746a7f 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -33,19 +33,28 @@ gsk_gpu_shader_op_print (GskGpuOp *op, GString *string, guint indent) { - GskGpuShaderOp *shader = (GskGpuShaderOp *) op; + GskGpuShaderOp *self = (GskGpuShaderOp *) op; const GskGpuShaderOpClass *shader_class = (const GskGpuShaderOpClass *) op->op_class; - gpointer instance; - - instance = gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset); + const char *shader_name; + guchar *instance; + gsize i; if (g_str_has_prefix (shader_class->shader_name, "gskgpu")) - gsk_gpu_print_op (string, indent, shader_class->shader_name + 6); + shader_name = shader_class->shader_name + 6; else - gsk_gpu_print_op (string, indent, shader_class->shader_name); - gsk_gpu_print_shader_info (string, shader->clip); - shader_class->print_instance (shader, instance, string); - gsk_gpu_print_newline (string); + shader_name = shader_class->shader_name; + + instance = gsk_gpu_frame_get_vertex_data (frame, self->vertex_offset); + + for (i = 0; i < self->n_ops; i++) + { + gsk_gpu_print_op (string, indent, shader_name); + gsk_gpu_print_shader_info (string, self->clip); + shader_class->print_instance (self, + instance + i * shader_class->vertex_size, + string); + gsk_gpu_print_newline (string); + } } #ifdef GDK_RENDERING_VULKAN @@ -67,7 +76,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, n = MAX_MERGE_OPS; else n = 1; - i = 1; + i = self->n_ops; desc = GSK_VULKAN_DESCRIPTORS (self->desc); if (desc && state->desc != desc) { @@ -86,7 +95,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, next_shader->vertex_offset != self->vertex_offset + i * shader_op_class->vertex_size) break; - i++; + i += next_shader->n_ops; } vkCmdBindPipeline (state->vk_command_buffer, @@ -160,7 +169,7 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, n = MAX_MERGE_OPS; else n = 1; - i = 1; + i = self->n_ops; for (next = op->next; next && i < n; next = next->next) { GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next; @@ -172,7 +181,7 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, next_shader->vertex_offset != self->vertex_offset + i * shader_op_class->vertex_size) break; - i++; + i += next_shader->n_ops; } if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE)) @@ -223,6 +232,7 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, else self->desc = NULL; self->vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size); + self->n_ops = 1; *((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, self->vertex_offset); } diff --git a/gsk/gpu/gskgpushaderopprivate.h b/gsk/gpu/gskgpushaderopprivate.h index 42d8bbc7ba..3276d1cdef 100644 --- a/gsk/gpu/gskgpushaderopprivate.h +++ b/gsk/gpu/gskgpushaderopprivate.h @@ -14,6 +14,7 @@ struct _GskGpuShaderOp guint32 variation; GskGpuShaderClip clip; gsize vertex_offset; + gsize n_ops; }; struct _GskGpuShaderOpClass From bad6e1e102dfd3312b2e9112dacd7186af06d921 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 19:25:07 +0100 Subject: [PATCH 5/7] gpu: Change the way we merge draw calls With potentially multiple ops per ShaderOp, we may encounter situations where 1 ShaderOp contains more ops than we want to merge. (With GSK_GPU_SKIP=merge, we don't want to merge at all.) So we still merge the ShaderOps (now unconditionally), but we then run a loop that potentially splits the merged ops again - exactly at the point we want to. This way we can merge ops inside of ShaderOps and merge ShaderOps, but still have the draw calls contain the exact number of ops we want. --- gsk/gpu/gskgpushaderop.c | 72 ++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index aa9d746a7f..d074feadf8 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -68,15 +68,15 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, GskGpuShaderOpClass *shader_op_class = (GskGpuShaderOpClass *) op->op_class; GskVulkanDescriptors *desc; GskGpuOp *next; - gsize i, n; + gsize i, n_ops, max_ops_per_draw; if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MERGE) && gsk_vulkan_device_has_feature (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING)) - n = MAX_MERGE_OPS; + max_ops_per_draw = MAX_MERGE_OPS; else - n = 1; - i = self->n_ops; + max_ops_per_draw = 1; + desc = GSK_VULKAN_DESCRIPTORS (self->desc); if (desc && state->desc != desc) { @@ -84,7 +84,8 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, state->desc = desc; } - for (next = op->next; next && i < n; next = next->next) + n_ops = self->n_ops; + for (next = op->next; next; next = next->next) { GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next; @@ -92,10 +93,10 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, next_shader->desc != self->desc || next_shader->variation != self->variation || next_shader->clip != self->clip || - next_shader->vertex_offset != self->vertex_offset + i * shader_op_class->vertex_size) + next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size) break; - i += next_shader->n_ops; + n_ops += next_shader->n_ops; } vkCmdBindPipeline (state->vk_command_buffer, @@ -109,10 +110,13 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, state->vk_format, state->vk_render_pass)); - vkCmdDraw (state->vk_command_buffer, - 6 * instance_scale, i, - 0, self->vertex_offset / shader_op_class->vertex_size); - + for (i = 0; i < n_ops; i += max_ops_per_draw) + { + vkCmdDraw (state->vk_command_buffer, + 6 * instance_scale, MIN (max_ops_per_draw, n_ops - i), + 0, self->vertex_offset / shader_op_class->vertex_size + i); + } + return next; } @@ -135,7 +139,7 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, GskGpuShaderOpClass *shader_op_class = (GskGpuShaderOpClass *) op->op_class; GskGLDescriptors *desc; GskGpuOp *next; - gsize i, n, n_external; + gsize i, n_ops, n_external, max_ops_per_draw; desc = GSK_GL_DESCRIPTORS (self->desc); if (desc) @@ -166,11 +170,12 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, } if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MERGE)) - n = MAX_MERGE_OPS; + max_ops_per_draw = MAX_MERGE_OPS; else - n = 1; - i = self->n_ops; - for (next = op->next; next && i < n; next = next->next) + max_ops_per_draw = 1; + + n_ops = self->n_ops; + for (next = op->next; next; next = next->next) { GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next; @@ -178,28 +183,31 @@ gsk_gpu_shader_op_gl_command_n (GskGpuOp *op, next_shader->desc != self->desc || next_shader->variation != self->variation || next_shader->clip != self->clip || - next_shader->vertex_offset != self->vertex_offset + i * shader_op_class->vertex_size) + next_shader->vertex_offset != self->vertex_offset + n_ops * shader_op_class->vertex_size) break; - i += next_shader->n_ops; + n_ops += next_shader->n_ops; } - if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE)) + for (i = 0; i < n_ops; i += max_ops_per_draw) { - glDrawArraysInstancedBaseInstance (GL_TRIANGLES, - 0, - 6 * instance_scale, - i, - self->vertex_offset / shader_op_class->vertex_size); - } - else - { - shader_op_class->setup_vao (self->vertex_offset); + if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE)) + { + glDrawArraysInstancedBaseInstance (GL_TRIANGLES, + 0, + 6 * instance_scale, + MIN (max_ops_per_draw, n_ops - i), + self->vertex_offset / shader_op_class->vertex_size + i); + } + else + { + shader_op_class->setup_vao (self->vertex_offset + i * shader_op_class->vertex_size); - glDrawArraysInstanced (GL_TRIANGLES, - 0, - 6 * instance_scale, - i); + glDrawArraysInstanced (GL_TRIANGLES, + 0, + 6 * instance_scale, + MIN (max_ops_per_draw, n_ops - i)); + } } return next; From d51912c0b42d86beb752caac578498daee9e8a34 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 5 Mar 2024 09:07:09 -0500 Subject: [PATCH 6/7] gsk: Add gsk_gpu_frame_get_last_op This function will be used in the future to find the previous op during node processing, so we can make optimization decisions based on that. --- gsk/gpu/gskgpuframe.c | 19 +++++++++++++++++-- gsk/gpu/gskgpuframeprivate.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index 7b60d5a32b..d4045968e3 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -40,6 +40,7 @@ struct _GskGpuFramePrivate GskGpuOps ops; GskGpuOp *first_op; + GskGpuOp *last_op; GskGpuBuffer *vertex_buffer; guchar *vertex_buffer_data; @@ -70,6 +71,8 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self) gsk_gpu_op_finish (op); } gsk_gpu_ops_set_size (&priv->ops, 0); + + priv->last_op = NULL; } static void @@ -331,7 +334,7 @@ gsk_gpu_frame_sort_ops (GskGpuFrame *self) { GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); SortData sort_data = { { NULL, }, }; - + gsk_gpu_frame_sort_render_pass (self, priv->first_op, &sort_data); if (sort_data.upload.first) @@ -343,6 +346,8 @@ gsk_gpu_frame_sort_ops (GskGpuFrame *self) priv->first_op = sort_data.command.first; if (sort_data.command.last) sort_data.command.last->next = NULL; + + priv->last_op = NULL; } gpointer @@ -360,7 +365,17 @@ gsk_gpu_frame_alloc_op (GskGpuFrame *self, NULL, size); - return gsk_gpu_ops_index (&priv->ops, pos); + priv->last_op = (GskGpuOp *) gsk_gpu_ops_index (&priv->ops, pos); + + return priv->last_op; +} + +GskGpuOp * +gsk_gpu_frame_get_last_op (GskGpuFrame *self) +{ + GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); + + return priv->last_op; } GskGpuImage * diff --git a/gsk/gpu/gskgpuframeprivate.h b/gsk/gpu/gskgpuframeprivate.h index db0681a9cc..10dfbf0aa9 100644 --- a/gsk/gpu/gskgpuframeprivate.h +++ b/gsk/gpu/gskgpuframeprivate.h @@ -85,6 +85,7 @@ void gsk_gpu_frame_download_texture (GskGpuF GdkMemoryFormat format, guchar *data, gsize stride); +GskGpuOp *gsk_gpu_frame_get_last_op (GskGpuFrame *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuFrame, g_object_unref) From 93cdcc5e88e861391a6d3ff352a1d453b6350365 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Mar 2024 19:30:42 +0100 Subject: [PATCH 7/7] gpu: Merge multiple ops into one ShaderOp When ops get allocated that use the same stats as the last op, put them into the same ShaderOp. This reduces the number of ShaderOps we need to record, which has 3 benefits: 1. It's less work when iterating over all the ops. This isn't a big win, but it makes submit() and print() run a bit faster. 2. We don't need to manage data per-op. This is a large win because we don't need to ref/unref descriptors as much anymore, and refcounting is visible on profiles. 3. We save memory. This is a pretty big win because we iterate over ops a lot, and when the array is large enough (I've managed to write testcases that makes it grow to over 4GB) it kills all the caches and that's bad. The main benefit of all this are glyphs, which used to emit 1 ShaderOp per glyph and can now end up with 1 ShaderOp for multiple text nodes, even if those text nodes use different fonts or colors - because they can all share the same ColorizeOp. --- gsk/gpu/gskgpushaderop.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index d074feadf8..5b076c429d 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -229,19 +229,39 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame, GskGpuDescriptors *desc, gpointer out_vertex_data) { - GskGpuShaderOp *self; + GskGpuOp *last; + GskGpuShaderOp *last_shader; + gsize vertex_offset; - self = (GskGpuShaderOp *) gsk_gpu_op_alloc (frame, &op_class->parent_class); + vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size); - self->variation = variation; - self->clip = clip; - if (desc) - self->desc = g_object_ref (desc); + last = gsk_gpu_frame_get_last_op (frame); + /* careful: We're casting without checking, but the if() does the check */ + last_shader = (GskGpuShaderOp *) last; + if (last && + last->op_class == (const GskGpuOpClass *) op_class && + last_shader->desc == desc && + last_shader->variation == variation && + last_shader->clip == clip && + last_shader->vertex_offset + last_shader->n_ops * op_class->vertex_size == vertex_offset) + { + last_shader->n_ops++; + } else - self->desc = NULL; - self->vertex_offset = gsk_gpu_frame_reserve_vertex_data (frame, op_class->vertex_size); - self->n_ops = 1; + { + GskGpuShaderOp *self; + self = (GskGpuShaderOp *) gsk_gpu_op_alloc (frame, &op_class->parent_class); - *((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, self->vertex_offset); + self->variation = variation; + self->clip = clip; + self->vertex_offset = vertex_offset; + if (desc) + self->desc = g_object_ref (desc); + else + self->desc = NULL; + self->n_ops = 1; + } + + *((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, vertex_offset); }