|
|
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 |
|