[gtk/half-float: 1/5] ngl: Use fp16 for colors




commit 20e1396bafa92a20bfcc7991a1719a7323b79076
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Apr 6 21:55:50 2021 -0400

    ngl: Use fp16 for colors
    
    This reduces the size of our Vertex struct from
    48 to 32 bytes. It would be nicer if we could store
    the colors in fp16 format in the rendernodes, and
    avoid conversion here. But this is still good.

 gsk/meson.build              |   1 +
 gsk/ngl/fp16private.h        | 111 +++++++++++++++++++++++++++++++++++++++
 gsk/ngl/gsknglcommandqueue.c |   4 +-
 gsk/ngl/gsknglrenderjob.c    | 120 ++++++++++++++++++++++++++-----------------
 gsk/ngl/gskngltypesprivate.h |   4 +-
 5 files changed, 188 insertions(+), 52 deletions(-)
---
diff --git a/gsk/meson.build b/gsk/meson.build
index 5c381b51c9..11be6a03f6 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -221,6 +221,7 @@ libgsk = static_library('gsk',
     '-DGTK_COMPILATION',
     '-DG_LOG_DOMAIN="Gsk"',
     '-DG_LOG_STRUCTURED=1',
+    '-mf16c'
   ] + common_cflags,
   link_with: libgdk,
 )
