gegl r2305 - in branches/branch_zhangjb: . bin bindings/pygegl bindings/pygegl/samples bindings/rgegl bindings/rgegl/samples bindings/rgegl/src docs examples gegl gegl/buffer gegl/graph gegl/operation gegl/property-types operations/common operations/external operations/external/v4lutils operations/generated operations/workshop tools
- From: zhangjb svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2305 - in branches/branch_zhangjb: . bin bindings/pygegl bindings/pygegl/samples bindings/rgegl bindings/rgegl/samples bindings/rgegl/src docs examples gegl gegl/buffer gegl/graph gegl/operation gegl/property-types operations/common operations/external operations/external/v4lutils operations/generated operations/workshop tools
- Date: Sat, 17 May 2008 17:52:01 +0000 (UTC)
Author: zhangjb
Date: Sat May 17 17:51:59 2008
New Revision: 2305
URL: http://svn.gnome.org/viewvc/gegl?rev=2305&view=rev
Log:
Merged this branch from the trunk 2304
Added:
branches/branch_zhangjb/examples/
- copied from r2304, /trunk/examples/
branches/branch_zhangjb/operations/common/color-temperature.c
- copied unchanged from r2304, /trunk/operations/common/color-temperature.c
branches/branch_zhangjb/operations/common/open-buffer.c
- copied unchanged from r2304, /trunk/operations/common/open-buffer.c
branches/branch_zhangjb/operations/common/rectangle.c
- copied unchanged from r2304, /trunk/operations/common/rectangle.c
branches/branch_zhangjb/operations/common/write-buffer.c
- copied unchanged from r2304, /trunk/operations/common/write-buffer.c
branches/branch_zhangjb/operations/external/v4l.c
- copied unchanged from r2304, /trunk/operations/external/v4l.c
branches/branch_zhangjb/operations/external/v4lutils/
- copied from r2304, /trunk/operations/external/v4lutils/
branches/branch_zhangjb/operations/workshop/stroke.c
- copied unchanged from r2304, /trunk/operations/workshop/stroke.c
Removed:
branches/branch_zhangjb/docs/hello-world-video.c
branches/branch_zhangjb/docs/hello-world.c
Modified:
branches/branch_zhangjb/AUTHORS
branches/branch_zhangjb/ChangeLog
branches/branch_zhangjb/Makefile.am
branches/branch_zhangjb/NEWS
branches/branch_zhangjb/bin/gegl-bin-gui-types.h
branches/branch_zhangjb/bin/gegl-view.c
branches/branch_zhangjb/bin/gegl-view.h
branches/branch_zhangjb/bin/gegl.c
branches/branch_zhangjb/bindings/pygegl/ChangeLog
branches/branch_zhangjb/bindings/pygegl/samples/render-test.py
branches/branch_zhangjb/bindings/rgegl/ChangeLog
branches/branch_zhangjb/bindings/rgegl/samples/render-test.rb
branches/branch_zhangjb/bindings/rgegl/src/rgegl-node.c
branches/branch_zhangjb/bindings/rgegl/src/rgegl.h
branches/branch_zhangjb/configure.ac
branches/branch_zhangjb/docs/ChangeLog
branches/branch_zhangjb/docs/Makefile.am
branches/branch_zhangjb/docs/index-static.txt.in
branches/branch_zhangjb/gegl/Makefile.am
branches/branch_zhangjb/gegl/buffer/Makefile.am
branches/branch_zhangjb/gegl/buffer/gegl-buffer-access.c
branches/branch_zhangjb/gegl/buffer/gegl-buffer-index.h
branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.c
branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.h
branches/branch_zhangjb/gegl/buffer/gegl-buffer-private.h
branches/branch_zhangjb/gegl/buffer/gegl-buffer-save.c
branches/branch_zhangjb/gegl/buffer/gegl-buffer-share.c
branches/branch_zhangjb/gegl/buffer/gegl-buffer.c
branches/branch_zhangjb/gegl/buffer/gegl-buffer.h
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.h
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-ram.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-tiledir.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.h
branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-cache.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-log.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-zoom.c
branches/branch_zhangjb/gegl/buffer/gegl-tile-source.h
branches/branch_zhangjb/gegl/buffer/gegl-tile-storage.c
branches/branch_zhangjb/gegl/buffer/gegl-tile.c
branches/branch_zhangjb/gegl/buffer/gegl-tile.h
branches/branch_zhangjb/gegl/gegl-chant.h
branches/branch_zhangjb/gegl/gegl-config.c
branches/branch_zhangjb/gegl/gegl-config.h
branches/branch_zhangjb/gegl/gegl-init.c
branches/branch_zhangjb/gegl/gegl.h.in
branches/branch_zhangjb/gegl/graph/gegl-node-context.c
branches/branch_zhangjb/gegl/graph/gegl-node.c
branches/branch_zhangjb/gegl/graph/gegl-node.h
branches/branch_zhangjb/gegl/operation/gegl-operation-area-filter.h
branches/branch_zhangjb/gegl/operation/gegl-operation-filter.h
branches/branch_zhangjb/gegl/operation/gegl-operation-point-filter.c
branches/branch_zhangjb/gegl/operation/gegl-operation-processors.c
branches/branch_zhangjb/gegl/operation/gegl-operation-sink.h
branches/branch_zhangjb/gegl/operation/gegl-operation-source.h
branches/branch_zhangjb/gegl/operation/gegl-operation.c
branches/branch_zhangjb/gegl/operation/gegl-operation.h
branches/branch_zhangjb/gegl/property-types/Makefile.am
branches/branch_zhangjb/gegl/property-types/gegl-color.c
branches/branch_zhangjb/gegl/property-types/gegl-color.h
branches/branch_zhangjb/gegl/property-types/gegl-vector.c
branches/branch_zhangjb/gegl/property-types/gegl-vector.h
branches/branch_zhangjb/operations/common/brightness-contrast.c
branches/branch_zhangjb/operations/common/invert.c
branches/branch_zhangjb/operations/common/whitebalance.c
branches/branch_zhangjb/operations/external/Makefile.am
branches/branch_zhangjb/operations/generated/other-blend.rb
branches/branch_zhangjb/operations/generated/svg-12-porter-duff.rb
branches/branch_zhangjb/tools/create-reference.rb
Modified: branches/branch_zhangjb/AUTHORS
==============================================================================
--- branches/branch_zhangjb/AUTHORS (original)
+++ branches/branch_zhangjb/AUTHORS Sat May 17 17:51:59 2008
@@ -6,7 +6,7 @@
Richard Kralovic, Kevin Cozens, Victor Bogado, Martin Nordholts, Geert
Jordaens, Michael Schumacher, John Marshall, Ãtienne Bersac, Mark Probst, HÃkon
Hitland, Tor Lillqvist, Hans Breuer, Deji Akingunola and Bradley Broom,
-Hans Petter Jansson.
+Hans Petter Jansson, Jan Heller.
Documentation:
^^^^^^^^^^^^^^
Modified: branches/branch_zhangjb/Makefile.am
==============================================================================
--- branches/branch_zhangjb/Makefile.am (original)
+++ branches/branch_zhangjb/Makefile.am Sat May 17 17:51:59 2008
@@ -1,11 +1,17 @@
AUTOMAKE_OPTIONS = dist-bzip2
-SUBDIRS= gegl operations bin tools tests/frequency
+SUBDIRS=\
+ gegl \
+ operations \
+ bin \
+ tools \
+ tests/frequency \
+ examples
+
if ENABLE_DOCS
SUBDIRS+= docs
endif
-
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gegl.pc
@@ -34,4 +40,4 @@
dist-hook: dist-check-w3m
website: all
- $(MAKE) -C docs website
+ $(MAKE) -C docs website
\ No newline at end of file
Modified: branches/branch_zhangjb/NEWS
==============================================================================
--- branches/branch_zhangjb/NEWS (original)
+++ branches/branch_zhangjb/NEWS Sat May 17 17:51:59 2008
@@ -7,15 +7,27 @@
Changes in GEGL 0.0.17
ââââââââââââââââââââââ
- â Performance of GeglBuffer improved.
- â Handle optimized versions of innerloops for operations.
- â SSE detection and optimization for some point ops.
+ â Configuration both from commandline arguments and at runtime.
+ â GeglBuffer
+ â Transparently sharable across processes.
+ â Fileformat compatible with swap format.
+ â Tunable cache size.
+ â Operations
+ â Handle variant implementations of GeglOperations.
+ â Optimized variants of some point and compositing operations reimplemented
+ using a new data type /g4float/ that allows writing cpu agnostic vectorized
+ code for GCC.
+ â New operations: write-buffer, v4l, color-temperature.
+
+Contributions from:
+ Ãyvind KolÃs, Kevin Cozens, Sven Neumann, Manish Singh, Martin Nordholts,
+ Ãtienne Bersac, Hans Petter Jansson, Jan Heller.
Changes in GEGL 0.0.16
ââââââââââââââââââââââ
â Install headers for development of external operation plug-ins.
â Added rowstride argument to gegl_buffer_set ()
- â Made it possible for sink operations to do cunkwise processing
+ â Made it possible for sink operations to do chunkwise processing
through GeglProcessor.
when processed using a GeglProcessor.
â constification of GeglRectangles and babl formats.
Modified: branches/branch_zhangjb/bin/gegl-bin-gui-types.h
==============================================================================
--- branches/branch_zhangjb/bin/gegl-bin-gui-types.h (original)
+++ branches/branch_zhangjb/bin/gegl-bin-gui-types.h Sat May 17 17:51:59 2008
@@ -25,7 +25,6 @@
typedef struct _Editor Editor;
typedef struct _GeglNodeEditor GeglNodeEditor;
typedef struct _GeglStore GeglStore;
-typedef struct _GeglView GeglView;
#endif /* GEGL_EDITOR_TYPES_H */
Modified: branches/branch_zhangjb/bin/gegl-view.c
==============================================================================
--- branches/branch_zhangjb/bin/gegl-view.c (original)
+++ branches/branch_zhangjb/bin/gegl-view.c Sat May 17 17:51:59 2008
@@ -23,14 +23,8 @@
#include <glib-object.h>
#include <gtk/gtk.h>
-#include "gegl-bin-gui-types.h"
-
#include "gegl.h"
-
#include "gegl-view.h"
-#include "gegl-tree-editor.h"
-#include "editor.h"
-
enum
{
@@ -48,13 +42,13 @@
gint x;
gint y;
gdouble scale;
- gint screen_x; /* coordinates of drag start */
+ gint screen_x; /* coordinates of drag start */
gint screen_y;
- gint orig_x; /* coordinates of drag start */
+ gint orig_x; /* coordinates of drag start */
gint orig_y;
- gint start_buf_x; /* coordinates of drag start */
+ gint start_buf_x; /* coordinates of drag start */
gint start_buf_y;
gint prev_x;
@@ -317,7 +311,9 @@
g_free (name);
g_free (operation);
#endif
+#if 0
tree_editor_set_active (editor.tree_editor, detected);
+#endif
}
}
Modified: branches/branch_zhangjb/bin/gegl-view.h
==============================================================================
--- branches/branch_zhangjb/bin/gegl-view.h (original)
+++ branches/branch_zhangjb/bin/gegl-view.h Sat May 17 17:51:59 2008
@@ -28,6 +28,7 @@
#define GEGL_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_VIEW))
#define GEGL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_VIEW, GeglViewClass))
+typedef struct _GeglView GeglView;
typedef struct _GeglViewClass GeglViewClass;
struct _GeglView
Modified: branches/branch_zhangjb/bin/gegl.c
==============================================================================
--- branches/branch_zhangjb/bin/gegl.c (original)
+++ branches/branch_zhangjb/bin/gegl.c Sat May 17 17:51:59 2008
@@ -100,9 +100,10 @@
}
else
{
+ gchar real_path[PATH_MAX];
gchar *temp1 = g_strdup (o->file);
gchar *temp2 = g_path_get_dirname (temp1);
- path_root = g_strdup (realpath (temp2, NULL));
+ path_root = g_strdup (realpath (temp2, real_path));
g_free (temp1);
g_free (temp2);
}
Modified: branches/branch_zhangjb/bindings/pygegl/samples/render-test.py
==============================================================================
--- branches/branch_zhangjb/bindings/pygegl/samples/render-test.py (original)
+++ branches/branch_zhangjb/bindings/pygegl/samples/render-test.py Sat May 17 17:51:59 2008
@@ -13,7 +13,7 @@
height = 40
gegl = Gegl.Node()
-fractal = gegl.new_child("FractalExplorer",
+fractal = gegl.new_child("fractal-explorer",
width=width,
height=height,
ncolors=3)
@@ -22,9 +22,8 @@
string="GEGL\n\n term",
size=height/4)
over = gegl.new_child("over")
-display = gegl.new_child("display")
-fractal >> contrast >> over >> display
+fractal >> contrast >> over
text >> over["aux"]
buffer = over.render((0,0,width,height), "Y u8")
Modified: branches/branch_zhangjb/bindings/rgegl/samples/render-test.rb
==============================================================================
--- branches/branch_zhangjb/bindings/rgegl/samples/render-test.rb (original)
+++ branches/branch_zhangjb/bindings/rgegl/samples/render-test.rb Sat May 17 17:51:59 2008
@@ -11,13 +11,12 @@
height=40
gegl = Gegl::Node.new
-fractal = gegl.new_child :FractalExplorer,:width=>width,:height=>height, :ncolors=>3
+fractal = gegl.new_child :fractal_explorer, :width=>width, :height=>height, :ncolors=>3
contrast= gegl.new_child :threshold, :value=>0.5
text = gegl.new_child :text, :string=>'GEGL\n\n term', :size=>height/4
over = gegl.new_child :over
-display = gegl.new_child :display
-fractal >> contrast >> over >> display
+fractal >> contrast >> over
text >> over[:aux]
x=0
Modified: branches/branch_zhangjb/bindings/rgegl/src/rgegl-node.c
==============================================================================
--- branches/branch_zhangjb/bindings/rgegl/src/rgegl-node.c (original)
+++ branches/branch_zhangjb/bindings/rgegl/src/rgegl-node.c Sat May 17 17:51:59 2008
@@ -357,6 +357,7 @@
return CSTR2RVAL (xml);
}
+#if 0
gpointer gegl_node_get_cache (GeglNode *node);
void gegl_buffer_save (gpointer buffer,
const gchar *path,
@@ -364,13 +365,14 @@
void gegl_buffer_load (gpointer buffer,
const gchar *path);
+
static VALUE
cnode_save_cache (self,
path)
VALUE self, path;
{
- gpointer cache = gegl_node_get_cache (_SELF (self));
- gegl_buffer_save (cache, RVAL2CSTR(path), NULL);
+ /*gpointer cache = gegl_node_get_cache (_SELF (self));
+ gegl_buffer_save (cache, RVAL2CSTR(path), NULL);*/
return Qnil;
}
@@ -379,11 +381,12 @@
path)
VALUE self, path;
{
- gpointer cache = gegl_node_get_cache (_SELF (self));
- gegl_buffer_load (cache, RVAL2CSTR(path));
+ /*gpointer cache = gegl_node_get_cache (_SELF (self));
+ gegl_buffer_load (cache, RVAL2CSTR(path));*/
/* FIXME: fix what is legal data for cache (or do it in load?)*/
return Qnil;
}
+#endif
gchar *gegl_to_dot (GeglNode *self);
@@ -483,8 +486,8 @@
rb_define_method(geglGeglNode, "set_property", cnode_set_property, 2);
rb_define_method(geglGeglNode, "processor", cnode_new_processor, 1);
rb_define_method(geglGeglNode, "xml", cnode_to_xml, 1);
- rb_define_method(geglGeglNode, "save_cache", cnode_save_cache, 1);
- rb_define_method(geglGeglNode, "load_cache", cnode_load_cache, 1);
+/* rb_define_method(geglGeglNode, "save_cache", cnode_save_cache, 1);
+ rb_define_method(geglGeglNode, "load_cache", cnode_load_cache, 1);*/
rb_define_module_function (mGegl, "init", c_gegl_init, 0);
rb_define_module_function (mGegl, "exit", c_gegl_exit, 0);
Modified: branches/branch_zhangjb/bindings/rgegl/src/rgegl.h
==============================================================================
--- branches/branch_zhangjb/bindings/rgegl/src/rgegl.h (original)
+++ branches/branch_zhangjb/bindings/rgegl/src/rgegl.h Sat May 17 17:51:59 2008
@@ -24,7 +24,7 @@
#include <gegl.h>
#include "rbgtk.h"
#include "rbgobject.h"
-#include "rbgeglversion.h"
+/*#include "rbgeglversion.h"*/
extern void Init_gegl(void);
extern void Init_gegl_buffer(VALUE);
Modified: branches/branch_zhangjb/configure.ac
==============================================================================
--- branches/branch_zhangjb/configure.ac (original)
+++ branches/branch_zhangjb/configure.ac Sat May 17 17:51:59 2008
@@ -845,6 +845,7 @@
docs/index-static.txt
docs/gallery/Makefile
docs/gallery/data/Makefile
+examples/Makefile
gegl.pc
gegl-uninstalled.pc
])
Modified: branches/branch_zhangjb/docs/Makefile.am
==============================================================================
--- branches/branch_zhangjb/docs/Makefile.am (original)
+++ branches/branch_zhangjb/docs/Makefile.am Sat May 17 17:51:59 2008
@@ -34,8 +34,6 @@
gegl.css \
gegl.devhelp \
devhelp.css \
- hello-world.c \
- hello-world-video.c \
index-static.txt.in \
$(HTML_FILES)
@@ -80,9 +78,9 @@
$(top_srcdir)/gegl/operation/gegl-operation.h\
$(top_srcdir)/tools/create-reference.rb
if HAVE_RUBY
- $(top_srcdir)/tools/create-reference.rb \
- $(top_srcdir)/gegl/gegl.h\
- $(top_srcdir)/gegl/buffer/gegl-buffer.h\
+ $(top_srcdir)/tools/create-reference.rb \
+ $(top_srcdir)/gegl/gegl.h \
+ $(top_srcdir)/gegl/buffer/gegl-buffer.h \
$(top_srcdir)/gegl/operation/gegl-operation.h $@
endif
@@ -90,9 +88,9 @@
$(top_srcdir)/AUTHORS \
gegl.css \
$(top_srcdir)/NEWS \
+ $(top_srcdir)/examples/hello-world.c \
$(top_builddir)/bin/gegl \
- Makefile.am \
- $(srcdir)/hello-world.c
+ Makefile.am
if HAVE_ASCIIDOC
@echo "HTML: $@"
cp $< $@
@@ -112,8 +110,8 @@
$(INSTALL) -d $(help_dir)
if HAVE_ENSCRIPT
$(INSTALL) $(srcdir)/brightness-contrast.c.html \
- $(srcdir)/gegl.h.html \
- $(srcdir)/gegl-operation.h.html \
+ $(srcdir)/gegl.h.html \
+ $(srcdir)/gegl-operation.h.html \
$(srcdir)/gegl-plugin.h.html $(help_dir)
endif
if HAVE_RUBY
@@ -132,13 +130,6 @@
endif
rm -f $(help_dir)/gegl.devhelp $(help_dir)/gegl.css
-hello-world: hello-world.c
- $(CC) $< -o $@ `pkg-config --cflags --libs gegl`
-
-hello-world-video: hello-world-video.c
- $(CC) $< -o $@ `pkg-config --cflags --libs gegl`
-
-
# require asciidoc when making dist
#
dist-check-asciidoc:
Modified: branches/branch_zhangjb/docs/index-static.txt.in
==============================================================================
--- branches/branch_zhangjb/docs/index-static.txt.in (original)
+++ branches/branch_zhangjb/docs/index-static.txt.in Sat May 17 17:51:59 2008
@@ -196,7 +196,7 @@
fractal
---------------------------
-sys::[cat hello-world.c]
+sys::[cat ../examples/hello-world.c]
---------------------------
$ gcc hello-world.c `pkg-config --libs --cflags gegl` -o hello-world
@@ -386,6 +386,9 @@
GEGL dirs
^^^^^^^^^
+Directories marked with â use GNU make extensions to include any .c file
+dropped into the directory in the build.
+
gegl-dist-root
â
â
@@ -409,23 +412,32 @@
â âââproperty-types specialized classes/paramspecs for GeglOperation
â properties.
â
+ âââexamples â hello-world and other example uses of the GEGL API.
+ â
+ âââtests various tests used to maintain stability when developing
+ â GEGL.
+ â
âââoperations Runtime loaded plug-ins for image processing operations.
â â
- â âââcore Basic operations tightly coupled with GEGL.
+ â âââcore â Basic operations tightly coupled with GEGL.
â âââaffine Transforming operations (rotate/scale/translate)
- â âââgenerated Operations generated from scripts (currently
+ â âââgenerated â Operations generated from scripts (currently
â âââexternal Operations with external dependencies.
- â âââcommon Other operations (drop .c files in here and they are built.)
- â âââworkshop Works in progress, (you must pass --enable-workshop to configure
- â â for the ops in here to be built.
+ â âââcommon â Other operations.
+ â âââworkshop â Works in progress, (you must pass --enable-workshop
+ â â when configurig to build these by default, you can enter
+ â â the directory manually and type make && sudo make install
+ â â as well.
â â
â âââexternal operations in the workshop with external dependencies.
â âââgenerated generated operations that are in the workshop.
â
â
- âââdocs A website for GEGL
+ âââdocs The GEGL website (this documentation), built for your
+ â â the corresponding sourcetree with correct documentation
+ â â etc.
â â
- â âââgallery A gallery of sample GEGL compositions, using the
+ â âââgallery â A gallery of sample GEGL compositions, using the
â â (not yet stabilized) XML format.
â â
â âââdata Image data used by the sample compositions.
Modified: branches/branch_zhangjb/gegl/Makefile.am
==============================================================================
--- branches/branch_zhangjb/gegl/Makefile.am (original)
+++ branches/branch_zhangjb/gegl/Makefile.am Sat May 17 17:51:59 2008
@@ -25,6 +25,7 @@
gegl-chant.h \
gegl-config.h \
gegl-cpuaccel.h \
+ gegl-debug.h \
gegl-dot.h \
gegl-init.h \
gegl-instrument.h \
Modified: branches/branch_zhangjb/gegl/buffer/Makefile.am
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/Makefile.am (original)
+++ branches/branch_zhangjb/gegl/buffer/Makefile.am Sat May 17 17:51:59 2008
@@ -32,6 +32,7 @@
BUFFER_headers = \
gegl-buffer.h \
gegl-buffer-private.h \
+ gegl-buffer-load.h \
gegl-buffer-save.h \
gegl-buffer-types.h \
gegl-cache.h \
@@ -62,5 +63,6 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/gegl \
+ -I$(top_srcdir)/gegl/buffer \
@DEP_CFLAGS@ @BABL_CFLAGS@
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-access.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-access.c Sat May 17 17:51:59 2008
@@ -41,6 +41,226 @@
#endif
+
+void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
+{
+ g_assert (i);
+ memset (i, 0, sizeof (GeglBufferTileIterator));
+ i->buffer = buffer;
+ i->roi = roi;
+ i->row = 0;
+ i->col = 0;
+ i->tile = NULL;
+ i->write = write;
+}
+
+
+GeglBufferTileIterator *
+gegl_buffer_tile_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
+{
+ GeglBufferTileIterator *i = g_malloc (sizeof (GeglBufferTileIterator));
+ gegl_buffer_tile_iterator_init (i, buffer, roi, write);
+ return i;
+}
+
+void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
+{
+ GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
+ g_assert (i);
+ memset (i, 0, sizeof (GeglBufferScanIterator));
+ gegl_buffer_tile_iterator_init (tile_i, buffer, roi, write);
+ i->max_size = tile_i->buffer->tile_storage->tile_width *
+ tile_i->buffer->tile_storage->tile_height *
+ tile_i->buffer->format->format.bytes_per_pixel;
+}
+
+GeglBufferScanIterator *gegl_buffer_scan_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
+{
+ GeglBufferScanIterator *i = g_malloc (sizeof (GeglBufferScanIterator));
+ gegl_buffer_scan_iterator_init (i, buffer, roi, write);
+ return i;
+}
+
+gboolean
+gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i)
+{
+ GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
+
+ if (tile_i->tile==NULL)
+ {
+ gulp:
+ if (!gegl_buffer_tile_iterator_next (tile_i))
+ return FALSE;
+ i->width = tile_i->subrect.width;
+ i->row = 0;
+ }
+ /* we should now have a valid tile */
+
+ if (tile_i->subrect.width == tile_i->buffer->tile_storage->tile_width &&
+ i->row < tile_i->subrect.height)
+ /* the entire contents of the tile can be expressed as one long scan */
+ {
+ gint px_size = tile_i->buffer->format->format.bytes_per_pixel;
+ guchar *data = tile_i->data;
+ i->width = tile_i->subrect.width * tile_i->subrect.height;
+ i->data = data + px_size * (tile_i->subrect.width * tile_i->subrect.y);
+ i->row = tile_i->subrect.height;
+ return TRUE;
+ }
+ else if (i->row < tile_i->subrect.height)
+ /* iterate thorugh the scanlines in the subrect */
+ {
+ guchar *data = tile_i->sub_data;
+ i->data = data + i->row * tile_i->rowstride;
+ i->row ++;
+ return TRUE;
+ }
+ else
+ { /* we're done with that tile go get another one if possible */
+ goto gulp;
+ }
+
+ return FALSE;
+}
+
+
+gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
+ GeglBuffer *output)
+{
+ if (input->tile_storage->tile_width !=
+ output->tile_storage->tile_width)
+ return FALSE;
+ if (input->tile_storage->tile_height !=
+ output->tile_storage->tile_height)
+ return FALSE;
+ if (input->shift_x !=
+ output->shift_x)
+ return FALSE;
+ if (input->shift_y !=
+ output->shift_y)
+ return FALSE;
+ return TRUE;
+}
+
+gboolean
+gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i)
+{
+ GeglBuffer *buffer = i->buffer;
+ gint tile_width = buffer->tile_storage->tile_width;
+ gint tile_height = buffer->tile_storage->tile_height;
+ gint buffer_shift_x = buffer->shift_x;
+ gint buffer_shift_y = buffer->shift_y;
+ gint buffer_x = buffer->extent.x + buffer_shift_x;
+ gint buffer_y = buffer->extent.y + buffer_shift_y;
+ gint buffer_abyss_x = buffer->abyss.x + buffer_shift_x;
+ gint abyss_x_total = buffer_abyss_x + buffer->abyss.width;
+
+ if (i->roi.width == 0 || i->roi.height == 0)
+ return FALSE;
+
+gulp:
+
+ /* unref previous held tile */
+ if (i->tile)
+ {
+ if (i->write)
+ {
+ gegl_tile_unlock (i->tile);
+ }
+ g_object_unref (i->tile);
+ i->tile = NULL;
+ }
+
+ if (i->col < i->roi.width)
+ { /* return tile on this row */
+ gint tiledx = buffer_x + i->col;
+ gint tiledy = buffer_y + i->row;
+ gint offsetx = gegl_tile_offset (tiledx, tile_width);
+ gint offsety = gegl_tile_offset (tiledy, tile_height);
+ gint pixels;
+
+ if (i->roi.width + offsetx - i->col < tile_width)
+ pixels = (i->roi.width + offsetx - i->col) - offsetx;
+ else
+ pixels = tile_width - offsetx;
+
+ if (!(buffer_x + i->col + tile_width >= buffer_abyss_x &&
+ buffer_x + i->col < abyss_x_total))
+ {
+ g_warning ("entire tile in abyss?");
+
+ i->col += tile_width - offsetx;
+ }
+ else
+ {
+ /* gap between left side of tile, and abyss */
+ i->subrect.x = offsetx;
+ i->subrect.y = offsety;
+ /* gap between right side of tile, and abyss */
+
+
+ i->subrect.width = (i->roi.width - i->col < tile_width) ?
+ (i->roi.width - i->col) - i->subrect.x:
+ tile_width - i->subrect.x;
+
+ i->subrect.height = (i->roi.height - i->row < tile_height) ?
+ (i->roi.height - i->row) - i->subrect.y:
+ tile_height - i->subrect.y;
+
+ i->tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
+ gegl_tile_indice (tiledx, tile_width),
+ gegl_tile_indice (tiledy, tile_height),
+ 0);
+ if (i->write)
+ {
+ gegl_tile_lock (i->tile);
+ }
+ i->data = gegl_tile_get_data (i->tile);
+
+ {
+ gint bpp = i->buffer->format->format.bytes_per_pixel;
+ i->rowstride = bpp * tile_width;
+ i->sub_data = (guchar*)(i->data) + bpp * (i->subrect.y * tile_width + i->subrect.x);
+ }
+
+ /* update with new future position (note this means that the
+ * coordinates read from the iterator do not make full sense
+ * */
+ i->col += tile_width - offsetx;
+
+ return TRUE;
+ }
+ }
+ else /* move down to next row */
+ {
+ gint tiledy = buffer_y + i->row;
+ gint offsety = gegl_tile_offset (tiledy, tile_height);
+
+ i->row += tile_height - offsety;
+ i->col=0;
+
+ if (i->row < i->roi.height)
+ {
+ goto gulp; /* return the first tile in the next row */
+ }
+
+ return FALSE;
+ }
+ return FALSE;
+}
+
+
+
#ifdef BABL
#undef BABL
#endif
@@ -164,8 +384,8 @@
GeglTile *tile = NULL;
if (buffer->hot_tile &&
- buffer->hot_tile->storage_x == indice_x &&
- buffer->hot_tile->storage_y == indice_y)
+ buffer->hot_tile->x == indice_x &&
+ buffer->hot_tile->y == indice_y)
{
tile = buffer->hot_tile;
}
@@ -249,8 +469,8 @@
GeglTile *tile = NULL;
if (buffer->hot_tile &&
- buffer->hot_tile->storage_x == indice_x &&
- buffer->hot_tile->storage_y == indice_y)
+ buffer->hot_tile->x == indice_x &&
+ buffer->hot_tile->y == indice_y)
{
tile = buffer->hot_tile;
}
@@ -310,6 +530,7 @@
}
+
static void inline
gegl_buffer_iterate (GeglBuffer *buffer,
guchar *buf,
@@ -579,6 +800,7 @@
#if ENABLE_MP
g_static_rec_mutex_lock (&mutex);
#endif
+ gegl_buffer_lock (buffer);
if (format == NULL)
format = buffer->format;
@@ -602,6 +824,11 @@
g_object_unref (sub_buf);
}
+ if (gegl_buffer_is_shared(buffer))
+ {
+ gegl_buffer_flush (buffer);
+ }
+ gegl_buffer_unlock (buffer); /* XXX: should this happen before flush? */
#if ENABLE_MP
g_static_rec_mutex_unlock (&mutex);
#endif
@@ -1138,3 +1365,102 @@
buffer->sampler = NULL;
}
}
+
+
+void
+gegl_buffer_copy (GeglBuffer *src,
+ const GeglRectangle *src_rect,
+ GeglBuffer *dst,
+ const GeglRectangle *dst_rect)
+{
+ /* FIXME: make gegl_buffer_copy work with COW shared tiles when possible */
+
+ GeglRectangle src_line;
+ GeglRectangle dst_line;
+ const Babl *format;
+ guchar *temp;
+ guint i;
+ gint pxsize;
+
+ g_return_if_fail (GEGL_IS_BUFFER (src));
+ g_return_if_fail (GEGL_IS_BUFFER (dst));
+
+ if (!src_rect)
+ {
+ src_rect = gegl_buffer_get_extent (src);
+ }
+
+ if (!dst_rect)
+ {
+ dst_rect = src_rect;
+ }
+
+ pxsize = src->tile_storage->px_size;
+ format = src->format;
+
+ src_line = *src_rect;
+ src_line.height = 1;
+
+ dst_line = *dst_rect;
+ dst_line.width = src_line.width;
+ dst_line.height = src_line.height;
+
+ temp = g_malloc (src_line.width * pxsize);
+
+ for (i=0; i<src_rect->height; i++)
+ {
+ gegl_buffer_get (src, 1.0, &src_line, format, temp, GEGL_AUTO_ROWSTRIDE);
+ gegl_buffer_set (dst, &dst_line, format, temp, GEGL_AUTO_ROWSTRIDE);
+ src_line.y++;
+ dst_line.y++;
+ }
+ g_free (temp);
+}
+
+void
+gegl_buffer_clear (GeglBuffer *dst,
+ const GeglRectangle *dst_rect)
+{
+ /* FIXME: make gegl_buffer_copy work with COW shared tiles when possible */
+
+ GeglRectangle dst_line;
+ const Babl *format;
+ guchar *temp;
+ guint i;
+ gint pxsize;
+
+ g_return_if_fail (GEGL_IS_BUFFER (dst));
+
+ if (!dst_rect)
+ {
+ dst_rect = gegl_buffer_get_extent (dst);
+ }
+
+ pxsize = dst->tile_storage->px_size;
+ format = dst->format;
+
+ dst_line = *dst_rect;
+ dst_line.height = 1;
+
+ temp = g_malloc0 (dst_line.width * pxsize);
+
+ for (i=0; i<dst_rect->height; i++)
+ {
+ gegl_buffer_set (dst, &dst_line, format, temp, GEGL_AUTO_ROWSTRIDE);
+ dst_line.y++;
+ }
+ g_free (temp);
+}
+
+GeglBuffer *
+gegl_buffer_dup (GeglBuffer *buffer)
+{
+ GeglBuffer *new;
+
+ g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
+
+ new = gegl_buffer_new (gegl_buffer_get_extent (buffer), buffer->format);
+ gegl_buffer_copy (buffer, gegl_buffer_get_extent (buffer),
+ new, gegl_buffer_get_extent (buffer));
+ return new;
+}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-index.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-index.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-index.h Sat May 17 17:51:59 2008
@@ -9,18 +9,21 @@
/* Increase this number when the structures change.*/
-#define GEGL_FILE_SPEC_REV 23
+#define GEGL_FILE_SPEC_REV 0
#define GEGL_MAGIC {'G','E','G','L'}
#define GEGL_FLAG_TILE 1
-#define GEGL_FLAG_FREE_TILE 2
+#define GEGL_FLAG_FREE_TILE 0xf+2
+
+/* a VOID message, indicating that the specified tile has been rewritten */
+#define GEGL_FLAG_INVALIDATED 2
/* these flags are used for the header, the lower bits of the
* header store the revision
*/
-#define GEGL_FLAG_LOCKED (0xff*(1<<0))
-#define GEGL_FLAG_FLUSHED (0xff*(1<<1))
-#define GEGL_FLAG_IS_HEADER (0xff*(1<<3))
+#define GEGL_FLAG_LOCKED (1<<(8+0))
+#define GEGL_FLAG_FLUSHED (1<<(8+1))
+#define GEGL_FLAG_IS_HEADER (1<<(8+3))
/* The default header we expect to see on a file is that it is
* flushed, and has the revision the file conforms to written
@@ -34,28 +37,29 @@
* This header is the first 256 bytes of the GEGL buffer.
*/
typedef struct {
- gchar magic[4]; /* - a 4 byte identifier */
- guint32 flags; /* the header flags is used to encode state and revision
+ gchar magic[4]; /* - a 4 byte identifier */
+ guint32 flags; /* the header flags is used to encode state and revision
*/
- guint64 next; /* offset to first GeglBufferBlock */
+ guint64 next; /* offset to first GeglBufferBlock */
+
+ guint32 tile_width;
+ guint32 tile_height;
+ guint16 bytes_per_pixel;
+
+ gchar description[64]; /* GEGL stores the string of the babl format
+ * here, as well as after the \0 a debug string
+ * describing the buffer.
+ */
+
+ /* the ROI could come as a separate block */
+ gint32 x; /* indication of bounding box for tiles stored. */
+ gint32 y; /* this isn't really needed as each GeglBuffer as */
+ guint32 width; /* represented on disk doesn't really have any */
+ guint32 height; /* dimension restriction. */
- guint32 tile_width;
- guint32 tile_height;
- guint16 bytes_per_pixel;
-
- gchar description[64]; /* GEGL stores the string of the babl format
- * here, as well as after the \0 a debug string
- * describing the buffer.
- */
-
- /* the ROI should come as a separate block */
- gint32 x; /* indication of bounding box for tiles stored. */
- gint32 y; /* this isn't really needed as each GeglBuffer as */
- guint32 width; /* represented on disk doesn't really have any */
- guint32 height; /* dimension restriction. */
+ guint32 rev; /* if it changes on disk it means the index has changed */
- guint32 entry_count; /* for integrity check. */
- gint32 padding[36]; /* Pad the structure to be 256 bytes long */
+ gint32 padding[36]; /* Pad the structure to be 256 bytes long */
} GeglBufferHeader;
/* the revision of the format is stored in the flags of the header in the
@@ -86,14 +90,19 @@
gint32 y;
gint32 z; /* mipmap subdivision level of tile (0=100%) */
+
+ guint32 rev; /* revision, if a buffer is monitored for header
+ revision changes, the existing loaded index
+ can be compare the revision of tiles and update
+ own state when revision differs. */
} GeglBufferTile;
/* A convenience union to allow quick and simple casting */
typedef union {
- guint32 length;
- GeglBufferBlock block;
- GeglBufferHeader header;
- GeglBufferTile tile;
+ guint32 length;
+ GeglBufferBlock block;
+ GeglBufferHeader header;
+ GeglBufferTile tile;
} GeglBufferItem;
/* functions to initialize data structures */
@@ -101,6 +110,10 @@
gint y,
gint z);
+/* intializing the header causes the format to be written out
+ * as well as a hidden comment after the zero terminated format
+ * with additional human readable information about the header.
+ */
void gegl_buffer_header_init (GeglBufferHeader *header,
gint tile_width,
gint tile_height,
@@ -109,10 +122,10 @@
void gegl_tile_entry_destroy (GeglBufferTile *entry);
-GeglBufferItem *gegl_buffer_read_header (GInputStream *i,
- goffset *offset);
-GList *gegl_buffer_read_index (GInputStream *i,
- goffset *offset);
+GeglBufferItem *gegl_buffer_read_header(GInputStream *i,
+ goffset *offset);
+GList *gegl_buffer_read_index (GInputStream *i,
+ goffset *offset);
#define struct_check_padding(type, size) \
if (sizeof (type) != size) \
@@ -126,7 +139,7 @@
}
#define GEGL_BUFFER_STRUCT_CHECK_PADDING \
{struct_check_padding (GeglBufferBlock, 16);\
- struct_check_padding (GeglBufferHeader, 256);}
+ struct_check_padding (GeglBufferHeader, 256);}
#define GEGL_BUFFER_SANITY {static gboolean done=FALSE;if(!done){GEGL_BUFFER_STRUCT_CHECK_PADDING;done=TRUE;}}
#endif
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.c Sat May 17 17:51:59 2008
@@ -27,7 +27,6 @@
#include "gegl-types.h"
#include "gegl-buffer-types.h"
#include "gegl-buffer.h"
-#include "gegl-buffer-load.h"
#include "gegl-tile-storage.h"
#include "gegl-tile-backend.h"
#include "gegl-tile-handler.h"
@@ -45,7 +44,6 @@
#include <glib/gprintf.h>
-#if 0
typedef struct
{
GeglBufferHeader header;
@@ -95,13 +93,14 @@
g_slice_free (LoadInfo, info);
}
-#endif
-
GeglBufferItem *
gegl_buffer_read_header (GInputStream *i,
goffset *offset)
{
+ goffset placeholder;
GeglBufferItem *ret;
+ if (offset==0)
+ offset = &placeholder;
if(!g_seekable_seek (G_SEEKABLE (i), 0, G_SEEK_SET, NULL, NULL))
g_warning ("failed seeking to %i", 0);
@@ -212,7 +211,6 @@
GList *ret = NULL;
GeglBufferItem *item;
- g_print ("%i\n", (gint)*offset);
for (item = read_block (i, offset); item; item = read_block (i, offset))
{
g_assert (item);
@@ -238,9 +236,11 @@
sanity();
return g_object_new (GEGL_TYPE_BUFFER, "path", path, NULL);
+}
-#if 0 /* old code that feeds tile by tile into the buffer */
-
+GeglBuffer *
+gegl_buffer_load (const gchar *path)
+{
GeglBuffer *ret;
LoadInfo *info = g_slice_new0 (LoadInfo);
@@ -333,5 +333,4 @@
load_info_destroy (info);
return ret;
-#endif
}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-load.h Sat May 17 17:51:59 2008
@@ -23,7 +23,5 @@
#include "gegl-buffer.h"
-void gegl_buffer_load (GeglBuffer *buffer,
- const gchar *path);
#endif
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-private.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-private.h Sat May 17 17:51:59 2008
@@ -63,6 +63,8 @@
gint tile_width;
gint tile_height;
gchar *path;
+
+ gint lock_count;
};
struct _GeglBufferClass
@@ -91,4 +93,54 @@
GeglTileBackend * gegl_buffer_backend (GeglBuffer *buffer);
+gboolean gegl_buffer_is_shared (GeglBuffer *buffer);
+
+gboolean gegl_buffer_try_lock (GeglBuffer *buffer);
+gboolean gegl_buffer_lock (GeglBuffer *buffer);
+gboolean gegl_buffer_unlock (GeglBuffer *buffer);
+
+
+typedef struct GeglBufferTileIterator
+{
+ GeglBuffer *buffer;
+ GeglTile *tile;
+ GeglRectangle roi;
+ gint col;
+ gint row;
+ gboolean write; /* perhaps in a subclass struct? */
+ GeglRectangle subrect; /* has negative x when entire tile is valid */
+ gpointer data;
+ gpointer sub_data;
+ gint rowstride;
+} GeglBufferTileIterator;
+
+typedef struct GeglBufferScanIterator {
+ GeglBufferTileIterator tile_iterator;
+ gint max_size; /* in bytes */
+ gint width;
+ gint row;
+ gpointer data;
+} GeglBufferScanIterator;
+
+gboolean gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i);
+gboolean gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i);
+GeglBufferTileIterator *gegl_buffer_tile_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+
+void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+GeglBufferScanIterator *gegl_buffer_scan_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
+ GeglBuffer *output);
+
+
#endif
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-save.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-save.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-save.c Sat May 17 17:51:59 2008
@@ -50,6 +50,7 @@
gint tile_size;
gint offset;
+ gint entry_count;
GeglBufferBlock *last_added;
GeglBufferBlock *in_holding; /* we need to write one block added behind
* to be able to recompute the forward pointing
@@ -63,7 +64,7 @@
gint y,
gint z)
{
- GeglBufferTile *entry = g_slice_new0 (GeglBufferTile);
+ GeglBufferTile *entry = g_malloc (sizeof(GeglBufferTile));
entry->block.flags = GEGL_FLAG_TILE;
entry->block.length = sizeof (GeglBufferTile);
@@ -76,7 +77,7 @@
void
gegl_tile_entry_destroy (GeglBufferTile *entry)
{
- g_slice_free (GeglBufferTile, entry);
+ g_free (entry);
}
static gsize write_block (SaveInfo *info,
@@ -174,17 +175,18 @@
strcpy (header->magic, "GEGL");
header->flags = GEGL_FLAG_HEADER;
-
header->tile_width = tile_width;
header->tile_height = tile_height;
header->bytes_per_pixel = bpp;
{
gchar buf[64];
- g_snprintf (buf, 64, "%s%c\n%iÃ%i %ibpp\n\n\n\n\n\n\n\n\n\n",
+ g_snprintf (buf, 64, "%s%c\n%iÃ%i %ibpp\n%ix%i\n\n\n\n\n\n\n\n\n",
format->instance.name, 0,
header->tile_width,
header->tile_height,
- header->bytes_per_pixel);
+ header->bytes_per_pixel,
+ (gint)header->width,
+ (gint)header->height);
memcpy ((header->description), buf, 64);
}
}
@@ -211,6 +213,10 @@
info->o = G_OUTPUT_STREAM (g_file_replace (info->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
g_object_get (buffer, "px-size", &bpp, NULL);
+ info->header.x = buffer->extent.x;
+ info->header.y = buffer->extent.y;
+ info->header.width = buffer->extent.width;
+ info->header.height = buffer->extent.height;
gegl_buffer_header_init (&info->header,
buffer->tile_storage->tile_width,
buffer->tile_storage->tile_height,
@@ -219,10 +225,6 @@
);
info->header.next = (prediction += sizeof (GeglBufferHeader));
- info->header.x = buffer->extent.x;
- info->header.y = buffer->extent.y;
- info->header.width = buffer->extent.width;
- info->header.height = buffer->extent.height;
info->tile_size = info->header.tile_width *
info->header.tile_height *
@@ -275,7 +277,7 @@
entry = gegl_tile_entry_new (tx, ty, z);
info->tiles = g_list_prepend (info->tiles, entry);
- info->header.entry_count++;
+ info->entry_count++;
}
bufx += (tile_width - offsetx) * factor;
}
@@ -298,7 +300,7 @@
{
GList *iter;
gint predicted_offset = sizeof (GeglBufferHeader) +
- sizeof (GeglBufferTile) * (info->header.entry_count);
+ sizeof (GeglBufferTile) * (info->entry_count);
for (iter = info->tiles; iter; iter = iter->next)
{
GeglBufferTile *entry = iter->data;
@@ -326,7 +328,9 @@
}
write_block (info, NULL); /* terminate the index */
- /* update header to point to start of new index */
+ /* update header to point to start of new index (already done for
+ * this serial saver, and the header is already written.
+ */
/* save each tile */
{
@@ -351,7 +355,6 @@
g_object_unref (G_OBJECT (tile));
i++;
}
- g_assert (i == info->header.entry_count);
}
save_info_destroy (info);
}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer-share.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer-share.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer-share.c Sat May 17 17:51:59 2008
@@ -28,6 +28,7 @@
#include "gegl-buffer-private.h"
#include "gegl-id-pool.h"
+#if 0
static GeglIDPool *pool = NULL;
guint
@@ -43,44 +44,6 @@
return id;
}
-
-void
-gegl_buffer_make_uri (gchar *buf_128,
- gchar *host,
- gint port,
- gint process,
- gint handle)
-{
- gchar *p=buf_128;
-
- g_sprintf (p, "buffer://%s", host?host:"");
- p+=strlen (p);
- if (port)
- {
- g_sprintf (p, ":%i", port);
- p+=strlen (p);
- }
- g_sprintf (p, "/");
- p+=strlen (p);
- if (process)
- {
- g_sprintf (p, "%i", process);
- p+=strlen (p);
- }
- g_sprintf (p, "/");
- p+=strlen (p);
- if (handle || 1)
- {
- g_sprintf (p, "%i", handle);
- p+=strlen (p);
- }
- else
- {
- g_warning ("no handle provided when building uri:\n%s\n", buf_128);
- }
-}
-
-#if 0
GeglBuffer*
gegl_buffer_open (const gchar *uri)
{
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer.c Sat May 17 17:51:59 2008
@@ -68,7 +68,6 @@
G_DEFINE_TYPE (GeglBuffer, gegl_buffer, GEGL_TYPE_TILE_HANDLER)
-
static GObjectClass * parent_class = NULL;
enum
@@ -92,13 +91,18 @@
PROP_PATH
};
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+guint gegl_buffer_signals[LAST_SIGNAL] = { 0 };
+
static GeglBuffer * gegl_buffer_new_from_format (const void *babl_format,
gint x,
gint y,
gint width,
gint height);
-static GeglBuffer *
-gegl_buffer_new_from_path (const gchar *path);
static inline gint needed_tiles (gint w,
gint stride)
@@ -275,6 +279,28 @@
static gint allocated_buffers = 0;
static gint de_allocated_buffers = 0;
+ /* this should only be possible if this buffer matches all the buffers down to
+ * storage, all of those parent buffers would change size as well, no tiles
+ * would be voided as a result of changing the extent.
+ */
+gboolean
+gegl_buffer_set_extent (GeglBuffer *buffer,
+ const GeglRectangle *extent)
+{
+ (*(GeglRectangle*)gegl_buffer_get_extent (buffer))=*extent;
+
+ if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))
+ {
+ GeglBufferHeader *header = ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header));
+ header->x = buffer->extent.x;
+ header->y = buffer->extent.x;
+ header->width = buffer->extent.width;
+ header->height = buffer->extent.height;
+ }
+
+ return TRUE;
+}
+
void gegl_buffer_stats (void)
{
g_warning ("Buffer statistics: allocated:%i deallocated:%i balance:%i",
@@ -312,12 +338,17 @@
buffer->hot_tile = NULL;
}
- de_allocated_buffers++; /* XXX: is it correct to count that, shouldn't that
- only be counted in finalize? */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
+static void
+gegl_buffer_finalize (GObject *object)
+{
+ de_allocated_buffers++;
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
GeglTileBackend *
gegl_buffer_backend (GeglBuffer *buffer)
{
@@ -356,6 +387,13 @@
void babl_backtrack (void);
+static void storage_changed (GeglTileStorage *storage,
+ const GeglRectangle *rect,
+ gpointer userdata)
+{
+ g_signal_emit_by_name (GEGL_BUFFER (userdata), "changed", rect, NULL);
+}
+
static GObject *
gegl_buffer_constructor (GType type,
guint n_params,
@@ -369,6 +407,11 @@
gint tile_width;
gint tile_height;
+ gint width;
+ gint height;
+ gint x;
+ gint y;
+
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
buffer = GEGL_BUFFER (object);
@@ -376,6 +419,11 @@
source = handler->source;
backend = gegl_buffer_backend (buffer);
+ x=buffer->extent.x;
+ y=buffer->extent.y;
+ width=buffer->extent.width;
+ height=buffer->extent.height;
+
if (source)
{
if (GEGL_IS_TILE_STORAGE (source))
@@ -388,13 +436,31 @@
{
/* if no source is specified if a format is specified, we
* we need to create our own
- * source (this adds a redirectin buffer in between for
+ * source (this adds a redirection buffer in between for
* all "allocated from format", type buffers.
*/
if (buffer->path)
{
GeglBufferHeader *header;
- source = GEGL_TILE_SOURCE (gegl_buffer_new_from_path (buffer->path));
+ GeglTileSource *storage;
+
+ if (buffer->format)
+ {
+ storage = GEGL_TILE_SOURCE (g_object_new (GEGL_TYPE_TILE_STORAGE,
+ "path", buffer->path,
+ "format", buffer->format,
+ NULL));
+ }
+ else
+ {
+ storage = GEGL_TILE_SOURCE (g_object_new (GEGL_TYPE_TILE_STORAGE,
+ "path", buffer->path,
+ "format", babl_format ("RGBA float"),
+ NULL));
+ }
+
+ source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
+
/* after construction,. x and y should be set to reflect
* the top level behavior exhibited by this buffer object.
*/
@@ -403,6 +469,9 @@
NULL);
g_object_unref (source);
+ g_signal_connect (storage, "changed",
+ G_CALLBACK(storage_changed), buffer);
+
g_assert (source);
backend = gegl_buffer_backend (GEGL_BUFFER (source));
g_assert (backend);
@@ -437,6 +506,20 @@
{
g_warning ("not enough data to have a tile source for our buffer");
}
+ {
+ /* we reset the size if it seems to have been set to 0 during a on
+ * disk buffer creation, nasty but it seems to do the job.
+ */
+
+ if (buffer->extent.width == 0 &&
+ buffer->extent.width == 0)
+ {
+ buffer->extent.width = width;
+ buffer->extent.height = height;
+ buffer->extent.x = x;
+ buffer->extent.y = y;
+ }
+ }
}
g_assert (backend);
@@ -556,6 +639,8 @@
if (tile)
{
GeglBuffer *buffer = GEGL_BUFFER (handler);
+
+ /* not sure if this plays well with shifting */
tile->x = x;
tile->y = y;
tile->z = z;
@@ -576,10 +661,10 @@
* coordinates.
*/
{
- tile->tile_storage = buffer->tile_storage;
- tile->storage_x = x;
- tile->storage_y = y;
- tile->storage_z = z;
+ tile->tile_storage = buffer->tile_storage;
+ tile->x = x;
+ tile->y = y;
+ tile->z = z;
}
}
@@ -613,6 +698,7 @@
parent_class = g_type_class_peek_parent (class);
gobject_class->dispose = gegl_buffer_dispose;
+ gobject_class->finalize = gegl_buffer_finalize;
gobject_class->constructor = gegl_buffer_constructor;
gobject_class->set_property = set_property;
gobject_class->get_property = get_property;
@@ -630,22 +716,22 @@
g_param_spec_int ("width", "width", "pixel width of buffer",
-1, G_MAXINT, -1,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, PROP_HEIGHT,
g_param_spec_int ("height", "height", "pixel height of buffer",
-1, G_MAXINT, -1,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, PROP_X,
g_param_spec_int ("x", "x", "local origin's offset relative to source origin",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, PROP_Y,
g_param_spec_int ("y", "y", "local origin's offset relative to source origin",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class, PROP_ABYSS_WIDTH,
g_param_spec_int ("abyss-width", "abyss-width", "pixel width of abyss",
-1, G_MAXINT, 0,
@@ -697,6 +783,17 @@
g_param_spec_string ("path", "Path",
"URI to where the buffer is stored",
NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
+
+ gegl_buffer_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GEGL_TYPE_RECTANGLE);
+
}
static void
@@ -778,69 +875,6 @@
NULL);
}
-void
-gegl_buffer_copy (GeglBuffer *src,
- const GeglRectangle *src_rect,
- GeglBuffer *dst,
- const GeglRectangle *dst_rect)
-{
- /* FIXME: make gegl_buffer_copy work with COW shared tiles when possible */
-
- GeglRectangle src_line;
- GeglRectangle dst_line;
- const Babl *format;
- guchar *temp;
- guint i;
- gint pxsize;
-
- g_return_if_fail (GEGL_IS_BUFFER (src));
- g_return_if_fail (GEGL_IS_BUFFER (dst));
-
- if (!src_rect)
- {
- src_rect = gegl_buffer_get_extent (src);
- }
-
- if (!dst_rect)
- {
- dst_rect = src_rect;
- }
-
- pxsize = src->tile_storage->px_size;
- format = src->format;
-
- src_line = *src_rect;
- src_line.height = 1;
-
- dst_line = *dst_rect;
- dst_line.width = src_line.width;
- dst_line.height = src_line.height;
-
- temp = g_malloc (src_line.width * pxsize);
-
- for (i=0; i<src_rect->height; i++)
- {
- gegl_buffer_get (src, 1.0, &src_line, format, temp, GEGL_AUTO_ROWSTRIDE);
- gegl_buffer_set (dst, &dst_line, format, temp, GEGL_AUTO_ROWSTRIDE);
- src_line.y++;
- dst_line.y++;
- }
- g_free (temp);
-}
-
-GeglBuffer *
-gegl_buffer_dup (GeglBuffer *buffer)
-{
- GeglBuffer *new;
-
- g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
-
- new = gegl_buffer_new (gegl_buffer_get_extent (buffer), buffer->format);
- gegl_buffer_copy (buffer, gegl_buffer_get_extent (buffer),
- new, gegl_buffer_get_extent (buffer));
- return new;
-}
-
void
gegl_buffer_destroy (GeglBuffer *buffer)
@@ -869,29 +903,6 @@
static GeglBuffer *
-gegl_buffer_new_from_path (const gchar *path)
-{
- GeglTileStorage *tile_storage;
- GeglBuffer *buffer;
-
- tile_storage = g_object_new (GEGL_TYPE_TILE_STORAGE,
- "format", babl_format,
- "path", path,
- NULL);
- buffer = g_object_new (GEGL_TYPE_BUFFER,
- "source", tile_storage,
- /*"x", x,
- "y", y,
- "width", width,
- "height", height,*/
- NULL);
- /* XXX: query backend about width/height? (this seems odd) */
-
- g_object_unref (tile_storage);
- return buffer;
-}
-
-static GeglBuffer *
gegl_buffer_new_from_format (const void *babl_format,
gint x,
gint y,
@@ -1005,3 +1016,49 @@
}
}
}
+
+gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
+{
+ GeglTileBackend *backend = gegl_buffer_backend (buffer);
+ return backend->shared;
+}
+
+gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
+{
+ GeglTileBackend *backend = gegl_buffer_backend (buffer);
+ gboolean ret;
+
+ if (buffer->lock_count>0)
+ {
+ buffer->lock_count++;
+ return TRUE;
+ }
+ if (gegl_buffer_is_shared(buffer))
+ ret =gegl_tile_backend_file_try_lock (GEGL_TILE_BACKEND_FILE (backend));
+ else
+ ret = TRUE;
+ if (ret)
+ buffer->lock_count++;
+ return TRUE;
+}
+
+gboolean gegl_buffer_lock (GeglBuffer *buffer)
+{
+ while (gegl_buffer_try_lock (buffer)==FALSE)
+ {
+ g_print ("failed to aquire lock blocking ..");
+ g_usleep (100000);
+ }
+ return TRUE;
+}
+
+gboolean gegl_buffer_unlock (GeglBuffer *buffer)
+{
+ GeglTileBackend *backend = gegl_buffer_backend (buffer);
+ g_assert (buffer->lock_count>=0);
+ buffer->lock_count--;
+ g_assert (buffer->lock_count>=0);
+ if (buffer->lock_count==0 && gegl_buffer_is_shared (buffer))
+ return gegl_tile_backend_file_unlock (GEGL_TILE_BACKEND_FILE (backend));
+ return TRUE;
+}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-buffer.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-buffer.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-buffer.h Sat May 17 17:51:59 2008
@@ -56,39 +56,54 @@
const Babl *format);
-/**
- * gegl_buffer_share:
- * @buffer: a #GeglBuffer.
+/**
+ * gegl_buffer_open:
+ * @path: the path to a gegl buffer on disk.
+ * be opened.
*
- * return a integer handle or 0 upon error, the handle returned is
- * unique for this process on this host,
+ * Open an existing on-disk GeglBuffer, this buffer is opened in a monitored
+ * state so multiple instances of gegl can share the same buffer. Sets on
+ * one buffer are reflected in the other.
*
- * An uri for this buffer can be constructed by gegl_buffer_make_uri.
+ * Returns: a GeglBuffer object.
+ */
+GeglBuffer* gegl_buffer_open (const gchar *path);
+
+/**
+ * gegl_buffer_save:
+ * @buffer: a #GeglBuffer.
+ * @path: the path where the gegl buffer will be saved, any writable GIO uri is valid.
+ * @roi: the region of interest to write, this is the tiles that will be collected and
+ * written to disk.
*
- * Returns: an integer handle for referring to this buffer.
+ * Write a GeglBuffer to a file.
*/
-guint gegl_buffer_share (GeglBuffer *buffer);
+void gegl_buffer_save (GeglBuffer *buffer,
+ const gchar *path,
+ const GeglRectangle *roi);
/**
- * gegl_buffer_open:
- * @uri: a uri referring to a local, other process or other host buffer to
+ * gegl_buffer_load:
+ * @path: the path to a gegl buffer on disk.
* be opened.
*
- * buffer://host:port/process/handle
- * buffer:////42 handle 42 from same GEGL instance.
+ * Loads an existing GeglBuffer from disk, if it has previously been saved with
+ * gegl_buffer_save it should be possible to open through any GIO transport, buffers
+ * that have been used as swap needs random access to be opened.
*
- * Returns: a GeglBuffer object.
+ * Returns: a #GeglBuffer object.
*/
+GeglBuffer *gegl_buffer_load (const gchar *path);
-GeglBuffer* gegl_buffer_open (const gchar *uri);
+/**
+ * gegl_buffer_flush:
+ * @buffer: a #GeglBuffer
+ *
+ * Flushes all unsaved data to disk, this is not neccesary for shared
+ * geglbuffers opened with gegl_buffer_open since they auto-sync on writes.
+ */
void gegl_buffer_flush (GeglBuffer *buffer);
-void
-gegl_buffer_make_uri (gchar *buf_128,
- gchar *host,
- gint port,
- gint process,
- gint handle);
/**
* gegl_buffer_create_sub_buffer:
@@ -120,6 +135,21 @@
*/
const GeglRectangle * gegl_buffer_get_extent (GeglBuffer *buffer);
+
+/**
+ * gegl_buffer_set_extent:
+ * @buffer: the buffer to operate on.
+ * @extent: new extent.
+ *
+ * Changes the size and position that is considered active in a buffer, this
+ * operation is valid on any buffer, reads on subbuffers outside the master
+ * buffers extent are at the moment undefined.
+ *
+ * Returns TRUE if the change of extent was succesful.
+ */
+gboolean gegl_buffer_set_extent (GeglBuffer *buffer,
+ const GeglRectangle *extent);
+
/* convenience access macros */
/**
@@ -158,7 +188,7 @@
* gegl_buffer_get_pixel_count:
* @buffer: a GeglBuffer
*
- * Evaluates to the total number of pixels in a buffer.
+ * Returns the number of pixels of the extent of the buffer.
*/
#define gegl_buffer_get_pixel_count(buffer) (gegl_buffer_get_width(buffer) * gegl_buffer_get_height(buffer))
@@ -210,6 +240,18 @@
/**
+ * gegl_buffer_clear:
+ * @buffer: a #GeglBuffer
+ * @roi: a rectangular region
+ *
+ * Clears the provided rectangular region by setting all the associated memory
+ * to 0
+ */
+void gegl_buffer_clear (GeglBuffer *buffer,
+ const GeglRectangle *roi);
+
+
+/**
* gegl_buffer_copy:
* @src: source buffer.
* @src_rect: source rectangle (or NULL to copy entire source buffer)
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.c Sat May 17 17:51:59 2008
@@ -28,9 +28,8 @@
#include "gegl-tile-backend.h"
#include "gegl-tile-backend-file.h"
#include "gegl-buffer-index.h"
-
#include "gegl-debug.h"
-
+#include "gegl-types.h"
struct _GeglTileBackendFile
{
@@ -40,14 +39,17 @@
GFile *file; /* gfile refering to our buffer */
GOutputStream *o; /* for writing */
GInputStream *i; /* for reading */
+ gboolean exist; /* the file exist (and we've thus been able
+ * to initialize i and o, the utility_call ensure_exist
+ * should be called before any code using i and o)
+ */
- /*gint fd;*/
GHashTable *index; /* hashtable containing all entries
- * of buffer, the index is
- * written to the swapfile conforming
- * to the structures laid out in
- * gegl-buffer-index.h
- */
+ * of buffer, the index is
+ * written to the swapfile conforming
+ * to the structures laid out in
+ * gegl-buffer-index.h
+ */
GSList *free_list; /* list of offsets to tiles that are free */
@@ -74,8 +76,17 @@
/* loading buffer */
GList *tiles;
+
+ /* cooperative sharing of file */
+
+ GFileMonitor *monitor; /* Before using mmap we'll use GIO's infrastructure
+ * for monitoring the file for changes, this should
+ * also be more portable.
+ */
+ guint32 rev; /* revision of last index sync */
};
+static void ensure_exist (GeglTileBackendFile *self);
static gboolean
write_block (GeglTileBackendFile *self,
@@ -94,7 +105,9 @@
gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
goffset offset = entry->offset;
- success = g_seekable_seek (G_SEEKABLE (self->i),
+ ensure_exist (self);
+
+ success = g_seekable_seek (G_SEEKABLE (self->i),
offset, G_SEEK_SET,
NULL, NULL);
if (success == FALSE)
@@ -120,7 +133,9 @@
}
to_be_read -= read;
}
- GEGL_NOTE (TILE_BACKEND, "read entry %i,%i,%i at %i", entry->x, entry->y, entry->z, (gint)offset);
+
+
+ GEGL_NOTE (TILE_BACKEND, "read entry %i,%i,%i at %i", entry->x, entry->y, entry->z, (gint)offset);
}
static void inline
@@ -133,7 +148,9 @@
gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
goffset offset = entry->offset;
- success = g_seekable_seek (G_SEEKABLE (self->o),
+ ensure_exist (self);
+
+ success = g_seekable_seek (G_SEEKABLE (self->o),
offset, G_SEEK_SET,
NULL, NULL);
if (success == FALSE)
@@ -159,7 +176,7 @@
}
to_be_written -= wrote;
}
- GEGL_NOTE (TILE_BACKEND, "read entry %i,%i,%i at %i", entry->x, entry->y, entry->z, (gint)offset);
+ GEGL_NOTE (TILE_BACKEND, "wrote entry %i,%i,%i at %i", entry->x, entry->y, entry->z, (gint)offset);
}
static inline GeglBufferTile *
@@ -169,13 +186,15 @@
GEGL_NOTE (TILE_BACKEND, "Creating new entry");
+ ensure_exist (self);
+
if (self->free_list)
{
/* XXX: losing precision ? */
gint offset = GPOINTER_TO_INT (self->free_list->data);
entry->offset = offset;
self->free_list = g_slist_remove (self->free_list, self->free_list->data);
-
+
GEGL_NOTE (TILE_BACKEND, " set offset %i from free list", ((gint)entry->offset));
}
else
@@ -189,7 +208,7 @@
if (self->next_pre_alloc >= self->total)
{
self->total = self->total + 32 * tile_size;
-
+
GEGL_NOTE (TILE_BACKEND, "growing file to %i bytes", (gint)self->total);
g_assert (g_seekable_truncate (G_SEEKABLE (self->o),
@@ -211,12 +230,16 @@
g_hash_table_remove (self->index, entry);
dbg_dealloc (GEGL_TILE_BACKEND (self)->tile_size);
- g_slice_free (GeglBufferTile, entry);
+ g_free (entry);
}
-static gboolean write_header (GeglTileBackendFile *self)
+static gboolean
+write_header (GeglTileBackendFile *self)
{
gboolean success;
+
+ ensure_exist (self);
+
success = g_seekable_seek (G_SEEKABLE (self->o), 0, G_SEEK_SET,
NULL, NULL);
if (success == FALSE)
@@ -233,6 +256,7 @@
write_block (GeglTileBackendFile *self,
GeglBufferBlock *block)
{
+ ensure_exist (self);
if (self->in_holding)
{
guint64 next_allocation = self->offset + self->in_holding->length;
@@ -256,7 +280,7 @@
(gint)self->in_holding->next,
(gint)self->offset);
self->offset += g_output_stream_write (self->o, self->in_holding,
- self->in_holding->length,
+ self->in_holding->length,
NULL, NULL);
g_assert (next_allocation == self->offset); /* true as long as
@@ -274,7 +298,7 @@
* header inside free list later
*/
- if(!g_seekable_seek (G_SEEKABLE (self->o),
+ if(!g_seekable_seek (G_SEEKABLE (self->o),
(goffset) self->offset, G_SEEK_SET,
NULL, NULL))
goto fail;
@@ -362,8 +386,8 @@
return NULL;
tile = gegl_tile_new (backend->tile_size);
- tile->stored_rev = 1;
- tile->rev = 1;
+ tile->rev = entry->rev;
+ tile->stored_rev = entry->rev;
file_entry_read (tile_backend_file, entry, tile->data);
return tile;
@@ -392,10 +416,8 @@
entry->z = z;
g_hash_table_insert (tile_backend_file->index, entry, entry);
}
+ entry->rev = tile->rev;
- g_assert (tile->flags == 0); /* when this one is triggered, dirty pyramid data
- has been tried written to persistent tile_storage.
- */
file_entry_write (tile_backend_file, entry, tile->data);
tile->stored_rev = tile->rev;
return NULL;
@@ -431,18 +453,17 @@
gint y,
gint z)
{
- GeglTileBackend *backend;
+ GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file;
- GeglBufferTile *entry;
+ GeglBufferTile *entry;
- backend = GEGL_TILE_BACKEND (self);
+ backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
- entry = lookup_entry (tile_backend_file, x, y, z);
+ entry = lookup_entry (tile_backend_file, x, y, z);
return entry!=NULL?((gpointer)0x1):NULL;
}
-#include "gegl-buffer-index.h"
static gpointer
flush (GeglTileSource *source,
@@ -458,9 +479,12 @@
backend = GEGL_TILE_BACKEND (source);
self = GEGL_TILE_BACKEND_FILE (backend);
+ ensure_exist (self);
+
GEGL_NOTE (TILE_BACKEND, "flushing %s", self->path);
+ self->header.rev ++;
self->header.next = self->next_pre_alloc; /* this is the offset
we start handing
out headers from*/
@@ -578,23 +602,30 @@
{
GeglTileBackendFile *self = (GeglTileBackendFile *) object;
- GEGL_NOTE (TILE_BACKEND, "finalizing buffer %s", self->path);
-
if (self->index)
g_hash_table_unref (self->index);
- if (self->i)
- g_object_unref (self->i);
- if (self->o)
- g_object_unref (self->o);
+
+ if (self->exist)
+ {
+ GEGL_NOTE (TILE_BACKEND, "finalizing buffer %s", self->path);
+
+ if (self->i)
+ g_object_unref (self->i);
+ if (self->o)
+ g_object_unref (self->o);
+
+ if (self->file)
+ {
+ g_file_delete (self->file, NULL, NULL);
+ g_object_unref (self->file);
+ }
+ }
if (self->path)
g_free (self->path);
- if (self->file)
- {
- g_file_delete (self->file, NULL, NULL);
- g_object_unref (self->file);
- }
+ if (self->monitor)
+ g_object_unref (self->monitor);
(*G_OBJECT_CLASS (parent_class)->finalize)(object);
}
@@ -642,68 +673,212 @@
return FALSE;
}
+
+static void
+load_index (GeglTileBackendFile *self,
+ gboolean block)
+{
+ GeglBufferHeader new_header;
+ GList *iter;
+ GeglTileBackend *backend;
+ goffset offset = 0;
+ goffset max=0;
+
+/* compute total from and next pre alloc by monitoring tiles as they
+ * are added here
+ */
+ /* reload header */
+ new_header = gegl_buffer_read_header (self->i, &offset)->header;
+
+ while (new_header.flags & GEGL_FLAG_LOCKED)
+ {
+ g_usleep (50000);
+ new_header = gegl_buffer_read_header (self->i, &offset)->header;
+ }
+
+ if (new_header.rev == self->header.rev)
+ {
+ GEGL_NOTE(TILE_BACKEND, "header not changed: %s", self->path);
+ return;
+ }
+ else
+ {
+ self->header=new_header;
+ GEGL_NOTE(TILE_BACKEND, "loading index: %s", self->path);
+ }
+
+
+ offset = self->header.next;
+ self->tiles = gegl_buffer_read_index (self->i, &offset);
+ backend = GEGL_TILE_BACKEND (self);
+
+ for (iter = self->tiles; iter; iter=iter->next)
+ {
+ GeglBufferItem *item = iter->data;
+
+ GeglBufferItem *existing = g_hash_table_lookup (self->index, item);
+
+ if (item->tile.offset > max)
+ max = item->tile.offset + backend->tile_size;
+
+ if (existing)
+ {
+ if (existing->tile.rev == item->tile.rev)
+ {
+ g_assert (existing->tile.offset == item->tile.offset);
+ existing->tile = item->tile;
+ g_free (item);
+ continue;
+ }
+ else
+ {
+ GeglRectangle rect;
+ g_hash_table_remove (self->index, existing);
+ gegl_tile_source_refetch (GEGL_TILE_SOURCE (backend->storage),
+ existing->tile.x,
+ existing->tile.y,
+ existing->tile.z);
+
+ if (existing->tile.z == 0)
+ {
+ rect.width = self->header.tile_width;
+ rect.height = self->header.tile_height;
+ rect.x = existing->tile.x * self->header.tile_width;
+ rect.y = existing->tile.y * self->header.tile_height;
+ }
+ g_free (existing);
+ g_signal_emit_by_name (backend->storage, "changed", &rect, NULL);
+ }
+ }
+ g_hash_table_insert (self->index, iter->data, iter->data);
+ }
+ g_list_free (self->tiles);
+ g_slist_free (self->free_list);
+ self->free_list = NULL;
+ self->next_pre_alloc = max; /* if bigger than own? */
+ self->total = max;
+ self->tiles = NULL;
+}
+
+static void
+file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ GeglTileBackendFile *self)
+{
+ if (event_type == G_FILE_MONITOR_EVENT_CHANGED)
+ /*if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)*/
+ {
+ load_index (self, TRUE);
+ }
+}
static GObject *
gegl_tile_backend_file_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
- GObject *object;
+ GObject *object;
GeglTileBackendFile *self;
- GeglTileBackend *backend;
+ GeglTileBackend *backend;
- object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
- self = GEGL_TILE_BACKEND_FILE (object);
+ object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
+ self = GEGL_TILE_BACKEND_FILE (object);
backend = GEGL_TILE_BACKEND (object);
GEGL_NOTE (TILE_BACKEND, "constructing file backend: %s", self->path);
self->file = g_file_new_for_commandline_arg (self->path);
-
+
self->index = g_hash_table_new (hashfunc, equalfunc);
- /* if the file already exist we try to open it for appending instead of replacing */
+ /* If the file already exists open it, assuming it is a GeglBuffer. */
if (g_file_query_exists (self->file, NULL))
{
- goffset offset;
+ goffset offset = 0;
- self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
- self->o = G_OUTPUT_STREAM (g_file_append_to (self->file, G_FILE_CREATE_NONE, NULL, NULL));
+ /* Install a monitor for changes to the file in case other applications
+ * might be writing to the buffer
+ */
+ self->monitor = g_file_monitor_file (self->file, G_FILE_MONITOR_NONE,
+ NULL, NULL);
+ g_signal_connect (self->monitor, "changed",
+ G_CALLBACK (file_changed),
+ self);
+
+#ifndef HACKED_GIO_WITH_READWRITE
+ g_error ("not able to open a file readwrite properly with GIO");
+#else
+ /* this construct uses a hacked up version of GIO that detects the
+ * createflag to be passed as G_FILE_CREATE_READWRITE for the append
+ * call on local files, and provides a suitable inputstream as istream
+ * data on the object.
+ */
+ self->o = G_OUTPUT_STREAM (g_file_append_to (self->file,
+ G_FILE_CREATE_READWRITE,
+ NULL, NULL));
+ self->i = g_object_get_data (G_OBJECT (self->o), "istream");
+#endif
+ /*self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));*/
self->header = gegl_buffer_read_header (self->i, &offset)->header;
+ self->header.rev = self->header.rev -1;
+
+ /* we are overriding all of the work of the actual constructor here */
backend->tile_width = self->header.tile_width;
backend->tile_height = self->header.tile_height;
backend->format = babl_format (self->header.description);
- /* we are overriding all of the work of the actual constructor here */
backend->px_size = backend->format->format.bytes_per_pixel;
backend->tile_size = backend->tile_width * backend->tile_height * backend->px_size;
- offset = self->header.next;
- self->tiles = gegl_buffer_read_index (self->i, &offset);
-
/* insert each of the entries into the hash table */
- {
- /* compute total from and next pre alloc by monitoring tiles as they
- * are added here
- */
- goffset max=0;
- GList *iter;
- for (iter = self->tiles; iter; iter=iter->next)
- {
- GeglBufferItem *item = iter->data;
- if (item->tile.offset > max)
- max = item->tile.offset + backend->tile_size;
- g_hash_table_insert (self->index, iter->data, iter->data);
- }
- g_list_free (self->tiles);
- self->next_pre_alloc = max;
- self->total = max;
- self->tiles = NULL;
+ load_index (self, TRUE);
+ self->exist = TRUE;
+ g_assert (self->i);
+ g_assert (self->o);
- }
+ /* to autoflush gegl_buffer_set */
+ backend->shared = TRUE;
}
else
{
+ self->exist = FALSE; /* this is also the default, the file will be created on demand */
+ }
+
+ g_assert (self->file);
+
+ backend->header = &self->header;
+
+ return object;
+}
+
+static void
+ensure_exist (GeglTileBackendFile *self)
+{
+ if (!self->exist)
+ {
+ GeglTileBackend *backend;
+
+ self->exist = TRUE;
+ backend = GEGL_TILE_BACKEND (self);
+
+ GEGL_NOTE (TILE_BACKEND, "creating swapfile %s", self->path);
+#ifdef HACKED_GIO_WITH_READWRITE
+
+ self->o = G_OUTPUT_STREAM (g_file_append_to (self->file,
+ G_FILE_CREATE_READWRITE,
+ NULL, NULL));
+ gegl_buffer_header_init (&self->header,
+ backend->tile_width,
+ backend->tile_height,
+ backend->px_size,
+ backend->format
+ );
+ write_header (self);
+ g_output_stream_flush (self->o, NULL, NULL);
+ self->i = g_object_get_data (G_OBJECT (self->o), "istream");
+#else
self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
g_output_stream_flush (self->o, NULL, NULL);
- self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+
self->next_pre_alloc = 256; /* reserved space for header */
self->total = 256; /* reserved space for header */
g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
@@ -714,17 +889,16 @@
backend->px_size,
backend->format
);
- /* FIXME: should probably write an initial header */
+ write_header (self);
+ g_output_stream_flush (self->o, NULL, NULL);
+ self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+#endif
+ /*self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));*/
+ self->next_pre_alloc = 256; /* reserved space for header */
+ self->total = 256; /* reserved space for header */
+ g_assert (self->i);
+ g_assert (self->o);
}
-
- g_assert (self->file);
- g_assert (self->i);
- g_assert (self->o);
-
-
- backend->header = &self->header;
-
- return object;
}
static void
@@ -742,6 +916,7 @@
gegl_tile_source_class->command = command;
+ GEGL_BUFFER_STRUCT_CHECK_PADDING;
g_object_class_install_property (gobject_class, PROP_PATH,
g_param_spec_string ("path",
@@ -764,3 +939,31 @@
self->next_pre_alloc = 256; /* reserved space for header */
self->total = 256; /* reserved space for header */
}
+
+gboolean
+gegl_tile_backend_file_try_lock (GeglTileBackendFile *self)
+{
+ GeglBufferHeader new_header;
+ new_header = gegl_buffer_read_header (self->i, NULL)->header;
+ if (new_header.flags & GEGL_FLAG_LOCKED)
+ {
+ return FALSE;
+ }
+ self->header.flags += GEGL_FLAG_LOCKED;
+ write_header (self);
+ g_output_stream_flush (self->o, NULL, NULL);
+ return TRUE;
+}
+
+gboolean gegl_tile_backend_file_unlock (GeglTileBackendFile *self)
+{
+ if (!(self->header.flags & GEGL_FLAG_LOCKED))
+ {
+ g_warning ("tried to unlock unlocked buffer");
+ return FALSE;
+ }
+ self->header.flags -= GEGL_FLAG_LOCKED;
+ write_header (self);
+ g_output_stream_flush (self->o, NULL, NULL);
+ return TRUE;
+}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-file.h Sat May 17 17:51:59 2008
@@ -44,6 +44,9 @@
void gegl_tile_backend_file_stats (void);
+gboolean gegl_tile_backend_file_try_lock (GeglTileBackendFile *file);
+gboolean gegl_tile_backend_file_unlock (GeglTileBackendFile *file);
+
G_END_DECLS
#endif
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-ram.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-ram.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-ram.c Sat May 17 17:51:59 2008
@@ -179,9 +179,6 @@
entry->z = z;
g_hash_table_insert (tile_backend_ram->entries, entry, entry);
}
- g_assert (tile->flags == 0); /* when this one is triggered, dirty pyramid data
- has been tried written to persistent tile_storage.
- */
ram_entry_write (tile_backend_ram, entry, tile->data);
tile->stored_rev = tile->rev;
return TRUE;
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-tiledir.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-tiledir.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend-tiledir.c Sat May 17 17:51:59 2008
@@ -170,9 +170,6 @@
GioEntry entry = {x,y,z};
- g_assert (tile->flags == 0); /* when this one is triggered, dirty pyramid data
- has been tried written to persistent tile_storage.
- */
gio_entry_write (tile_backend_tiledir, &entry, tile->data);
tile->stored_rev = tile->rev;
return NULL;
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.c Sat May 17 17:51:59 2008
@@ -159,4 +159,5 @@
static void
gegl_tile_backend_init (GeglTileBackend *self)
{
+ self->shared = FALSE;
}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-backend.h Sat May 17 17:51:59 2008
@@ -42,6 +42,8 @@
/* private */
gpointer header;
+ gpointer storage;
+ gboolean shared;
};
struct _GeglTileBackendClass
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-cache.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-cache.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-cache.c Sat May 17 17:51:59 2008
@@ -35,18 +35,11 @@
static gint cache_misses = 0;
static gint cache_total = 0; /* approximate amount of bytes stored */
-static gint clones_ones = 0; /* approximate amount of bytes stored */
struct _GeglTileHandlerCache
{
GeglTileHandler parent_instance;
GSList *free_list;
-
-/* GQueue *queue;
- gint size;
- gint wash_percentage;
- gint hits;
- gint misses;*/
};
void gegl_tile_cache_init (void)
@@ -82,6 +75,10 @@
gint x,
gint y,
gint z);
+static void gegl_tile_handler_cache_invalidate (GeglTileHandlerCache *cache,
+ gint x,
+ gint y,
+ gint z);
G_DEFINE_TYPE (GeglTileHandlerCache, gegl_tile_handler_cache, GEGL_TYPE_TILE_HANDLER)
@@ -121,13 +118,12 @@
dispose (GObject *object)
{
GeglTileHandlerCache *cache;
- CacheItem *item;
- GSList *iter;
- cache = (GeglTileHandlerCache *) object;
+ CacheItem *item;
+ GSList *iter;
+ cache = GEGL_TILE_HANDLER_CACHE (object);
- /* only throw out items belonging to this cache instance
- (XXX: should probably have a local list for that)*/
+ /* only throw out items belonging to this cache instance */
cache->free_list = NULL;
g_queue_foreach (cache_queue, queue_each, cache);
@@ -137,7 +133,6 @@
if (item->tile)
{
cache_total -= item->tile->size;
- clones_ones = 0; /* XXX */
g_object_unref (item->tile);
}
g_queue_remove (cache_queue, item);
@@ -157,8 +152,7 @@
{
GeglTileHandlerCache *cache = GEGL_TILE_HANDLER_CACHE (tile_store);
GeglTileSource *source = GEGL_HANDLER (tile_store)->source;
- GeglTile *tile = NULL;
-
+ GeglTile *tile = NULL;
tile = gegl_tile_handler_cache_get_tile (cache, x, y, z);
if (tile)
@@ -191,9 +185,6 @@
/* FIXME: replace with switch */
switch (command)
{
- case GEGL_TILE_SET:
- /* nothing to do */
- break; /* chain up */
case GEGL_TILE_FLUSH:
{
GList *link;
@@ -210,7 +201,7 @@
}
}
}
- break; /* chain up */
+ break;
case GEGL_TILE_GET:
/* XXX: we should perhaps store a NIL result, and place the empty
* generator after the cache, this would have to be possible to disable
@@ -225,7 +216,7 @@
if (exist)
return (gpointer)TRUE;
}
- break; /* chain up */
+ break;
case GEGL_TILE_IDLE:
{
gboolean action = gegl_tile_handler_cache_wash (cache);
@@ -233,14 +224,16 @@
return (gpointer)action;
break;
}
+ case GEGL_TILE_REFETCH:
+ gegl_tile_handler_cache_invalidate (cache, x, y, z);
+ break;
case GEGL_TILE_VOID:
gegl_tile_handler_cache_void (cache, x, y, z);
- if (z!=0)
- return (void*)0xdead700;
- /* fallthrough */
+ break;
default:
break;
}
+
return gegl_tile_handler_chain_up (handler, command, x, y, z, data);
}
@@ -363,6 +356,36 @@
return FALSE;
}
+static void
+gegl_tile_handler_cache_invalidate (GeglTileHandlerCache *cache,
+ gint x,
+ gint y,
+ gint z)
+{
+ GList *link;
+
+ for (link = g_queue_peek_head_link (cache_queue); link; link = link->next)
+ {
+ CacheItem *item = link->data;
+ GeglTile *tile = item->tile;
+
+ if (tile != NULL &&
+ item->x == x &&
+ item->y == y &&
+ item->z == z &&
+ item->handler == cache)
+ {
+ cache_total -= item->tile->size;
+ tile->tile_storage = NULL;
+ tile->stored_rev = tile->rev; /* to cheat it out of being stored */
+ g_object_unref (tile);
+ g_slice_free (CacheItem, item);
+ g_queue_delete_link (cache_queue, link);
+ return;
+ }
+ }
+}
+
static void
gegl_tile_handler_cache_void (GeglTileHandlerCache *cache,
@@ -414,10 +437,10 @@
count = g_queue_get_length (cache_queue);
- if (cache_total > gegl_config()->cache_size)
+ while (cache_total > gegl_config()->cache_size)
{
- GEGL_NOTE(CACHE, "cache_total:%i > cache_size:%i\n", cache_total, gegl_config()->cache_size);
- GEGL_NOTE(CACHE, "%f%% hit:%i miss:%i %i]", cache_hits*100.0/(cache_hits+cache_misses), cache_hits, cache_misses, g_queue_get_length (cache_queue));
+ /*GEGL_NOTE(CACHE, "cache_total:%i > cache_size:%i", cache_total, gegl_config()->cache_size);
+ GEGL_NOTE(CACHE, "%f%% hit:%i miss:%i %i]", cache_hits*100.0/(cache_hits+cache_misses), cache_hits, cache_misses, g_queue_get_length (cache_queue));*/
gegl_tile_handler_cache_trim (cache);
}
}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-log.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-log.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-log.c Sat May 17 17:51:59 2008
@@ -33,12 +33,8 @@
"is_cached",
"exist",
"-", /*void*/
- "void tl",
- "void tr",
- "void bl",
- "void br",
"flush",
- "invalidated",
+ "refetch",
"last command",
"eeek",
NULL
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-zoom.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-zoom.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-handler-zoom.c Sat May 17 17:51:59 2008
@@ -215,15 +215,8 @@
tile = gegl_tile_source_get_tile (source, x, y, z);
}
- if (tile != NULL)
- {
- /* Check that the tile is fully valid */
- if (!(tile->flags & (GEGL_TILE_DIRT_TL |
- GEGL_TILE_DIRT_TR |
- GEGL_TILE_DIRT_BL |
- GEGL_TILE_DIRT_BR)))
- return tile;
- }
+ if (tile)
+ return tile;
if (z == 0)/* at base level with no tile found->send null, and shared empty
tile will be used instead */
@@ -240,38 +233,13 @@
{
gint i, j;
guchar *data;
- gboolean had_tile = tile != NULL;
GeglTile *source_tile[2][2] = { { NULL, NULL }, { NULL, NULL } };
- gboolean fetch[2][2] = { { FALSE, FALSE },
- { FALSE, FALSE } };
-
- if (had_tile)
- {
- if (tile->flags & GEGL_TILE_DIRT_TL)
- fetch[0][0] = TRUE;
- if (tile->flags & GEGL_TILE_DIRT_TR)
- fetch[1][0] = TRUE;
- if (tile->flags & GEGL_TILE_DIRT_BL)
- fetch[0][1] = TRUE;
- if (tile->flags & GEGL_TILE_DIRT_BR)
- fetch[1][1] = TRUE;
-
- tile->flags = 0;
- }
- else
- {
- fetch[0][0] = TRUE;
- fetch[1][0] = TRUE;
- fetch[0][1] = TRUE;
- fetch[1][1] = TRUE;
- }
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
{
/* we get the tile from ourselves, to make successive rescales work
* correctly */
- if (fetch[i][j])
source_tile[i][j] = gegl_tile_source_get_tile (gegl_tile_source,
x * 2 + i, y * 2 + j, z - 1);
}
@@ -281,33 +249,25 @@
source_tile[1][0] == NULL &&
source_tile[1][1] == NULL)
{
- if (had_tile)
- {
- g_object_unref (tile);
- }
return NULL; /* no data from level below, return NULL and let GeglTileHandlerEmpty
fill in the shared empty tile */
}
- if (!had_tile)
+ g_assert (tile == NULL);
+ if (tile == NULL)
{
tile = gegl_tile_new (tile_size);
- /* it is a bit hacky, but adding enough information (probably too much)
- * enabling the tile_storage system to attempt swapping out of zoom tiles
- */
- tile->storage_x = x;
- tile->storage_y = y;
- tile->storage_z = z;
tile->x = x;
tile->y = y;
tile->z = z;
- tile->tile_storage = zoom->tile_storage;
+ tile->tile_storage = zoom->tile_storage;
tile->stored_rev = 1;
tile->rev = 1;
{
- GeglTileHandlerCache *cache = g_object_get_data (G_OBJECT (gegl_tile_source), "cache");
+ GeglTileHandlerCache *cache;
+ cache = g_object_get_data (G_OBJECT (gegl_tile_source), "cache");
if (cache)
{
gegl_tile_handler_cache_insert (cache, tile, x, y, z);
@@ -325,20 +285,14 @@
set_half (tile, source_tile[i][j], tile_width, tile_height, format, i, j);
g_object_unref (source_tile[i][j]);
}
- else if (fetch[i][j])
+ else
{
set_blank (tile, tile_width, tile_height, format, i, j);
}
- else
- {
- /* keep old data around */
- }
}
gegl_tile_unlock (tile);
}
- tile->flags = 0;
-
return tile;
}
@@ -353,43 +307,14 @@
GeglTileHandler *handler = GEGL_HANDLER (tile_store);
/*GeglTileSource *source = handler->source;*/
- if (command == GEGL_TILE_GET)
- return get_tile (tile_store, x, y, z);
- if (command == GEGL_TILE_VOID_TL ||
- command == GEGL_TILE_VOID_TR ||
- command == GEGL_TILE_VOID_BL ||
- command == GEGL_TILE_VOID_BR)
+ switch (command)
{
- GeglTile *tile = gegl_tile_source_get_tile (tile_store, x, y, z);
-
- if (!tile)
- return FALSE;
- switch (command)
- {
- case GEGL_TILE_VOID_TL:
- tile->flags |= GEGL_TILE_DIRT_TL;
- break;
-
- case GEGL_TILE_VOID_TR:
- tile->flags |= GEGL_TILE_DIRT_TR;
- break;
-
- case GEGL_TILE_VOID_BL:
- tile->flags |= GEGL_TILE_DIRT_BL;
- break;
-
- case GEGL_TILE_VOID_BR:
- tile->flags |= GEGL_TILE_DIRT_BR;
- break;
-
- default:
- break;
- }
- g_object_unref (tile);
- return FALSE;
+ case GEGL_TILE_GET:
+ return get_tile (tile_store, x, y, z);
+ default:
+ /* pass the command on */
+ return gegl_tile_handler_chain_up (handler, command, x, y, z, data);
}
- /* pass the command on */
- return gegl_tile_handler_chain_up (handler, command, x, y, z, data);
}
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-source.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-source.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-source.h Sat May 17 17:51:59 2008
@@ -26,7 +26,7 @@
G_BEGIN_DECLS
-#define GEGL_TYPE_TILE_SOURCE (gegl_tile_source_get_type ())
+#define GEGL_TYPE_TILE_SOURCE (gegl_tile_source_get_type ())
#define GEGL_TILE_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_TILE_SOURCE, GeglTileSource))
#define GEGL_TILE_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_TILE_SOURCE, GeglTileSourceClass))
#define GEGL_IS_TILE_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_TILE_SOURCE))
@@ -35,23 +35,6 @@
typedef gint GeglTileCommand;
-enum _GeglTileCommand
-{
- GEGL_TILE_IDLE = 0,
- GEGL_TILE_SET,
- GEGL_TILE_GET,
- GEGL_TILE_IS_CACHED,
- GEGL_TILE_EXIST,
- GEGL_TILE_VOID,
- GEGL_TILE_VOID_TL,
- GEGL_TILE_VOID_TR,
- GEGL_TILE_VOID_BL,
- GEGL_TILE_VOID_BR,
- GEGL_TILE_FLUSH,
- GEGL_TILE_INVALIDATED,
- GEGL_TILE_LAST_COMMAND
-};
-
struct _GeglTileSource
{
GObject parent_instance;
@@ -71,49 +54,154 @@
GType gegl_tile_source_get_type (void) G_GNUC_CONST;
+gpointer gegl_tile_source_command (GeglTileSource *tile_source,
+ GeglTileCommand command,
+ gint x,
+ gint y,
+ gint z,
+ gpointer data);
-gpointer gegl_tile_source_command (GeglTileSource *gegl_tile_source,
- GeglTileCommand command,
- gint x,
- gint y,
- gint z,
- gpointer data);
-#define gegl_tile_source_idle(source) \
- gegl_tile_source_command(source,GEGL_TILE_IDLE,0,0,0,NULL)
+/* All commands have the ability to pass commands to all tiles the handlers
+ * add abstraction to the commands the documentaiton given here is valid
+ * when the commands are issued to a full blown GeglBuffer instance.
+ */
+
+enum _GeglTileCommand
+{
+ GEGL_TILE_IDLE = 0,
+ GEGL_TILE_SET,
+ GEGL_TILE_GET,
+ GEGL_TILE_IS_CACHED,
+ GEGL_TILE_EXIST,
+ GEGL_TILE_VOID,
+ GEGL_TILE_FLUSH,
+ GEGL_TILE_REFETCH,
+ GEGL_TILE_LAST_COMMAND
+};
+
+#ifdef NOT_REALLY_COS_THIS_IS_MACROS
+
+/**
+ * gegl_tile_source_get_tile:
+ * @source: a GeglTileSource *
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: tile zoom level
+ *
+ * Get a GeglTile *from the buffer, mipmap tiles for levels z!=0 will be
+ * created on the fly as needed, empty tiles returned are copy on write
+ * and must be locked before written to, and unlocked afterwards.
+ *
+ * Returns: the tile at x,y,z or NULL if the tile could not be provided.
+ */
+GeglTile *gegl_tile_source_get_tile (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z);
+
+/**
+ * gegl_tile_source_set_tile:
+ * @source: a GeglTileSource *
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: tile zoom level
+ * @tile: a #GeglTile
+ *
+ * Get a GeglTile *from the buffer.
+ *
+ * Returns: the TRUE if the set was successful.
+ */
+gboolean gegl_tile_source_set_tile (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z,
+ GeglTile *tile);
+/**
+ * gegl_tile_source_is_cached:
+ * @source: a GeglTileSource *
+ * @x: tile x coordinate
+ * @y: tile y coordinate
+ * @z: tile zoom level
+ *
+ * Checks if a tile is in cache and easily retrieved.
+ */
+gboolean gegl_tile_source_is_cached (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z);
+/**
+ * gegl_tile_source_exist:
+ * @source: a GeglTileSource *
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: tile zoom level
+ *
+ * Checks if a tile exists, this check would not cause the tile to be swapped
+ * in.
+ */
+gboolean gegl_tile_source_exist (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z);
+/**
+ * gegl_tile_source_void:
+ * @source: a GeglTileSource *
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: tile zoom level
+ *
+ * Causes all references to a tile to be removed.
+ */
+void gegl_tile_source_void (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z);
+/* INTERNAL API
+ * gegl_tile_source_refetch:
+ * @source: a GeglTileSource *
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: tile zoom level
+ *
+ * A message used internally when watching external buffers to indicate that
+ * a refresh of all data relating to the coordinates needs to be refetched.
+ * Subsequent get calls should get new and valid data for the tile coordinates.
+ */
+void gegl_tile_source_refetch (GegTileSource *source,
+ gint x,
+ gint y,
+ gint z);
+/* INTERNAL API
+ * gegl_tile_source_idle:
+ * @source: a GeglTileSource *
+ *
+ * Allow different parts of the buffer to do idle work (saving cached
+ * data lazily, perhaps prefetching in the future?), monitoring for
+ * changes or other tasks. Used internally by the buffer object.
+ *
+ * Returns: the TRUE if some work was done.
+ */
+gboolean gegl_tile_source_idle (GegTileSource *source);
+
+#endif
#define gegl_tile_source_set_tile(source,x,y,z,tile) \
(gboolean)gegl_tile_source_command(source,GEGL_TILE_SET,x,y,z,tile)
-
#define gegl_tile_source_get_tile(source,x,y,z) \
(GeglTile*)gegl_tile_source_command(source,GEGL_TILE_GET,x,y,z,NULL)
-
#define gegl_tile_source_is_cached(source,x,y,z) \
(gboolean)gegl_tile_source_command(source,GEGL_TILE_IS_CACHED,x,y,z,NULL)
-
#define gegl_tile_source_exist(source,x,y,z) \
(gboolean)gegl_tile_source_command(source,GEGL_TILE_EXIST,x,y,z,NULL)
-
#define gegl_tile_source_void(source,x,y,z) \
gegl_tile_source_command(source,GEGL_TILE_VOID,x,y,z,NULL)
+#define gegl_tile_source_refetch(source,x,y,z) \
+ gegl_tile_source_command(source,GEGL_TILE_REFETCH,x,y,z,NULL)
+#define gegl_tile_source_idle(source) \
+ (gboolean)gegl_tile_source_command(source,GEGL_TILE_IDLE,0,0,0,NULL)
-#define gegl_tile_source_void_tl(source,x,y,z) \
- gegl_tile_source_command(source,GEGL_TILE_VOID_TL,x,y,z,NULL)
-
-#define gegl_tile_source_void_tr(source,x,y,z) \
- gegl_tile_source_command(source,GEGL_TILE_VOID_TR,x,y,z,NULL)
-
-#define gegl_tile_source_void_bl(source,x,y,z) \
- gegl_tile_source_command(source,GEGL_TILE_VOID_BL,x,y,z,NULL)
-
-#define gegl_tile_source_void_br(source,x,y,z) \
- gegl_tile_source_command(source,GEGL_TILE_VOID_BR,x,y,z,NULL)
-
-#define gegl_tile_source_undo_start_group(source,x,y,z) \
- gegl_tile_source_command(source,GEGL_TILE_UNDO_START_GROUP,x,y,z,NULL)
-
-
G_END_DECLS
#endif
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile-storage.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile-storage.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile-storage.c Sat May 17 17:51:59 2008
@@ -29,6 +29,8 @@
#include "gegl-tile-handler-zoom.h"
#include "gegl-tile-handler-cache.h"
#include "gegl-tile-handler-log.h"
+#include "gegl-types.h"
+#include "gegl-utils.h"
G_DEFINE_TYPE (GeglTileStorage, gegl_tile_storage, GEGL_TYPE_TILE_HANDLER_CHAIN)
@@ -51,6 +53,14 @@
PROP_PATH
};
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
+guint gegl_tile_storage_signals[LAST_SIGNAL] = { 0 };
+
static void
get_property (GObject *gobject,
guint property_id,
@@ -160,11 +170,10 @@
return FALSE;
}
- gegl_tile_source_idle (GEGL_TILE_SOURCE (tile_storage));
-
- return TRUE;
+ return gegl_tile_source_idle (GEGL_TILE_SOURCE (tile_storage));
}
+GeglTileBackend *gegl_buffer_backend (GObject *buffer);
static GObject *
gegl_tile_storage_constructor (GType type,
@@ -231,18 +240,20 @@
g_object_new (GEGL_TYPE_TILE_HANDLER_LOG, NULL));
- cache = gegl_tile_handler_chain_add (tile_handler_chain,
- g_object_new (GEGL_TYPE_TILE_HANDLER_CACHE, NULL));
+ cache = g_object_new (GEGL_TYPE_TILE_HANDLER_CACHE,
+ NULL);
+ empty = g_object_new (GEGL_TYPE_TILE_HANDLER_EMPTY,
+ "backend", handler->source,
+ NULL);
+ zoom = g_object_new (GEGL_TYPE_TILE_HANDLER_ZOOM,
+ "backend", handler->source,
+ "tile_storage", tile_storage,
+ NULL);
+
+ gegl_tile_handler_chain_add (tile_handler_chain, cache);
+ gegl_tile_handler_chain_add (tile_handler_chain, zoom);
+ gegl_tile_handler_chain_add (tile_handler_chain, empty);
- zoom = gegl_tile_handler_chain_add (tile_handler_chain,
- g_object_new (GEGL_TYPE_TILE_HANDLER_ZOOM,
- "backend", handler->source,
- "tile_storage", tile_storage,
- NULL));
- empty = gegl_tile_handler_chain_add (tile_handler_chain,
- g_object_new (GEGL_TYPE_TILE_HANDLER_EMPTY,
- "backend", handler->source,
- NULL));
if (g_getenv("GEGL_LOG_TILE_CACHE"))
gegl_tile_handler_chain_add (tile_handler_chain,
@@ -250,6 +261,11 @@
g_object_set_data (G_OBJECT (empty), "cache", cache);
g_object_set_data (G_OBJECT (zoom), "cache", cache);
+ {
+ GeglTileBackend *backend;
+ backend = gegl_buffer_backend (object);
+ backend->storage = (gpointer)object;
+ }
tile_storage->idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
250,
@@ -323,6 +339,17 @@
g_param_spec_pointer ("format", "format", "babl format",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+
+ gegl_tile_storage_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GEGL_TYPE_RECTANGLE);
+
}
static void
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile.c
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile.c (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile.c Sat May 17 17:51:59 2008
@@ -106,6 +106,8 @@
}
}
+#include "gegl-utils.h"
+
static void
dispose (GObject *object)
{
@@ -118,7 +120,7 @@
{
if (tile->next_shared == tile)
{ /* no clones */
- g_free (tile->data);
+ gegl_free (tile->data);
tile->data = NULL;
}
else
@@ -178,7 +180,6 @@
tile->rev = 0;
tile->lock = 0;
tile->data = NULL;
- tile->flags = 0;
tile->next_shared = tile;
tile->prev_shared = tile;
@@ -212,7 +213,7 @@
{
GeglTile *tile = g_object_new (GEGL_TYPE_TILE, NULL);
- tile->data = g_malloc (size);
+ tile->data = gegl_malloc (size);
tile->size = size;
tile->stored_rev = 1;
@@ -220,6 +221,15 @@
return tile;
}
+static gpointer
+gegl_memdup (gpointer src, gsize size)
+{
+ gpointer ret;
+ ret = gegl_malloc (size);
+ memcpy (ret, src, size);
+ return ret;
+}
+
static void
gegl_tile_unclone (GeglTile *tile)
{
@@ -228,7 +238,7 @@
/* the tile data is shared with other tiles,
* create a local copy
*/
- tile->data = g_memdup (tile->data, tile->size);
+ tile->data = gegl_memdup (tile->data, tile->size);
tile->prev_shared->next_shared = tile->next_shared;
tile->next_shared->prev_shared = tile->prev_shared;
tile->prev_shared = tile;
@@ -244,7 +254,8 @@
{
if (tile->lock != 0)
{
- g_warning ("locking a tile for the second time");
+ g_print ("hm\n");
+ g_warning ("strange tile lock count: %i", tile->lock);
}
total_locks++;
@@ -260,56 +271,28 @@
}
static void
+_gegl_tile_void_pyramid (GeglTileSource *source,
+ gint x,
+ gint y,
+ gint z)
+{
+ if (z>10)
+ return;
+ gegl_tile_source_void (source, x, y, z);
+ _gegl_tile_void_pyramid (source, x/2, y/2, z+1);
+}
+
+static void
gegl_tile_void_pyramid (GeglTile *tile)
{
- /* should, to tile->tile_storage, request it's toplevel tile, and mark
- * it as dirty, to force a recomputation of it's toplevel at the
- * next subdivision request. NB: a full voiding might not be neccesary,
- * forcing a rerender of just the dirtied part might be better, more
- * similar to how it was done in horizon, this will only work with 4->1 px
- * averageing.
- */
- gint x, y, z;
-
- x = tile->storage_x;
- y = tile->storage_y;
- z = 0;/*tile->storage_z;*/
-
- for (z = 1; z < 10; z++)
+ if (tile->tile_storage &&
+ tile->z == 0) /* we only accepting voiding the base level */
{
-#if 0
- gint ver = (y % 2);
- gint hor = (x % 2);
-#endif
- x /= 2;
- y /= 2;
-
- gegl_tile_source_void (GEGL_TILE_SOURCE (tile->tile_storage), x, y, z);
-#if 0
- /* FIXME: reenable this code */
- if (!ver)
- {
- if (!hor)
- {
- gegl_tile_source_void_tl (GEGL_TILE_SOURCE (tile->tile_storage), x,y,z);
- }
- else
- {
- gegl_tile_source_void_tr (GEGL_TILE_SOURCE (tile->tile_storage), x,y,z);
- }
- }
- else
- {
- if (!hor)
- {
- gegl_tile_source_void_bl (GEGL_TILE_SOURCE (tile->tile_storage), x,y,z);
- }
- else
- {
- gegl_tile_source_void_br (GEGL_TILE_SOURCE (tile->tile_storage), x,y,z);
- }
- }
-#endif
+ _gegl_tile_void_pyramid (GEGL_TILE_SOURCE (tile->tile_storage),
+ tile->x/2,
+ tile->y/2,
+ tile->z+1);
+ return;
}
}
@@ -326,8 +309,9 @@
tile->z == 0)
{
gegl_tile_void_pyramid (tile);
- tile->rev++;
}
+ if (tile->lock==0)
+ tile->rev++;
#if ENABLE_MP
g_mutex_unlock (tile->mutex);
#endif
@@ -345,9 +329,8 @@
{
tile->stored_rev = tile->rev;
tile->tile_storage = NULL;
- /* FIXME: make sure the tile is evicted from any tile_storage/buffer caches
- * as well
- */
+ if (tile->z==0)
+ gegl_tile_void_pyramid (tile);
}
void
@@ -356,7 +339,7 @@
{
gegl_tile_lock (dst);
- g_free (dst->data);
+ gegl_free (dst->data);
dst->data = NULL;
dst->next_shared = src->next_shared;
@@ -401,9 +384,10 @@
if (tile->tile_storage == NULL)
return FALSE;
return gegl_tile_source_set_tile (GEGL_TILE_SOURCE (tile->tile_storage),
- tile->storage_x,
- tile->storage_y,
- tile->storage_z, tile);
+ tile->x,
+ tile->y,
+ tile->z,
+ tile);
}
/* compute the tile indice of a coordinate
Modified: branches/branch_zhangjb/gegl/buffer/gegl-tile.h
==============================================================================
--- branches/branch_zhangjb/gegl/buffer/gegl-tile.h (original)
+++ branches/branch_zhangjb/gegl/buffer/gegl-tile.h Sat May 17 17:51:59 2008
@@ -35,42 +35,33 @@
*/
struct _GeglTile
{
- GObject parent_instance;
+ GObject parent_instance;
- guchar *data; /* A small linear buffer for pixel data */
- gint size; /* The size of the data element in bytes */
+ guchar *data; /* actual pixel data for tile, a linear buffer*/
+ gint size; /* The size of the linear buffer */
- GeglTileStorage *tile_storage; /* the buffer from which this tile was retrieved
- * needed for the tile to be able to store itself
- * back when it is unreffed for the last time
- */
- gint storage_x, storage_y, storage_z;
- gint x, y, z;
-
-
- guint rev; /* this tile revision */
- guint stored_rev; /* what revision was we when we from tile_storage?
- (currently set to 1 when loaded from disk */
-
- guint flags; /* used to store zoom dirt info */
-
- gchar lock; /* number of times the tile is write locked
- * should in theory just have the values 0/1
- */
+ 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
+ * unreffed for the last time)
+ */
+ gint x, y, z;
+
+
+ guint rev; /* this tile revision */
+ guint stored_rev; /* what revision was we when we from tile_storage?
+ (currently set to 1 when loaded from disk */
+
+ gchar lock; /* number of times the tile is write locked
+ * should in theory just have the values 0/1
+ */
#if ENABLE_MP
- GMutex *mutex;
+ GMutex *mutex;
#endif
/* the shared list is a doubly linked circular list */
- GeglTile *next_shared;
- GeglTile *prev_shared;
-};
-
-enum {
- GEGL_TILE_DIRT_TL = 1<<0,
- GEGL_TILE_DIRT_TR = 1<<1,
- GEGL_TILE_DIRT_BL = 1<<2,
- GEGL_TILE_DIRT_BR = 1<<3
+ GeglTile *next_shared;
+ GeglTile *prev_shared;
};
struct _GeglTileClass
@@ -78,25 +69,44 @@
GObjectClass parent_class;
};
-GType gegl_tile_get_type (void) G_GNUC_CONST;
+GType gegl_tile_get_type (void) G_GNUC_CONST;
+
+GeglTile * gegl_tile_new (gint size);
+void * gegl_tile_get_format (GeglTile *tile);
+
+
+/* lock a tile for writing, this would allow writing to buffers
+ * later gotten with get_data()
+ */
+void gegl_tile_lock (GeglTile *tile);
+/* get a pointer to the linear buffer of the tile.
+ */
+guchar * gegl_tile_get_data (GeglTile *tile);
+/* unlock the tile notifying the tile that we're done manipulating
+ * the data.
+ */
+void gegl_tile_unlock (GeglTile *tile);
+
+
+
+gboolean gegl_tile_is_stored (GeglTile *tile);
+gboolean gegl_tile_store (GeglTile *tile);
+void gegl_tile_void (GeglTile *tile);
+GeglTile *gegl_tile_dup (GeglTile *tile);
+
+
+/* helper functions to compute tile indices and offsets for coordinates
+ * based on a tile stride (tile_width or tile_height)
+ */
+gint gegl_tile_indice (gint coordinate,
+ gint stride);
+gint gegl_tile_offset (gint coordinate,
+ gint stride);
-GeglTile * gegl_tile_new (gint size);
-guchar * gegl_tile_get_data (GeglTile *tile);
-void * gegl_tile_get_format (GeglTile *tile);
-void gegl_tile_lock (GeglTile *tile);
-void gegl_tile_unlock (GeglTile *tile);
-gboolean gegl_tile_is_stored (GeglTile *tile);
-gboolean gegl_tile_store (GeglTile *tile);
-void gegl_tile_void (GeglTile *tile);
-GeglTile *gegl_tile_dup (GeglTile *tile);
/* utility low-level functions used by undo system */
-void gegl_tile_swp (GeglTile *a,
- GeglTile *b);
-void gegl_tile_cpy (GeglTile *src,
- GeglTile *dst);
-gint gegl_tile_indice (gint coordinate,
- gint stride);
-gint gegl_tile_offset (gint coordinate,
- gint stride);
+void gegl_tile_swp (GeglTile *a,
+ GeglTile *b);
+void gegl_tile_cpy (GeglTile *src,
+ GeglTile *dst);
#endif
Modified: branches/branch_zhangjb/gegl/gegl-chant.h
==============================================================================
--- branches/branch_zhangjb/gegl/gegl-chant.h (original)
+++ branches/branch_zhangjb/gegl/gegl-chant.h Sat May 17 17:51:59 2008
@@ -493,7 +493,7 @@
} \
properties->name = g_value_dup_object (value); \
g_signal_connect (G_OBJECT (properties->name), "changed", \
- G_CALLBACK(gegl_operation_vector_prop_changed), self); \
+ G_CALLBACK(gegl_operation_vector_prop_changed), gobject); \
break; /*XXX*/
#include GEGL_CHANT_C_FILE
Modified: branches/branch_zhangjb/gegl/gegl-config.c
==============================================================================
--- branches/branch_zhangjb/gegl/gegl-config.c (original)
+++ branches/branch_zhangjb/gegl/gegl-config.c Sat May 17 17:51:59 2008
@@ -31,7 +31,8 @@
PROP_QUALITY,
PROP_CACHE_SIZE,
PROP_SWAP,
- PROP_BABL_ERROR
+ PROP_BABL_ERROR,
+ PROP_NODE_CACHES
};
static void
@@ -60,6 +61,10 @@
g_value_set_string (value, config->swap);
break;
+ case PROP_NODE_CACHES:
+ g_value_set_boolean (value, config->node_caches);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
@@ -88,8 +93,9 @@
config->babl_error = g_value_get_double (value);
g_sprintf (buf, "%f", config->babl_error);
g_setenv ("BABL_ERROR", buf, 0);
- /* babl picks up the babl error through the environment,
- * not sure if it is cached or not
+ /* babl picks up the babl error through the environment, babl
+ * caches valid conversions though so this needs to be set
+ * before any processing is done
*/
}
return;
@@ -98,7 +104,9 @@
g_free (config->swap);
config->swap = g_value_dup_string (value);
break;
-
+ case PROP_NODE_CACHES:
+ config->node_caches = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
@@ -127,6 +135,10 @@
gobject_class->get_property = get_property;
gobject_class->finalize = finalize;
+ g_object_class_install_property (gobject_class, PROP_NODE_CACHES,
+ g_param_spec_boolean ("node-caches", "Node caches", "Whether GEGL caches the results at each node in the graph.", TRUE,
+ G_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class, PROP_CACHE_SIZE,
g_param_spec_double ("cachei-size", "Cache size", "size of cache in bytes",
0.0, 1.0, 1.0,
@@ -153,4 +165,5 @@
self->swap = NULL;
self->quality = 1.0;
self->cache_size = 256*1024*1024;
+ self->node_caches = TRUE;
}
Modified: branches/branch_zhangjb/gegl/gegl-config.h
==============================================================================
--- branches/branch_zhangjb/gegl/gegl-config.h (original)
+++ branches/branch_zhangjb/gegl/gegl-config.h Sat May 17 17:51:59 2008
@@ -36,12 +36,13 @@
struct _GeglConfig
{
- GObject parent_instance;
+ GObject parent_instance;
- gchar *swap;
- gint cache_size;
- gdouble quality;
- gdouble babl_error;
+ gchar *swap;
+ gint cache_size;
+ gdouble quality;
+ gdouble babl_error;
+ gboolean node_caches;
};
struct _GeglConfigClass
@@ -49,7 +50,6 @@
GObjectClass parent_class;
};
-
GType gegl_config_get_type (void) G_GNUC_CONST;
#ifndef __GEGL_INIT_H__
GeglConfig * gegl_config (void);
Modified: branches/branch_zhangjb/gegl/gegl-init.c
==============================================================================
--- branches/branch_zhangjb/gegl/gegl-init.c (original)
+++ branches/branch_zhangjb/gegl/gegl-init.c Sat May 17 17:51:59 2008
@@ -164,6 +164,7 @@
static gchar *cmd_gegl_cache_size=NULL;
static gchar *cmd_gegl_quality=NULL;
static gchar *cmd_babl_error=NULL;
+static gboolean cmd_no_node_caches=FALSE;
static const GOptionEntry cmd_entries[]=
{
@@ -183,6 +184,11 @@
N_("How much memory to (approximately) use for caching imagery"), "<megabytes>"
},
{
+ "gegl-no-node-caches", 0, 0,
+ G_OPTION_ARG_NONE, &cmd_no_node_caches,
+ N_("Don't use per node caches to speed up _re_evaluation of the graph"),
+ },
+ {
"gegl-quality", 0, 0,
G_OPTION_ARG_STRING, &cmd_gegl_quality,
N_("The quality of rendering a value between 0.0(fast) and 1.0(reference)"), "<quality>"
@@ -350,7 +356,9 @@
if (g_getenv ("GEGL_CACHE_SIZE"))
config->cache_size = atoi(g_getenv("GEGL_CACHE_SIZE"))* 1024*1024;
-
+ config->node_caches = !cmd_no_node_caches;
+ if (g_getenv ("GEGL_NO_NODE_CACHES"))
+ g_object_set (config, "node-caches", FALSE, NULL);
if (gegl_swap_dir())
config->swap = g_strdup(gegl_swap_dir ());
if (cmd_gegl_swap)
Modified: branches/branch_zhangjb/gegl/gegl.h.in
==============================================================================
--- branches/branch_zhangjb/gegl/gegl.h.in (original)
+++ branches/branch_zhangjb/gegl/gegl.h.in Sat May 17 17:51:59 2008
@@ -820,6 +820,16 @@
*/
void gegl_processor_destroy (GeglProcessor *processor);
+/**
+ * gegl_config:
+ *
+ * Returns a GObject with properties that can be manipulated to control
+ * GEGLs behavior. Properties available on the object are:
+ *
+ * "cache-size" "quality" and "swap", the two first is an integer denoting
+ * number of bytes, the secons a double value between 0 and 1 and the last
+ * the path of the directory to swap to (or "ram" to not use diskbased swap)
+ */
GObject * gegl_config (void);
Modified: branches/branch_zhangjb/gegl/graph/gegl-node-context.c
==============================================================================
--- branches/branch_zhangjb/gegl/graph/gegl-node-context.c (original)
+++ branches/branch_zhangjb/gegl/graph/gegl-node-context.c Sat May 17 17:51:59 2008
@@ -30,6 +30,7 @@
#include "gegl-node-context.h"
#include "gegl-node.h"
#include "gegl-pad.h"
+#include "gegl-config.h"
#include "operation/gegl-operation.h"
@@ -272,9 +273,12 @@
node = context->node;
operation = node->operation;
pspec = gegl_node_find_property (node, padname);
- g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
- g_value_set_object (&value, data);
- gegl_node_context_set_property (context, padname, &value);
+ if (pspec)
+ {
+ g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_value_set_object (&value, data);
+ gegl_node_context_set_property (context, padname, &value);
+ }
g_value_unset (&value);
g_object_unref (data); /* are we stealing the initial reference? */
}
@@ -337,20 +341,18 @@
result = &context->result_rect;
-#if 1 /* change to 0 to disable per node caches */
- if (GEGL_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation))->no_cache)
+ if (gegl_config()->node_caches &&
+ node->dont_cache == FALSE &&
+ ! GEGL_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation))->no_cache)
{
- output = gegl_buffer_new (result, format);
+ GeglBuffer *cache;
+ cache = GEGL_BUFFER (gegl_node_get_cache (node));
+ output = gegl_buffer_create_sub_buffer (cache, result);
}
else
{
- GeglBuffer *cache;
- cache = GEGL_BUFFER (gegl_node_get_cache (node));
- output = gegl_buffer_create_sub_buffer (cache, result);
- }
-#else
- output = gegl_buffer_new (result, format);
-#endif
+ output = gegl_buffer_new (result, format);
+ }
gegl_node_context_set_object (context, padname, G_OBJECT (output));
return output;
Modified: branches/branch_zhangjb/gegl/graph/gegl-node.c
==============================================================================
--- branches/branch_zhangjb/gegl/graph/gegl-node.c (original)
+++ branches/branch_zhangjb/gegl/graph/gegl-node.c Sat May 17 17:51:59 2008
@@ -53,7 +53,8 @@
PROP_0,
PROP_OP_CLASS,
PROP_OPERATION,
- PROP_NAME
+ PROP_NAME,
+ PROP_DONT_CACHE
};
enum
@@ -149,6 +150,14 @@
G_PARAM_CONSTRUCT |
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_DONT_CACHE,
+ g_param_spec_boolean ("dont-cache",
+ "Do not cache",
+ "Do not cache the result of this operation, the property is inherithed by children created from a node.",
+ TRUE,
+ G_PARAM_READWRITE));
+
+
g_object_class_install_property (gobject_class, PROP_NAME,
g_param_spec_string ("name",
"Name",
@@ -303,6 +312,10 @@
gegl_node_set_name (node, g_value_get_string (value));
break;
+ case PROP_DONT_CACHE:
+ node->dont_cache = g_value_get_boolean (value);
+ break;
+
case PROP_OP_CLASS:
gegl_node_set_op_class (node, g_value_get_string (value), NULL, NULL);
break;
@@ -332,6 +345,9 @@
g_value_set_string (value, GEGL_OPERATION_GET_CLASS (node->operation)->name);
break;
+ case PROP_DONT_CACHE:
+ g_value_set_boolean (value, node->dont_cache);
+ break;
case PROP_NAME:
g_value_set_string (value, gegl_node_get_name (node));
break;
@@ -1898,6 +1914,8 @@
self->is_graph = TRUE;
child_priv->parent = self;
+ child->dont_cache = self->dont_cache;
+
return child;
}
@@ -2027,7 +2045,9 @@
node = g_object_new (GEGL_TYPE_NODE, NULL);
if (parent)
- gegl_node_add_child (parent, node);
+ {
+ gegl_node_add_child (parent, node);
+ }
name = first_property_name;
va_start (var_args, first_property_name);
@@ -2043,9 +2063,15 @@
gegl_node_create_child (GeglNode *self,
const gchar *operation)
{
+ GeglNode *ret;
g_return_val_if_fail (operation != NULL, NULL);
- return gegl_node_new_child (self, "operation", operation, NULL);
+ ret = gegl_node_new_child (self, "operation", operation, NULL);
+ if (ret && self)
+ {
+ ret->dont_cache = self->dont_cache;
+ }
+ return ret;
}
static void
Modified: branches/branch_zhangjb/gegl/graph/gegl-node.h
==============================================================================
--- branches/branch_zhangjb/gegl/graph/gegl-node.h (original)
+++ branches/branch_zhangjb/gegl/graph/gegl-node.h Sat May 17 17:51:59 2008
@@ -63,6 +63,8 @@
reused for all subsequent requests for the cache
object.*/
+ gboolean dont_cache; /* whether result is cached or not, inherited
+ by children */
GMutex *mutex;
/*< private >*/
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-area-filter.h
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-area-filter.h (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-area-filter.h Sat May 17 17:51:59 2008
@@ -35,7 +35,7 @@
{
GeglOperationFilter parent_instance;
- gint left;
+ gint left; /* extra pixels needed in each direction */
gint right;
gint top;
gint bottom;
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-filter.h
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-filter.h (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-filter.h Sat May 17 17:51:59 2008
@@ -44,7 +44,7 @@
gboolean (* process) (GeglOperation *self,
GeglBuffer *input,
GeglBuffer *output,
- const GeglRectangle *result);
+ const GeglRectangle *roi);
};
GType gegl_operation_filter_get_type (void) G_GNUC_CONST;
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-point-filter.c
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-point-filter.c (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-point-filter.c Sat May 17 17:51:59 2008
@@ -28,6 +28,9 @@
#include "gegl-utils.h"
#include <string.h>
+#include "gegl-buffer-private.h"
+#include "gegl-tile-storage.h"
+
static gboolean process_inner (GeglOperation *operation,
GeglBuffer *input,
GeglBuffer *output,
@@ -56,6 +59,7 @@
{
}
+
static gboolean
process_inner (GeglOperation *operation,
GeglBuffer *input,
@@ -65,6 +69,9 @@
GeglPad *pad;
const Babl *in_format;
const Babl *out_format;
+ GeglOperationPointFilterClass *point_filter_class;
+
+ point_filter_class = GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation);
pad = gegl_node_get_pad (operation->node, "input");
in_format = gegl_pad_get_format (pad);
@@ -84,33 +91,99 @@
if ((result->width > 0) && (result->height > 0))
{
- /* eek: this fails,..
- if (!(input->width == output->width &&
- input->height == output->height))
+ if (gegl_buffer_scan_compatible (input, output))
+ /* We can use the fastest possible path with the least possible
+ * copies using paralell scan iteratator with possibly direct
+ * read write access to buffers.
+ */
{
- g_warning ("%ix%i -> %ix%i", input->width, input->height, output->width, output->height);
- }
- g_assert (input->width == output->width &&
- input->height == output->height);
- */
- if (in_format == out_format)
- {
- gfloat *buf;
- buf = gegl_malloc (in_format->format.bytes_per_pixel *
- output->extent.width * output->extent.height);
-
- gegl_buffer_get (input, 1.0, result, in_format, buf, GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation)->process (
- operation,
- buf,
- buf,
- output->extent.width * output->extent.height);
-
- gegl_buffer_set (output, result, out_format, buf, GEGL_AUTO_ROWSTRIDE);
- gegl_free (buf);
+ gint input_bpp = in_format->format.bytes_per_pixel;
+ gint output_bpp = output->format->format.bytes_per_pixel;
+ gpointer *in_buf = NULL;
+ gpointer *out_buf = NULL;
+ Babl *infish;
+ Babl *outfish;
+
+ GeglBufferScanIterator read;
+ GeglBufferScanIterator write;
+ gegl_buffer_scan_iterator_init (&read, input, *result, FALSE);
+ gegl_buffer_scan_iterator_init (&write, output, *result, TRUE);
+
+ g_assert (input->tile_storage->tile_width == output->tile_storage->tile_width);
+
+
+ infish = babl_fish (input->format, in_format);
+ outfish = babl_fish (out_format, output->format);
+
+ gegl_buffer_lock (output);
+ {
+ gboolean a = FALSE, b = FALSE;
+ if (in_format == input->format &&
+ out_format == output->format)
+ {
+ while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
+ (b = gegl_buffer_scan_iterator_next (&write)))
+ {
+ g_assert (read.width == write.width);
+ point_filter_class->process (operation, read.data, write.data, write.width);
+ }
+ }
+ else if (in_format == input->format &&
+ out_format != output->format)
+ {
+ out_buf = gegl_malloc (output_bpp * write.max_size);
+ while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
+ (b = gegl_buffer_scan_iterator_next (&write)))
+ {
+ g_assert (read.width == write.width);
+ point_filter_class->process (operation, read.data, out_buf, read.width);
+ babl_process (outfish, out_buf, write.data, write.width);
+ }
+ }
+ else if (in_format != input->format &&
+ out_format == output->format)
+ {
+ in_buf = gegl_malloc (input_bpp * read.max_size);
+ while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
+ (b = gegl_buffer_scan_iterator_next (&write)))
+ {
+ if (read.width < 0)
+ continue;
+ g_assert (read.width == write.width);
+ babl_process (infish, read.data, in_buf, read.width);
+ point_filter_class->process (operation, in_buf, write.data, read.width);
+ }
+ }
+ else if (in_format != input->format &&
+ out_format != output->format)
+ {
+ in_buf = gegl_malloc (input_bpp * read.max_size);
+ out_buf = gegl_malloc (output_bpp * write.max_size);
+ while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
+ (b = gegl_buffer_scan_iterator_next (&write)))
+ {
+ g_assert (read.width == write.width);
+ babl_process (infish, read.data, in_buf, read.width);
+ point_filter_class->process (operation, in_buf, out_buf, read.width);
+ babl_process (outfish, out_buf, write.data, write.width);
+ }
+ }
+
+ if (a)
+ while (gegl_buffer_scan_iterator_next (&read));
+ if (b)
+ while (gegl_buffer_scan_iterator_next (&write));
+ }
+
+ if (in_buf)
+ gegl_free (in_buf);
+ if (out_buf)
+ gegl_free (out_buf);
+ gegl_buffer_unlock (output);
}
+#if 0
else
+ /* do the entire buffer */
{
gfloat *in_buf;
gfloat *out_buf;
@@ -130,7 +203,42 @@
gegl_buffer_set (output, result, out_format, out_buf, GEGL_AUTO_ROWSTRIDE);
gegl_free (in_buf);
gegl_free (out_buf);
+#else
+ else
+ /* do it in vertical chunks of 32 scanlines */
+ {
+ gfloat *in_buf;
+ GeglRectangle roi;
+ gint skip = 32;
+ gfloat *out_buf;
+ in_buf = gegl_malloc (in_format->format.bytes_per_pixel * result->width * skip);
+ out_buf = gegl_malloc (out_format->format.bytes_per_pixel * result->width * skip);
+
+
+ roi = *result;
+ while (roi.y < result->y + result->height && skip >0 )
+ {
+ for (roi.height=skip; (roi.y + skip <= result->y + result->height);
+ roi.y+=skip)
+ {
+ gegl_buffer_get (input, 1.0, &roi, in_format, in_buf, GEGL_AUTO_ROWSTRIDE);
+
+ GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation)->process (
+ operation,
+ in_buf,
+ out_buf,
+ result->width * skip);
+
+ gegl_buffer_set (output, &roi, out_format, out_buf, GEGL_AUTO_ROWSTRIDE);
+ }
+ skip /= 2;
+ }
+
+
+ gegl_free (in_buf);
+ gegl_free (out_buf);
}
+#endif
}
return TRUE;
}
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-processors.c
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-processors.c (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-processors.c Sat May 17 17:51:59 2008
@@ -48,16 +48,12 @@
#include <glib/gprintf.h>
-/* FIXME:
- *
- * pick the correct processor at runtime rather than at class init time
- * to allow the gegl_config request to override the initial conditions
- */
-
typedef struct VFuncData
{
GCallback callback[MAX_PROCESSOR];
gchar *string[MAX_PROCESSOR];
+ gdouble cached_quality;
+ gint cached;
} VFuncData;
void
@@ -66,6 +62,85 @@
GCallback process,
const gchar *string);
+/* this dispatcher allows overriding a callback without checking how many parameters
+ * are passed and how many parameters are needed, hopefully in a compiler/archi
+ * portable manner.
+ */
+static void
+dispatch (GObject *object,
+ gpointer arg1,
+ gpointer arg2,
+ gpointer arg3,
+ gpointer arg4,
+ gpointer arg5,
+ gpointer arg6,
+ gpointer arg7,
+ gpointer arg8,
+ gpointer arg9)
+{
+ void (*dispatch) (GObject *object,
+ gpointer arg1,
+ gpointer arg2,
+ gpointer arg3,
+ gpointer arg4,
+ gpointer arg5,
+ gpointer arg6,
+ gpointer arg7,
+ gpointer arg8,
+ gpointer arg9)=NULL;
+ VFuncData *data;
+ gint fast = 0;
+ gint good = 0;
+ gint reference = 0;
+ gint simd = 0;
+ gint i;
+ gint choice;
+
+
+ data = g_type_get_qdata (G_OBJECT_TYPE(object),
+ g_quark_from_string("dispatch-data"));
+ if (!data)
+ {
+ g_error ("dispatch called on object without dispatch-data");
+ }
+
+ if (gegl_config()->quality == data->cached_quality)
+ {
+ dispatch = (void*)data->callback[data->cached];
+ dispatch (object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+ return;
+ }
+
+ for (i=0;i<MAX_PROCESSOR;i++)
+ {
+ const gchar *string = data->string[i];
+ GCallback cb = data->callback[i];
+
+ if (string && cb!=NULL)
+ {
+ if (g_str_equal (string, "fast")) fast = i;
+ if (g_str_equal (string, "simd")) simd = i;
+ else if (g_str_equal (string, "good")) good = i;
+ else if (g_str_equal (string, "reference"))
+ reference = i;
+ }
+ }
+ reference = 0;
+ g_assert (data->callback[reference]);
+
+ choice = reference;
+ if (gegl_config()->quality <= 1.0 && simd) choice = simd;
+ if (gegl_config()->quality <= 0.75 && good) choice = good;
+ if (gegl_config()->quality <= 0.25 && fast) choice = fast;
+
+ GEGL_NOTE(PROCESSOR, "Using %s implementation for %s", data->string[choice], g_type_name (G_OBJECT_TYPE(object)));
+
+ data->cached = choice;
+ data->cached_quality = gegl_config()->quality;
+ dispatch = (void*)data->callback[data->cached];
+ dispatch (object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+}
+
void
gegl_class_register_alternate_vfunc (GObjectClass *cclass,
gpointer vfunc_ptr2,
@@ -85,7 +160,9 @@
if (!data)
{
data = g_new0 (VFuncData, 1);
+ data->cached_quality = -1.0;
g_type_set_qdata (type, quark, data);
+ g_type_set_qdata (type, g_quark_from_string("dispatch-data"), data);
}
/* Store the default implementation */
@@ -94,15 +171,21 @@
if (*vfunc_ptr == NULL)
g_error ("%s: No existing default () vfunc defined for %s",
G_STRFUNC, g_type_name (type));
- data->callback[0]=callback;
+ data->callback[0]=*vfunc_ptr;
data->string[0]=g_strdup ("reference");
}
-
+ *vfunc_ptr = (void*)dispatch; /* make our bootstrap replacement for the
+ * reference implementation take over
+ * dispatching of arguments, not sure if
+ * this is portable C or not.
+ */
+
/* Find a free slot for this one */
for (i=1; i<MAX_PROCESSOR; i++)
{
if (data->callback[i]==NULL)
{
+ /* store the callback and it's given name */
data->callback[i]=callback;
data->string[i]=g_strdup (string);
break;
@@ -113,50 +196,6 @@
g_warning ("Too many callbacks added to %s",
g_type_name (G_TYPE_FROM_CLASS (cclass)));
}
-
- {
- gint fast = 0;
- gint good = 0;
- gint reference = 0;
- gint g4f = 0;
-
- gint choice = 0;
-
- for (i=0;i<MAX_PROCESSOR;i++)
- {
- const gchar *string = data->string[i];
- GCallback cb = data->callback[i];
-
- if (string && cb!=NULL)
- {
- if (g_str_equal (string, "fast"))
- fast = i;
- if (g_str_equal (string, "g4float"))
- g4f = i;
- else if (g_str_equal (string, "good"))
- good = i;
- else if (g_str_equal (string, "reference"))
- reference = i;
- }
- }
- reference = 0;
- g_assert (data->callback[reference]);
-
- if (gegl_config()->quality <= 0.5)
- {
- if (good) choice = good;
- if (g4f) choice = g4f;
- }
- if (gegl_config()->quality <= 0.2)
- {
- if (good) choice = good;
- if (g4f) choice = g4f;
- if (fast) choice = fast;
- }
-
- GEGL_NOTE(PROCESSOR, "Using %s implementation for %s", data->string[choice], g_type_name (G_TYPE_FROM_CLASS (cclass)));
- *vfunc_ptr = data->callback[choice];
- }
}
void
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-sink.h
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-sink.h (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-sink.h Sat May 17 17:51:59 2008
@@ -45,7 +45,7 @@
gboolean (* process) (GeglOperation *self,
GeglBuffer *input,
- const GeglRectangle *result);
+ const GeglRectangle *roi);
};
GType gegl_operation_sink_get_type (void) G_GNUC_CONST;
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation-source.h
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation-source.h (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation-source.h Sat May 17 17:51:59 2008
@@ -43,7 +43,7 @@
gboolean (* process) (GeglOperation *self,
GeglBuffer *output,
- const GeglRectangle *result);
+ const GeglRectangle *roi);
};
GType gegl_operation_source_get_type (void) G_GNUC_CONST;
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation.c
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation.c (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation.c Sat May 17 17:51:59 2008
@@ -406,3 +406,18 @@
return pad->format;
}
+
+void
+gegl_operation_invalidate (GeglOperation *operation,
+ const GeglRectangle *roi)
+{
+ GeglNode *node = NULL;
+
+ if (!operation)
+ return;
+
+ g_return_if_fail (GEGL_IS_OPERATION (operation));
+ node = operation->node;
+
+ gegl_node_invalidated (node, roi);
+}
Modified: branches/branch_zhangjb/gegl/operation/gegl-operation.h
==============================================================================
--- branches/branch_zhangjb/gegl/operation/gegl-operation.h (original)
+++ branches/branch_zhangjb/gegl/operation/gegl-operation.h Sat May 17 17:51:59 2008
@@ -138,15 +138,10 @@
GeglNode* (*detect) (GeglOperation *operation,
gint x,
gint y);
-
-
- GCallback processor[MAX_PROCESSOR];
- gchar *processor_string[MAX_PROCESSOR];
};
-
GType gegl_operation_get_type (void) G_GNUC_CONST;
GeglRectangle gegl_operation_get_invalidated_by_change
@@ -217,10 +212,12 @@
/* internal utility functions used by gegl, these should not be used
* externally */
-gboolean gegl_operation_calc_source_regions (GeglOperation *operation,
- gpointer context_id);
-void gegl_operation_vector_prop_changed (GeglVector *vector,
- GeglOperation *operation);
+gboolean gegl_operation_calc_source_regions (GeglOperation *operation,
+ gpointer context_id);
+void gegl_operation_vector_prop_changed (GeglVector *vector,
+ GeglOperation *operation);
+void gegl_operation_invalidate (GeglOperation *operation,
+ const GeglRectangle *roi);
G_END_DECLS
Modified: branches/branch_zhangjb/gegl/property-types/Makefile.am
==============================================================================
--- branches/branch_zhangjb/gegl/property-types/Makefile.am (original)
+++ branches/branch_zhangjb/gegl/property-types/Makefile.am Sat May 17 17:51:59 2008
@@ -19,5 +19,6 @@
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/gegl \
+ -I$(top_srcdir)/gegl/buffer \
@DEP_CFLAGS@ @BABL_CFLAGS@
Modified: branches/branch_zhangjb/gegl/property-types/gegl-color.c
==============================================================================
--- branches/branch_zhangjb/gegl/property-types/gegl-color.c (original)
+++ branches/branch_zhangjb/gegl/property-types/gegl-color.c Sat May 17 17:51:59 2008
@@ -249,6 +249,15 @@
return FALSE;
}
+const gfloat *
+gegl_color_float4 (GeglColor *self)
+{
+ GeglColorPrivate *priv;
+ /*g_return_val_if_fail (GEGL_IS_COLOR (self), NULL);*/
+ priv = GEGL_COLOR_GET_PRIVATE (self);
+ return &priv->rgba_color[0];
+}
+
void
gegl_color_get_rgba (GeglColor *self,
gfloat *r,
Modified: branches/branch_zhangjb/gegl/property-types/gegl-color.h
==============================================================================
--- branches/branch_zhangjb/gegl/property-types/gegl-color.h (original)
+++ branches/branch_zhangjb/gegl/property-types/gegl-color.h Sat May 17 17:51:59 2008
@@ -58,6 +58,7 @@
gfloat b,
gfloat a);
+const gfloat*gegl_color_float4 (GeglColor *color);
#define GEGL_TYPE_PARAM_COLOR (gegl_param_color_get_type ())
#define GEGL_IS_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GEGL_TYPE_PARAM_COLOR))
Modified: branches/branch_zhangjb/gegl/property-types/gegl-vector.c
==============================================================================
--- branches/branch_zhangjb/gegl/property-types/gegl-vector.c (original)
+++ branches/branch_zhangjb/gegl/property-types/gegl-vector.c Sat May 17 17:51:59 2008
@@ -13,8 +13,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
+ * Copyright 2008 Ãyvind KolÃs <pippin gimp org>
* Copyright 2006 Mark Probst <mark probst gmail com>
- * Spline Code Copyright 1997 David Mosberger
*/
#include "config.h"
@@ -25,7 +25,11 @@
#include "gegl-types.h"
+#include "gegl-buffer-private.h"
#include "gegl-vector.h"
+#include "gegl-color.h"
+
+
/* ###################################################################### */
/* path code copied from horizon */
@@ -50,8 +54,8 @@
typedef struct Point
{
- gint x;
- gint y;
+ gfloat x;
+ gfloat y;
} Point;
struct _Path
@@ -61,45 +65,71 @@
gchar type;
};
+
+
typedef struct _Path Head;
+typedef struct _GeglVectorPrivate GeglVectorPrivate;
+typedef struct _VectorNameEntity VectorNameEntity;
+
+struct _GeglVectorPrivate
+{
+ Path *path;
+
+ Path *axis[8];
+ gint n_axes;
+};
+
+enum
+{
+ PROP_0,
+};
+
+
+enum
+{
+ GEGL_VECTOR_CHANGED,
+ GEGL_VECTOR_LAST_SIGNAL
+};
+
+guint gegl_vector_signals[GEGL_VECTOR_LAST_SIGNAL] = { 0 };
+
-/*** fixed point subdivision bezier ***/
+static void finalize (GObject *self);
+static void set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+G_DEFINE_TYPE (GeglVector, gegl_vector, G_TYPE_OBJECT);
+
+#define GEGL_VECTOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),\
+ GEGL_TYPE_VECTOR, GeglVectorPrivate))
+
+
+/*** subdivision bezier approximation: ***/
/* linear interpolation between two point */
static void
lerp (Point *dest,
Point *a,
Point *b,
- gint t)
-{
- dest->x = a->x + (b->x-a->x) * t / 65536;
- dest->y = a->y + (b->y-a->y) * t / 65536;
-}
-
-#define iter1(N) \
- try = root + (1 << (N)); \
- if (n >= try << (N)) \
- { n -= try << (N); \
- root |= 2 << (N); \
- }
-
-static inline guint isqrt (guint n)
+ gfloat t)
{
- guint root = 0, try;
- iter1 (15); iter1 (14); iter1 (13); iter1 (12);
- iter1 (11); iter1 (10); iter1 ( 9); iter1 ( 8);
- iter1 ( 7); iter1 ( 6); iter1 ( 5); iter1 ( 4);
- iter1 ( 3); iter1 ( 2); iter1 ( 1); iter1 ( 0);
- return root >> 1;
+ dest->x = a->x + (b->x-a->x) * t;
+ dest->y = a->y + (b->y-a->y) * t;
}
-static gint
+static gfloat
point_dist (Point *a,
Point *b)
{
- return isqrt ((a->x-b->x)*(a->x-b->x) +
- (a->y-b->y)*(a->y-b->y));
+ return sqrt ((a->x-b->x)*(a->x-b->x) +
+ (a->y-b->y)*(a->y-b->y));
}
@@ -111,7 +141,7 @@
static void
bezier (Point **curve,
Point *dest,
- gint t)
+ gfloat t)
{
Point ab,bc,cd,abbc,bccd;
@@ -123,8 +153,8 @@
lerp (dest, &abbc, &bccd, t);
}
-
-gint
+#if 0
+static gint
path_last_x (Path *path)
{
if (path)
@@ -132,13 +162,14 @@
return 0;
}
-gint
+static gint
path_last_y (Path *path)
{
if (path)
return path->point.y;
return 0;
}
+#endif
/* types:
* 'u' : unitilitlalized state
@@ -151,10 +182,10 @@
*/
static Path *
-path_add (Path *head,
- gchar type,
- gint x,
- gint y)
+path_add (Path *head,
+ gchar type,
+ gfloat x,
+ gfloat y)
{
Path *iter = head;
Path *prev = NULL;
@@ -260,8 +291,9 @@
/* chop off unneeded elements */
curve[0]->next = NULL;
- { /* create piecevize linear approximation of bezier curve */
+ { /* create piecevise linear approximation of bezier curve */
gint i;
+ gfloat f;
Point foo[4];
Point *pts[4];
@@ -272,11 +304,11 @@
pts[i]->y = curve[i]->point.y;
}
- for (i=0;i<65536;i+=65536 / BEZIER_SEGMENTS)
+ for (f=0; f<1.0; f += 1.0 / BEZIER_SEGMENTS)
{
Point iter;
- bezier (pts, &iter, i);
+ bezier (pts, &iter, f);
head = path_add (head, 'l', iter.x, iter.y);
}
@@ -303,13 +335,15 @@
return head;
}
-Path *
+#if 0
+static Path *
path_new (void)
{
return path_add (NULL, 'u', 0, 0);
}
+#endif
-Path *
+static Path *
path_destroy (Path *path)
{
g_slice_free_chain (Path, path, next);
@@ -317,32 +351,32 @@
return NULL;
}
-Path *
-path_move_to (Path *path,
- gint x,
- gint y)
+static Path *
+path_move_to (Path *path,
+ gfloat x,
+ gfloat y)
{
path = path_add (path, 'm', x, y);
return path;
}
-Path *
-path_line_to (Path *path,
- gint x,
- gint y)
+static Path *
+path_line_to (Path *path,
+ gfloat x,
+ gfloat y)
{
path = path_add (path, 'l', x, y);
return path;
}
-Path *
-path_curve_to (Path *path,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- gint x3,
- gint y3)
+static Path *
+path_curve_to (Path *path,
+ gfloat x1,
+ gfloat y1,
+ gfloat x2,
+ gfloat y2,
+ gfloat x3,
+ gfloat y3)
{
path = path_add (path, 'c', x1, y1);
path = path_add (path, '.', x2, y2);
@@ -350,30 +384,30 @@
return path;
}
-Path *
-path_rel_move_to (Path *path,
- gint x,
- gint y)
+static Path *
+path_rel_move_to (Path *path,
+ gfloat x,
+ gfloat y)
{
return path_move_to (path, path->point.x + x, path->point.y + y);
}
-Path *
-path_rel_line_to (Path *path,
- gint x,
- gint y)
+static Path *
+path_rel_line_to (Path *path,
+ gfloat x,
+ gfloat y)
{
return path_line_to (path, path->point.x + x, path->point.y + y);
}
-Path *
-path_rel_curve_to (Path *path,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- gint x3,
- gint y3)
+static Path *
+path_rel_curve_to (Path *path,
+ gfloat x1,
+ gfloat y1,
+ gfloat x2,
+ gfloat y2,
+ gfloat x3,
+ gfloat y3)
{
return path_curve_to (path,
path->point.x + x1, path->point.y + y1,
@@ -381,30 +415,271 @@
path->point.x + x3, path->point.y + y3);
}
-#if 0
+#include <gegl-buffer.h>
-/* drawing code follows */
+static gint compare_ints (gconstpointer a,
+ gconstpointer b)
+{
+ return GPOINTER_TO_INT (a)-GPOINTER_TO_INT (b);
+}
-#include "canvas/canvas.h"
-#include "brush.h"
-#include "tools/tool_library.h"
+/* speedy way of doing vectors on gegl, would be to build a runlength
+ * encoded instruction stream for fill n pixels which could be used on
+ * linear buffers.
+ */
-/* code to stroke with a specified tool */
-void
-path_stroke_tool (Path *path,
- Canvas *canvas,
- Tool *tool)
-{
- Path *iter = path;
- gint traveled_length = 0;
- gint need_to_travel = 0;
- gint x = 0,y = 0;
+void gegl_vector_fill (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gboolean winding)
+{
+ gdouble xmin, xmax, ymin, ymax;
+ GeglRectangle extent;
+ gint samples = gegl_vector_get_length (vector);
+ gegl_vector_get_bounds (vector, &xmin, &xmax, &ymin, &ymax);
+
+ extent.x = floor (xmin);
+ extent.y = floor (ymin);
+ extent.width = ceil (xmax) - extent.x;
+ extent.height = ceil (ymax) - extent.y;
+
+ {
+ GSList *scanlines[extent.height];
+
+ gdouble xs[samples];
+ gdouble ys[samples];
+
+ gint i;
+ gdouble prev_x;
+ gint prev_y;
+ gdouble first_x;
+ gint first_y;
+ gint lastline=-1;
+ gint lastdir=-2;
+
+ gegl_vector_calc_values (vector, samples, xs, ys);
+
+ /* clear scanline intersection lists */
+ for (i=0; i < extent.height; i++)
+ scanlines[i]=NULL;
+
+ first_x = prev_x = xs[0];
+ first_y = prev_y = ys[0];
+
+
+ /* saturate scanline intersection list */
+ for (i=1; i<samples; i++)
+ {
+ gint dest_x = xs[i];
+ gint dest_y = ys[i];
+ gint ydir;
+ gint dx;
+ gint dy;
+ gint y;
+fill_close: /* label used for goto to close last segment */
+ dx = dest_x - prev_x;
+ dy = dest_y - prev_y;
+
+ if (dy < 0)
+ ydir = -1;
+ else
+ ydir = 1;
+
+ /* do linear interpolation between vertexes */
+ for (y=prev_y; y!= dest_y; y += ydir)
+ {
+ if (y-extent.y >= 0 &&
+ y-extent.y < extent.height &&
+ lastline != y)
+ {
+ gint x = prev_x + (dx * (y-prev_y)) / dy;
+
+ scanlines[ y - extent.y ]=
+ g_slist_insert_sorted (scanlines[ y - extent.y],
+ GINT_TO_POINTER(x),
+ compare_ints);
+ if (ydir != lastdir &&
+ lastdir != -2)
+ scanlines[ y - extent.y ]=
+ g_slist_insert_sorted (scanlines[ y - extent.y],
+ GINT_TO_POINTER(x),
+ compare_ints);
+ lastdir = ydir;
+ lastline = y;
+ }
+ }
+
+ prev_x = dest_x;
+ prev_y = dest_y;
+
+ /* if we're on the last knot, fake the first vertex being a next one */
+ if (i+1 == samples)
+ {
+ dest_x = first_x;
+ dest_y = first_y;
+ i++; /* to make the loop finally end */
+ goto fill_close;
+ }
+ }
+
+ /* for each scanline */
+{
+ gfloat *buf = NULL;
+ const gfloat *col = gegl_color_float4 (color);
+ Babl *format = babl_format ("RGBA float");
+ buf = g_malloc (extent.width * 4 *4);
+ for (i=0; i < extent.width; i++)
+ {
+ buf[i*4+0] = col[0];
+ buf[i*4+1] = col[1];
+ buf[i*4+2] = col[2];
+ buf[i*4+3] = col[3];
+ }
+
+ if (gegl_buffer_is_shared (buffer))
+ while (!gegl_buffer_try_lock (buffer));
+ for (i=0; i < extent.height; i++)
+ {
+ GSList *iter = scanlines[i];
+ while (iter)
+ {
+ GSList *next = iter->next;
+ gint startx, endx;
+ if (!next)
+ break;
- if (!tool)
- tool = lookup_tool ("Paint");
+ startx = GPOINTER_TO_INT (iter->data);
+ endx = GPOINTER_TO_INT (next->data);
+
+ {
+ GeglRectangle roi={startx, extent.y + i, endx - startx, 1};
+ gegl_buffer_set (buffer, &roi, format, buf, 0);
+ }
+
+ iter = next->next;
+ }
+ if (scanlines[i])
+ g_slist_free (scanlines[i]);
+ }
+ if (gegl_buffer_is_shared (buffer))
+ gegl_buffer_unlock (buffer);
+ g_free (buf);
+}
+ }
+
+}
+typedef struct StampStatic {
+ gboolean valid;
+ Babl *format;
+ gfloat *buf;
+ gdouble radius;
+}StampStatic;
+
+void gegl_vector_stamp (GeglBuffer *buffer,
+ gdouble x,
+ gdouble y,
+ gdouble radius,
+ gdouble hardness,
+ GeglColor *color);
+
+void gegl_vector_stamp (GeglBuffer *buffer,
+ gdouble x,
+ gdouble y,
+ gdouble radius,
+ gdouble hardness,
+ GeglColor *color)
+{
+ const gfloat *col = gegl_color_float4 (color);
+ static StampStatic s = {FALSE,}; /* XXX:
+ we will ultimately leak the last valid
+ cached brush. */
+
+ GeglRectangle roi = {floor(x-radius),
+ floor(y-radius),
+ ceil (x+radius) - floor (x-radius),
+ ceil (y+radius) - floor (y-radius)};
+
+ if (s.format == NULL)
+ s.format = babl_format ("RGBA float");
+ if (s.buf == NULL ||
+ s.radius != radius)
+ {
+ if (s.buf != NULL)
+ g_free (s.buf);
+ /* allocate a little bit more, just in case due to rounding errors and
+ * such */
+ s.buf = g_malloc (4*4* (roi.width + 2 ) * (roi.height + 2));
+ s.radius = radius;
+ s.valid = TRUE;
+ }
+ g_assert (s.buf);
+
+ gegl_buffer_get (buffer, 1.0, &roi, s.format, s.buf, 0);
+
+ {
+ gint u, v;
+ gint i=0;
+
+ gfloat radius_squared = radius * radius;
+ gfloat inner_radius_squared = (radius * hardness)*(radius * hardness);
+ gfloat soft_range = radius_squared - inner_radius_squared;
+
+ for (u= roi.x; u < roi.x + roi.width; u++)
+ for (v= roi.y; v < roi.y + roi.height ; v++)
+ {
+ gfloat o = (u-x) * (u-x) + (v-y) * (v-y);
+
+ if (o < inner_radius_squared)
+ o = col[3];
+ else if (o < radius_squared)
+ {
+ o = (1.0 - (o-inner_radius_squared) / (soft_range)) * col[3];
+ }
+ else
+ {
+ o=0.0;
+ }
+ if (o!=0.0)
+ {
+ gint c;
+ for (c=0;c<4;c++)
+ s.buf[i*4+c] = (s.buf[i*4+c] * (1.0-o) + col[c] * o);
+ /*s.buf[i*4+3] = s.buf[i*4+3] + o * (1.0-o);*/
+ }
+ i++;
+ }
+ }
+ gegl_buffer_set (buffer, &roi, s.format, s.buf, 0);
+}
+
+
+void gegl_vector_stroke (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gdouble linewidth,
+ gdouble hardness)
+{
+ GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (vector);
+ gfloat traveled_length = 0;
+ gfloat need_to_travel = 0;
+ gfloat x = 0,y = 0;
gboolean had_move_to = FALSE;
+ Path *iter = priv->path;
+ gdouble xmin, xmax, ymin, ymax;
+ GeglRectangle extent;
+
+ gegl_vector_get_bounds (vector, &xmin, &xmax, &ymin, &ymax);
+ extent.x = floor (xmin);
+ extent.y = floor (ymin);
+ extent.width = ceil (xmax) - extent.x;
+ extent.height = ceil (ymax) - extent.y;
+
+ if (gegl_buffer_is_shared (buffer))
+ while (!gegl_buffer_try_lock (buffer));
+
+ gegl_buffer_clear (buffer, &extent);
while (iter)
{
@@ -421,13 +696,13 @@
case 'l':
{
Point a,b;
- ToolSetting *ts = tool_with_brush_get_toolsetting (tool);
- gint spacing;
- gint local_pos;
- gint distance;
- gint offset;
- gint leftover;
+ gfloat spacing;
+ gfloat local_pos;
+ gfloat distance;
+ gfloat offset;
+ gfloat leftover;
+ gfloat radius = linewidth / 2.0;
a.x = x;
@@ -436,10 +711,7 @@
b.x = iter->point.x;
b.y = iter->point.y;
- spacing = ts->spacing * (ts->radius * MAX_RADIUS / 65536) / 65536;
-
- if (spacing < MIN_SPACING * SPP / 65536)
- spacing = MIN_SPACING * SPP / 65536;
+ spacing = 0.2 * radius;
distance = point_dist (&a, &b);
@@ -454,18 +726,17 @@
local_pos += spacing)
{
Point spot;
- gint ratio = 65536 * local_pos / distance;
- gint radius;
+ gfloat ratio = local_pos / distance;
+ gfloat radius = linewidth / 2;
+ /* horizon used to refetch the radius
+ * for each step from the tool, to be
+ * able to have variable line width
+ */
lerp (&spot, &a, &b, ratio);
- radius = ts->radius * MAX_RADIUS / 65536,
-
- canvas_stamp (canvas,
- spot.x, spot.y, radius,
- ts->opacity * MAX_OPACITY / 65536,
- ts->hardness,
- ts->red, ts->green, ts->blue);
+ gegl_vector_stamp (buffer,
+ spot.x, spot.y, radius, hardness, color);
traveled_length += spacing;
}
@@ -488,98 +759,11 @@
}
iter=iter->next;
}
-}
-
-extern Tool *tool_paint_new ();
-static Tool *path_tool (Path *path)
-{
- Head *head = (Head*)path;
- if (!head)
- return NULL;
- if (head->tool == NULL)
- head->tool = tool_paint_new ();
- return head->tool;
-}
-
-void
-path_set_line_width (Path *path,
- gint line_width)
-{
- ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
- ts->radius = line_width / 2;
+ if (gegl_buffer_is_shared (buffer))
+ gegl_buffer_unlock (buffer);
}
-void
-path_set_rgba (Path *path,
- gint red,
- gint green,
- gint blue,
- gint alpha)
-{
- ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
- ts->red = red;
- ts->green = green;
- ts->blue = blue;
- ts->opacity = alpha;
-}
-
-void
-path_set_hardness (Path *path,
- gint hardness)
-{
- ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
- ts->hardness = hardness;
-}
-
-void
-path_stroke (Path *path,
- Canvas *canvas)
-{
- path_stroke_tool (path, canvas, path_tool (path));
-}
-#endif
-
-/* ###################################################################### */
-
-
-
-enum
-{
- PROP_0,
-};
-
-typedef struct _GeglVectorPrivate GeglVectorPrivate;
-typedef struct _VectorNameEntity VectorNameEntity;
-
-struct _GeglVectorPrivate
-{
- Path *path;
-};
-
-enum
-{
- GEGL_VECTOR_CHANGED,
- GEGL_VECTOR_LAST_SIGNAL
-};
-
-guint gegl_vector_signals[GEGL_VECTOR_LAST_SIGNAL] = { 0 };
-
-
-static void finalize (GObject *self);
-static void set_property (GObject *gobject,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void get_property (GObject *gobject,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-G_DEFINE_TYPE (GeglVector, gegl_vector, G_TYPE_OBJECT);
-
-#define GEGL_VECTOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),\
- GEGL_TYPE_VECTOR, GeglVectorPrivate))
static void
gegl_vector_init (GeglVector *self)
@@ -623,6 +807,8 @@
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
self = NULL;
+ if (priv->path)
+ path_destroy (priv->path);
priv = NULL;
G_OBJECT_CLASS (gegl_vector_parent_class)->finalize (gobject);
@@ -679,13 +865,80 @@
gegl_vector_emit_changed (self);
}
+void
+gegl_vector_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_move_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3)
+{
+ GeglVectorPrivate *priv;
+ g_print ("foo\n");
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
+ gegl_vector_emit_changed (self);
+ g_print ("bar\n");
+}
+
+
+void
+gegl_vector_rel_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_line_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_rel_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_move_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_rel_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
+ gegl_vector_emit_changed (self);
+}
+
+
gdouble
gegl_vector_get_length (GeglVector *self)
{
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
Path *iter = priv->path;
- gint traveled_length = 0;
- gint x = 0, y = 0;
+ gfloat traveled_length = 0;
+ gfloat x = 0, y = 0;
while (iter)
{
@@ -698,7 +951,7 @@
case 'l':
{
Point a,b;
- gint distance;
+ gfloat distance;
a.x = x;
a.y = y;
@@ -769,9 +1022,9 @@
{
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
Path *iter = priv->path;
- gint traveled_length = 0;
- gint need_to_travel = 0;
- gint x = 0, y = 0;
+ gfloat traveled_length = 0;
+ gfloat need_to_travel = 0;
+ gfloat x = 0, y = 0;
gboolean had_move_to = FALSE;
@@ -791,11 +1044,11 @@
{
Point a,b;
- gint spacing;
- gint local_pos;
- gint distance;
- gint offset;
- gint leftover;
+ gfloat spacing;
+ gfloat local_pos;
+ gfloat distance;
+ gfloat offset;
+ gfloat leftover;
a.x = x;
@@ -804,7 +1057,7 @@
b.x = iter->point.x;
b.y = iter->point.y;
- spacing = 10;
+ spacing = 0.2;
distance = point_dist (&a, &b);
@@ -819,7 +1072,7 @@
local_pos += spacing)
{
Point spot;
- gint ratio = 65536 * local_pos / distance;
+ gfloat ratio = local_pos / distance;
lerp (&spot, &a, &b, ratio);
Modified: branches/branch_zhangjb/gegl/property-types/gegl-vector.h
==============================================================================
--- branches/branch_zhangjb/gegl/property-types/gegl-vector.h (original)
+++ branches/branch_zhangjb/gegl/property-types/gegl-vector.h Sat May 17 17:51:59 2008
@@ -46,6 +46,39 @@
GeglVector * gegl_vector_new (void);
+
+void gegl_vector_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3);
+
+void gegl_vector_rel_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_rel_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_rel_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3);
+
void gegl_vector_get_bounds (GeglVector *self,
gdouble *min_x,
gdouble *max_x,
@@ -54,9 +87,6 @@
gdouble gegl_vector_get_length (GeglVector *self);
-void gegl_vector_line_to (GeglVector *self,
- gdouble x,
- gdouble y);
void gegl_vector_calc (GeglVector *self,
gdouble pos,
@@ -80,6 +110,19 @@
GeglVector *default_vector,
GParamFlags flags);
+#include <gegl-buffer.h>
+
+void gegl_vector_fill (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gboolean winding);
+
+void gegl_vector_stroke (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gdouble linewidth,
+ gdouble hardness);
+
G_END_DECLS
#endif /* __GEGL_VECTOR_H__ */
Modified: branches/branch_zhangjb/operations/common/brightness-contrast.c
==============================================================================
--- branches/branch_zhangjb/operations/common/brightness-contrast.c (original)
+++ branches/branch_zhangjb/operations/common/brightness-contrast.c Sat May 17 17:51:59 2008
@@ -95,13 +95,13 @@
for (i=0; i<n_pixels; i++)
{
gint component;
- for (component=0; component<3; component++)
+ for (component=0; component <3 ; component++)
{
out_pixel[component] =
(in_pixel[component] - 0.5) * contrast + brightness + 0.5;
}
out_pixel[3] = in_pixel[3]; /* copy the alpha */
- in_pixel += 4;
+ in_pixel += 4;
out_pixel += 4;
}
return TRUE;
@@ -109,12 +109,16 @@
#ifdef HAS_G4FLOAT
+/* The compiler supports vector extensions allowing an version of
+ * the process code that produces more optimal instructions on the
+ * target platform.
+ */
static gboolean
-process_gcc_vectors (GeglOperation *op,
- void *in_buf,
- void *out_buf,
- glong samples)
+process_simd (GeglOperation *op,
+ void *in_buf,
+ void *out_buf,
+ glong samples)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (op);
g4float *in = in_buf;
@@ -126,7 +130,7 @@
g4float contrast = g4float_all(o->contrast);
g4float half = g4float_half;
- while (--samples)
+ while (samples--)
{
*out = (*in - half) * contrast + brightness;
g4floatA(*out)=g4floatA(*in);
@@ -175,7 +179,7 @@
* broken and not conforming to the reference implementation.
*/
gegl_operation_class_add_processor (operation_class,
- G_CALLBACK (process_gcc_vectors), "g4float");
+ G_CALLBACK (process_simd), "simd");
#endif
}
Modified: branches/branch_zhangjb/operations/common/invert.c
==============================================================================
--- branches/branch_zhangjb/operations/common/invert.c (original)
+++ branches/branch_zhangjb/operations/common/invert.c Sat May 17 17:51:59 2008
@@ -56,7 +56,7 @@
#ifdef HAS_G4FLOAT
static gboolean
-process_g4f (GeglOperation *op,
+process_simd (GeglOperation *op,
void *in_buf,
void *out_buf,
glong samples)
@@ -65,7 +65,7 @@
g4float *out = out_buf;
g4float one = g4float_one;
- while (--samples)
+ while (samples--)
{
gfloat a= g4float_a(*in)[3];
*out = one - *in;
@@ -96,7 +96,7 @@
#ifdef HAS_G4FLOAT
gegl_operation_class_add_processor (operation_class,
- G_CALLBACK (process_g4f), "g4float");
+ G_CALLBACK (process_simd), "simd");
#endif
}
Modified: branches/branch_zhangjb/operations/common/whitebalance.c
==============================================================================
--- branches/branch_zhangjb/operations/common/whitebalance.c (original)
+++ branches/branch_zhangjb/operations/common/whitebalance.c Sat May 17 17:51:59 2008
@@ -48,14 +48,16 @@
glong n_pixels)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (op);
- gfloat *pixel;
+ gfloat *in_pixel;
+ gfloat *out_pixel;
gfloat a_base;
gfloat a_scale;
gfloat b_base;
gfloat b_scale;
glong i;
- pixel = in_buf;
+ in_pixel = in_buf;
+ out_pixel = out_buf;
a_scale = (o->high_a_delta - o->low_a_delta);
a_base = o->low_a_delta;
@@ -64,11 +66,16 @@
for (i=0; i<n_pixels; i++)
{
- pixel[1] += pixel[0] * a_scale + a_base;
- pixel[2] += pixel[0] * b_scale + b_base;
- pixel[1] = pixel[1] * o->saturation;
- pixel[2] = pixel[2] * o->saturation;
- pixel += 4;
+ out_pixel[0] = in_pixel[0];
+ out_pixel[1] = in_pixel[1];
+ out_pixel[2] = in_pixel[2];
+ out_pixel[3] = in_pixel[3];
+ out_pixel[1] += in_pixel[0] * a_scale + a_base;
+ out_pixel[2] += in_pixel[0] * b_scale + b_base;
+ out_pixel[1] = out_pixel[1] * o->saturation;
+ out_pixel[2] = out_pixel[2] * o->saturation;
+ in_pixel += 4;
+ out_pixel += 4;
}
return TRUE;
}
Modified: branches/branch_zhangjb/operations/external/Makefile.am
==============================================================================
--- branches/branch_zhangjb/operations/external/Makefile.am (original)
+++ branches/branch_zhangjb/operations/external/Makefile.am Sat May 17 17:51:59 2008
@@ -60,6 +60,14 @@
display_la_CFLAGS = $(SDL_CFLAGS)
endif
+#if HAVE_V4L
+ops += v4l.la
+v4l_la_SOURCES = v4l.c
+v4l_la_LIBADD = $(op_libs)
+#endif
+
+EXTRA_DIST=v4lutils/v4lutils.c v4lutils/v4lutils.h
+
if HAVE_AVCODEC
if HAVE_AVFORMAT
ops += ff-load.la
Modified: branches/branch_zhangjb/operations/generated/other-blend.rb
==============================================================================
--- branches/branch_zhangjb/operations/generated/other-blend.rb (original)
+++ branches/branch_zhangjb/operations/generated/other-blend.rb Sat May 17 17:51:59 2008
@@ -92,7 +92,7 @@
#ifdef HAS_G4FLOAT
gegl_operation_class_add_processor (operation_class,
- G_CALLBACK (process_gegl4float), "g4float");
+ G_CALLBACK (process_gegl4float), "simd");
#endif
'
Modified: branches/branch_zhangjb/operations/generated/svg-12-porter-duff.rb
==============================================================================
--- branches/branch_zhangjb/operations/generated/svg-12-porter-duff.rb (original)
+++ branches/branch_zhangjb/operations/generated/svg-12-porter-duff.rb Sat May 17 17:51:59 2008
@@ -121,7 +121,7 @@
#ifdef HAS_G4FLOAT
gegl_operation_class_add_processor (operation_class,
- G_CALLBACK (process_gegl4float), "g4float");
+ G_CALLBACK (process_gegl4float), "simd");
#endif
'
Modified: branches/branch_zhangjb/tools/create-reference.rb
==============================================================================
--- branches/branch_zhangjb/tools/create-reference.rb (original)
+++ branches/branch_zhangjb/tools/create-reference.rb Sat May 17 17:51:59 2008
@@ -260,7 +260,7 @@
display: block;
font-style: italic;
color: #22F;
- width: 8em;
+ width: 10em;
float: left;
}
div.arg_name{
@@ -538,6 +538,7 @@
file.puts "<sub name='#{element.name}' link='api.html\##{element.name.gsub(' ','_')}'/>"
end
}
+ file.puts "<sub name='Operations' link='operations.html'/>"
file.puts "</chapters>"
file.puts "<functions>"
@@ -548,6 +549,15 @@
if element.is_a? Section and !element.name.empty? and element.name=~ /^Gegl/
file.puts "<function name='#{element.name}' link='api.html\##{element.name.gsub(' ','_')}'/>"
end
+
+
+ }
+
+ IO.foreach("operations.html"){ |line|
+ if line =~ /^<li><a href='#op_.*'>.*<\/a><\/li>/
+ opname=line.gsub(/.*op_/,'').gsub(/'.*/,'').strip
+ file.puts "<function name='gegl-#{opname}' link='operations.html#op_#{opname}'/>"
+ end
}
file.puts "</functions>"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]