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




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

    ngl: Use fp16 for colors

 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..7f3348c23c
--- /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 float *
+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]