[gegl/gsoc2011-opencl: 8/12] support for GeglClTexture in GeglTile



commit 88fec51fd3cff7f34e735b95fc294737161fd8f0
Author: Victor Oliveira <victormatheus gmail com>
Date:   Wed Jun 1 17:18:08 2011 -0300

    support for GeglClTexture in GeglTile

 gegl/buffer/gegl-buffer-private.h |    8 +++++
 gegl/buffer/gegl-tile.c           |   59 +++++++++++++++++++++++++++++++++---
 gegl/buffer/gegl-tile.h           |    4 ++
 gegl/opencl/gegl-cl-texture.c     |   17 +++++++++--
 4 files changed, 80 insertions(+), 8 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-private.h b/gegl/buffer/gegl-buffer-private.h
index 2966c2b..d065ba8 100644
--- a/gegl/buffer/gegl-buffer-private.h
+++ b/gegl/buffer/gegl-buffer-private.h
@@ -25,6 +25,9 @@
 #include "gegl-tile-handler.h"
 #include "gegl-buffer-iterator.h"
 
+#include "gegl-cl-init.h"
+#include "gegl-cl-texture.h"
+
 #define GEGL_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GEGL_TYPE_BUFFER, GeglBufferClass))
 #define GEGL_IS_BUFFER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER))
 #define GEGL_IS_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GEGL_TYPE_BUFFER))
@@ -142,6 +145,8 @@ struct _GeglTile
   guchar          *data;        /* actual pixel data for tile, a linear buffer*/
   gint             size;        /* The size of the linear buffer */
 
+  GeglClTexture   *cl_data;     /* OpenCL pixel data for tile */
+
   GeglTileStorage *tile_storage; /* the buffer from which this tile was
                                   * retrieved needed for the tile to be able to
                                   * store itself back (for instance when it is
@@ -151,6 +156,7 @@ struct _GeglTile
 
 
   guint            rev;         /* this tile revision */
+  guint            cl_rev;      /* this tile revision for OpenCL buffer*/
   guint            stored_rev;  /* what revision was we when we from tile_storage?
                                    (currently set to 1 when loaded from disk */
 
@@ -164,7 +170,9 @@ struct _GeglTile
   GeglTile        *prev_shared;
 
   void (*destroy_notify) (gpointer pixels,
+                          GeglClTexture *cl_data,
                           gpointer data);
+
   gpointer         destroy_notify_data;
 };
 
diff --git a/gegl/buffer/gegl-tile.c b/gegl/buffer/gegl-tile.c
index 79ac438..c59b184 100644
--- a/gegl/buffer/gegl-tile.c
+++ b/gegl/buffer/gegl-tile.c
@@ -39,10 +39,17 @@
 
 #include "gegl-utils.h"
 
+#include "gegl-cl-init.h"
+#include "gegl-cl-texture.h"
+
 static void default_free (gpointer data,
+                          GeglClTexture *cl_data,
                           gpointer userdata)
 {
   gegl_free (data);
+
+  if (cl_data)
+    gegl_cl_texture_free(cl_data);
 }
 
 GeglTile *gegl_tile_ref (GeglTile *tile)
@@ -63,13 +70,14 @@ void gegl_tile_unref (GeglTile *tile)
   if (!gegl_tile_is_stored (tile))
     gegl_tile_store (tile);
 
-  if (tile->data)
+  if (tile->data || tile->cl_data)
     {
       if (tile->next_shared == tile)
         { /* no clones */
           if (tile->destroy_notify)
-            tile->destroy_notify (tile->data, tile->destroy_notify_data);
+            tile->destroy_notify (tile->data, tile->cl_data, tile->destroy_notify_data);
           tile->data = NULL;
+          tile->cl_data = NULL;
         }
       else
         {
@@ -94,8 +102,10 @@ gegl_tile_new_bare (void)
   tile->tile_storage = NULL;
   tile->stored_rev = 1;
   tile->rev        = 1;
+  tile->cl_rev     = 0;
   tile->lock       = 0;
   tile->data       = NULL;
+  tile->cl_data    = NULL;
 
   tile->next_shared = tile;
   tile->prev_shared = tile;
@@ -113,6 +123,7 @@ gegl_tile_dup (GeglTile *src)
 
   tile->tile_storage    = src->tile_storage;
   tile->data       = src->data;
+  tile->cl_data    = src->cl_data;
   tile->size       = src->size;
 
   tile->next_shared              = src->next_shared;
@@ -142,6 +153,19 @@ gegl_tile_new (gint size)
   return tile;
 }
 
+gboolean
+gegl_tile_cl_enable (GeglTile *tile,
+                     gint width,
+                     gint height)
+{
+  if (gegl_cl_is_accelerated ())
+    // if there is no memory available,
+    // tile->cl_data will be NULL anyway
+    tile->cl_data = gegl_cl_texture_new (width, height);
+
+  return (tile->cl_data != NULL);
+}
+
 static gpointer
 gegl_memdup (gpointer src, gsize size)
 {
@@ -164,6 +188,9 @@ gegl_tile_unclone (GeglTile *tile)
       tile->next_shared->prev_shared = tile->prev_shared;
       tile->prev_shared              = tile;
       tile->next_shared              = tile;
+
+      if (tile->cl_data)
+        tile->cl_data = gegl_cl_texture_dup (tile->cl_data);
     }
 }
 #if 0
