[gtk+/wip/otte/shader: 51/55] gsksltype: Add concept of components



commit dea0d1dc31151b072457407f4fe03818c91063e7
Author: Benjamin Otte <otte redhat com>
Date:   Mon Oct 2 21:29:49 2017 +0200

    gsksltype: Add concept of components
    
    A type has components, if it is essentially an array of tighly packed
    scalar values. In this case, a GskSlValue's data is essentially
      ScalarType data[n_components];

 gsk/gskslexpression.c   |   17 +-----------
 gsk/gsksltype.c         |   60 ++++++++++++++++++++++++++++++++++++++++++-
 gsk/gsksltypeprivate.h  |    3 ++
 gsk/gskslvalue.c        |   65 ++++++++++++++++++++++++++++++++++++++++++++--
 gsk/gskslvalueprivate.h |    2 +
 5 files changed, 128 insertions(+), 19 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index abe5f62..aaae809 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1266,19 +1266,6 @@ gsk_sl_expression_error_new (void)
   return (GskSlExpression *) constant;
 }
 
-static gsize
-gsk_sl_constructor_get_args_by_type (const GskSlType *type)
-{
-  if (gsk_sl_type_is_scalar (type))
-    return 1;
-  else if (gsk_sl_type_is_vector (type))
-    return gsk_sl_type_get_length (type);
-  else if (gsk_sl_type_is_matrix (type))
-    return gsk_sl_type_get_length (type) * gsk_sl_constructor_get_args_by_type (gsk_sl_type_get_index_type 
(type));
-  else
-    return 0;
-}
-
 GskSlExpression *
 gsk_sl_expression_parse_function_call (GskSlScope           *scope,
                                        GskSlPreprocessor    *stream,
@@ -1301,7 +1288,7 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
   gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
 
   if (function && gsk_sl_function_is_builtin_constructor (function))
-    missing_args = gsk_sl_constructor_get_args_by_type (gsk_sl_function_get_return_type (function));
+    missing_args = gsk_sl_type_get_n_components (gsk_sl_function_get_return_type (function));
   else
     missing_args = -1;
 
@@ -1351,7 +1338,7 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
           else if (missing_args > 0)
             {
               GskSlType *type = gsk_sl_expression_get_return_type (expression);
-              gsize provided = gsk_sl_constructor_get_args_by_type (type);
+              gsize provided = gsk_sl_type_get_n_components (type);
 
               if (provided == 0)
                 {
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 09444c2..416aab3 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -41,7 +41,6 @@ struct _GskSlTypeMember {
   gsize offset;
 };
 
-
 struct _GskSlType
 {
   const GskSlTypeClass *class;
@@ -58,6 +57,7 @@ struct _GskSlTypeClass {
   gsize                 (* get_index_stride)                    (GskSlType           *type);
   guint                 (* get_length)                          (GskSlType           *type);
   gsize                 (* get_size)                            (GskSlType           *type);
+  gsize                 (* get_n_components)                    (GskSlType           *type);
   guint                 (* get_n_members)                       (GskSlType           *type);
   const GskSlTypeMember * (* get_member)                        (GskSlType           *type,
                                                                  guint                n);
@@ -378,6 +378,12 @@ gsk_sl_type_void_get_size (GskSlType *type)
   return 0;
 }
 
+static gsize
+gsk_sl_type_void_get_n_components (GskSlType *type)
+{
+  return 0;
+}
+
 static guint
 gsk_sl_type_void_get_n_members (GskSlType *type)
 {
@@ -439,6 +445,7 @@ static const GskSlTypeClass GSK_SL_TYPE_VOID = {
   gsk_sl_type_void_get_index_stride,
   gsk_sl_type_void_get_length,
   gsk_sl_type_void_get_size,
+  gsk_sl_type_void_get_n_components,
   gsk_sl_type_void_get_n_members,
   gsk_sl_type_void_get_member,
   gsk_sl_type_void_can_convert,
@@ -505,6 +512,12 @@ gsk_sl_type_scalar_get_size (GskSlType *type)
   return scalar_infos[scalar->scalar].size;
 }
 
+static gsize
+gsk_sl_type_scalar_get_n_components (GskSlType *type)
+{
+  return 1;
+}
+
 static guint
 gsk_sl_type_scalar_get_n_members (GskSlType *type)
 {
@@ -630,6 +643,7 @@ static const GskSlTypeClass GSK_SL_TYPE_SCALAR = {
   gsk_sl_type_scalar_get_index_stride,
   gsk_sl_type_scalar_get_length,
   gsk_sl_type_scalar_get_size,
+  gsk_sl_type_scalar_get_n_components,
   gsk_sl_type_scalar_get_n_members,
   gsk_sl_type_scalar_get_member,
   gsk_sl_type_scalar_can_convert,
@@ -704,6 +718,14 @@ gsk_sl_type_vector_get_size (GskSlType *type)
   return vector->length * scalar_infos[vector->scalar].size;
 }
 
+static gsize
+gsk_sl_type_vector_get_n_components (GskSlType *type)
+{
+  GskSlTypeVector *vector = (GskSlTypeVector *) type;
+
+  return vector->length;
+}
+
 static guint
 gsk_sl_type_vector_get_n_members (GskSlType *type)
 {
@@ -818,6 +840,7 @@ static const GskSlTypeClass GSK_SL_TYPE_VECTOR = {
   gsk_sl_type_vector_get_index_stride,
   gsk_sl_type_vector_get_length,
   gsk_sl_type_vector_get_size,
+  gsk_sl_type_vector_get_n_components,
   gsk_sl_type_vector_get_n_members,
   gsk_sl_type_vector_get_member,
   gsk_sl_type_vector_can_convert,
@@ -893,6 +916,14 @@ gsk_sl_type_matrix_get_size (GskSlType *type)
   return matrix->columns * matrix->rows * scalar_infos[matrix->scalar].size;
 }
 
+static gsize
+gsk_sl_type_matrix_get_n_components (GskSlType *type)
+{
+  GskSlTypeMatrix *matrix = (GskSlTypeMatrix *) type;
+
+  return matrix->columns * matrix->rows;
+}
+
 static guint
 gsk_sl_type_matrix_get_n_members (GskSlType *type)
 {
@@ -1008,6 +1039,7 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
   gsk_sl_type_matrix_get_index_stride,
   gsk_sl_type_matrix_get_length,
   gsk_sl_type_matrix_get_size,
+  gsk_sl_type_matrix_get_n_components,
   gsk_sl_type_matrix_get_n_members,
   gsk_sl_type_matrix_get_member,
   gsk_sl_type_matrix_can_convert,
@@ -1088,6 +1120,12 @@ gsk_sl_type_struct_get_size (GskSlType *type)
   return struc->size;
 }
 
+static gsize
+gsk_sl_type_struct_get_n_components (GskSlType *type)
+{
+  return 0;
+}
+
 static guint
 gsk_sl_type_struct_get_n_members (GskSlType *type)
 {
@@ -1203,6 +1241,7 @@ static const GskSlTypeClass GSK_SL_TYPE_STRUCT = {
   gsk_sl_type_struct_get_index_stride,
   gsk_sl_type_struct_get_length,
   gsk_sl_type_struct_get_size,
+  gsk_sl_type_struct_get_n_components,
   gsk_sl_type_struct_get_n_members,
   gsk_sl_type_struct_get_member,
   gsk_sl_type_struct_can_convert,
@@ -1283,6 +1322,12 @@ gsk_sl_type_block_get_size (GskSlType *type)
   return block->size;
 }
 
+static gsize
+gsk_sl_type_block_get_n_components (GskSlType *type)
+{
+  return 0;
+}
+
 static guint
 gsk_sl_type_block_get_n_members (GskSlType *type)
 {
@@ -1404,6 +1449,7 @@ static const GskSlTypeClass GSK_SL_TYPE_BLOCK = {
   gsk_sl_type_block_get_index_stride,
   gsk_sl_type_block_get_length,
   gsk_sl_type_block_get_size,
+  gsk_sl_type_block_get_n_components,
   gsk_sl_type_block_get_n_members,
   gsk_sl_type_block_get_member,
   gsk_sl_type_block_can_convert,
@@ -1414,6 +1460,12 @@ static const GskSlTypeClass GSK_SL_TYPE_BLOCK = {
 
 /* API */
 
+gsize
+gsk_sl_scalar_type_get_size (GskSlScalarType type)
+{
+  return scalar_infos[type].size;
+}
+
 static GskSlType *
 gsk_sl_type_parse_struct (GskSlScope        *scope,
                           GskSlPreprocessor *preproc)
@@ -2054,6 +2106,12 @@ gsk_sl_type_get_size (const GskSlType *type)
   return type->class->get_size (type);
 }
 
+gsize
+gsk_sl_type_get_n_components (const GskSlType *type)
+{
+  return type->class->get_n_components (type);
+}
+
 guint
 gsk_sl_type_get_n_members (const GskSlType *type)
 {
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index 4e89f6a..0768b85 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -27,6 +27,8 @@ G_BEGIN_DECLS
 
 typedef struct _GskSlTypeBuilder GskSlTypeBuilder;
 
+gsize                   gsk_sl_scalar_type_get_size             (GskSlScalarType      type);
+
 GskSlType *             gsk_sl_type_new_parse                   (GskSlScope          *scope,
                                                                  GskSlPreprocessor   *preproc);
 GskSlType *             gsk_sl_type_get_void                    (void);
@@ -54,6 +56,7 @@ GskSlType *             gsk_sl_type_get_index_type              (const GskSlType
 gsize                   gsk_sl_type_get_index_stride            (const GskSlType     *type);
 guint                   gsk_sl_type_get_length                  (const GskSlType     *type);
 gsize                   gsk_sl_type_get_size                    (const GskSlType     *type);
+gsize                   gsk_sl_type_get_n_components            (const GskSlType     *type);
 guint                   gsk_sl_type_get_n_members               (const GskSlType     *type);
 GskSlType *             gsk_sl_type_get_member_type             (const GskSlType     *type,
                                                                  guint                n);
diff --git a/gsk/gskslvalue.c b/gsk/gskslvalue.c
index 91ed63b..fce41fa 100644
--- a/gsk/gskslvalue.c
+++ b/gsk/gskslvalue.c
@@ -170,6 +170,65 @@ gsk_sl_value_new_member (GskSlValue *value,
   return gsk_sl_value_new_for_data (value->type, data, g_free, data);
 }
 
+/**
+ * gsk_sl_value_convert_components:
+ * @source: (transfer full): value to convert
+ * @scalar: new scalar type to convert to
+ *
+ * Converts the scalar components of @source into the @scalar.
+ * This function uses the extended conversion rules for constructors.
+ *
+ * Returns: A value containing the converted values. This may or may not
+ *     be the original @source.
+ **/
+GskSlValue *
+gsk_sl_value_convert_components (GskSlValue      *source,
+                                 GskSlScalarType  scalar)
+{
+  GskSlValue *result;
+  GskSlType *result_type;
+  guchar *sdata, *ddata;
+  gsize sstride, dstride;
+  gsize i, n;
+  GskSlScalarType sscalar;
+
+  sscalar = gsk_sl_type_get_scalar_type (source->type);
+  if (sscalar == scalar)
+    return source;
+
+  if (gsk_sl_type_is_scalar (source->type))
+    result_type = gsk_sl_type_get_scalar (scalar);
+  else if (gsk_sl_type_is_vector (source->type))
+    result_type = gsk_sl_type_get_vector (scalar, gsk_sl_type_get_length (source->type));
+  else if (gsk_sl_type_is_matrix (source->type))
+    result_type = gsk_sl_type_get_matrix (scalar,
+                                          gsk_sl_type_get_length (source->type),
+                                          gsk_sl_type_get_length (gsk_sl_type_get_index_type 
(source->type)));
+  else
+    {
+      g_return_val_if_reached (NULL);
+    }
+
+  result = gsk_sl_value_new (result_type);
+
+  n = gsk_sl_type_get_n_components (result_type);
+  sdata = gsk_sl_value_get_data (source);
+  sstride = gsk_sl_scalar_type_get_size (sscalar);
+  ddata = gsk_sl_value_get_data (result);
+  dstride = gsk_sl_scalar_type_get_size (scalar);
+  for (i = 0; i < n; i++)
+    {
+      gsk_sl_scalar_type_convert_value (scalar,
+                                        ddata + i * dstride,
+                                        sscalar,
+                                        sdata + i * sstride);
+    }
+
+  gsk_sl_value_free (source);
+
+  return result;
+}
+
 GskSlValue *
 gsk_sl_value_copy (GskSlValue *source)
 {
@@ -202,10 +261,10 @@ gsk_sl_value_componentwise (GskSlValue    *value,
   gsize stride;
   gsize i, n;
 
-  g_return_if_fail (gsk_sl_type_is_scalar (value->type) || gsk_sl_type_is_vector (value->type) || 
gsk_sl_type_is_matrix (value->type));
+  g_return_if_fail (gsk_sl_type_get_n_components (value->type) > 0);
 
-  stride = gsk_sl_type_get_size (gsk_sl_type_get_scalar (gsk_sl_type_get_scalar_type (value->type)));
-  n = gsk_sl_type_get_size (value->type) / stride;
+  stride = gsk_sl_scalar_type_get_size (gsk_sl_type_get_scalar_type (value->type));
+  n = gsk_sl_type_get_n_components (value->type);
 
   for (i = 0; i < n; i++)
     {
diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h
index 51e4de5..dc8460e 100644
--- a/gsk/gskslvalueprivate.h
+++ b/gsk/gskslvalueprivate.h
@@ -35,6 +35,8 @@ GskSlValue *            gsk_sl_value_new_member                 (GskSlValue
 GskSlValue *            gsk_sl_value_copy                       (GskSlValue          *source);
 void                    gsk_sl_value_free                       (GskSlValue          *value);
 
+GskSlValue *            gsk_sl_value_convert_components         (GskSlValue          *source,
+                                                                 GskSlScalarType      scalar);
 void                    gsk_sl_value_componentwise              (GskSlValue          *value,
                                                                  void (* func)       (gpointer, gpointer),
                                                                  gpointer             user_data);


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