1 /* This file is part of GEGL. 2 * 3 * This library is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU Lesser General Public 5 * License as published by the Free Software Foundation; either 6 * version 3 of the License, or (at your option) any later version. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with this library; if not, see <https://www.gnu.org/licenses/>. 15 * 16 * Copyright 2006-2008 Øyvind Kolås <pippin@gimp.org> 17 */ 18 19 #ifndef __GEGL_BUFFER_PRIVATE_H__ 20 #define __GEGL_BUFFER_PRIVATE_H__ 21 22 #include "gegl-buffer-types.h" 23 #include "gegl-buffer.h" 24 #include "gegl-tile-handler.h" 25 #include "gegl-buffer-iterator.h" 26 27 #define GEGL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_BUFFER, GeglBufferClass)) 28 #define GEGL_IS_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_BUFFER)) 29 #define GEGL_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_BUFFER, GeglBufferClass)) 30 31 typedef struct _GeglBufferClass GeglBufferClass; 32 33 struct _GeglBuffer 34 { 35 GeglTileHandler parent_instance; /* which is a GeglTileHandler which has a 36 source field which is used for chaining 37 sub buffers with their anchestors */ 38 39 GeglRectangle extent; /* the dimensions of the buffer */ 40 41 const Babl *format; /* the pixel format used for pixels in this 42 buffer */ 43 const Babl *soft_format; /* the format the buffer pretends to be, might 44 be different from format */ 45 46 gint shift_x; /* The relative offset of origins compared with */ 47 gint shift_y; /* anchestral tile_storage buffer, during */ 48 /* construction relative to immediate source */ 49 50 GeglRectangle abyss; 51 gboolean abyss_tracks_extent; /* specifies whether the abyss rectangle 52 should track any modifications to the 53 extent rectangle */ 54 55 GeglTileStorage *tile_storage; 56 57 gint tile_width; 58 gint tile_height; 59 gchar *path; 60 61 gint lock_count; 62 63 gpointer *alloc_stack_trace; /* Stack trace for allocation, 64 useful for debugging */ 65 gint alloc_stack_size; 66 67 gint changed_signal_connections; /* to avoid firing changed signals 68 with no listeners */ 69 gint changed_signal_freeze_count; 70 GeglRectangle changed_signal_accumulator; 71 72 GeglTileBackend *backend; 73 74 gboolean initialized; 75 }; 76 77 struct _GeglBufferClass 78 { 79 GeglTileHandlerClass parent_class; 80 }; 81 82 83 gint gegl_buffer_leaks (void); 84 85 void gegl_buffer_stats (void); 86 87 void gegl_tile_cache_init (void); 88 89 void gegl_tile_cache_destroy (void); 90 91 void gegl_tile_backend_swap_cleanup (void); 92 93 GeglTileBackend * gegl_buffer_backend (GeglBuffer *buffer); 94 GeglTileBackend * gegl_buffer_backend2 (GeglBuffer *buffer); /* non-cached */ 95 96 gboolean gegl_buffer_is_shared (GeglBuffer *buffer); 97 98 #define GEGL_BUFFER_DISABLE_LOCKS 1 99 100 #ifdef GEGL_BUFFER_DISABLE_LOCKS 101 #define gegl_buffer_try_lock(a) (TRUE) 102 #define gegl_buffer_lock(a) do{}while(0) 103 #define gegl_buffer_unlock(a) do{}while(0) 104 #else 105 gboolean gegl_buffer_try_lock (GeglBuffer *buffer); 106 gboolean gegl_buffer_lock (GeglBuffer *buffer); 107 gboolean gegl_buffer_unlock (GeglBuffer *buffer); 108 #endif 109 110 void gegl_buffer_set_unlocked (GeglBuffer *buffer, 111 const GeglRectangle *rect, 112 gint level, 113 const Babl *format, 114 const void *src, 115 gint rowstride); 116 117 void gegl_buffer_set_unlocked_no_notify (GeglBuffer *buffer, 118 const GeglRectangle *rect, 119 gint level, 120 const Babl *format, 121 const void *src, 122 gint rowstride); 123 124 void gegl_buffer_get_unlocked (GeglBuffer *buffer, 125 gdouble scale, 126 const GeglRectangle *rect, 127 const Babl *format, 128 gpointer dest_buf, 129 gint rowstride, 130 GeglAbyssPolicy repeat_mode); 131 132 GeglBuffer * gegl_buffer_new_ram (const GeglRectangle *extent, 133 const Babl *format); 134 135 void gegl_buffer_emit_changed_signal (GeglBuffer *buffer, 136 const GeglRectangle *rect); 137 138 /* the instance size of a GeglTile is a bit large, and should if possible be 139 * trimmed down 140 */ 141 struct _GeglTile 142 { 143 /* GObject parent_instance;*/ 144 gint ref_count; 145 146 guchar *data; /* actual pixel data for tile, a linear buffer*/ 147 gint size; /* The size of the linear buffer */ 148 149 GeglTileStorage *tile_storage; /* the buffer from which this tile was 150 * retrieved needed for the tile to be able to 151 * store itself back (for instance when it is 152 * unreffed for the last time) 153 */ 154 gint x, y, z; 155 156 157 guint rev; /* this tile revision */ 158 guint stored_rev; /* what revision was we when we from tile_storage? 159 (currently set to 1 when loaded from disk */ 160 161 gint lock_count; /* number of outstanding write locks */ 162 gint read_lock_count; /* number of outstanding read locks */ 163 guint is_zero_tile:1; /* whether the tile data is fully zeroed 164 * (allowing for false negatives, but not 165 * false positives) 166 */ 167 guint is_global_tile:1; /* whether the tile data is global (and 168 * therefore can never be owned by a 169 * single mutable tile) 170 */ 171 guint keep_identity:1; /* maintain data pointer identity, rather 172 * than data content only 173 */ 174 175 gint clone_state; /* tile clone/unclone state & spinlock */ 176 gint *n_clones; /* an array of two atomic counters, shared 177 * among all tiles sharing the same data. 178 * the first counter indicates the number of 179 * tiles sharing the data, and the second 180 * counter indicates how many of those tiles 181 * are in the cache. 182 */ 183 184 guint64 damage; 185 186 /* called when the tile is about to be destroyed */ 187 GDestroyNotify destroy_notify; 188 gpointer destroy_notify_data; 189 190 /* called when the tile has been unlocked which typically means tile 191 * data has changed 192 */ 193 GeglTileCallback unlock_notify; 194 gpointer unlock_notify_data; 195 }; 196 197 gboolean gegl_tile_needs_store (GeglTile *tile); 198 void gegl_tile_unlock_no_void (GeglTile *tile); 199 gboolean gegl_tile_damage (GeglTile *tile, 200 guint64 damage); 201 202 void _gegl_buffer_drop_hot_tile (GeglBuffer *buffer); 203 204 GeglRectangle _gegl_get_required_for_scale (const GeglRectangle *roi, 205 gdouble scale); 206 207 gboolean gegl_buffer_scan_compatible (GeglBuffer *bufferA, 208 gint xA, 209 gint yA, 210 GeglBuffer *bufferB, 211 gint xB, 212 gint yB); 213 214 215 extern void (*gegl_tile_handler_cache_ext_flush) (void *tile_handler_cache, const GeglRectangle *rect); 216 extern void (*gegl_buffer_ext_flush) (GeglBuffer *buffer, const GeglRectangle *rect); 217 extern void (*gegl_buffer_ext_invalidate) (GeglBuffer *buffer, const GeglRectangle *rect); 218 219 220 #ifndef __GEGL_TILE_H__ 221 #define gegl_tile_get_data(tile) ((tile)->data) 222 #endif 223 224 #define gegl_tile_n_clones(tile) (&(tile)->n_clones[0]) 225 #define gegl_tile_n_cached_clones(tile) (&(tile)->n_clones[1]) 226 227 /* computes the positive integer remainder (also for negative dividends) 228 */ 229 #define GEGL_REMAINDER(dividend, divisor) \ 230 (((dividend) < 0) ? \ 231 (divisor) - 1 - ((-((dividend) + 1)) % (divisor)) : \ 232 (dividend) % (divisor)) 233 234 #define gegl_tile_offset(coordinate, stride) GEGL_REMAINDER((coordinate), (stride)) 235 236 /* helper function to compute tile indices and offsets for coordinates 237 * based on a tile stride (tile_width or tile_height) 238 */ 239 #define gegl_tile_indice(coordinate,stride) \ 240 (((coordinate) >= 0)?\ 241 (coordinate) / (stride):\ 242 ((((coordinate) + 1) /(stride)) - 1)) 243 244 #endif 245