[gtk/wip/chergert/glproto: 794/920] implement non-sliced shadows




commit 444b3cbe0d64b9a367afc341c64a589f883787da
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jan 28 13:34:49 2021 -0800

    implement non-sliced shadows

 gsk/next/gskglrenderjob.c | 200 +++++++++++++++++++++++++++-------------------
 1 file changed, 118 insertions(+), 82 deletions(-)
---
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index 3e0a8ce67d..9cdbd8576a 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -2103,17 +2103,21 @@ static void
 gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
                                                     GskRenderNode  *node)
 {
+  static const GdkRGBA white = { 1, 1, 1, 1 };
+
   const GskRoundedRect *outline = gsk_outset_shadow_node_get_outline (node);
   const GdkRGBA *color = gsk_outset_shadow_node_get_color (node);
-  const float scale_x = job->scale_x;
-  const float scale_y = job->scale_y;
-  const float blur_radius = gsk_outset_shadow_node_get_blur_radius (node);
-  const float blur_extra = blur_radius * 2.0f; /* 2.0 = shader radius_multiplier */
-  const int extra_blur_pixels = (int) ceilf(blur_extra / 2.0 * MAX (scale_x, scale_y)); /* TODO: No need to 
MAX() here actually */
-  const float spread = gsk_outset_shadow_node_get_spread (node);
-  const float dx = gsk_outset_shadow_node_get_dx (node);
-  const float dy = gsk_outset_shadow_node_get_dy (node);
+  float scale_x = job->scale_x;
+  float scale_y = job->scale_y;
+  float blur_radius = gsk_outset_shadow_node_get_blur_radius (node);
+  float blur_extra = blur_radius * 2.0f; /* 2.0 = shader radius_multiplier */
+  float half_blur_extra = blur_extra / 2.0f;
+  int extra_blur_pixels = ceilf (blur_extra / 2.0 * scale_x);
+  float spread = gsk_outset_shadow_node_get_spread (node);
+  float dx = gsk_outset_shadow_node_get_dx (node);
+  float dy = gsk_outset_shadow_node_get_dy (node);
   GskRoundedRect scaled_outline;
+  GskGLRenderOffscreen offscreen = {0};
   int texture_width, texture_height;
   int blurred_texture_id;
   int cached_tid;
@@ -2126,7 +2130,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
   if (outline->bounds.size.width < blur_extra ||
       outline->bounds.size.height < blur_extra)
     {
-      do_slicing = false;
+      do_slicing = FALSE;
       gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
     }
   else
@@ -2136,119 +2140,151 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
       /* Increase by the spread */
       gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
       /* Grow bounds but don't grow corners */
-      graphene_rect_inset (&scaled_outline.bounds, - blur_extra / 2.0, - blur_extra / 2.0);
+      graphene_rect_inset (&scaled_outline.bounds, -half_blur_extra, -half_blur_extra);
       /* For the center part, we add a few pixels */
       scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
       scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
 
-      do_slicing = true;
+      do_slicing = TRUE;
     }
 
-  texture_width  = (int)ceil ((scaled_outline.bounds.size.width  + blur_extra) * scale_x);
-  texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
+  texture_width = ceil ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
+  texture_height = ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
 
   scaled_outline.bounds.origin.x = extra_blur_pixels;
   scaled_outline.bounds.origin.y = extra_blur_pixels;
   scaled_outline.bounds.size.width = texture_width - (extra_blur_pixels * 2);
   scaled_outline.bounds.size.height = texture_height - (extra_blur_pixels * 2);
 
-  for (guint i = 0; i < 4; i ++)
+  for (guint i = 0; i < G_N_ELEMENTS (scaled_outline.corner); i++)
     {
       scaled_outline.corner[i].width *= scale_x;
       scaled_outline.corner[i].height *= scale_y;
     }
 
