[mutter] cogl: Add support for partial update



commit 87965b5ce2c5600846bc002b4b359c6ecf805ede
Author: Erico Nunes <nunes erico gmail com>
Date:   Wed Sep 22 22:25:37 2021 +0200

    cogl: Add support for partial update
    
    Add support for a cogl function to set the damage_region on an onscreen
    framebuffer.
    The goal of this is to enable using the EGL_KHR_partial_update extension
    which can potentially reduce memory bandwidth usage by some GPUs,
    particularly on embedded GPUs that operate on a tiling rendering model.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2023>

 cogl/cogl/cogl-onscreen.c                          | 13 +++++++++++
 cogl/cogl/cogl-onscreen.h                          | 21 +++++++++++++++++
 cogl/cogl/winsys/cogl-onscreen-egl.c               | 27 ++++++++++++++++++++++
 .../winsys/cogl-winsys-egl-feature-functions.h     | 11 +++++++++
 4 files changed, 72 insertions(+)
---
diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c
index cff5df50c5..ff9e1749a7 100644
--- a/cogl/cogl/cogl-onscreen.c
+++ b/cogl/cogl/cogl-onscreen.c
@@ -300,6 +300,19 @@ cogl_onscreen_bind (CoglOnscreen *onscreen)
   COGL_ONSCREEN_GET_CLASS (onscreen)->bind (onscreen);
 }
 
+void
+cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
+                                   const int    *rectangles,
+                                   int           n_rectangles)
+{
+  CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen);
+
+  if (!klass->queue_damage_region)
+    return;
+
+  klass->queue_damage_region (onscreen, rectangles, n_rectangles);
+}
+
 void
 cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
                                         const int *rectangles,
diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h
index 7284e04d56..6778934932 100644
--- a/cogl/cogl/cogl-onscreen.h
+++ b/cogl/cogl/cogl-onscreen.h
@@ -74,6 +74,10 @@ struct _CoglOnscreenClass
                         CoglFrameInfo *info,
                         gpointer       user_data);
 
+  void (* queue_damage_region) (CoglOnscreen *onscreen,
+                                const int    *rectangles,
+                                int           n_rectangles);
+
   gboolean (* direct_scanout) (CoglOnscreen   *onscreen,
                                CoglScanout    *scanout,
                                CoglFrameInfo  *info,
@@ -227,6 +231,23 @@ cogl_onscreen_swap_buffers (CoglOnscreen  *onscreen,
 COGL_EXPORT int
 cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
 
+/**
+ * cogl_onscreen_queue_damage_region:
+ * @onscreen: A #CoglOnscreen framebuffer
+ * @rectangles: An array of integer 4-tuples representing damaged
+ *              rectangles as (x, y, width, height) tuples.
+ * @n_rectangles: The number of 4-tuples to be read from @rectangles
+ *
+ * Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt
+ * This immediately queues state to OpenGL that will be used for the
+ * next swap.
+ * This needs to be called every frame.
+ */
+COGL_EXPORT void
+cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
+                                   const int    *rectangles,
+                                   int           n_rectangles);
+
 /**
  * cogl_onscreen_swap_buffers_with_damage:
  * @onscreen: A #CoglOnscreen framebuffer
diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c
index 20b3c60efe..8a587049e8 100644
--- a/cogl/cogl/winsys/cogl-onscreen-egl.c
+++ b/cogl/cogl/winsys/cogl-onscreen-egl.c
@@ -242,6 +242,31 @@ cogl_onscreen_egl_swap_region (CoglOnscreen  *onscreen,
     g_warning ("Error reported by eglSwapBuffersRegion");
 }
 
+static void
+cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
+                                       const int    *rectangles,
+                                       int           n_rectangles)
+{
+  CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
+  CoglOnscreenEglPrivate *priv =
+    cogl_onscreen_egl_get_instance_private (onscreen_egl);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+  CoglRenderer *renderer = context->display->renderer;
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+  g_return_if_fail (n_rectangles > 0);
+
+  if (!egl_renderer->pf_eglSetDamageRegion)
+    return;
+
+  if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy,
+                                           priv->egl_surface,
+                                           rectangles,
+                                           n_rectangles) == EGL_FALSE)
+    g_warning ("Error reported by eglSetDamageRegion");
+}
+
 static void
 cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen  *onscreen,
                                             const int     *rectangles,
@@ -345,6 +370,8 @@ cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass)
   object_class->dispose = cogl_onscreen_egl_dispose;
 
   onscreen_class->bind = cogl_onscreen_egl_bind;
+  onscreen_class->queue_damage_region =
+    cogl_onscreen_egl_queue_damage_region;
   onscreen_class->swap_buffers_with_damage =
     cogl_onscreen_egl_swap_buffers_with_damage;
   onscreen_class->swap_region = cogl_onscreen_egl_swap_region;
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h 
b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h
index e10c019385..53d9bd27b1 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h
+++ b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h
@@ -116,6 +116,17 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamage,
                                EGLint n_rects))
 COGL_WINSYS_FEATURE_END ()
 
+COGL_WINSYS_FEATURE_BEGIN (partial_update,
+                           "KHR\0",
+                           "partial_update\0",
+                           COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)
+COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSetDamageRegion,
+                              (EGLDisplay dpy,
+                               EGLSurface surface,
+                               const EGLint *rects,
+                               EGLint n_rects))
+COGL_WINSYS_FEATURE_END ()
+
 #if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
 COGL_WINSYS_FEATURE_BEGIN (fence_sync,
                            "KHR\0",


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