Blame SOURCES/0001-cogl-Prefer-swizzling-to-convert-BGRA-buffers.patch

67f8b7
From 32faf80489f8ee7b4c973660c286f6d228f8e738 Mon Sep 17 00:00:00 2001
67f8b7
From: Carlos Garnacho <carlosg@gnome.org>
67f8b7
Date: Sat, 25 Feb 2017 23:21:06 +0100
67f8b7
Subject: [PATCH] cogl: Prefer swizzling to convert BGRA buffers
67f8b7
67f8b7
(squashed/rebased for gnome-3-22)
67f8b7
67f8b7
If the GL implementation/hw supports the GL_*_texture_swizzle extension,
67f8b7
pretend that BGRA textures shall contain RGBA data, and let the flipping
67f8b7
happen when the texture will be used in the rendering pipeline.
67f8b7
67f8b7
This avoids rather expensive format conversions when forcing BGRA buffers
67f8b7
into RGBA textures, which happens rather often with WL_SHM_FORMAT_ARGB8888
67f8b7
buffers (like gtk+ uses) in little-endian machines.
67f8b7
67f8b7
In intel/mesa/wayland, the performance improvement is rather noticeable,
67f8b7
CPU% as seen by top decreases from 45-50% to 25-30% when running
67f8b7
gtk+/tests/scrolling-performance with a cairo renderer.
67f8b7
67f8b7
https://bugzilla.gnome.org/show_bug.cgi?id=779234
67f8b7
---
67f8b7
 cogl/cogl/cogl-driver.h                         |  7 +++++
67f8b7
 cogl/cogl/driver/gl/cogl-framebuffer-gl.c       |  9 ++++++
67f8b7
 cogl/cogl/driver/gl/cogl-texture-2d-gl.c        | 11 ++++----
67f8b7
 cogl/cogl/driver/gl/gl/cogl-driver-gl.c         | 37 +++++++++++++++++++++----
67f8b7
 cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c | 12 ++++++++
67f8b7
 cogl/cogl/driver/gl/gles/cogl-driver-gles.c     | 26 +++++++++++++----
67f8b7
 cogl/cogl/driver/nop/cogl-driver-nop.c          |  1 +
67f8b7
 7 files changed, 87 insertions(+), 16 deletions(-)
67f8b7
67f8b7
diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h
67f8b7
index 648228c..85aa0d8 100644
67f8b7
--- a/cogl/cogl/cogl-driver.h
67f8b7
+++ b/cogl/cogl/cogl-driver.h
67f8b7
@@ -55,6 +55,13 @@ struct _CoglDriverVtable
67f8b7
                           GLenum *out_glintformat,
67f8b7
                           GLenum *out_glformat,
67f8b7
                           GLenum *out_gltype);
67f8b7
+  CoglPixelFormat
67f8b7
+  (* pixel_format_to_gl_with_target) (CoglContext *context,
67f8b7
+                                      CoglPixelFormat format,
67f8b7
+                                      CoglPixelFormat target_format,
67f8b7
+                                      GLenum *out_glintformat,
67f8b7
+                                      GLenum *out_glformat,
67f8b7
+                                      GLenum *out_gltype);
67f8b7
 
67f8b7
   CoglBool
67f8b7
   (* update_features) (CoglContext *context,
67f8b7
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
67f8b7
index 18ba08a..2af36f0 100644
67f8b7
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
67f8b7
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
67f8b7
@@ -1418,6 +1418,15 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
67f8b7
                                                             &gl_format,
67f8b7
                                                             &gl_type);
67f8b7
 