-#if 0
-  cached_tid = gsk_gl_shadow_library_get_texture_id (job->driver->shadows,
-                                                     &scaled_outline,
-                                                     blur_radius);
-
+  cached_tid = gsk_gl_shadow_library_lookup (job->driver->shadows, &scaled_outline, blur_radius);
 
   if (cached_tid == 0)
     {
-      int texture_id, render_target;
-      int prev_render_target;
-      graphene_matrix_t prev_projection;
-      graphene_rect_t prev_viewport;
-      graphene_matrix_t item_proj;
-
-      gsk_gl_driver_create_render_target (self->gl_driver,
-                                          texture_width, texture_height,
-                                          GL_NEAREST, GL_NEAREST,
-                                          &texture_id, &render_target);
-      if (gdk_gl_context_has_debug (self->gl_context))
+      GdkGLContext *context = job->command_queue->context;
+      GskGLRenderTarget *render_target;
+      GskGLRenderState state;
+
+      gsk_next_driver_create_render_target (job->driver,
+                                            texture_width, texture_height,
+                                            GL_NEAREST, GL_NEAREST,
+                                            &render_target);
+
+      if (gdk_gl_context_has_debug (context))
         {
-          gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
-                                              "Outset Shadow Temp %d", texture_id);
-          gdk_gl_context_label_object_printf  (self->gl_context, GL_FRAMEBUFFER, render_target,
-                                               "Outset Shadow FB Temp %d", render_target);
+          gdk_gl_context_label_object_printf (context,
+                                              GL_TEXTURE,
+                                              render_target->texture_id,
+                                              "Outset Shadow Temp %d",
+                                              render_target->texture_id);
+          gdk_gl_context_label_object_printf  (context,
+                                               GL_FRAMEBUFFER,
+                                               render_target->framebuffer_id,
+                                               "Outset Shadow FB Temp %d",
+                                               render_target->framebuffer_id);
         }
 
-      ops_set_program (builder, &self->programs->color_program);
-      init_projection_matrix (&item_proj,
+      /* Change state for offscreen */
+      gsk_gl_render_state_save (&state, job);
+      init_projection_matrix (&job->projection,
                               &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
+      job->viewport = GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height);
+      gsk_gl_render_job_set_modelview (job, NULL);
+      gsk_gl_render_job_push_clip (job, &scaled_outline);
 
-      prev_render_target = ops_set_render_target (builder, render_target);
-      ops_begin (builder, OP_CLEAR);
-      prev_projection = ops_set_projection (builder, &item_proj);
-      ops_set_modelview (builder, NULL);
-      prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
+      /* Bind render target and clear it */
+      gsk_gl_command_queue_bind_framebuffer (job->command_queue,
+                                             render_target->framebuffer_id);
+      gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
 
-      /* Draw outline */
-      ops_push_clip (builder, &scaled_outline);
-      ops_set_color (builder, &COLOR_WHITE);
-      load_float_vertex_data (ops_draw (builder, NULL), builder,
-                              0, 0, texture_width, texture_height);
+      /* Draw using coloring program the outline */
+      gsk_gl_program_begin_draw (job->driver->color,
+                                 &job->viewport,
+                                 &job->projection,
+                                 gsk_gl_render_job_get_modelview_matrix (job),
+                                 gsk_gl_render_job_get_clip (job),
+                                 job->alpha);
+      gsk_gl_program_set_uniform_color (job->driver->color,
+                                        UNIFORM_COLOR_COLOR,
+                                        &white);
+      gsk_gl_render_job_draw (job, 0, 0, texture_width, texture_height);
+      gsk_gl_program_end_draw (job->driver->color);
 
-      ops_pop_clip (builder);
-      ops_set_viewport (builder, &prev_viewport);
-      ops_pop_modelview (builder);
-      ops_set_projection (builder, &prev_projection);
-      ops_set_render_target (builder, prev_render_target);
+      /* Reset state from offscreen */
+      gsk_gl_render_job_pop_clip (job);
+      gsk_gl_render_job_pop_modelview (job);
+      gsk_gl_render_state_restore (&state, job);
 
       /* Now blur the outline */
-      blurred_texture_id = blur_texture (self, builder,
-                                         &(TextureRegion) { texture_id, 0, 0, 1, 1 },
-                                         texture_width,
-                                         texture_height,
-                                         blur_radius * scale_x,
-                                         blur_radius * scale_y);
-
-      gsk_gl_driver_mark_texture_permanent (self->gl_driver, blurred_texture_id);
-      gsk_gl_shadow_cache_commit (&self->shadow_cache,
-                                  &scaled_outline,
-                                  blur_radius,
-                                  blurred_texture_id);
+      offscreen.texture_id = gsk_next_driver_release_render_target (job->driver, render_target, FALSE);
+      offscreen.area = GRAPHENE_RECT_INIT (0, 0, 1, 1);
+      blurred_texture_id = blur_offscreen (job,
+                                           &offscreen,
+                                           texture_width,
+                                           texture_height,
+                                           blur_radius * scale_x,
+                                           blur_radius * scale_y);
+
+      gsk_gl_shadow_library_insert (job->driver->shadows,
+                                    &scaled_outline,
+                                    blur_radius,
+                                    blurred_texture_id);
     }
   else
     {
       blurred_texture_id = cached_tid;
     }
 
