[gegl] operation: use GeglTileBackendBuffer in gegl_operation_context_dup_input_maybe_copy()
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operation: use GeglTileBackendBuffer in gegl_operation_context_dup_input_maybe_copy()
- Date: Thu, 3 May 2018 20:23:49 +0000 (UTC)
commit 417221a05e59fc857a2dee07f6bafe49af5ecd6d
Author: Ell <ell_se yahoo com>
Date: Thu May 3 16:12:44 2018 -0400
operation: use GeglTileBackendBuffer in gegl_operation_context_dup_input_maybe_copy()
In gegl_operation_context_dup_input_maybe_copy(), use a
GeglTileBackendBuffer, backed by the input buffer, as the backend
for the local-copy buffer, instead of copying the required portion
of the input buffer into the local-copy buffer. This allows input-
buffer tiles to be COWed on-demand, instead of upfront, into the
local-copy, which can significantly improve performance if the op's
get_required_for_output() returns a larger region than actually
necessary (in particular, if it always returns the entire input
extents). This also allows using the local-copy optimization when
processing a level > 0.
Leave the original version #if 0-ed, since it may be useful for
testing.
gegl/operation/gegl-operation-context.c | 169 ++++++++++++++++++------------
1 files changed, 101 insertions(+), 68 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-context.c b/gegl/operation/gegl-operation-context.c
index 98c43e0..c4787b6 100644
--- a/gegl/operation/gegl-operation-context.c
+++ b/gegl/operation/gegl-operation-context.c
@@ -31,6 +31,7 @@
#include "gegl-operation-context-private.h"
#include "gegl-node-private.h"
#include "gegl-buffer-private.h"
+#include "gegl-tile-backend-buffer.h"
#include "gegl-config.h"
#include "operation/gegl-operation.h"
@@ -405,27 +406,15 @@ gegl_operation_context_dup_input_maybe_copy (GeglOperationContext *context,
const gchar *padname,
const GeglRectangle *roi)
{
- GeglBuffer *input;
- GeglBuffer *output;
- GeglBuffer *result;
- GeglRectangle required;
- GeglRectangle temp;
- gint shift_x;
- gint shift_y;
- gint tile_width;
- gint tile_height;
+ GeglBuffer *input;
+ GeglBuffer *output;
+ GeglBuffer *result;
input = GEGL_BUFFER (gegl_operation_context_get_object (context, padname));
if (! input)
return NULL;
- /* return input directly when processing a level greater than 0, since
- * gegl_buffer_copy() only copies level-0 tiles
- */
- if (context->level > 0)
- return g_object_ref (input);
-
output = GEGL_BUFFER (gegl_operation_context_get_object (context, "output"));
/* return input directly when processing in-place, otherwise, the copied
@@ -434,63 +423,107 @@ gegl_operation_context_dup_input_maybe_copy (GeglOperationContext *context,
if (input == output)
return g_object_ref (input);
- /* get required region to copy */
- required = gegl_operation_get_required_for_output (context->operation,
- padname, roi);
-
- /* return input directly if the required rectangle is infinite, so that we
- * don't attempt to copy an infinite region
- */
- if (gegl_rectangle_is_infinite_plane (&required))
- return g_object_ref (input);
+#if 1
+ {
+ GeglTileBackend *backend;
+
+ backend = gegl_tile_backend_buffer_new (input);
+ gegl_tile_backend_set_flush_on_destroy (backend, FALSE);
+
+ /* create new buffer with similar characteristics to the input buffer */
+ result = g_object_new (GEGL_TYPE_BUFFER,
+ "format", input->soft_format,
+ "x", input->extent.x,
+ "y", input->extent.y,
+ "width", input->extent.width,
+ "height", input->extent.height,
+ "abyss-x", input->abyss.x,
+ "abyss-y", input->abyss.y,
+ "abyss-width", input->abyss.width,
+ "abyss-height", input->abyss.height,
+ "shift-x", input->shift_x,
+ "shift-y", input->shift_y,
+ "tile-width", input->tile_width,
+ "tile-height", input->tile_height,
+ "backend", backend,
+ NULL);
+
+ g_object_unref (backend);
+ }
+#else
+ {
+ GeglRectangle required;
+ GeglRectangle temp;
+ gint shift_x;
+ gint shift_y;
+ gint tile_width;
+ gint tile_height;
+
+ /* return input directly when processing a level greater than 0, since
+ * gegl_buffer_copy() only copies level-0 tiles
+ */
+ if (context->level > 0)
+ return g_object_ref (input);
- /* align required region to the tile grid */
- shift_x = input->shift_x;
- shift_y = input->shift_y;
- tile_width = input->tile_width;
- tile_height = input->tile_height;
-
- temp.x = (gint) floor ((gdouble) (required.x + shift_x) / tile_width) * tile_width;
- temp.y = (gint) floor ((gdouble) (required.y + shift_y) / tile_height) *
tile_height;
- temp.width = (gint) ceil ((gdouble) (required.x + required.width + shift_x) / tile_width) * tile_width
- temp.x;
- temp.height = (gint) ceil ((gdouble) (required.y + required.height + shift_y) / tile_height) *
tile_height - temp.y;
-
- temp.x -= shift_x;
- temp.y -= shift_y;
-
- required = temp;
-
- /* intersect required region with input abyss */
- gegl_rectangle_intersect (&required, &required, &input->abyss);
-
- /* create new buffer with similar characteristics to the input buffer */
- result = g_object_new (GEGL_TYPE_BUFFER,
- "format", input->soft_format,
- "x", input->extent.x,
- "y", input->extent.y,
- "width", input->extent.width,
- "height", input->extent.height,
- "abyss-x", input->abyss.x,
- "abyss-y", input->abyss.y,
- "abyss-width", input->abyss.width,
- "abyss-height", input->abyss.height,
- "shift-x", shift_x,
- "shift-y", shift_y,
- "tile-width", tile_width,
- "tile-height", tile_height,
- NULL);
-
- /* if the tile size doesn't match, bail */
- if (result->tile_width != tile_width || result->tile_height != tile_height)
- {
- g_object_unref (result);
+ /* get required region to copy */
+ required = gegl_operation_get_required_for_output (context->operation,
+ padname, roi);
+ /* return input directly if the required rectangle is infinite, so that we
+ * don't attempt to copy an infinite region
+ */
+ if (gegl_rectangle_is_infinite_plane (&required))
return g_object_ref (input);
- }
- /* copy required region from input to result -- tiles will generally be COWed */
- gegl_buffer_copy (input, &required, GEGL_ABYSS_NONE,
- result, &required);
+ /* align required region to the tile grid */
+ shift_x = input->shift_x;
+ shift_y = input->shift_y;
+ tile_width = input->tile_width;
+ tile_height = input->tile_height;
+
+ temp.x = (gint) floor ((gdouble) (required.x + shift_x) / tile_width) *
tile_width;
+ temp.y = (gint) floor ((gdouble) (required.y + shift_y) / tile_height) *
tile_height;
+ temp.width = (gint) ceil ((gdouble) (required.x + required.width + shift_x) / tile_width) *
tile_width - temp.x;
+ temp.height = (gint) ceil ((gdouble) (required.y + required.height + shift_y) / tile_height) *
tile_height - temp.y;
+
+ temp.x -= shift_x;
+ temp.y -= shift_y;
+
+ required = temp;
+
+ /* intersect required region with input abyss */
+ gegl_rectangle_intersect (&required, &required, &input->abyss);
+
+ /* create new buffer with similar characteristics to the input buffer */
+ result = g_object_new (GEGL_TYPE_BUFFER,
+ "format", input->soft_format,
+ "x", input->extent.x,
+ "y", input->extent.y,
+ "width", input->extent.width,
+ "height", input->extent.height,
+ "abyss-x", input->abyss.x,
+ "abyss-y", input->abyss.y,
+ "abyss-width", input->abyss.width,
+ "abyss-height", input->abyss.height,
+ "shift-x", shift_x,
+ "shift-y", shift_y,
+ "tile-width", tile_width,
+ "tile-height", tile_height,
+ NULL);
+
+ /* if the tile size doesn't match, bail */
+ if (result->tile_width != tile_width || result->tile_height != tile_height)
+ {
+ g_object_unref (result);
+
+ return g_object_ref (input);
+ }
+
+ /* copy required region from input to result -- tiles will generally be COWed */
+ gegl_buffer_copy (input, &required, GEGL_ABYSS_NONE,
+ result, &required);
+ }
+#endif
return result;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]