[gtk/wip/otte/transform: 1/4] gsk: Add GskMatrixCategory



commit 91545a78bbbbed202b30f2bf13f2f78b8e3b44ae
Author: Benjamin Otte <otte redhat com>
Date:   Tue Feb 19 06:52:36 2019 +0100

    gsk: Add GskMatrixCategory
    
    We'll use that soon.

 gsk/gskrendernodeimpl.c    | 46 ++++++++++++++++++++++++++++++++++++++++++----
 gsk/gskrendernodeprivate.h | 43 +++++++++++++++++++++++++++++++++++++++++++
 gtk/inspector/recorder.c   |  9 +++++++++
 3 files changed, 94 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 8b704aedda..34dd509d1f 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -2387,6 +2387,7 @@ struct _GskTransformNode
 
   GskRenderNode *child;
   graphene_matrix_t transform;
+  GskMatrixCategory category;
 };
 
 static void
@@ -2422,7 +2423,7 @@ gsk_transform_node_draw (GskRenderNode *node,
     }
 }
 
-#define GSK_TRANSFORM_NODE_VARIANT_TYPE "(dddddddddddddddduv)"
+#define GSK_TRANSFORM_NODE_VARIANT_TYPE "(idddddddddddddddduv)"
 
 static GVariant *
 gsk_transform_node_serialize (GskRenderNode *node)