@@ -191,6 +218,20 @@ gegl_tile_lock (GeglTile *tile)
   /*fprintf (stderr, "global tile locking: %i %i\n", locks, unlocks);*/
 
   gegl_tile_unclone (tile);
+
+  if (gegl_cl_is_accelerated ())
+    {
+      if (tile->rev > tile->cl_rev)
+        {
+          gegl_cl_texture_set (tile->cl_data, tile->data);
+          tile->cl_rev = tile->rev;
+        }
+      else if (tile->cl_rev > tile->rev)
+        {
+          gegl_cl_texture_get (tile->cl_data, tile->data);
+          tile->rev = tile->cl_rev;
+        }
+    }
 }
 
 static void
@@ -231,13 +272,21 @@ gegl_tile_unlock (GeglTile *tile)
       g_warning ("unlocked a tile with lock count == 0");
     }
   tile->lock--;
+
   if (tile->lock == 0 &&
       tile->z == 0)
     {
       gegl_tile_void_pyramid (tile);
     }
+
   if (tile->lock==0)
-    tile->rev++;
+    {
+      if (gegl_cl_is_accelerated ())
+          tile->rev = tile->cl_rev = MAX(tile->rev, tile->cl_rev)+1;
+      else
+          tile->rev++;
+    }
+
   g_mutex_unlock (tile->mutex);
 }
 
@@ -251,13 +300,13 @@ gegl_tile_mark_as_stored (GeglTile *tile)
 gboolean
 gegl_tile_is_stored (GeglTile *tile)
 {
-  return tile->stored_rev == tile->rev;
+  return tile->stored_rev == MAX(tile->rev, tile->cl_rev);
 }
 
 void
 gegl_tile_void (GeglTile *tile)
 {
-  tile->stored_rev = tile->rev;
+  tile->stored_rev = MAX(tile->rev, tile->cl_rev);
   tile->tile_storage = NULL;
   if (tile->z==0)
     gegl_tile_void_pyramid (tile);
diff --git a/gegl/buffer/gegl-tile.h b/gegl/buffer/gegl-tile.h
index 05d5469..fbc52a9 100644
--- a/gegl/buffer/gegl-tile.h
+++ b/gegl/buffer/gegl-tile.h
@@ -50,4 +50,8 @@ guint        gegl_tile_get_rev        (GeglTile *tile);
 
 guchar      *gegl_tile_get_data       (GeglTile *tile);
 
+gboolean     gegl_tile_cl_enable      (GeglTile *tile,
+                                       gint width,
+                                       gint height);
+
 #endif
diff --git a/gegl/opencl/gegl-cl-texture.c b/gegl/opencl/gegl-cl-texture.c
index 01254eb..cadad01 100644
--- a/gegl/opencl/gegl-cl-texture.c
+++ b/gegl/opencl/gegl-cl-texture.c
@@ -20,6 +20,7 @@ gegl_cl_texture_new (const gint width, const gint height)
                                          texture->width,
                                          texture->height,
                                          0,  NULL, &errcode);
+
   if (errcode != CL_SUCCESS)
   {
     g_warning("OpenCL Alloc Error: %s", gegl_cl_errstring(errcode));
@@ -27,6 +28,12 @@ gegl_cl_texture_new (const gint width, const gint height)
     return NULL;
   }
 
+  /* XXX: DEBUG */
+  /*{
+    gfloat color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
+    gegl_cl_texture_fill (texture, NULL, color);
+  }*/
+
   return texture;
 }
 
@@ -87,14 +94,18 @@ gegl_cl_texture_dup (const GeglClTexture *texture)
 
 void
 gegl_cl_texture_copy (const GeglClTexture  *src,
-                      GeglRectangle        *src_rect,
+                      GeglRectangle        *_src_rect,
                       GeglClTexture        *dst,
                       gint                  dst_x,
                       gint                  dst_y)
 {
-  const size_t src_origin[3] = {src_rect->x, src_rect->y, 0};
+  GeglRectangle src_rect = {0, 0, src->width, src->height};
+  if (_src_rect)
+    src_rect = *_src_rect;
+
+  const size_t src_origin[3] = {src_rect.x, src_rect.y, 0};
   const size_t dst_origin[3] = {dst_x, dst_y, 0};
-  const size_t region[3] = {src_rect->width, src_rect->height, 1};
+  const size_t region[3] = {src_rect.width, src_rect.height, 1};
 
   gegl_clEnqueueCopyImage (gegl_cl_get_command_queue(),
                            src->data, dst->data,



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