67f8b7
+  /* As we are reading pixels, we want to consider the bitmap according to
67f8b7
+   * its real pixel format, not the swizzled channels we pretend face to the
67f8b7
+   * pipeline.
67f8b7
+   */
67f8b7
+  if ((format == COGL_PIXEL_FORMAT_BGRA_8888 ||
67f8b7
+       format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
67f8b7
+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
67f8b7
+    gl_format = GL_BGRA;
67f8b7
+
67f8b7
   /* NB: All offscreen rendering is done upside down so there is no need
67f8b7
    * to flip in this case... */
67f8b7
   if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
67f8b7
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
67f8b7
index 1193df4..817dd53 100644
67f8b7
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
67f8b7
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
67f8b7
@@ -657,11 +657,12 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
67f8b7
 
67f8b7
   upload_format = cogl_bitmap_get_format (upload_bmp);
67f8b7
 
67f8b7
-  ctx->driver_vtable->pixel_format_to_gl (ctx,
67f8b7
-                                          upload_format,
67f8b7
-                                          NULL, /* internal format */
67f8b7
-                                          &gl_format,
67f8b7
-                                          &gl_type);
67f8b7
+  ctx->driver_vtable->pixel_format_to_gl_with_target (ctx,
67f8b7
+                                                      upload_format,
67f8b7
+                                                      _cogl_texture_get_format (tex),
67f8b7
+                                                      NULL, /* internal gl format */
67f8b7
+                                                      &gl_format,
67f8b7
+                                                      &gl_type);
67f8b7
 
67f8b7
   /* If this touches the first pixel then we'll update our copy */
67f8b7
   if (dst_x == 0 && dst_y == 0 &&
67f8b7
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
67f8b7
index 2b9a49c..178262a 100644
67f8b7
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
67f8b7
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
67f8b7
@@ -96,11 +96,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
67f8b7
 }
67f8b7
 
67f8b7
 static CoglPixelFormat
67f8b7
-_cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
-                                 CoglPixelFormat  format,
67f8b7
-                                 GLenum *out_glintformat,
67f8b7
-                                 GLenum *out_glformat,
67f8b7
-                                 GLenum *out_gltype)
67f8b7
+_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
67f8b7
+                                             CoglPixelFormat format,
67f8b7
+                                             CoglPixelFormat target_format,
67f8b7
+                                             GLenum *out_glintformat,
67f8b7
+                                             GLenum *out_glformat,
67f8b7
+                                             GLenum *out_gltype)
67f8b7
 {
67f8b7
   CoglPixelFormat required_format;
67f8b7
   GLenum glintformat = 0;
67f8b7
@@ -174,7 +175,16 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
     case COGL_PIXEL_FORMAT_BGRA_8888:
67f8b7
     case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
67f8b7
       glintformat = GL_RGBA;
67f8b7
-      glformat = GL_BGRA;
67f8b7
+      /* If the driver has texture_swizzle, pretend internal
67f8b7
+       * and buffer format are the same here, the pixels
67f8b7
+       * will be flipped through this extension.
67f8b7
+       */
67f8b7
+      if (target_format == format &&
67f8b7
+          _cogl_has_private_feature
67f8b7
+          (context, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
67f8b7
+        glformat = GL_RGBA;
67f8b7
+      else
67f8b7
+        glformat = GL_BGRA;
67f8b7
       gltype = GL_UNSIGNED_BYTE;
67f8b7
       break;
67f8b7
 
67f8b7
@@ -289,6 +299,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
   return required_format;
67f8b7
 }
67f8b7
 
67f8b7
+static CoglPixelFormat
67f8b7
+_cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
+                                 CoglPixelFormat  format,
67f8b7
+                                 GLenum *out_glintformat,
67f8b7
+                                 GLenum *out_glformat,
67f8b7
+                                 GLenum *out_gltype)
67f8b7
+{
67f8b7
+  return _cogl_driver_pixel_format_to_gl_with_target (context,
67f8b7
+                                                      format, format,
67f8b7
+                                                      out_glintformat,
67f8b7
+                                                      out_glformat,
67f8b7
+                                                      out_gltype);
67f8b7
+}
67f8b7
+
67f8b7
 static CoglBool
67f8b7
 _cogl_get_gl_version (CoglContext *ctx,
67f8b7
                       int *major_out,
67f8b7
@@ -669,6 +693,7 @@ _cogl_driver_gl =
67f8b7
   {
67f8b7
     _cogl_driver_pixel_format_from_gl_internal,
67f8b7
     _cogl_driver_pixel_format_to_gl,
67f8b7
+    _cogl_driver_pixel_format_to_gl_with_target,
67f8b7
     _cogl_driver_update_features,
67f8b7
     _cogl_offscreen_gl_allocate,
67f8b7
     _cogl_offscreen_gl_free,
67f8b7
diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
67f8b7
index c76a0cf..d5ee4b4 100644
67f8b7
--- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
67f8b7
+++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
67f8b7
@@ -114,6 +114,18 @@ _cogl_texture_driver_gen (CoglContext *ctx,
67f8b7
                                  red_swizzle) );
67f8b7
     }
67f8b7
 
67f8b7
+  /* If swizzle extension is available, prefer it to flip bgra buffers to rgba */
67f8b7
+  if ((internal_format == COGL_PIXEL_FORMAT_BGRA_8888 ||
67f8b7
+       internal_format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
67f8b7
+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
67f8b7
+    {
67f8b7
+      static const GLint bgra_swizzle[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
67f8b7
+
67f8b7
+      GE( ctx, glTexParameteriv (gl_target,
67f8b7
+                                 GL_TEXTURE_SWIZZLE_RGBA,
67f8b7
+                                 bgra_swizzle) );
67f8b7
+    }
67f8b7
+
67f8b7
   return tex;
67f8b7
 }
67f8b7
 
67f8b7
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
67f8b7
index bf63fcc..521f6ef 100644
67f8b7
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
67f8b7
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
67f8b7
@@ -67,11 +67,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
67f8b7
 }
67f8b7
 
67f8b7
 static CoglPixelFormat
67f8b7
-_cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
-                                 CoglPixelFormat  format,
67f8b7
-                                 GLenum *out_glintformat,
67f8b7
-                                 GLenum *out_glformat,
67f8b7
-                                 GLenum *out_gltype)
67f8b7
+_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
67f8b7
+                                             CoglPixelFormat format,
67f8b7
+                                             CoglPixelFormat target_format,
67f8b7
+                                             GLenum *out_glintformat,
67f8b7
+                                             GLenum *out_glformat,
67f8b7
+                                             GLenum *out_gltype)
67f8b7
 {
67f8b7
   CoglPixelFormat required_format;
67f8b7
   GLenum glintformat;
67f8b7
@@ -219,6 +220,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
   return required_format;
67f8b7
 }
