[gegl] Improving cl-cache



commit 70c96296f82963125111617786961930f2c77214
Author: Victor Oliveira <victormatheus gmail com>
Date:   Tue Mar 27 12:45:20 2012 -0300

    Improving cl-cache
    
    nowi opencl synchronization is done in tile-handler-cache

 gegl/buffer/gegl-buffer-access.c      |   16 +--
 gegl/buffer/gegl-buffer-cl-cache.c    |  273 ++++++++-------------------------
 gegl/buffer/gegl-buffer-cl-cache.h    |   20 +--
 gegl/buffer/gegl-buffer.c             |    2 +-
 gegl/buffer/gegl-tile-handler-cache.c |    5 +
 gegl/operation/gegl-operation-sink.c  |    3 -
 operations/affine/affine.c            |    8 -
 operations/core/clone.c               |    3 -
 operations/core/crop.c                |    3 -
 9 files changed, 86 insertions(+), 247 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index df0e6fc..9b801a5 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -580,6 +580,11 @@ gegl_buffer_set_unlocked (GeglBuffer          *buffer,
   if (format == NULL)
     format = buffer->soft_format;
 
+  if (gegl_cl_is_accelerated ())
+    {
+      gegl_buffer_cl_cache_flush (buffer, rect);
+    }
+
 #if 0 /* XXX: not thread safe */
   if (rect && rect->width == 1 && rect->height == 1) /* fast path */
     {
@@ -951,16 +956,7 @@ gegl_buffer_get_unlocked (GeglBuffer          *buffer,
 
   if (gegl_cl_is_accelerated ())
     {
-      if (GEGL_FLOAT_EQUAL (scale, 1.0))
-        {
-          if (gegl_buffer_cl_cache_from (buffer, rect, dest_buf, format, rowstride))
-            return;
-        }
-      else
-        {
-          /* doesn't support scaling in the GPU */
-          gegl_buffer_cl_cache_invalidate (buffer, rect);
-        }
+      gegl_buffer_cl_cache_flush (buffer, rect);
     }
 
   if (!rect && scale == 1.0)
diff --git a/gegl/buffer/gegl-buffer-cl-cache.c b/gegl/buffer/gegl-buffer-cl-cache.c
index 07b5d52..b5f8f8e 100644
--- a/gegl/buffer/gegl-buffer-cl-cache.c
+++ b/gegl/buffer/gegl-buffer-cl-cache.c
@@ -8,12 +8,16 @@
 #include "gegl-buffer-types.h"
 #include "gegl-buffer.h"
 #include "gegl-buffer-private.h"
+#include "gegl-tile-handler-cache.h"
+#include "gegl-tile-storage.h"
+
 #include "gegl-buffer-cl-cache.h"
 #include "opencl/gegl-cl.h"
 
 typedef struct
 {
   GeglBuffer           *buffer;
+  GeglTileStorage      *tile_storage;
   GeglRectangle         roi;
   cl_mem                tex;
   gboolean              valid;
@@ -21,17 +25,26 @@ typedef struct
 
 static GList *cache_entries = NULL;
 
-typedef struct
+static GStaticMutex cache_mutex = G_STATIC_MUTEX_INIT;
+
+static gboolean
+cache_entry_find_invalid (gpointer *data)
 {
-  GeglBuffer   *buffer;
-  GeglBuffer   *buffer_origin;
-  GeglRectangle roi;
-  gboolean      valid;
-} CacheBuffer;
+  GList *elem;
 
-static GList *cache_buffer = NULL; /* this is used in color conversions from the cache */
+  for (elem=cache_entries; elem; elem=elem->next)
+    {
+      CacheEntry *e = elem->data;
+      if (!e->valid)
+        {
+          *data = e;
+          return TRUE;
+        }
+    }
 
-static GStaticMutex cache_mutex = G_STATIC_MUTEX_INIT;
+  *data = NULL;
+  return FALSE;
+}
 
 cl_mem
 gegl_buffer_cl_cache_get (GeglBuffer          *buffer,
@@ -62,6 +75,7 @@ gegl_buffer_cl_cache_new (GeglBuffer            *buffer,
   CacheEntry *e = g_slice_new (CacheEntry);
 
   e->buffer =  buffer;
+  e->tile_storage = buffer->tile_storage;
   e->roi    = *roi;
   e->tex    =  tex;
   e->valid  =  TRUE;
@@ -75,27 +89,27 @@ gegl_buffer_cl_cache_new (GeglBuffer            *buffer,
 #define CL_ERROR {GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error in %s:%d %s - %s\n", __FILE__, __LINE__, __func__, gegl_cl_errstring(cl_err)); goto error;}
 
 gboolean
-gegl_buffer_cl_cache_merge (GeglBuffer          *buffer,
-                            const GeglRectangle *roi)
+gegl_buffer_cl_cache_flush2 (GeglTileHandlerCache *cache,
+                             const GeglRectangle  *roi)
 {
   size_t size;
   GList *elem;
   GeglRectangle tmp;
   cl_int cl_err = 0;
 
-  if (!roi)
-    roi = &buffer->extent;
-
-  gegl_cl_color_babl (buffer->soft_format, &size);
+  gpointer data;
+  gboolean need_cl = FALSE;
 
   for (elem=cache_entries; elem; elem=elem->next)
     {
       CacheEntry *entry = elem->data;
 
-      if (entry->valid && entry->buffer == buffer
-          && (gegl_rectangle_intersect (&tmp, roi, &entry->roi)))
+      if (entry->valid && entry->tile_storage->cache == cache
+          && (!roi || gegl_rectangle_intersect (&tmp, roi, &entry->roi)))
         {
-          gpointer data;
+          entry->valid = FALSE; /* avoid possible infinite recursion */
+
+          gegl_cl_color_babl (buffer->soft_format, &size);
 
           data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), entry->tex, CL_TRUE,
                                          CL_MAP_READ, 0, entry->roi.width * entry->roi.height * size,
@@ -108,74 +122,60 @@ gegl_buffer_cl_cache_merge (GeglBuffer          *buffer,
           cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), entry->tex, data,
                                                  0, NULL, NULL);
           if (cl_err != CL_SUCCESS) CL_ERROR;
+
+          need_cl = TRUE;
         }
     }
 
-  return TRUE;
-
-error:
-  /* XXX : result is corrupted */
-  return FALSE;
-}
+  if (need_cl)
+    {
+      cl_err = gegl_clFinish (gegl_cl_get_command_queue ());
+      if (cl_err != CL_SUCCESS) CL_ERROR;
+    }
 
-static gboolean
-cache_buffer_find_invalid (gpointer *data)
-{
-  GList *elem;
+  g_static_mutex_lock (&cache_mutex);
 
-  for (elem=cache_buffer; elem; elem=elem->next)
+  while (cache_entry_find_invalid (&data))
     {
-      CacheBuffer *cb = elem->data;
-      if (!cb->valid)
-        {
-          *data = cb;
-          return TRUE;
-        }
+      g_slice_free (CacheEntry, data);
+      cache_entries = g_list_remove (cache_entries, data);
     }
 
-  *data = NULL;
-  return FALSE;
-}
+  g_static_mutex_unlock (&cache_mutex);
 
+  return TRUE;
 
-static gboolean
-cache_entry_find_invalid (gpointer *data)
-{
-  GList *elem;
+error:
 
-  for (elem=cache_entries; elem; elem=elem->next)
+  g_static_mutex_lock (&cache_mutex);
+
+  while (cache_entry_find_invalid (&data))
     {
-      CacheEntry *cb = elem->data;
-      if (!cb->valid)
-        {
-          *data = cb;
-          return TRUE;
-        }
+      g_slice_free (CacheEntry, data);
+      cache_entries = g_list_remove (cache_entries, data);
     }
 
-  *data = NULL;
+  g_static_mutex_unlock (&cache_mutex);
+
+  /* XXX : result is corrupted */
   return FALSE;
 }
 
+gboolean
+gegl_buffer_cl_cache_flush (GeglBuffer          *buffer,
+                            const GeglRectangle *roi)
+{
+  return gegl_buffer_cl_cache_flush2 (buffer->tile_storage->cache, roi);
+}
+
 void
-gegl_buffer_cl_cache_remove (GeglBuffer          *buffer,
-                             const GeglRectangle *roi)
+gegl_buffer_cl_cache_invalidate (GeglBuffer          *buffer,
+                                 const GeglRectangle *roi)
 {
   GeglRectangle tmp;
   GList *elem;
   gpointer data;
 
-  for (elem=cache_buffer; elem; elem=elem->next)
-    {
-      CacheBuffer *cb = elem->data;
-      if (cb->valid && cb->buffer_origin == buffer
-          && (!roi || gegl_rectangle_intersect (&tmp, &cb->roi, roi)))
-        {
-          gegl_buffer_destroy (cb->buffer);
-          cb->valid = FALSE;
-        }
-    }
-
   for (elem=cache_entries; elem; elem=elem->next)
     {
       CacheEntry *e = elem->data;
@@ -189,12 +189,6 @@ gegl_buffer_cl_cache_remove (GeglBuffer          *buffer,
 
   g_static_mutex_lock (&cache_mutex);
 
-  while (cache_buffer_find_invalid (&data))
-    {
-      g_slice_free (CacheBuffer, data);
-      cache_buffer = g_list_remove (cache_buffer, data);
-    }
-
   while (cache_entry_find_invalid (&data))
     {
       g_slice_free (CacheEntry, data);
@@ -205,151 +199,14 @@ gegl_buffer_cl_cache_remove (GeglBuffer          *buffer,
 
 #if 0
   g_printf ("-- ");
-  for (elem=cache_buffer; elem; elem=elem->next)
+  for (elem=cache_entry; elem; elem=elem->next)
     {
-      CacheBuffer *cb = elem->data;
-      g_printf ("%p %p {%d, %d, %d, %d} %d | ", cb->buffer, cb->buffer_origin, cb->roi.x, cb->roi.y, cb->roi.width, cb->roi.height, cb->valid);
+      CacheEntry *e = elem->data;
+      g_printf ("%p %p {%d, %d, %d, %d} %d | ", e->tex, e->buffer, e->roi.x, e->roi.y, e->roi.width, e->roi.height, e->valid);
     }
   g_printf ("\n");
 #endif
 
 }
 
-void
-gegl_buffer_cl_cache_invalidate (GeglBuffer          *buffer,
-                                 const GeglRectangle *roi)
-{
-  gegl_buffer_cl_cache_merge (buffer, roi);
-  gegl_clFinish (gegl_cl_get_command_queue ());
-  gegl_buffer_cl_cache_remove (buffer, roi);
-}
-
-gboolean
-gegl_buffer_cl_cache_from (GeglBuffer          *buffer,
-                           const GeglRectangle *roi,
-                           gpointer             dest_buf,
-                           const Babl          *format,
-                           gint                 rowstride)
-{
-  size_t buf_size, dest_size;
-  cl_mem tex_dest = NULL;
-  GList *elem_cache, *elem_buffer;
-
-  gegl_cl_color_op conv = gegl_cl_color_supported (buffer->soft_format, format);
-  gegl_cl_color_babl (buffer->soft_format, &buf_size);
-  gegl_cl_color_babl (format,         &dest_size);
-
-  for (elem_cache=cache_entries; elem_cache; elem_cache=elem_cache->next)
-    {
-      CacheEntry *entry = elem_cache->data;
-
-      if (entry->valid && entry->buffer == buffer
-          && gegl_rectangle_contains (&entry->roi, roi))
-        {
-          cl_int cl_err;
-
-          switch (conv)
-            {
-              case GEGL_CL_COLOR_NOT_SUPPORTED:
-              case GEGL_CL_COLOR_EQUAL:
-
-              {
-              gegl_buffer_cl_cache_invalidate (buffer, &entry->roi);
-
-              return FALSE;
-              }
-
-              case GEGL_CL_COLOR_CONVERT:
-
-              {
-
-              for (elem_buffer=cache_buffer; elem_buffer; elem_buffer=elem_buffer->next)
-                {
-                  CacheBuffer *cb = elem_buffer->data;
-                  if (cb->valid && cb->buffer &&
-                      cb->buffer_origin == buffer &&
-                      cb->buffer->soft_format == format &&
-                      gegl_rectangle_contains (&cb->roi, roi))
-                    {
-                      gegl_buffer_get (cb->buffer,
-                                       roi,
-                                       1.0,
-                                       format,
-                                       dest_buf,
-                                       rowstride,
-                                       GEGL_ABYSS_NONE);
-                      return TRUE;
-                    }
-                }
-
-                {
-                  gpointer data;
-                  CacheBuffer *cb;
-
-                  g_static_mutex_lock (&cache_mutex);
-                  {
-                  cb = g_slice_new (CacheBuffer);
-                  cb->buffer        = gegl_buffer_new (&entry->roi, format);
-                  cb->buffer_origin = buffer;
-                  cb->roi           = entry->roi;
-                  cb->valid         = TRUE;
-                  cache_buffer = g_list_prepend (cache_buffer, cb);
-                  }
-                  g_static_mutex_unlock (&cache_mutex);
-
-                  tex_dest = gegl_clCreateBuffer (gegl_cl_get_context (),
-                                                  CL_MEM_WRITE_ONLY,
-                                                  entry->roi.width * entry->roi.height * dest_size,
-                                                  NULL, &cl_err);
-                  if (cl_err != CL_SUCCESS) CL_ERROR;
-
-                  cl_err = gegl_cl_color_conv (entry->tex, tex_dest, entry->roi.width * entry->roi.height, buffer->soft_format, format);
-                  if (cl_err == FALSE) CL_ERROR;
-
-                  data = gegl_clEnqueueMapBuffer(gegl_cl_get_command_queue(), tex_dest, CL_TRUE,
-                                                 CL_MAP_READ,
-                                                 0, entry->roi.width * entry->roi.height * dest_size,
-                                                 0, NULL, NULL, &cl_err);
-                  if (cl_err != CL_SUCCESS) CL_ERROR;
-
-                  gegl_buffer_set (cb->buffer, &entry->roi, 0, format, data, GEGL_AUTO_ROWSTRIDE);
-
-                  cl_err = gegl_clEnqueueUnmapMemObject (gegl_cl_get_command_queue(), tex_dest, data,
-                                                         0, NULL, NULL);
-                  if (cl_err != CL_SUCCESS) CL_ERROR;
-
-                  cl_err = gegl_clFinish(gegl_cl_get_command_queue());
-                  if (cl_err != CL_SUCCESS) CL_ERROR;
-
-                  gegl_buffer_get (cb->buffer,
-                                   roi,
-                                   1.0,
-                                   format,
-                                   dest_buf,
-                                   rowstride,
-                                   GEGL_ABYSS_NONE);
-
-                  if (tex_dest) gegl_clReleaseMemObject (tex_dest);
-
-                  return TRUE;
-                }
-              }
-            }
-        }
-    }
-
-  gegl_buffer_cl_cache_invalidate (buffer, roi);
-
-  return FALSE;
-
-error:
-
-  /* this function isn`t supposed to fail, there is no memory alloc here */
-  gegl_buffer_cl_cache_invalidate (buffer, roi);
-
-  if (tex_dest) gegl_clReleaseMemObject (tex_dest);
-
-  return FALSE;
-}
-
 #undef CL_ERROR
diff --git a/gegl/buffer/gegl-buffer-cl-cache.h b/gegl/buffer/gegl-buffer-cl-cache.h
index 4145558..b3baf5a 100644
--- a/gegl/buffer/gegl-buffer-cl-cache.h
+++ b/gegl/buffer/gegl-buffer-cl-cache.h
@@ -6,6 +6,9 @@
 #include "gegl-buffer-types.h"
 #include "gegl-buffer.h"
 #include "gegl-buffer-private.h"
+#include "gegl-tile-handler-cache.h"
+#include "gegl-tile-storage.h"
+
 #include "opencl/gegl-cl.h"
 
 cl_mem
@@ -16,22 +19,17 @@ void
 gegl_buffer_cl_cache_new (GeglBuffer            *buffer,
                           const GeglRectangle   *roi,
                           cl_mem                 tex);
-gboolean
-gegl_buffer_cl_cache_merge (GeglBuffer          *buffer,
-                            const GeglRectangle *roi);
 
-void
-gegl_buffer_cl_cache_remove (GeglBuffer          *buffer,
+gboolean
+gegl_buffer_cl_cache_flush  (GeglBuffer          *buffer,
                              const GeglRectangle *roi);
 
+gboolean
+gegl_buffer_cl_cache_flush2 (GeglTileHandlerCache *cache,
+                             const GeglRectangle  *roi);
+
 void
 gegl_buffer_cl_cache_invalidate (GeglBuffer          *buffer,
                                  const GeglRectangle *roi);
 
-gboolean
-gegl_buffer_cl_cache_from (GeglBuffer          *buffer,
-                           const GeglRectangle *roi,
-                           gpointer             dest_buf,
-                           const Babl          *format,
-                           gint                 rowstride);
 #endif
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index 82fd96b..153ce13 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -395,7 +395,7 @@ gegl_buffer_dispose (GObject *object)
   gegl_buffer_sample_cleanup (buffer);
 
   if (gegl_cl_is_accelerated ())
-    gegl_buffer_cl_cache_remove (GEGL_BUFFER (object), NULL);
+    gegl_buffer_cl_cache_invalidate (GEGL_BUFFER (object), NULL);
 
   if (handler->source &&
       GEGL_IS_TILE_STORAGE (handler->source))
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index 574ad6e..ba3dc06 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -213,6 +213,11 @@ gegl_tile_handler_cache_get_tile_command (GeglTileSource *tile_store,
   GeglTileSource       *source = GEGL_TILE_HANDLER (tile_store)->source;
   GeglTile             *tile     = NULL;
 
+  if (gegl_cl_is_accelerated ())
+    {
+      gegl_buffer_cl_cache_flush2 (cache, NULL);
+    }
+
   tile = gegl_tile_handler_cache_get_tile (cache, x, y, z);
   if (tile)
     {
diff --git a/gegl/operation/gegl-operation-sink.c b/gegl/operation/gegl-operation-sink.c
index a0de9ed..9107d05 100644
--- a/gegl/operation/gegl-operation-sink.c
+++ b/gegl/operation/gegl-operation-sink.c
@@ -135,9 +135,6 @@ gegl_operation_sink_process (GeglOperation        *operation,
   input = gegl_operation_context_get_source (context, "input");
   if (input)
     {
-      if (gegl_cl_is_accelerated ())
-        gegl_buffer_cl_cache_invalidate (input, NULL);
-
       success = klass->process (operation, input, result, level);
       g_object_unref (input);
     }
diff --git a/operations/affine/affine.c b/operations/affine/affine.c
index ba7465a..f869143 100644
--- a/operations/affine/affine.c
+++ b/operations/affine/affine.c
@@ -851,14 +851,6 @@ gegl_affine_process (GeglOperation        *operation,
 
   gegl_affine_create_composite_matrix (affine, &matrix);
 
-  input  = gegl_operation_context_get_source (context, "input");
-  if (input)
-    {
-      if (gegl_cl_is_accelerated ())
-        gegl_buffer_cl_cache_invalidate (input, NULL);
-      g_object_unref (input);
-    }
-
   if (gegl_affine_is_intermediate_node (affine) ||
       gegl_matrix3_is_identity (&matrix))
     {
diff --git a/operations/core/clone.c b/operations/core/clone.c
index 0d7688a..19465b5 100644
--- a/operations/core/clone.c
+++ b/operations/core/clone.c
@@ -91,9 +91,6 @@ process (GeglOperation        *operation,
       return FALSE;
     }
 
-  if (gegl_cl_is_accelerated ())
-    gegl_buffer_cl_cache_invalidate (input, NULL);
-
   gegl_operation_context_take_object (context, "output", G_OBJECT (input));
   return TRUE;
 }
diff --git a/operations/core/crop.c b/operations/core/crop.c
index 9623520..978f26b 100644
--- a/operations/core/crop.c
+++ b/operations/core/crop.c
@@ -138,9 +138,6 @@ gegl_crop_process (GeglOperation        *operation,
     {
       GeglBuffer *output;
 
-      if (gegl_cl_is_accelerated ())
-        gegl_buffer_cl_cache_invalidate (input, &extent);
-
       output = gegl_buffer_create_sub_buffer (input, &extent);
 
       if (gegl_object_get_has_forked (input))



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