From 4b3bbe0ecda3042f2705093ecc8d103eecb59c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Fri, 18 Dec 2020 17:29:51 +0100 Subject: [PATCH] gl renderer: Create shader-global uniform ops on draw() This way we can render the first frame of tests/testoutsetshadowdrawing in 153 ops instead of 183. And the first frame of gtk4-demo in 260 instead of 300. --- gsk/gl/gskglrenderops.c | 188 +++++++++++----------------------------- 1 file changed, 53 insertions(+), 135 deletions(-) diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c index 20bd178a3f..be7eff6fba 100644 --- a/gsk/gl/gskglrenderops.c +++ b/gsk/gl/gskglrenderops.c @@ -208,10 +208,9 @@ ops_free (RenderOpBuilder *builder) void ops_set_program (RenderOpBuilder *builder, - Program *program) + Program *program) { OpProgram *op; - ProgramState *program_state = NULL; if (builder->current_program == program) return; @@ -220,86 +219,6 @@ ops_set_program (RenderOpBuilder *builder, op->program = program; builder->current_program = program; - - program_state = &program->state; - - if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0) - { - OpMatrix *opm; - - opm = ops_begin (builder, OP_CHANGE_PROJECTION); - opm->matrix = builder->current_projection; - program_state->projection = builder->current_projection; - } - - if (program_state->modelview == NULL || - !gsk_transform_equal (builder->current_modelview, program_state->modelview)) - { - OpMatrix *opm; - - opm = ops_begin (builder, OP_CHANGE_MODELVIEW); - gsk_transform_to_matrix (builder->current_modelview, &opm->matrix); - gsk_transform_unref (program_state->modelview); - program_state->modelview = gsk_transform_ref (builder->current_modelview); - } - - if (!rect_equal (&builder->current_viewport, &program_state->viewport)) - { - OpViewport *opv; - - opv = ops_begin (builder, OP_CHANGE_VIEWPORT); - opv->viewport = builder->current_viewport; - program_state->viewport = builder->current_viewport; - } - - if (!rounded_rect_equal (builder->current_clip, &program_state->clip)) - { - OpClip *opc; - - opc = ops_begin (builder, OP_CHANGE_CLIP); - opc->clip = *builder->current_clip; - opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip); - program_state->clip = *builder->current_clip; - } - - if (program_state->opacity != builder->current_opacity) - { - OpOpacity *opo; - - opo = ops_begin (builder, OP_CHANGE_OPACITY); - opo->opacity = builder->current_opacity; - program_state->opacity = builder->current_opacity; - } -} - -static void -ops_set_clip (RenderOpBuilder *builder, - const GskRoundedRect *clip) -{ - ProgramState *current_program_state = get_current_program_state (builder); - OpClip *op; - - if (current_program_state && - rounded_rect_equal (¤t_program_state->clip, clip)) - return; - - if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP))) - { - op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP); - op->send_corners = !current_program_state || - !rounded_rect_corners_equal (¤t_program_state->clip, clip); - } - else - { - /* If the op before sent the corners, this one needs, too */ - op->send_corners |= !current_program_state || - !rounded_rect_corners_equal (¤t_program_state->clip, clip); - } - - op->clip = *clip; - - if (current_program_state) - current_program_state->clip = *clip; } void @@ -318,7 +237,6 @@ ops_push_clip (RenderOpBuilder *self, g_array_append_val (self->clip_stack, entry); self->current_clip = &g_array_index (self->clip_stack, ClipStackEntry, self->clip_stack->len - 1).rect; self->clip_is_rectilinear = entry.is_rectilinear; - ops_set_clip (self, clip); } void @@ -336,7 +254,6 @@ ops_pop_clip (RenderOpBuilder *self) { self->current_clip = &head->rect; self->clip_is_rectilinear = head->is_rectilinear; - ops_set_clip (self, &head->rect); } else { @@ -352,31 +269,6 @@ ops_has_clip (RenderOpBuilder *self) self->clip_stack->len > 1; } -static void -ops_set_modelview_internal (RenderOpBuilder *builder, - GskTransform *transform) -{ - ProgramState *current_program_state = get_current_program_state (builder); - - if (current_program_state && - gsk_transform_equal (current_program_state->modelview, transform)) - { - /* We can save us this op entirely... */ - } - else - { - OpMatrix *op = op_buffer_add (&builder->render_ops, OP_CHANGE_MODELVIEW); - - gsk_transform_to_matrix (transform, &op->matrix); - } - - if (builder->current_program != NULL) - { - gsk_transform_unref (current_program_state->modelview); - current_program_state->modelview = gsk_transform_ref (transform); - } -} - /** * ops_set_modelview: * @builder @@ -409,7 +301,6 @@ ops_set_modelview (RenderOpBuilder *builder, builder->current_modelview = entry->transform; builder->scale_x = entry->metadata.scale_x; builder->scale_y = entry->metadata.scale_y; - ops_set_modelview_internal (builder, entry->transform); } /* This sets the given modelview to the one we get when multiplying @@ -455,7 +346,6 @@ ops_push_modelview (RenderOpBuilder *builder, builder->scale_x = entry->metadata.scale_x; builder->scale_y = entry->metadata.scale_y; builder->current_modelview = entry->transform; - ops_set_modelview_internal (builder, entry->transform); } void @@ -479,7 +369,6 @@ ops_pop_modelview (RenderOpBuilder *builder) builder->scale_x = head->metadata.scale_x; builder->scale_y = head->metadata.scale_y; builder->current_modelview = head->transform; - ops_set_modelview_internal (builder, head->transform); } else { @@ -491,17 +380,7 @@ graphene_matrix_t ops_set_projection (RenderOpBuilder *builder, const graphene_matrix_t *projection) { - ProgramState *current_program_state = get_current_program_state (builder); graphene_matrix_t prev_mv; - OpMatrix *op; - - if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_PROJECTION))) - op = op_buffer_add (&builder->render_ops, OP_CHANGE_PROJECTION); - - op->matrix = *projection; - - if (builder->current_program != NULL) - current_program_state->projection = *projection; prev_mv = builder->current_projection; builder->current_projection = *projection; @@ -517,9 +396,8 @@ ops_set_viewport (RenderOpBuilder *builder, OpViewport *op; graphene_rect_t prev_viewport; - if (current_program_state != NULL && - rect_equal (¤t_program_state->viewport, viewport)) - return current_program_state->viewport; + if (rect_equal (&builder->current_viewport, viewport)) + return *viewport; op = ops_begin (builder, OP_CHANGE_VIEWPORT); op->viewport = *viewport; @@ -585,24 +463,14 @@ float ops_set_opacity (RenderOpBuilder *builder, float opacity) { - ProgramState *current_program_state = get_current_program_state (builder); - OpOpacity *op; float prev_opacity; if (builder->current_opacity == opacity) return opacity; - if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_OPACITY))) - op = op_buffer_add (&builder->render_ops, OP_CHANGE_OPACITY); - - op->opacity = opacity; - prev_opacity = builder->current_opacity; builder->current_opacity = opacity; - if (builder->current_program != NULL) - current_program_state->opacity = opacity; - return prev_opacity; } @@ -754,8 +622,58 @@ GskQuadVertex * ops_draw (RenderOpBuilder *builder, const GskQuadVertex vertex_data[GL_N_VERTICES]) { + ProgramState *program_state = get_current_program_state (builder); OpDraw *op; + if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0) + { + OpMatrix *opm; + + opm = ops_begin (builder, OP_CHANGE_PROJECTION); + opm->matrix = builder->current_projection; + program_state->projection = builder->current_projection; + } + + if (program_state->modelview == NULL || + !gsk_transform_equal (builder->current_modelview, program_state->modelview)) + { + OpMatrix *opm; + + opm = ops_begin (builder, OP_CHANGE_MODELVIEW); + gsk_transform_to_matrix (builder->current_modelview, &opm->matrix); + gsk_transform_unref (program_state->modelview); + program_state->modelview = gsk_transform_ref (builder->current_modelview); + } + + if (!rect_equal (&builder->current_viewport, &program_state->viewport)) + { + OpViewport *opv; + + opv = ops_begin (builder, OP_CHANGE_VIEWPORT); + opv->viewport = builder->current_viewport; + program_state->viewport = builder->current_viewport; + } + + if (!rounded_rect_equal (builder->current_clip, &program_state->clip)) + { + OpClip *opc; + + opc = ops_begin (builder, OP_CHANGE_CLIP); + opc->clip = *builder->current_clip; + opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip); + program_state->clip = *builder->current_clip; + } + + if (program_state->opacity != builder->current_opacity) + { + OpOpacity *opo; + + opo = ops_begin (builder, OP_CHANGE_OPACITY); + opo->opacity = builder->current_opacity; + program_state->opacity = builder->current_opacity; + } + + /* TODO: Did the additions above break the following optimization? */ if ((op = op_buffer_peek_tail_checked (&builder->render_ops, OP_DRAW))) { op->vao_size += GL_N_VERTICES;