-
   if (!do_slicing)
     {
-      const float min_x = floorf (outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx);
-      const float min_y = floorf (outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy);
-
-      ops_set_program (builder, &self->programs->outset_shadow_program);
-      ops_set_color (builder, color);
-      ops_set_texture (builder, blurred_texture_id);
-
-      shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
-      shadow->outline.value = transform_rect (self, builder, outline);
-      shadow->outline.send = TRUE;
-
-      load_vertex_data_with_region (ops_draw (builder, NULL),
-                                    &GRAPHENE_RECT_INIT (
-                                      min_x, min_y,
-                                      texture_width / scale_x, texture_height / scale_y
-                                    ), builder,
-                                    &(TextureRegion) { 0, 0, 0, 1, 1 },
-                                    FALSE);
+      float min_x = floorf (outline->bounds.origin.x - spread - half_blur_extra + dx);
+      float min_y = floorf (outline->bounds.origin.y - spread - half_blur_extra + dy);
+      GskRoundedRect transformed_outline;
+
+      gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
+
+      gsk_gl_program_begin_draw (job->driver->outset_shadow,
+                                 &job->viewport,
+                                 &job->projection,
+                                 gsk_gl_render_job_get_modelview_matrix (job),
+                                 gsk_gl_render_job_get_clip (job),
+                                 job->alpha);
+      gsk_gl_program_set_uniform_color (job->driver->outset_shadow,
+                                        UNIFORM_OUTSET_SHADOW_COLOR,
+                                        color);
+      gsk_gl_program_set_uniform_texture (job->driver->outset_shadow,
+                                          UNIFORM_SHARED_SOURCE,
+                                          GL_TEXTURE_2D,
+                                          GL_TEXTURE0,
+                                          blurred_texture_id);
+      gsk_gl_program_set_uniform_rounded_rect (job->driver->outset_shadow,
+                                               UNIFORM_OUTSET_SHADOW_OUTLINE_RECT,
+                                               &transformed_outline);
+      gsk_gl_program_end_draw (job->driver->outset_shadow);
+
+      offscreen.was_offscreen = FALSE;
+      offscreen.texture_id = blurred_texture_id;
+      offscreen.area.origin.x = 0;
+      offscreen.area.origin.y = 0;
+      offscreen.area.size.width = 1;
+      offscreen.area.size.height = 1;
+
+      gsk_gl_render_job_load_vertices_from_offscreen (job,
+                                                      &GRAPHENE_RECT_INIT (min_x,
+                                                                           min_y,
+                                                                           texture_width / scale_x,
+                                                                           texture_height / scale_y),
+                                                      &offscreen);
+
       return;
     }
 
+#if 0
 
   ops_set_program (builder, &self->programs->outset_shadow_program);
   ops_set_color (builder, color);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]