[gtk/wip/ebassi/gdk-egl-x11-v2: 4/7] gl: Convert pixel data from rgba to argb.



commit 26f65d2a7db93bfcbf9af74050b2b86b1282641d
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 file changed, 66 insertions(+)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 74dad4077c..65a22e98c4 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,
@@ -300,6 +363,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]