@@ -2433,6 +2434,7 @@ gsk_transform_node_serialize (GskRenderNode *node)
   graphene_matrix_to_float (&self->transform, mat);
 
   return g_variant_new (GSK_TRANSFORM_NODE_VARIANT_TYPE,
+                        self->category,
                         (double) mat[0], (double) mat[1], (double) mat[2], (double) mat[3],
                         (double) mat[4], (double) mat[5], (double) mat[6], (double) mat[7],
                         (double) mat[8], (double) mat[9], (double) mat[10], (double) mat[11],
@@ -2448,6 +2450,7 @@ gsk_transform_node_deserialize (GVariant  *variant,
   graphene_matrix_t transform;
   double mat[16];
   guint32 child_type;
+  gint32 category;
   GVariant *child_variant;
   GskRenderNode *result, *child;
 
@@ -2455,6 +2458,7 @@ gsk_transform_node_deserialize (GVariant  *variant,
     return NULL;
 
   g_variant_get (variant, GSK_TRANSFORM_NODE_VARIANT_TYPE,
+                 &category,
                  &mat[0], &mat[1], &mat[2], &mat[3],
                  &mat[4], &mat[5], &mat[6], &mat[7],
                  &mat[8], &mat[9], &mat[10], &mat[11],
@@ -2475,7 +2479,7 @@ gsk_transform_node_deserialize (GVariant  *variant,
                                        mat[12], mat[13], mat[14], mat[15]
                                    });
 
-  result = gsk_transform_node_new (child, &transform);
+  result = gsk_transform_node_new_with_category (child, &transform, category);
 
   gsk_render_node_unref (child);
 
@@ -2508,15 +2512,39 @@ GskRenderNode *
 gsk_transform_node_new (GskRenderNode           *child,
                         const graphene_matrix_t *transform)
 {
-  GskTransformNode *self;
-
   g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
   g_return_val_if_fail (transform != NULL, NULL);
 
+  return gsk_transform_node_new_with_category (child, transform, GSK_MATRIX_CATEGORY_UNKNOWN);
+}
+
+/*<private>
+ * gsk_transform_node_new_with_category:
+ * @child: The node to transform
+ * @transform: The transform to apply
+ * @category: The category @transform belongs to
+ *
+ * Creates a #GskRenderNode that will transform the given @child
+ * with the given @transform.
+ *
+ * The given @category will be used by renderers for optimizations and must
+ * be correct. If you do not know the category of @transform, use
+ * %GSK_MATRIX_CATEGORY_UNKNOWN.
+ *
+ * Returns: A new #GskRenderNode
+ **/
+GskRenderNode *
+gsk_transform_node_new_with_category (GskRenderNode           *child,
+                                      const graphene_matrix_t *transform,
+                                      GskMatrixCategory        category)
+{
+  GskTransformNode *self;
+
   self = (GskTransformNode *) gsk_render_node_new (&GSK_TRANSFORM_NODE_CLASS, 0);
 
   self->child = gsk_render_node_ref (child);
   graphene_matrix_init_from_matrix (&self->transform, transform);
+  self->category = category;
 
   graphene_matrix_transform_bounds (&self->transform,
                                     &child->bounds,
@@ -2552,6 +2580,16 @@ gsk_transform_node_peek_transform (GskRenderNode *node)
   return &self->transform;
 }
 
+GskMatrixCategory
+gsk_transform_node_get_category (GskRenderNode *node)
+{
+  GskTransformNode *self = (GskTransformNode *) node;
+
+  g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_TRANSFORM_NODE), GSK_MATRIX_CATEGORY_UNKNOWN);
+
+  return self->category;
+}
+
 /*** GSK_OFFSET_NODE ***/
 
 typedef struct _GskOffsetNode GskOffsetNode;
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 145fec0955..1f0565cfab 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -6,6 +6,44 @@
 
 G_BEGIN_DECLS
 
+/*<private>
+ * GskMatrixCategory:
+ * @GSK_MATRIX_CATEGORY_UNKNOWN: The category of the matrix has not been
+ *     determined.
+ * @GSK_MATRIX_CATEGORY_ANY: Analyzing the matrix concluded that it does
+ *     not fit in any other category.
+ * @GSK_MATRIX_CATEGORY_INVERTIBLE: The matrix is linear independant and
+ *     should therefor be invertible. Note that this is not guaranteed
+ *     to actually be true due to rounding errors when inverting.
+ * @GSK_MATRIX_CATEGORY_2D: The matrix is a 2D matrix. This is equivalent
+ *     to graphene_matrix_is_2d() returning %TRUE. In particular, this
+ *     means that Cairo can deal with the matrix.
+ * @GSK_MATRIX_CATEGORY_2D_AFFINE: The matrix is a combination of 2D scale
+ *     and 2D translation operations. In particular, this means that any
+ *     rectangle can be transformed exactly using this matrix.
+ * @GSK_MATRIX_CATEGORY_2D_TRANSLATE: The matrix is a 2D translation.
+ * @GSK_MATRIX_CATEGORY_IDENTITY: The matrix is the identity matrix.
+ *
+ * The categories of matrices relevant for GSK and GTK. Note that any
+ * category includes matrices of all later categories. So if you want
+ * to for example check if a matrix is a 2D matrix,
+ * `category >= GSK_MATRIX_CATEGORY_2D` is the way to do this.
+ *
+ * Also keep in mind that rounding errors may cause matrices to not
+ * conform to their categories. Otherwise, matrix operations done via
+ * mutliplication will not worsen categories. So for the matrix
+ * multiplication `C = A * B`, `category(C) = MIN (category(A), category(B))`.
+ */
+typedef enum
+{
+  GSK_MATRIX_CATEGORY_UNKNOWN,
+  GSK_MATRIX_CATEGORY_ANY,
+  GSK_MATRIX_CATEGORY_INVERTIBLE,
+  GSK_MATRIX_CATEGORY_2D_AFFINE,
+  GSK_MATRIX_CATEGORY_2D_TRANSLATE,
+  GSK_MATRIX_CATEGORY_IDENTITY
+} GskMatrixCategory;
+
 typedef struct _GskRenderNodeClass GskRenderNodeClass;
 
 #define GSK_IS_RENDER_NODE_TYPE(node,type) (GSK_IS_RENDER_NODE (node) && (node)->node_class->node_type == 
(type))
@@ -58,6 +96,11 @@ GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType          typ
 GskRenderNode * gsk_cairo_node_new_for_surface   (const graphene_rect_t    *bounds,
                                                   cairo_surface_t          *surface);
 
+GskRenderNode *         gsk_transform_node_new_with_category    (GskRenderNode                  *child,
+                                                                 const graphene_matrix_t        *transform,
+                                                                 GskMatrixCategory               category);
+GskMatrixCategory       gsk_transform_node_get_category         (GskRenderNode                  *node);
+
 GskRenderNode * gsk_text_node_new_with_bounds     (PangoFont                *font,
                                                    PangoGlyphString         *glyphs,
                                                    const GdkRGBA            *color,
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index 26ae9cbdd2..0a56aefb8a 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -901,6 +901,14 @@ populate_render_node_properties (GtkListStore  *store,
 
     case GSK_TRANSFORM_NODE:
       {
+        static const char * category_names[] = {
+          [GSK_MATRIX_CATEGORY_UNKNOWN] = "unknown",
+          [GSK_MATRIX_CATEGORY_ANY] = "any",
+          [GSK_MATRIX_CATEGORY_INVERTIBLE] = "invertible",
+          [GSK_MATRIX_CATEGORY_2D_AFFINE] = "2D affine",
+          [GSK_MATRIX_CATEGORY_2D_TRANSLATE] = "2D transform",
+          [GSK_MATRIX_CATEGORY_IDENTITY] = "identity"
+        };
         float f[16];
         guint i;
 
@@ -913,6 +921,7 @@ populate_render_node_properties (GtkListStore  *store,
             add_text_row (store, i == 0 ? "Matrix" : "", row_string);
             g_free (row_string);
           }
+        add_text_row (store, "Category", category_names[gsk_transform_node_get_category (node)]);
       }
       break;
 


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