[gimp] app: add GimpTileHandlerProjection and use it to validate the projection
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add GimpTileHandlerProjection and use it to validate the projection
- Date: Thu, 5 Jul 2012 19:44:12 +0000 (UTC)
commit 6b6d39fc6457de41f4d7e58cd6002ae9543ac3f3
Author: Michael Natterer <mitch gimp org>
Date: Thu Jul 5 21:42:26 2012 +0200
app: add GimpTileHandlerProjection and use it to validate the projection
as the projection buffer is being read from. Projection performance is
now back at its old speed.
app/core/gimpprojection.c | 144 ++++-----------
app/core/gimpprojection.h | 12 +-
app/display/gimpdisplayshell-render.c | 61 +++----
app/display/gimpdisplayshell.c | 5 +-
app/file/file-open.c | 4 +
app/gegl/Makefile.am | 4 +-
app/gegl/gimptilehandlerprojection.c | 325 +++++++++++++++++++++++++++++++++
app/gegl/gimptilehandlerprojection.h | 70 +++++++
8 files changed, 465 insertions(+), 160 deletions(-)
---
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index dfa89b7..b8cee63 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -17,11 +17,13 @@
#include "config.h"
+#include <cairo.h>
#include <gegl.h>
#include "core-types.h"
#include "gegl/gimp-gegl-utils.h"
+#include "gegl/gimptilehandlerprojection.h"
#include "gimp.h"
#include "gimp-utils.h"
@@ -66,6 +68,7 @@ static gdouble gimp_projection_get_opacity_at (GimpPickable *picka
gint x,
gint y);
+static void gimp_projection_free_buffer (GimpProjection *proj);
static void gimp_projection_add_update_area (GimpProjection *proj,
gint x,
gint y,
@@ -138,11 +141,6 @@ gimp_projection_class_init (GimpProjectionClass *klass)
static void
gimp_projection_init (GimpProjection *proj)
{
- proj->projectable = NULL;
- proj->buffer = NULL;
- proj->update_areas = NULL;
- proj->idle_render.idle_id = 0;
- proj->idle_render.update_areas = NULL;
}
static void
@@ -174,24 +172,7 @@ gimp_projection_finalize (GObject *object)
gimp_area_list_free (proj->idle_render.update_areas);
proj->idle_render.update_areas = NULL;
- if (proj->buffer)
- {
- g_object_unref (proj->buffer);
- proj->buffer = NULL;
- }
-
- if (proj->graph)
- {
- g_object_unref (proj->graph);
- proj->graph = NULL;
- proj->sink_node = NULL;
- }
-
- if (proj->processor)
- {
- g_object_unref (proj->processor);
- proj->processor = NULL;
- }
+ gimp_projection_free_buffer (proj);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -286,22 +267,22 @@ gimp_projection_get_buffer (GimpPickable *pickable)
if (! proj->buffer)
{
+ GeglNode *graph;
const Babl *format;
gint width;
gint height;
+ graph = gimp_projectable_get_graph (proj->projectable);
format = gimp_projection_get_format (GIMP_PICKABLE (proj));
gimp_projectable_get_size (proj->projectable, &width, &height);
proj->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
format);
- if (proj->sink_node)
- {
- gegl_node_set (proj->sink_node,
- "buffer", proj->buffer,
- NULL);
- }
+ proj->validate_handler = gimp_tile_handler_projection_new (graph);
+ gegl_buffer_add_handler (proj->buffer, proj->validate_handler);
+ gimp_tile_handler_projection_invalidate (proj->validate_handler,
+ 0, 0, width, height);
}
return proj->buffer;
@@ -360,44 +341,6 @@ gimp_projection_new (GimpProjectable *projectable)
return proj;
}
-#ifdef USE_BUFFER
-GeglNode *
-gimp_projection_get_sink_node (GimpProjection *proj)
-{
- GeglNode *graph;
- GeglBuffer *buffer;
-
- g_return_val_if_fail (GIMP_IS_PROJECTION (proj), NULL);
-
- if (proj->sink_node)
- return proj->sink_node;
-
- proj->graph = gegl_node_new ();
-
-#if 0
- g_object_set (proj->graph,
- "dont-cache", TRUE,
- NULL);
-#endif
-
- graph = gimp_projectable_get_graph (proj->projectable);
- gegl_node_add_child (proj->graph, graph);
-
- buffer = gimp_projection_get_buffer (GIMP_PICKABLE (proj));
-
- proj->sink_node =
- gegl_node_new_child (proj->graph,
- "operation", "gegl:write-buffer",
- "buffer", buffer,
- NULL);
-
- gegl_node_connect_to (graph, "output",
- proj->sink_node, "input");
-
- return proj->sink_node;
-}
-#endif
-
void
gimp_projection_flush (GimpProjection *proj)
{
@@ -423,10 +366,6 @@ gimp_projection_finish_draw (GimpProjection *proj)
if (proj->idle_render.idle_id)
{
-#if 0
- g_printerr ("%s: flushing idle render queue\n", G_STRFUNC);
-#endif
-
g_source_remove (proj->idle_render.idle_id);
proj->idle_render.idle_id = 0;
@@ -438,6 +377,25 @@ gimp_projection_finish_draw (GimpProjection *proj)
/* private functions */
static void
+gimp_projection_free_buffer (GimpProjection *proj)
+{
+ if (proj->buffer)
+ {
+ if (proj->validate_handler)
+ gegl_buffer_remove_handler (proj->buffer, proj->validate_handler);
+
+ g_object_unref (proj->buffer);
+ proj->buffer = NULL;
+ }
+
+ if (proj->validate_handler)
+ {
+ g_object_unref (proj->validate_handler);
+ proj->validate_handler = NULL;
+ }
+}
+
+static void
gimp_projection_add_update_area (GimpProjection *proj,
gint x,
gint y,
@@ -695,36 +653,6 @@ gimp_projection_paint_area (GimpProjection *proj,
y2 - y1);
}
-#ifdef USE_BUFFER
-static void
-gimp_projection_construct (GimpProjection *proj,
- gint x,
- gint y,
- gint w,
- gint h)
-{
- GeglRectangle rect = { x, y, w, h };
-
- g_return_if_fail (GIMP_IS_PROJECTION (proj));
-
- /* GEGL should really do this for us... */
- gegl_buffer_clear (gimp_projection_get_buffer (GIMP_PICKABLE (proj)), &rect);
-
- if (! proj->processor)
- {
- GeglNode *sink = gimp_projection_get_sink_node (proj);
-
- proj->processor = gegl_node_new_processor (sink, &rect);
- }
- else
- {
- gegl_processor_set_rectangle (proj->processor, &rect);
- }
-
- while (gegl_processor_work (proj->processor, NULL));
-}
-#endif
-
static void
gimp_projection_invalidate (GimpProjection *proj,
guint x,
@@ -732,11 +660,9 @@ gimp_projection_invalidate (GimpProjection *proj,
guint w,
guint h)
{
- /* FIXME: this should happen as we actually *read* from the buffer
- */
-#ifdef USE_BUFFER
- gimp_projection_construct (proj, x, y, w, h);
-#endif
+ if (proj->validate_handler)
+ gimp_tile_handler_projection_invalidate (proj->validate_handler,
+ x, y, w, h);
}
@@ -780,11 +706,7 @@ gimp_projection_projectable_changed (GimpProjectable *projectable,
gimp_area_list_free (proj->update_areas);
proj->update_areas = NULL;
- if (proj->buffer)
- {
- g_object_unref (proj->buffer);
- proj->buffer = NULL;
- }
+ gimp_projection_free_buffer (proj);
gimp_projectable_get_offset (proj->projectable, &off_x, &off_y);
gimp_projectable_get_size (projectable, &width, &height);
diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h
index 657fd40..95040d7 100644
--- a/app/core/gimpprojection.h
+++ b/app/core/gimpprojection.h
@@ -19,9 +19,6 @@
#define __GIMP_PROJECTION_H__
-#define USE_BUFFER 1
-
-
#include "gimpobject.h"
@@ -58,10 +55,7 @@ struct _GimpProjection
GimpProjectable *projectable;
GeglBuffer *buffer;
-
- GeglNode *graph;
- GeglNode *sink_node;
- GeglProcessor *processor;
+ gpointer validate_handler;
GSList *update_areas;
GimpProjectionIdleRender idle_render;
@@ -86,10 +80,6 @@ GType gimp_projection_get_type (void) G_GNUC_CONST;
GimpProjection * gimp_projection_new (GimpProjectable *projectable);
-#if USE_BUFFER
-GeglNode * gimp_projection_get_sink_node (GimpProjection *proj);
-#endif
-
void gimp_projection_flush (GimpProjection *proj);
void gimp_projection_flush_now (GimpProjection *proj);
void gimp_projection_finish_draw (GimpProjection *proj);
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index f68327f..252e4d4 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -51,42 +51,37 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gint w,
gint h)
{
-#ifdef USE_BUFFER
+ GimpImage *image;
GimpProjection *projection;
GeglBuffer *buffer;
-#endif
- GimpImage *image;
+ gint viewport_offset_x;
+ gint viewport_offset_y;
+ gint viewport_width;
+ gint viewport_height;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (cr != NULL);
g_return_if_fail (w > 0 && h > 0);
- image = gimp_display_get_image (shell->display);
-
-#ifdef USE_BUFFER
+ image = gimp_display_get_image (shell->display);
projection = gimp_image_get_projection (image);
- buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (projection));
+ buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (projection));
+
+ gimp_display_shell_scroll_get_scaled_viewport (shell,
+ &viewport_offset_x,
+ &viewport_offset_y,
+ &viewport_width,
+ &viewport_height);
gegl_buffer_get (buffer,
- GEGL_RECTANGLE (x + shell->offset_x,
- y + shell->offset_y,
+ GEGL_RECTANGLE (x + viewport_offset_x,
+ y + viewport_offset_y,
w, h),
shell->scale_x,
babl_format ("cairo-ARGB32"),
cairo_image_surface_get_data (shell->render_surface),
cairo_image_surface_get_stride (shell->render_surface),
GEGL_ABYSS_NONE);
-#else
- gegl_node_blit (gimp_projectable_get_graph (GIMP_PROJECTABLE (image)),
- shell->scale_x,
- GEGL_RECTANGLE (src_x * shell->scale_x,
- src_y * shell->scale_y,
- w, h),
- babl_format ("cairo-ARGB32"),
- cairo_image_surface_get_data (shell->render_surface),
- cairo_image_surface_get_stride (shell->render_surface),
- 0);
-#endif
/* apply filters to the rendered projection */
if (shell->filter_stack)
@@ -136,24 +131,22 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#endif
/* put it to the screen */
- {
- cairo_save (cr);
+ cairo_save (cr);
- cairo_rectangle (cr, x, y, w, h);
- cairo_clip (cr);
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_clip (cr);
- cairo_set_source_surface (cr, shell->render_surface, x, y);
- cairo_paint (cr);
+ cairo_set_source_surface (cr, shell->render_surface, x, y);
+ cairo_paint (cr);
#if 0
- if (shell->mask)
- {
- gimp_cairo_set_source_rgba (cr, &shell->mask_color);
- cairo_mask_surface (cr, shell->mask_surface,
- x + disp_xoffset, y + disp_yoffset);
- }
+ if (shell->mask)
+ {
+ gimp_cairo_set_source_rgba (cr, &shell->mask_color);
+ cairo_mask_surface (cr, shell->mask_surface,
+ x + disp_xoffset, y + disp_yoffset);
+ }
#endif
- cairo_restore (cr);
- }
+ cairo_restore (cr);
}
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index aca40f1..4479dd3 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -1388,9 +1388,8 @@ gimp_display_shell_fill (GimpDisplayShell *shell,
/* we double buffer image drawing manually */
gtk_widget_set_double_buffered (shell->canvas, FALSE);
- shell->fill_idle_id = g_idle_add_full (G_PRIORITY_LOW,
- (GSourceFunc) gimp_display_shell_fill_idle,
- shell, NULL);
+ shell->fill_idle_id = g_idle_add ((GSourceFunc) gimp_display_shell_fill_idle,
+ shell);
}
/* We used to calculate the scale factor in the SCALEFACTOR_X() and
diff --git a/app/file/file-open.c b/app/file/file-open.c
index e4f8d59..478776f 100644
--- a/app/file/file-open.c
+++ b/app/file/file-open.c
@@ -658,6 +658,9 @@ file_open_sanitize_image (GimpImage *image,
*/
gimp_image_clean_all (image);
+#if 0
+ /* XXX this is not needed any longer, remove it when sure */
+
/* make sure the entire projection is properly constructed, because
* load plug-ins are not required to call gimp_drawable_update() or
* anything.
@@ -670,6 +673,7 @@ file_open_sanitize_image (GimpImage *image,
/* same for drawable previews */
gimp_image_invalidate_previews (image);
+#endif
}
/* Converts items from one image to another */
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index e1fa3ca..4a90b1e 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -35,7 +35,9 @@ libappgegl_a_sources = \
gimp-gegl-utils.c \
gimp-gegl-utils.h \
gimpapplicator.c \
- gimpapplicator.h
+ gimpapplicator.h \
+ gimptilehandlerprojection.c \
+ gimptilehandlerprojection.h
libappgegl_a_built_sources = gimp-gegl-enums.c
diff --git a/app/gegl/gimptilehandlerprojection.c b/app/gegl/gimptilehandlerprojection.c
new file mode 100644
index 0000000..c2a4808
--- /dev/null
+++ b/app/gegl/gimptilehandlerprojection.c
@@ -0,0 +1,325 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+
+#include "gimp-gegl-types.h"
+
+#include "gimptilehandlerprojection.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_FORMAT,
+ PROP_TILE_WIDTH,
+ PROP_TILE_HEIGHT
+};
+
+
+static void gimp_tile_handler_projection_finalize (GObject *object);
+static void gimp_tile_handler_projection_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_tile_handler_projection_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static gpointer gimp_tile_handler_projection_command (GeglTileSource *source,
+ GeglTileCommand command,
+ gint x,
+ gint y,
+ gint z,
+ gpointer data);
+
+
+G_DEFINE_TYPE (GimpTileHandlerProjection, gimp_tile_handler_projection,
+ GEGL_TYPE_TILE_HANDLER)
+
+#define parent_class gimp_tile_handler_projection_parent_class
+
+
+static void
+gimp_tile_handler_projection_class_init (GimpTileHandlerProjectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gimp_tile_handler_projection_finalize;
+ object_class->set_property = gimp_tile_handler_projection_set_property;
+ object_class->get_property = gimp_tile_handler_projection_get_property;
+
+ g_object_class_install_property (object_class, PROP_FORMAT,
+ g_param_spec_pointer ("format", NULL, NULL,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_TILE_WIDTH,
+ g_param_spec_int ("tile-width", NULL, NULL,
+ 1, G_MAXINT, 1,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (object_class, PROP_TILE_HEIGHT,
+ g_param_spec_int ("tile-height", NULL, NULL,
+ 1, G_MAXINT, 1,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+gimp_tile_handler_projection_init (GimpTileHandlerProjection *projection)
+{
+ GeglTileSource *source = GEGL_TILE_SOURCE (projection);
+
+ source->command = gimp_tile_handler_projection_command;
+
+ projection->dirty_region = cairo_region_create ();
+}
+
+static void
+gimp_tile_handler_projection_finalize (GObject *object)
+{
+ GimpTileHandlerProjection *projection = GIMP_TILE_HANDLER_PROJECTION (object);
+
+ if (projection->graph)
+ {
+ g_object_unref (projection->graph);
+ projection->graph = NULL;
+ }
+
+ cairo_region_destroy (projection->dirty_region);
+ projection->dirty_region = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_tile_handler_projection_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpTileHandlerProjection *projection = GIMP_TILE_HANDLER_PROJECTION (object);
+
+ switch (property_id)
+ {
+ case PROP_FORMAT:
+ projection->format = g_value_get_pointer (value);
+ break;
+ case PROP_TILE_WIDTH:
+ projection->tile_width = g_value_get_int (value);
+ break;
+ case PROP_TILE_HEIGHT:
+ projection->tile_height = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_tile_handler_projection_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpTileHandlerProjection *projection = GIMP_TILE_HANDLER_PROJECTION (object);
+
+ switch (property_id)
+ {
+ case PROP_FORMAT:
+ g_value_set_pointer (value, (gpointer) projection->format);
+ break;
+ case PROP_TILE_WIDTH:
+ g_value_set_int (value, projection->tile_width);
+ break;
+ case PROP_TILE_HEIGHT:
+ g_value_set_int (value, projection->tile_height);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GeglTile *
+gimp_tile_handler_projection_validate (GeglTileSource *source,
+ GeglTile *tile,
+ gint x,
+ gint y)
+{
+ GimpTileHandlerProjection *projection;
+ cairo_region_t *tile_region;
+ cairo_rectangle_int_t tile_rect;
+
+ projection = GIMP_TILE_HANDLER_PROJECTION (source);
+
+ if (cairo_region_is_empty (projection->dirty_region))
+ return tile;
+
+ tile_region = cairo_region_copy (projection->dirty_region);
+
+ tile_rect.x = x * projection->tile_width;
+ tile_rect.y = y * projection->tile_height;
+ tile_rect.width = projection->tile_width;
+ tile_rect.height = projection->tile_height;
+
+ cairo_region_intersect_rectangle (tile_region, &tile_rect);
+
+ if (! cairo_region_is_empty (tile_region))
+ {
+ gint tile_bpp;
+ gint tile_stride;
+ gint n_rects;
+ gint i;
+
+ if (! tile)
+ tile = gegl_tile_handler_create_tile (GEGL_TILE_HANDLER (source),
+ x, y, 0);
+
+ cairo_region_subtract_rectangle (projection->dirty_region, &tile_rect);
+
+ tile_bpp = babl_format_get_bytes_per_pixel (projection->format);
+ tile_stride = tile_bpp * projection->tile_width;
+
+ gegl_tile_lock (tile);
+
+ n_rects = cairo_region_num_rectangles (tile_region);
+
+#if 0
+ g_printerr ("%d ", n_rects);
+#endif
+
+ for (i = 0; i < n_rects; i++)
+ {
+ cairo_rectangle_int_t blit_rect;
+
+ cairo_region_get_rectangle (tile_region, i, &blit_rect);
+
+#if 0
+ g_printerr ("constructing projection at %d %d %d %d\n",
+ blit_rect.x,
+ blit_rect.y,
+ blit_rect.width,
+ blit_rect.height);
+#endif
+
+ gegl_node_blit (projection->graph, 1.0,
+ GEGL_RECTANGLE (blit_rect.x,
+ blit_rect.y,
+ blit_rect.width,
+ blit_rect.height),
+ projection->format,
+ gegl_tile_get_data (tile) +
+ (blit_rect.y % projection->tile_height) * tile_stride +
+ (blit_rect.x % projection->tile_width) * tile_bpp,
+ tile_stride,
+ GEGL_ABYSS_NONE);
+ }
+
+ gegl_tile_unlock (tile);
+ }
+
+ cairo_region_destroy (tile_region);
+
+ return tile;
+}
+
+static gpointer
+gimp_tile_handler_projection_command (GeglTileSource *source,
+ GeglTileCommand command,
+ gint x,
+ gint y,
+ gint z,
+ gpointer data)
+{
+ gpointer retval;
+
+ retval = gegl_tile_handler_source_command (source, command, x, y, z, data);
+
+ if (command == GEGL_TILE_GET && z == 0)
+ retval = gimp_tile_handler_projection_validate (source, retval, x, y);
+
+ return retval;
+}
+
+GeglTileHandler *
+gimp_tile_handler_projection_new (GeglNode *graph)
+{
+ GimpTileHandlerProjection *projection;
+
+ g_return_val_if_fail (GEGL_IS_NODE (graph), NULL);
+
+ projection = g_object_new (GIMP_TYPE_TILE_HANDLER_PROJECTION, NULL);
+
+ projection->graph = g_object_ref (graph);
+
+ return GEGL_TILE_HANDLER (projection);
+}
+
+static void
+gimp_tile_handler_projection_void_pyramid (GeglTileSource *source,
+ gint x,
+ gint y,
+ gint z)
+{
+ gegl_tile_source_void (source, x, y, z);
+
+ if (x / 2 != x || y / 2 != y)
+ gimp_tile_handler_projection_void_pyramid (source, x / 2, y / 2, z + 1);
+}
+
+void
+gimp_tile_handler_projection_invalidate (GimpTileHandlerProjection *projection,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ cairo_rectangle_int_t rect = { x, y, width, height };
+ gint tile_x1;
+ gint tile_y1;
+ gint tile_x2;
+ gint tile_y2;
+ gint tile_x;
+ gint tile_y;
+
+ g_return_if_fail (GIMP_IS_TILE_HANDLER_PROJECTION (projection));
+
+ cairo_region_union_rectangle (projection->dirty_region, &rect);
+
+ tile_x1 = x / projection->tile_width;
+ tile_y1 = y / projection->tile_height;
+ tile_x2 = (x + width) / projection->tile_width;
+ tile_y2 = (y + height) / projection->tile_height;
+
+ for (tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
+ {
+ for (tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
+ {
+ gimp_tile_handler_projection_void_pyramid (GEGL_TILE_SOURCE (projection),
+ tile_x / 2, tile_y / 2, 1);
+ }
+ }
+}
diff --git a/app/gegl/gimptilehandlerprojection.h b/app/gegl/gimptilehandlerprojection.h
new file mode 100644
index 0000000..eec9980
--- /dev/null
+++ b/app/gegl/gimptilehandlerprojection.h
@@ -0,0 +1,70 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_TILE_HANDLER_PROJECTION_H__
+#define __GIMP_TILE_HANDLER_PROJECTION_H__
+
+#include <gegl-buffer-backend.h>
+
+/***
+ * GimpTileHandlerProjection is a GeglTileHandler that renders the
+ * projection.
+ */
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_TILE_HANDLER_PROJECTION (gimp_tile_handler_projection_get_type ())
+#define GIMP_TILE_HANDLER_PROJECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TILE_HANDLER_PROJECTION, GimpTileHandlerProjection))
+#define GIMP_TILE_HANDLER_PROJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TILE_HANDLER_PROJECTION, GimpTileHandlerProjectionClass))
+#define GIMP_IS_TILE_HANDLER_PROJECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TILE_HANDLER_PROJECTION))
+#define GIMP_IS_TILE_HANDLER_PROJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TILE_HANDLER_PROJECTION))
+#define GIMP_TILE_HANDLER_PROJECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TILE_HANDLER_PROJECTION, GimpTileHandlerProjectionClass))
+
+
+typedef struct _GimpTileHandlerProjection GimpTileHandlerProjection;
+typedef struct _GimpTileHandlerProjectionClass GimpTileHandlerProjectionClass;
+
+struct _GimpTileHandlerProjection
+{
+ GeglTileHandler parent_instance;
+
+ GeglNode *graph;
+ cairo_region_t *dirty_region;
+ const Babl *format;
+ gint tile_width;
+ gint tile_height;
+};
+
+struct _GimpTileHandlerProjectionClass
+{
+ GeglTileHandlerClass parent_class;
+};
+
+
+GType gimp_tile_handler_projection_get_type (void) G_GNUC_CONST;
+GeglTileHandler * gimp_tile_handler_projection_new (GeglNode *graph);
+
+void gimp_tile_handler_projection_invalidate (GimpTileHandlerProjection *projection,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
+
+G_END_DECLS
+
+#endif /* __GIMP_TILE_HANDLER_PROJECTION_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]