1 /*
2  * Cogl
3  *
4  * A Low Level GPU Graphics and Utilities API
5  *
6  * Copyright (C)2010 Intel Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation
10  * files (the "Software"), to deal in the Software without
11  * restriction, including without limitation the rights to use, copy,
12  * modify, merge, publish, distribute, sublicense, and/or sell copies
13  * of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be
17  * included in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  *
28  *
29  *
30  * Authors:
31  *   Damien Lespiau <damien.lespiau@intel.com>
32  *   Robert Bragg <robert@linux.intel.com>
33  */
34 
35 #if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
36 #error "Only <cogl/cogl.h> can be included directly."
37 #endif
38 
39 #ifndef __COGL_BUFFER_H__
40 #define __COGL_BUFFER_H__
41 
42 #include <cogl/cogl-types.h>
43 #include <cogl/cogl-error.h>
44 
45 COGL_BEGIN_DECLS
46 
47 /**
48  * SECTION:cogl-buffer
49  * @short_description: Common buffer functions, including data upload APIs
50  * @stability: unstable
51  *
52  * The CoglBuffer API provides a common interface to manipulate
53  * buffers that have been allocated either via cogl_pixel_buffer_new()
54  * or cogl_attribute_buffer_new(). The API allows you to upload data
55  * to these buffers and define usage hints that help Cogl manage your
56  * buffer optimally.
57  *
58  * Data can either be uploaded by supplying a pointer and size so Cogl
59  * can copy your data, or you can mmap() a CoglBuffer and then you can
60  * copy data to the buffer directly.
61  *
62  * One of the most common uses for CoglBuffers is to upload texture
63  * data asynchronously since the ability to mmap the buffers into
64  * the CPU makes it possible for another thread to handle the IO
65  * of loading an image file and unpacking it into the mapped buffer
66  * without blocking other Cogl operations.
67  */
68 
69 #if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \
70   !defined(COGL_GIR_SCANNING)
71 /* For the public C api we typedef interface types as void to avoid needing
72  * lots of casting in code and instead we will rely on runtime type checking
73  * for these objects. */
74 typedef void CoglBuffer;
75 #else
76 typedef struct _CoglBuffer CoglBuffer;
77 #define COGL_BUFFER(buffer) ((CoglBuffer *)(buffer))
78 #endif
79 
80 #define COGL_BUFFER_ERROR (_cogl_buffer_error_domain ())
81 
82 /**
83  * CoglBufferError:
84  * @COGL_BUFFER_ERROR_MAP: A buffer could not be mapped either
85  *    because the feature isn't supported or because a system
86  *    limitation was hit.
87  *
88  * Error enumeration for #CoglBuffer
89  *
90  * Stability: unstable
91  */
92 typedef enum { /*< prefix=COGL_BUFFER_ERROR >*/
93   COGL_BUFFER_ERROR_MAP
94 } CoglBufferError;
95 
96 uint32_t
97 _cogl_buffer_error_domain (void);
98 
99 /**
100  * cogl_is_buffer:
101  * @object: a buffer object
102  *
103  * Checks whether @buffer is a buffer object.
104  *
105  * Return value: %TRUE if the handle is a CoglBuffer, and %FALSE otherwise
106  *
107  * Since: 1.2
108  * Stability: unstable
109  */
110 CoglBool
111 cogl_is_buffer (void *object);
112 
113 /**
114  * cogl_buffer_get_size:
115  * @buffer: a buffer object
116  *
117  * Retrieves the size of buffer
118  *
119  * Return value: the size of the buffer in bytes
120  *
121  * Since: 1.2
122  * Stability: unstable
123  */
124 unsigned int
125 cogl_buffer_get_size (CoglBuffer *buffer);
126 
127 /**
128  * CoglBufferUpdateHint:
129  * @COGL_BUFFER_UPDATE_HINT_STATIC: the buffer will not change over time
130  * @COGL_BUFFER_UPDATE_HINT_DYNAMIC: the buffer will change from time to time
131  * @COGL_BUFFER_UPDATE_HINT_STREAM: the buffer will be used once or a couple of
132  *   times
133  *
134  * The update hint on a buffer allows the user to give some detail on how often
135  * the buffer data is going to be updated.
136  *
137  * Since: 1.2
138  * Stability: unstable
139  */
140 typedef enum { /*< prefix=COGL_BUFFER_UPDATE_HINT >*/
141   COGL_BUFFER_UPDATE_HINT_STATIC,
142   COGL_BUFFER_UPDATE_HINT_DYNAMIC,
143   COGL_BUFFER_UPDATE_HINT_STREAM
144 } CoglBufferUpdateHint;
145 
146 /**
147  * cogl_buffer_set_update_hint:
148  * @buffer: a buffer object
149  * @hint: the new hint
150  *
151  * Sets the update hint on a buffer. See #CoglBufferUpdateHint for a description
152  * of the available hints.
153  *
154  * Since: 1.2
155  * Stability: unstable
156  */
157 void
158 cogl_buffer_set_update_hint (CoglBuffer          *buffer,
159                              CoglBufferUpdateHint hint);
160 
161 /**
162  * cogl_buffer_get_update_hint:
163  * @buffer: a buffer object
164  *
165  * Retrieves the update hints set using cogl_buffer_set_update_hint()
166  *
167  * Return value: the #CoglBufferUpdateHint currently used by the buffer
168  *
169  * Since: 1.2
170  * Stability: unstable
171  */
172 CoglBufferUpdateHint
173 cogl_buffer_get_update_hint (CoglBuffer *buffer);
174 
175 /**
176  * CoglBufferAccess:
177  * @COGL_BUFFER_ACCESS_READ: the buffer will be read
178  * @COGL_BUFFER_ACCESS_WRITE: the buffer will written to
179  * @COGL_BUFFER_ACCESS_READ_WRITE: the buffer will be used for both reading and
180  *   writing
181  *
182  * The access hints for cogl_buffer_set_update_hint()
183  *
184  * Since: 1.2
185  * Stability: unstable
186  */
187 typedef enum { /*< prefix=COGL_BUFFER_ACCESS >*/
188  COGL_BUFFER_ACCESS_READ       = 1 << 0,
189  COGL_BUFFER_ACCESS_WRITE      = 1 << 1,
190  COGL_BUFFER_ACCESS_READ_WRITE = COGL_BUFFER_ACCESS_READ | COGL_BUFFER_ACCESS_WRITE
191 } CoglBufferAccess;
192 
193 
194 /**
195  * CoglBufferMapHint:
196  * @COGL_BUFFER_MAP_HINT_DISCARD: Tells Cogl that you plan to replace
197  *    all the buffer's contents. When this flag is used to map a
198  *    buffer, the entire contents of the buffer become undefined, even
199  *    if only a subregion of the buffer is mapped.
200  * @COGL_BUFFER_MAP_HINT_DISCARD_RANGE: Tells Cogl that you plan to
201  *    replace all the contents of the mapped region. The contents of
202  *    the region specified are undefined after this flag is used to
203  *    map a buffer.
204  *
205  * Hints to Cogl about how you are planning to modify the data once it
206  * is mapped.
207  *
208  * Since: 1.4
209  * Stability: unstable
210  */
211 typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/
212   COGL_BUFFER_MAP_HINT_DISCARD = 1 << 0,
213   COGL_BUFFER_MAP_HINT_DISCARD_RANGE = 1 << 1
214 } CoglBufferMapHint;
215 
216 /**
217  * cogl_buffer_map:
218  * @buffer: a buffer object
219  * @access: how the mapped buffer will be used by the application
220  * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how
221  *   the data will be modified once mapped.
222  *
223  * Maps the buffer into the application address space for direct
224  * access. This is equivalent to calling cogl_buffer_map_range() with
225  * zero as the offset and the size of the entire buffer as the size.
226  *
227  * It is strongly recommended that you pass
228  * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace
229  * all the buffer's data. This way if the buffer is currently being
230  * used by the GPU then the driver won't have to stall the CPU and
231  * wait for the hardware to finish because it can instead allocate a
232  * new buffer to map.
233  *
234  * The behaviour is undefined if you access the buffer in a way
235  * conflicting with the @access mask you pass. It is also an error to
236  * release your last reference while the buffer is mapped.
237  *
238  * Return value: (transfer none): A pointer to the mapped memory or
239  *        %NULL is the call fails
240  *
241  * Since: 1.2
242  * Stability: unstable
243  */
244 void *
245 cogl_buffer_map (CoglBuffer *buffer,
246                  CoglBufferAccess access,
247                  CoglBufferMapHint hints);
248 
249 /**
250  * cogl_buffer_map_range:
251  * @buffer: a buffer object
252  * @offset: Offset within the buffer to start the mapping
253  * @size: The size of data to map
254  * @access: how the mapped buffer will be used by the application
255  * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how
256  *   the data will be modified once mapped.
257  * @error: A #CoglError for catching exceptional errors
258  *
259  * Maps a sub-region of the buffer into the application's address space
260  * for direct access.
261  *
262  * It is strongly recommended that you pass
263  * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace
264  * all the buffer's data. This way if the buffer is currently being
265  * used by the GPU then the driver won't have to stall the CPU and
266  * wait for the hardware to finish because it can instead allocate a
267  * new buffer to map. You can pass
268  * %COGL_BUFFER_MAP_HINT_DISCARD_RANGE instead if you want the
269  * regions outside of the mapping to be retained.
270  *
271  * The behaviour is undefined if you access the buffer in a way
272  * conflicting with the @access mask you pass. It is also an error to
273  * release your last reference while the buffer is mapped.
274  *
275  * Return value: (transfer none): A pointer to the mapped memory or
276  *        %NULL is the call fails
277  *
278  * Since: 2.0
279  * Stability: unstable
280  */
281 void *
282 cogl_buffer_map_range (CoglBuffer *buffer,
283                        size_t offset,
284                        size_t size,
285                        CoglBufferAccess access,
286                        CoglBufferMapHint hints,
287                        CoglError **error);
288 
289 /**
290  * cogl_buffer_unmap:
291  * @buffer: a buffer object
292  *
293  * Unmaps a buffer previously mapped by cogl_buffer_map().
294  *
295  * Since: 1.2
296  * Stability: unstable
297  */
298 void
299 cogl_buffer_unmap (CoglBuffer *buffer);
300 
301 /**
302  * cogl_buffer_set_data:
303  * @buffer: a buffer object
304  * @offset: destination offset (in bytes) in the buffer
305  * @data: a pointer to the data to be copied into the buffer
306  * @size: number of bytes to copy
307  *
308  * Updates part of the buffer with new data from @data. Where to put this new
309  * data is controlled by @offset and @offset + @data should be less than the
310  * buffer size.
311  *
312  * Return value: %TRUE is the operation succeeded, %FALSE otherwise
313  *
314  * Since: 1.2
315  * Stability: unstable
316  */
317 CoglBool
318 cogl_buffer_set_data (CoglBuffer *buffer,
319                       size_t offset,
320                       const void *data,
321                       size_t size);
322 
323 COGL_END_DECLS
324 
325 #endif /* __COGL_BUFFER_H__ */
326