[gtk+/wip/ebassi/gdk-egl-x11: 56/58] gl: Convert pixel data from rgba to argb.



commit 7c394e82532ae76779f3c8180baa3ca7dc61ef11
Author: Juan Pablo Ugarte <ugarte endlessm com>
Date:   Fri Dec 16 18:39:44 2016 -0300

    gl: Convert pixel data from rgba to argb.
    
    Cairo expects data to be in ARGB format, but on OpenGL ES we can only
    read data back from the buffer in RGBA chunks. This means we need to
    flip the channels after reading the whole image.

 gdk/gdkglcontext.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 1891d47..8b4a88d 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -236,6 +236,69 @@ gdk_gl_context_get_property (GObject    *gobject,
     }
 }
 
+/* Based on gdk_cairo_surface_paint_pixbuf() */
+static inline void
+image_surface_rgba_to_argb (cairo_surface_t *image)
+{
+  gint i, width, height, stride;
+  cairo_format_t format;
+  guint t1,t2,t3;
+  guchar *data;
+
+  width = cairo_image_surface_get_width (image);
+  height = cairo_image_surface_get_height (image);
+  stride = cairo_image_surface_get_stride (image);
+  format = cairo_image_surface_get_format (image);
+  data = cairo_image_surface_get_data (image);
+
+#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END
+
+  for (i = 0; i < height; i++)
+    {
+      guchar *q = data + i * stride;
+      guchar *end = q + 4 * width;
+
+      if (format == CAIRO_FORMAT_RGB24)
+        while (q < end)
+          {
+            guint32 data = *((guint32*)q);
+            guchar *p = (guchar*) &data;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+            q[0] = p[2];
+            q[1] = p[1];
+            q[2] = p[0];
+#else
+            q[1] = p[0];
+            q[2] = p[1];
+            q[3] = p[2];
+#endif
+            q += 4;
+          }
+      else if (format == CAIRO_FORMAT_ARGB32)
+        while (q < end)
+          {
+            guint32 data = *((guint32*)q);
+            guchar *p = (guchar*) &data;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+            MULT(q[0], p[2], p[3], t1);
+            MULT(q[1], p[1], p[3], t2);
+            MULT(q[2], p[0], p[3], t3);
+            q[3] = p[3];
+#else
+            q[0] = p[3];
+            MULT(q[1], p[0], p[3], t1);
+            MULT(q[2], p[1], p[3], t2);
+            MULT(q[3], p[2], p[3], t3);
+#endif
+            q += 4;
+          }
+    }
+
+#undef MULT
+}
+
 void
 gdk_gl_context_download_texture (GdkGLContext    *context,
                                  int              x,
@@ -285,6 +348,9 @@ gdk_gl_context_download_texture (GdkGLContext    *context,
                           (unsigned char *) data + (i * stride));
         }
     }
+
+  if (priv->use_es)
+    image_surface_rgba_to_argb (image_surface);
 }
 
 void


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