general: Store the iter initializer in a one-entry pixman_iter_info_t table
authorSøren Sandmann Pedersen <ssp@redhat.com>
Wed, 22 May 2013 12:05:55 +0000 (08:05 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Wed, 22 May 2013 13:43:21 +0000 (09:43 -0400)
In preparation for sharing all iterator initialization code from all
the implementations, move the general implementation to use a table of
pixman_iter_info_t.

The existing src_iter_init and dest_iter_init functions are
consolidated into one general_iter_init() function that checks the
iter_flags for whether it is dealing with a source or destination
iterator.

Unlike in the other implementations, the general_iter_init() function
stores its own get_scanline() and write_back() functions in the
iterator, so it relies on the initializer being called after
get_scanline and write_back being copied from the struct to the
iterator.

pixman/pixman-general.c

index c674ffa..91e33c4 100644 (file)
 #include <string.h>
 #include "pixman-private.h"
 
-static pixman_bool_t
-general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+static void
+general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info)
 {
     pixman_image_t *image = iter->image;
 
-    if (image->type == LINEAR)
-       _pixman_linear_gradient_iter_init (image, iter);
-    else if (image->type == RADIAL)
+    switch (image->type)
+    {
+    case BITS:
+        if ((iter->iter_flags & ITER_SRC) == ITER_SRC)
+            _pixman_bits_image_src_iter_init (image, iter);
+        else
+            _pixman_bits_image_dest_iter_init (image, iter);
+        break;
+
+    case LINEAR:
+        _pixman_linear_gradient_iter_init (image, iter);
+        break;
+
+    case RADIAL:
        _pixman_radial_gradient_iter_init (image, iter);
-    else if (image->type == CONICAL)
+        break;
+
+    case CONICAL:
        _pixman_conical_gradient_iter_init (image, iter);
-    else if (image->type == BITS)
-       _pixman_bits_image_src_iter_init (image, iter);
-    else if (image->type == SOLID)
+        break;
+
+    case SOLID:
         _pixman_log_error (FUNC, "Solid image not handled by noop");
-    else         
-       _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+        break;
 
-    return TRUE;
+    default:
+       _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+        break;
+    }
 }
 
+static const pixman_iter_info_t general_iters[] =
+{
+    { PIXMAN_any, 0, 0, general_iter_init, NULL, NULL },
+    { PIXMAN_null },
+};
+
 static pixman_bool_t
-general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+general_iter_init_common (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
-    if (iter->image->type == BITS)
-    {
-       _pixman_bits_image_dest_iter_init (iter->image, iter);
+    const pixman_iter_info_t *info;
 
-       return TRUE;
-    }
-    else
+    for (info = general_iters; info->format != PIXMAN_null; ++info)
     {
-       _pixman_log_error (FUNC, "Trying to write to a non-writable image");
-
-       return FALSE;
+       if ((info->format == PIXMAN_any ||
+            info->format == iter->image->common.extended_format_code)   &&
+           (info->image_flags & iter->image_flags) == info->image_flags &&
+           (info->iter_flags & iter->iter_flags) == info->iter_flags)
+       {
+           iter->get_scanline = info->get_scanline;
+           iter->write_back = info->write_back;
+
+           if (info->initializer)
+               info->initializer (iter, info);
+           return TRUE;
+       }
     }
+
+    return FALSE;
+}
+
+static pixman_bool_t
+general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+{
+    return general_iter_init_common (imp, iter);
+}
+
+static pixman_bool_t
+general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
+{
+    return general_iter_init_common (imp, iter);
 }
 
 typedef struct op_info_t op_info_t;