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 GEGL; if not, see <https://www.gnu.org/licenses/>.
15  *
16  * Copyright 2006-2011 Øyvind Kolås <pippin@gimp.org>
17  */
18 
19 #ifndef __GEGL_TILE_SOURCE_H__
20 #define __GEGL_TILE_SOURCE_H__
21 
22 #include <glib-object.h>
23 #include <babl/babl.h>
24 #include "gegl-tile.h"
25 
26 /***
27  * GeglTileSource is the very top classes of the tile/buffer handling of Gegl. It defines the generic
28  * command mechanism to interact with a set of tiles. This classe is derived in GeglTileBackend and
29  * GeglTileHandler.
30  */
31 
32 G_BEGIN_DECLS
33 
34 #define GEGL_TYPE_TILE_SOURCE            (gegl_tile_source_get_type ())
35 #define GEGL_TILE_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_TILE_SOURCE, GeglTileSource))
36 #define GEGL_TILE_SOURCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GEGL_TYPE_TILE_SOURCE, GeglTileSourceClass))
37 #define GEGL_IS_TILE_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_TILE_SOURCE))
38 #define GEGL_IS_TILE_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GEGL_TYPE_TILE_SOURCE))
39 #define GEGL_TILE_SOURCE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GEGL_TYPE_TILE_SOURCE, GeglTileSourceClass))
40 
41 typedef struct _GeglTileSourceClass GeglTileSourceClass;
42 typedef gpointer  (*GeglTileSourceCommand)  (GeglTileSource  *gegl_tile_source,
43                          GeglTileCommand  command,
44                          gint             x,
45                          gint             y,
46                          gint             z,
47                          gpointer         data);
48 
49 struct _GeglTileSource
50 {
51   GObject               parent_instance;
52   GeglTileSourceCommand command;
53   gpointer              padding[4];
54 };
55 
56 struct _GeglTileSourceClass
57 {
58   GObjectClass  parent_class;
59   gpointer      padding[4];
60 };
61 
62 GType      gegl_tile_source_get_type (void) G_GNUC_CONST;
63 
64 static inline gpointer
gegl_tile_source_command(GeglTileSource * source,GeglTileCommand command,gint x,gint y,gint z,gpointer data)65 gegl_tile_source_command (GeglTileSource  *source,
66                           GeglTileCommand  command,
67                           gint             x,
68                           gint             y,
69                           gint             z,
70                           gpointer         data)
71 {
72   return source->command (source, command, x, y, z, data);
73 }
74 
75 /**
76  * gegl_tile_source_get_tile:
77  * @source: a GeglTileSource *
78  * @x: x coordinate
79  * @y: y coordinate
80  * @z: tile zoom level
81  *
82  * Get a GeglTile *from the buffer, mipmap tiles for levels z!=0 will be
83  * created on the fly as needed, empty tiles returned are copy on write
84  * and must be locked before written to, and unlocked afterwards.
85  *
86  * Returns: the tile at x,y,z or NULL if the tile could not be provided.
87  */
88 static inline GeglTile *
gegl_tile_source_get_tile(GeglTileSource * source,gint x,gint y,gint z)89 gegl_tile_source_get_tile (GeglTileSource *source,
90                            gint            x,
91                            gint            y,
92                            gint            z)
93 {
94 
95   GeglTile *tile;
96 
97 
98   tile = (GeglTile *) gegl_tile_source_command (source, GEGL_TILE_GET,
99                                                 x, y, z, NULL);
100 
101   return tile;
102 }
103 
104 
105 /**
106  * gegl_buffer_get_tile: (skip)
107  */
108 
109 GeglTile *
110 gegl_buffer_get_tile (GeglBuffer *buffer,
111                       gint        x,
112                       gint        y,
113                       gint        z);
114 
115 
116 /**
117  * gegl_tile_source_set_tile:
118  * @source: a GeglTileSource *
119  * @x: x coordinate
120  * @y: y coordinate
121  * @z: tile zoom level
122  * @tile: a #GeglTile
123  *
124  * Set a GeglTile in *from the buffer.
125  *
126  * Returns: the TRUE if the set was successful.
127  */
128 static inline gboolean
gegl_tile_source_set_tile(GeglTileSource * source,gint x,gint y,gint z,GeglTile * tile)129 gegl_tile_source_set_tile (GeglTileSource *source,
130                            gint            x,
131                            gint            y,
132                            gint            z,
133                            GeglTile       *tile)
134 {
135   return gegl_tile_source_command (source, GEGL_TILE_SET, x, y, z, tile) != NULL;
136 }
137 /**
138  * gegl_tile_source_is_cached:
139  * @source: a GeglTileSource *
140  * @x: tile x coordinate
141  * @y: tile y coordinate
142  * @z: tile zoom level
143  *
144  * Checks if a tile is in cache and easily retrieved.
145  */
146 static inline gboolean
gegl_tile_source_is_cached(GeglTileSource * source,gint x,gint y,gint z)147 gegl_tile_source_is_cached (GeglTileSource *source,
148                             gint            x,
149                             gint            y,
150                             gint            z)
151 {
152   return gegl_tile_source_command (source, GEGL_TILE_IS_CACHED, x, y, z, NULL) != NULL;
153 }
154 /**
155  * gegl_tile_source_exist:
156  * @source: a GeglTileSource *
157  * @x: x coordinate
158  * @y: y coordinate
159  * @z: tile zoom level
160  *
161  * Checks if a tile exists, this check would not cause the tile to be swapped
162  * in.
163  */
164 static inline gboolean
gegl_tile_source_exist(GeglTileSource * source,gint x,gint y,gint z)165 gegl_tile_source_exist (GeglTileSource *source,
166                         gint            x,
167                         gint            y,
168                         gint            z)
169 {
170   return gegl_tile_source_command (source, GEGL_TILE_EXIST, x, y, z, NULL) != NULL;
171 }
172 
173 /**
174  * gegl_tile_source_reinit:
175  * @source: a GeglTileSource *
176  *
177  * Causes all tiles in cache to be refetched.
178  */
179 static inline void
gegl_tile_source_reinit(GeglTileSource * source)180 gegl_tile_source_reinit (GeglTileSource *source)
181 {
182   gegl_tile_source_command (source, GEGL_TILE_REINIT, 0, 0, 0, NULL);
183 }
184 
185 /**
186  * gegl_tile_source_void:
187  * @source: a GeglTileSource *
188  * @x: x coordinate
189  * @y: y coordinate
190  * @z: tile zoom level
191  *
192  * Causes all references to a tile to be removed.
193  */
194 static inline void
gegl_tile_source_void(GeglTileSource * source,gint x,gint y,gint z)195 gegl_tile_source_void (GeglTileSource *source,
196                        gint            x,
197                        gint            y,
198                        gint            z)
199 {
200   gegl_tile_source_command (source, GEGL_TILE_VOID, x, y, z, NULL);
201 }
202 
203 /**
204  * gegl_tile_source_copy:
205  * @source: a GeglTileSource *
206  * @x: x coordinate
207  * @y: y coordinate
208  * @z: tile zoom level
209  * @dst_buffer: destination buffer, or #NULL
210  * @dst_x: x coordinate of destination tile
211  * @dst_y: y coordinate of destination tile
212  * @dst_z: z coordinate of destination tile
213  *
214  * Copies a tile from @source to @dst_buffer, or, if @dst_buffer is #NULL, to
215  * the buffer @source belongs to.
216  *
217  * Returns: #TRUE if the tile was copied.
218  */
219 static inline gboolean
gegl_tile_source_copy(GeglTileSource * source,gint x,gint y,gint z,GeglBuffer * dst_buffer,gint dst_x,gint dst_y,gint dst_z)220 gegl_tile_source_copy (GeglTileSource *source,
221                        gint            x,
222                        gint            y,
223                        gint            z,
224                        GeglBuffer     *dst_buffer,
225                        gint            dst_x,
226                        gint            dst_y,
227                        gint            dst_z)
228 {
229   GeglTileCopyParams params;
230 
231   params.dst_buffer = dst_buffer;
232 
233   params.dst_x      = dst_x;
234   params.dst_y      = dst_y;
235   params.dst_z      = dst_z;
236 
237   if (gegl_tile_source_command (source, GEGL_TILE_COPY, x, y, z, &params))
238     return TRUE;
239   else
240     return FALSE;
241 }
242 
243 /*    INTERNAL API
244  * gegl_tile_source_refetch:
245  * @source: a GeglTileSource *
246  * @x: x coordinate
247  * @y: y coordinate
248  * @z: tile zoom level
249  *
250  * A message used internally when watching external buffers to indicate that
251  * a refresh of all data relating to the coordinates needs to be refetched.
252  * Subsequent get calls should get new and valid data for the tile coordinates.
253  */
254 static inline void
gegl_tile_source_refetch(GeglTileSource * source,gint x,gint y,gint z)255 gegl_tile_source_refetch (GeglTileSource *source,
256                           gint            x,
257                           gint            y,
258                           gint            z)
259 {
260   gegl_tile_source_command (source, GEGL_TILE_REFETCH, x, y, z, NULL);
261 }
262 /*   INTERNAL API
263  * gegl_tile_source_idle:
264  * @source: a GeglTileSource *
265  *
266  * Allow different parts of the buffer to do idle work (saving cached
267  * data lazily, perhaps prefetching in the future?), monitoring for
268  * changes or other tasks. Used internally by the buffer object.
269  *
270  * Returns: the TRUE if some work was done.
271  */
272 static inline gboolean
gegl_tile_source_idle(GeglTileSource * source)273 gegl_tile_source_idle (GeglTileSource *source)
274 {
275   return gegl_tile_source_command (source, GEGL_TILE_IDLE, 0, 0, 0, NULL) != NULL;
276 }
277 
278 G_END_DECLS
279 
280 #endif
281