diff --git a/gsk/ngl/fp16private.h b/gsk/ngl/fp16private.h
new file mode 100644
index 0000000000..b285bf450c
--- /dev/null
+++ b/gsk/ngl/fp16private.h
@@ -0,0 +1,111 @@
+/* ninesliceprivate.h
+ *
+ * Copyright 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef __FP16_PRIVATE_H__
+#define __FP16_PRIVATE_H__
+
+#include <glib.h>
+#include <graphene.h>
+
+#ifdef GRAPHENE_USE_SSE
+#include <immintrin.h>
+#endif
+
+G_BEGIN_DECLS
+
+#ifdef GRAPHENE_USE_SSE
+
+static inline void
+float_to_half4 (const float f[4],
+                guint16     h[4])
+{
+  __m128 s = _mm_loadu_ps (f);
+  __m128i i = _mm_cvtps_ph (s, 0);
+  _mm_storel_epi64 ((__m128i*)h, i);
+}
+
+static inline void
+half_to_float4 (const guint16 h[4],
+                float         f[4])
+{
+  __m128i i = _mm_loadl_epi64 ((__m128i_u const *)h);
+  __m128 s = _mm_cvtph_ps (i);
+  _mm_store_ps (f, s);
+}
+
+#else  /* GRAPHENE_USE_SSE */
+
+static inline guint
+as_uint (const float x)
+{
+  return *(guint*)&x;
+}
+
+static inline float
+as_float (const guint x)
+{
+  return *(float*)&x;
+}
+
+// IEEE-754 16-bit floating-point format (without infinity): 1-5-10
+
+static inline float
+half_to_float (const guint16 x)
+{
+  const guint e = (x&0x7C00)>>10; // exponent
+  const guint m = (x&0x03FF)<<13; // mantissa
+  const guint v = as_uint((float)m)>>23;
+  return as_float((x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | 
((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000)));
+}
+
+static inline guint16
+float_to_half (const float x)
+{
+  const guint b = as_uint(x)+0x00001000; // round-to-nearest-even
+  const guint e = (b&0x7F800000)>>23; // exponent
+  const guint m = b&0x007FFFFF; // mantissa
+  return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | 
((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; // sign : normalized : denormalized : 
saturate
+}
+
+static inline void
+float_to_half4 (const float f[4],
+                guint16     h[4])
+{
+  h[0] = float_to_half (f[0]);
+  h[1] = float_to_half (f[1]);
+  h[2] = float_to_half (f[2]);
+  h[3] = float_to_half (f[3]);
+}
+
+static inline void
+half_to_float4 (const guint16 h[4],
+                float         f[4])
+{
+  f[0] = half_to_float (h[0]);
+  f[1] = half_to_float (h[1]);
+  f[2] = half_to_float (h[2]);
+  f[3] = half_to_float (h[3]);
+}
+
+#endif  /* GRAPHENE_USE_SSE */
+
+G_END_DECLS
+
+#endif
diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c
index e160076c57..bdfef2f35c 100644
--- a/gsk/ngl/gsknglcommandqueue.c
+++ b/gsk/ngl/gsknglcommandqueue.c
@@ -1003,13 +1003,13 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue   *self,
 
   /* 2 = color location */
   glEnableVertexAttribArray (2);
-  glVertexAttribPointer (2, 4, GL_FLOAT, GL_FALSE,
+  glVertexAttribPointer (2, 4, GL_HALF_FLOAT, GL_FALSE,
                          sizeof (GskNglDrawVertex),
                          (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color));
 
   /* 3 = color2 location */
   glEnableVertexAttribArray (3);
-  glVertexAttribPointer (3, 4, GL_FLOAT, GL_FALSE,
+  glVertexAttribPointer (3, 4, GL_HALF_FLOAT, GL_FALSE,
                          sizeof (GskNglDrawVertex),
                          (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color2));
 
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 3e823dedab..ecaadc7458 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -43,6 +43,7 @@
 #include "gsknglshadowlibraryprivate.h"
 
 #include "ninesliceprivate.h"
+#include "fp16private.h"
 
 #define ORTHO_NEAR_PLANE   -10000
 #define ORTHO_FAR_PLANE     10000
@@ -884,6 +885,13 @@ gsk_ngl_render_job_update_clip (GskNglRenderJob     *job,
   return TRUE;
 }
 
+static inline void
+rgba_to_half (const GdkRGBA *c,
+              guint16        h[4])
+{
+  float_to_half4 ((const float *)c, h);
+}
+
 /* fill_vertex_data */
 static void
 gsk_ngl_render_job_draw_coords (GskNglRenderJob *job,
@@ -898,13 +906,16 @@ gsk_ngl_render_job_draw_coords (GskNglRenderJob *job,
                                 const GdkRGBA   *color)
 {
   GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
+  guint16 c[4];
+
+  rgba_to_half (color, c);
 
-  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { min_u, min_v }, { color->red, color->green, 
color->blue, color->alpha } };
-  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { color->red, color->green, 
color->blue, color->alpha } };
-  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { color->red, color->green, 
color->blue, color->alpha } };
-  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { max_u, max_v }, { color->red, color->green, 
color->blue, color->alpha } };
-  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { color->red, color->green, 
color->blue, color->alpha } };
-  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { color->red, color->green, 
color->blue, color->alpha } };
+  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { min_u, min_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { max_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { c[0], c[1], c[2],c[3] } };
 }
 
 /* load_vertex_data_with_region */
@@ -1658,7 +1669,7 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
                                       const GskRenderNode *node)
 {
   const GskRoundedRect *rounded_outline = gsk_border_node_get_outline (node);
-  const GdkRGBA *c = gsk_border_node_get_colors (node);
+  const GdkRGBA *colors = gsk_border_node_get_colors (node);
   const float *widths = gsk_border_node_get_widths (node);
   struct {
     float w;
@@ -1669,6 +1680,7 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
   float max_x = min_x + node->bounds.size.width;
   float max_y = min_y + node->bounds.size.height;
   GskRoundedRect outline;
+  guint16 c[4];
 
   memset (sizes, 0, sizeof sizes);
 
@@ -1712,52 +1724,60 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
+      rgba_to_half (&colors[0], c);
 
-      vertices[3] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 1, 0 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0].red, 
c[0].green, c[0].blue, c[0].alpha } };
+      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
+
+      vertices[3] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 1, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
     }
 
   if (widths[1] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 0, 1 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
+      rgba_to_half (&colors[1], c);
+
+      vertices[0] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 0, 1 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
 
-      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[1].red, 
c[1].green, c[1].blue, c[1].alpha } };
+      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
     }
 
   if (widths[2] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 0, 1 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
+      rgba_to_half (&colors[2], c);
+
+      vertices[0] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 0, 1 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
 
-      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x            ,  max_y              }, { 0, 0 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[2].red, 
c[2].green, c[2].blue, c[2].alpha } };
+      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x            ,  max_y              }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
     }
 
   if (widths[3] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
+      rgba_to_half (&colors[3], c);
 
-      vertices[3] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 1, 0 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[3].red, 
c[3].green, c[3].blue, c[3].alpha } };
+      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
+
+      vertices[3] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 1, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], 
c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[0], c[1], 
c[2], c[3] } };
     }
 
   gsk_ngl_render_job_end_draw (job);
