[gtk/wip/chergert/glproto: 228/493] apply scissor clip while processing fbo changes




commit e582dfb631e8f21661e56420fa479698577ec6c2
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jan 20 23:22:02 2021 -0800

    apply scissor clip while processing fbo changes

 gsk/next/gskglcommandqueue.c        | 54 ++++++++++++++++++++++++++++++++++---
 gsk/next/gskglcommandqueueprivate.h |  5 +++-
 gsk/next/gskglrenderjob.c           | 12 ++++++---
 3 files changed, 64 insertions(+), 7 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index 4228da2398..bd80a296c6 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -665,15 +665,43 @@ apply_viewport (guint16 *current_width,
     }
 }
 
+static inline void
+apply_scissor (guint                        framebuffer,
+               guint                        surface_height,
+               guint                        scale_factor,
+               const cairo_rectangle_int_t *scissor,
+               gboolean                     has_scissor)
+{
+  if (framebuffer != 0 || !has_scissor)
+    {
+      glDisable (GL_SCISSOR_TEST);
+      return;
+    }
+
+  glEnable (GL_SCISSOR_TEST);
+  glScissor (scissor->x * scale_factor,
+             surface_height - (scissor->height * scale_factor) - (scissor->y * scale_factor),
+             scissor->width * scale_factor,
+             scissor->height * scale_factor);
+
+}
+
 /**
  * gsk_gl_command_queue_execute:
  * @self: a #GskGLCommandQueue
+ * @surface_height: the height of the backing surface
+ * @scale_factor: the scale factor of the backing surface
+ * #scissor: (nullable): the scissor clip if any
  *
  * Executes all of the batches in the command queue.
  */
 void
-gsk_gl_command_queue_execute (GskGLCommandQueue *self)
+gsk_gl_command_queue_execute (GskGLCommandQueue    *self,
+                              guint                 surface_height,
+                              guint                 scale_factor,
+                              const cairo_region_t *scissor)
 {
+  cairo_rectangle_int_t scissor_rect;
   GLuint framebuffer = 0;
   GLuint vao_id;
   int next_batch_index;
@@ -715,8 +743,18 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self)
                          sizeof (GskGLDrawVertex),
                          (void *) G_STRUCT_OFFSET (GskGLDrawVertex, uv));
 
-  /* Start without a scissor clip */
-  glDisable (GL_SCISSOR_TEST);
+  /* Setup initial scissor clip */
+  if (scissor != NULL)
+    {
+      g_assert (cairo_region_num_rectangles (scissor) == 1);
+      cairo_region_get_rectangle (scissor, 0, &scissor_rect);
+    }
+
+  apply_scissor (framebuffer,
+                 surface_height,
+                 scale_factor,
+                 &scissor_rect,
+                 scissor != NULL);
 
   next_batch_index = 0;
 
@@ -735,6 +773,11 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self)
             {
               framebuffer = batch->clear.framebuffer;
               glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+              apply_scissor (framebuffer,
+                             surface_height,
+                             scale_factor,
+                             &scissor_rect,
+                             scissor != NULL);
             }
 
           apply_viewport (&width,
@@ -764,6 +807,11 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self)
             {
               framebuffer = batch->draw.framebuffer;
               glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+              apply_scissor (framebuffer,
+                             surface_height,
+                             scale_factor,
+                             &scissor_rect,
+                             scissor != NULL);
             }
 
           apply_viewport (&width,
diff --git a/gsk/next/gskglcommandqueueprivate.h b/gsk/next/gskglcommandqueueprivate.h
index beaef7478f..6e406a274e 100644
--- a/gsk/next/gskglcommandqueueprivate.h
+++ b/gsk/next/gskglcommandqueueprivate.h
@@ -115,7 +115,10 @@ GdkGLContext      *gsk_gl_command_queue_get_context          (GskGLCommandQueue
 void               gsk_gl_command_queue_make_current         (GskGLCommandQueue        *self);
 void               gsk_gl_command_queue_begin_frame          (GskGLCommandQueue        *self);
 void               gsk_gl_command_queue_end_frame            (GskGLCommandQueue        *self);
-void               gsk_gl_command_queue_execute              (GskGLCommandQueue        *self);
+void               gsk_gl_command_queue_execute              (GskGLCommandQueue        *self,
+                                                              guint                     surface_height,
+                                                              guint                     scale_factor,
+                                                              const cairo_region_t     *scissor);
 int                gsk_gl_command_queue_upload_texture       (GskGLCommandQueue        *self,
                                                               GdkTexture               *texture,
                                                               guint                     x_offset,
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index fdb45c1067..09144ecd04 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -3455,12 +3455,14 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
   GdkGLContext *context;
   guint framebuffer_id;
   guint texture_id;
+  guint surface_height;
 
   g_return_if_fail (job != NULL);
   g_return_if_fail (root != NULL);
   g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
 
   context = gsk_next_driver_get_context (job->driver);
+  surface_height = job->viewport.size.height;
 
   gdk_gl_context_make_current (context);
 
@@ -3509,7 +3511,7 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
   gsk_gl_program_end_draw (job->driver->blit);
 
   gdk_gl_context_push_debug_group (context, "Executing command queue");
-  gsk_gl_command_queue_execute (job->command_queue);
+  gsk_gl_command_queue_execute (job->command_queue, surface_height, 1, NULL);
   gdk_gl_context_pop_debug_group (context);
 
   gsk_next_driver_end_frame (job->driver);
@@ -3525,12 +3527,16 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
                           GskRenderNode  *root)
 {
   GdkGLContext *context;
+  guint scale_factor;
+  guint surface_height;
 
   g_return_if_fail (job != NULL);
   g_return_if_fail (root != NULL);
   g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
 
   context = gsk_next_driver_get_context (job->driver);
+  scale_factor = MAX (job->scale_x, job->scale_y);
+  surface_height = job->viewport.size.height;
 
   gsk_next_driver_begin_frame (job->driver);
 
@@ -3551,7 +3557,7 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
 #endif
 
   gdk_gl_context_push_debug_group (context, "Executing command queue");
-  gsk_gl_command_queue_execute (job->command_queue);
+  gsk_gl_command_queue_execute (job->command_queue, surface_height, scale_factor, job->region);
   gdk_gl_context_pop_debug_group (context);
 
   gsk_next_driver_end_frame (job->driver);
@@ -3592,7 +3598,6 @@ gsk_gl_render_job_new (GskNextDriver         *driver,
   job->scale_x = scale_factor;
   job->scale_y = scale_factor;
   job->viewport = *viewport;
-  job->region = region ? cairo_region_copy (region) : NULL;
   job->alpha = 1.0;
 
   init_projection_matrix (&job->projection, viewport);
@@ -3615,6 +3620,7 @@ gsk_gl_render_job_new (GskNextDriver         *driver,
                                                                extents.height),
                                           &transformed_extents);
       clip_rect = &transformed_extents;
+      job->region = cairo_region_create_rectangle (&extents);
     }
 
   gsk_gl_render_job_push_clip (job,


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