67f8b7
 
67f8b7
+static CoglPixelFormat
67f8b7
+_cogl_driver_pixel_format_to_gl (CoglContext *context,
67f8b7
+                                 CoglPixelFormat  format,
67f8b7
+                                 GLenum *out_glintformat,
67f8b7
+                                 GLenum *out_glformat,
67f8b7
+                                 GLenum *out_gltype)
67f8b7
+{
67f8b7
+  return _cogl_driver_pixel_format_to_gl_with_target (context,
67f8b7
+                                                      format, format,
67f8b7
+                                                      out_glintformat,
67f8b7
+                                                      out_glformat,
67f8b7
+                                                      out_gltype);
67f8b7
+}
67f8b7
+
67f8b7
 static CoglBool
67f8b7
 _cogl_get_gl_version (CoglContext *ctx,
67f8b7
                       int *major_out,
67f8b7
@@ -457,6 +472,7 @@ _cogl_driver_gles =
67f8b7
   {
67f8b7
     _cogl_driver_pixel_format_from_gl_internal,
67f8b7
     _cogl_driver_pixel_format_to_gl,
67f8b7
+    _cogl_driver_pixel_format_to_gl_with_target,
67f8b7
     _cogl_driver_update_features,
67f8b7
     _cogl_offscreen_gl_allocate,
67f8b7
     _cogl_offscreen_gl_free,
67f8b7
diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c
67f8b7
index d9b1d0f..6e04e71 100644
67f8b7
--- a/cogl/cogl/driver/nop/cogl-driver-nop.c
67f8b7
+++ b/cogl/cogl/driver/nop/cogl-driver-nop.c
67f8b7
@@ -61,6 +61,7 @@ _cogl_driver_nop =
67f8b7
   {
67f8b7
     NULL, /* pixel_format_from_gl_internal */
67f8b7
     NULL, /* pixel_format_to_gl */
67f8b7
+    NULL, /* pixel_format_to_gl_with_target */
67f8b7
     _cogl_driver_update_features,
67f8b7
     _cogl_offscreen_nop_allocate,
67f8b7
     _cogl_offscreen_nop_free,
67f8b7
-- 
67f8b7
2.9.3
67f8b7