@@ -1775,8 +1795,8 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
                                          const GskRenderNode *node2)
 {
   const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
-  const GdkRGBA *c2 = gsk_color_node_get_color (child);
-  const GdkRGBA *c = gsk_border_node_get_colors (node2);
+  const GdkRGBA *color = gsk_border_node_get_colors (node2);
+  const GdkRGBA *color2 = gsk_color_node_get_color (child);
   const GskRoundedRect *rounded_outline = gsk_border_node_get_outline (node2);
   const float *widths = gsk_border_node_get_widths (node2);
   float min_x = job->offset_x + node2->bounds.origin.x;
@@ -1785,10 +1805,14 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
   float max_y = min_y + node2->bounds.size.height;
   GskRoundedRect outline;
   GskNglDrawVertex *vertices;
+  guint16 c[4], c2[4];
 
   if (node_is_invisible (node2))
     return;
 
+  rgba_to_half (&color[0], c);
+  rgba_to_half (color2, c2);
+
   gsk_ngl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
 
   gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, filled_border));
@@ -1803,12 +1827,12 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
 
   vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, 
c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
+  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
+  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
+  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
+  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
+  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
+  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], 
c2[2], c2[3] } };
 
   gsk_ngl_render_job_end_draw (job);
 }
@@ -2690,7 +2714,7 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
   guint last_texture = 0;
   GskNglDrawVertex *vertices;
   guint used = 0;
-  GdkRGBA c;
+  guint16 c[4];
   const PangoGlyphInfo *gi;
   guint i;
   int yshift;
@@ -2703,9 +2727,9 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
    * We tell the shader by setting the color to vec4(-1).
    */
   if (!force_color && gsk_text_node_has_color_glyphs (node))
-    c = (GdkRGBA) { -1.f, -1.f, -1.f, -1.f };
+    rgba_to_half (&(GdkRGBA){ -1.f, -1.f, -1.f, -1.f }, c);
   else
-    c = *color;
+    rgba_to_half (color, c);
 
   lookup.font = (PangoFont *)font;
   lookup.scale = (guint) (text_scale * 1024);
@@ -2783,13 +2807,13 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
       glyph_x2 = glyph_x + glyph->ink_rect.width;
       glyph_y2 = glyph_y + glyph->ink_rect.height;
 
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y  }, { tx,  ty  }, { c.red, c.green, c.blue, 
c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c.red, c.green, c.blue, 
c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c.red, c.green, c.blue, 
c.alpha } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y  }, { tx,  ty  }, { c[0], c[1], c[2], c[3] } 
};
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c[0], c[1], c[2], c[3] } 
};
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c[0], c[1], c[2], c[3] } 
};
 
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y2 }, { tx2, ty2 }, { c.red, c.green, c.blue, 
c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c.red, c.green, c.blue, 
c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c.red, c.green, c.blue, 
c.alpha } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y2 }, { tx2, ty2 }, { c[0], c[1], c[2], c[3] } 
};
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c[0], c[1], c[2], c[3] } 
};
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c[0], c[1], c[2], c[3] } 
};
 
       batch->draw.vbo_count += GSK_NGL_N_VERTICES;
       used++;
diff --git a/gsk/ngl/gskngltypesprivate.h b/gsk/ngl/gskngltypesprivate.h
index a65130c19f..dda4365271 100644
--- a/gsk/ngl/gskngltypesprivate.h
+++ b/gsk/ngl/gskngltypesprivate.h
@@ -55,8 +55,8 @@ struct _GskNglDrawVertex
 {
   float position[2];
   float uv[2];
-  float color[4];
-  float color2[4];
+  guint16 color[4];
+  guint16 color2[4];
 };
 
 G_END_DECLS


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