1 /*
2  * Cogl
3  *
4  * A Low Level GPU Graphics and Utilities API
5  *
6  * Copyright (C) 2007,2008,2009 Intel Corporation.
7  * Copyright (C) 2019 DisplayLink (UK) Ltd.
8  *
9  * Permission is hereby granted, free of charge, to any person
10  * obtaining a copy of this software and associated documentation
11  * files (the "Software"), to deal in the Software without
12  * restriction, including without limitation the rights to use, copy,
13  * modify, merge, publish, distribute, sublicense, and/or sell copies
14  * of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  *
29  *
30  */
31 
32 #ifndef __COGL_FRAMEBUFFER_PRIVATE_H
33 #define __COGL_FRAMEBUFFER_PRIVATE_H
34 
35 #include "cogl-framebuffer-driver.h"
36 #include "cogl-object-private.h"
37 #include "cogl-matrix-stack-private.h"
38 #include "cogl-journal-private.h"
39 #include "winsys/cogl-winsys-private.h"
40 #include "cogl-attribute-private.h"
41 #include "cogl-clip-stack.h"
42 
43 typedef enum
44 {
45   COGL_FRAMEBUFFER_DRIVER_TYPE_FBO,
46   COGL_FRAMEBUFFER_DRIVER_TYPE_BACK,
47 } CoglFramebufferDriverType;
48 
49 struct _CoglFramebufferDriverConfig
50 {
51   CoglFramebufferDriverType type;
52 
53   gboolean disable_depth_and_stencil;
54 };
55 
56 typedef struct
57 {
58   CoglSwapChain *swap_chain;
59   gboolean need_stencil;
60   int samples_per_pixel;
61   gboolean stereo_enabled;
62 } CoglFramebufferConfig;
63 
64 /* XXX: The order of these indices determines the order they are
65  * flushed.
66  *
67  * Flushing clip state may trash the modelview and projection matrices
68  * so we must do it before flushing the matrices.
69  */
70 typedef enum _CoglFramebufferStateIndex
71 {
72   COGL_FRAMEBUFFER_STATE_INDEX_BIND               = 0,
73   COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT           = 1,
74   COGL_FRAMEBUFFER_STATE_INDEX_CLIP               = 2,
75   COGL_FRAMEBUFFER_STATE_INDEX_DITHER             = 3,
76   COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW          = 4,
77   COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION         = 5,
78   COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6,
79   COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE        = 7,
80   COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE        = 8,
81   COGL_FRAMEBUFFER_STATE_INDEX_MAX                = 9
82 } CoglFramebufferStateIndex;
83 
84 typedef enum _CoglFramebufferState
85 {
86   COGL_FRAMEBUFFER_STATE_BIND               = 1<<0,
87   COGL_FRAMEBUFFER_STATE_VIEWPORT           = 1<<1,
88   COGL_FRAMEBUFFER_STATE_CLIP               = 1<<2,
89   COGL_FRAMEBUFFER_STATE_DITHER             = 1<<3,
90   COGL_FRAMEBUFFER_STATE_MODELVIEW          = 1<<4,
91   COGL_FRAMEBUFFER_STATE_PROJECTION         = 1<<5,
92   COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6,
93   COGL_FRAMEBUFFER_STATE_DEPTH_WRITE        = 1<<7,
94   COGL_FRAMEBUFFER_STATE_STEREO_MODE        = 1<<8
95 } CoglFramebufferState;
96 
97 #define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
98 
99 /* Private flags that can internally be added to CoglReadPixelsFlags */
100 typedef enum
101 {
102   /* If this is set then the data will not be flipped to compensate
103      for GL's upside-down coordinate system but instead will be left
104      in whatever order GL gives us (which will depend on whether the
105      framebuffer is offscreen or not) */
106   COGL_READ_PIXELS_NO_FLIP = 1L << 30
107 } CoglPrivateReadPixelsFlags;
108 
109 typedef struct _CoglFramebufferBits
110 {
111   int red;
112   int blue;
113   int green;
114   int alpha;
115   int depth;
116   int stencil;
117 } CoglFramebufferBits;
118 
119 gboolean
120 cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer);
121 
122 void
123 cogl_framebuffer_init_config (CoglFramebuffer             *framebuffer,
124                               const CoglFramebufferConfig *config);
125 
126 const CoglFramebufferConfig *
127 cogl_framebuffer_get_config (CoglFramebuffer *framebuffer);
128 
129 void
130 cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer,
131                                            int              samples_per_pixel);
132 
133 void
134 cogl_framebuffer_update_size (CoglFramebuffer *framebuffer,
135                               int              width,
136                               int              height);
137 
138 /* XXX: For a public api we might instead want a way to explicitly
139  * set the _premult status of a framebuffer or what components we
140  * care about instead of exposing the CoglPixelFormat
141  * internal_format.
142  *
143  * The current use case for this api is where we create an offscreen
144  * framebuffer for a shared atlas texture that has a format of
145  * RGBA_8888 disregarding the premultiplied alpha status for
146  * individual atlased textures or whether the alpha component is being
147  * discarded. We want to overried the internal_format that will be
148  * derived from the texture.
149  */
150 void
151 _cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer,
152                                        CoglPixelFormat internal_format);
153 
154 CoglPixelFormat
155 cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer);
156 
157 void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
158 
159 const CoglWinsysVtable *
160 _cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer);
161 
162 void
163 _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
164                                          unsigned long buffers,
165                                          float red,
166                                          float green,
167                                          float blue,
168                                          float alpha);
169 
170 void
171 _cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer);
172 
173 void
174 cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer);
175 
176 /*
177  * _cogl_framebuffer_get_clip_stack:
178  * @framebuffer: A #CoglFramebuffer
179  *
180  * Gets a pointer to the current clip stack. A reference is not taken on the
181  * stack so if you want to keep it you should call
182  * _cogl_clip_stack_ref().
183  *
184  * Return value: a pointer to the @framebuffer clip stack.
185  */
186 CoglClipStack *
187 _cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer);
188 
189 COGL_EXPORT CoglMatrixStack *
190 _cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer);
191 
192 COGL_EXPORT CoglMatrixStack *
193 _cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer);
194 
195 void
196 _cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer,
197                                   CoglFramebuffer *dependency);
198 
199 void
200 _cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer);
201 
202 void
203 _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer);
204 
205 void
206 cogl_context_flush_framebuffer_state (CoglContext          *context,
207                                       CoglFramebuffer      *draw_buffer,
208                                       CoglFramebuffer      *read_buffer,
209                                       CoglFramebufferState  state);
210 
211 CoglFramebuffer *
212 _cogl_get_read_framebuffer (void);
213 
214 GSList *
215 _cogl_create_framebuffer_stack (void);
216 
217 void
218 _cogl_free_framebuffer_stack (GSList *stack);
219 
220 void
221 _cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer);
222 
223 void
224 _cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer);
225 
226 /* This can be called directly by the CoglJournal to draw attributes
227  * skipping the implicit journal flush, the framebuffer flush and
228  * pipeline validation. */
229 void
230 _cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
231                                    CoglPipeline *pipeline,
232                                    CoglVerticesMode mode,
233                                    int first_vertex,
234                                    int n_vertices,
235                                    CoglAttribute **attributes,
236                                    int n_attributes,
237                                    CoglDrawFlags flags);
238 
239 void
240 _cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
241                                            CoglPipeline *pipeline,
242                                            CoglVerticesMode mode,
243                                            int first_vertex,
244                                            int n_vertices,
245                                            CoglIndices *indices,
246                                            CoglAttribute **attributes,
247                                            int n_attributes,
248                                            CoglDrawFlags flags);
249 
250 void
251 cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer,
252                                   float *viewport);
253 
254 void
255 cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer,
256                                  float           *viewport_x,
257                                  float           *viewport_y,
258                                  float           *viewport_width,
259                                  float           *viewport_height);
260 
261 unsigned long
262 _cogl_framebuffer_compare (CoglFramebuffer *a,
263                            CoglFramebuffer *b,
264                            unsigned long state);
265 
266 static inline CoglMatrixEntry *
_cogl_framebuffer_get_modelview_entry(CoglFramebuffer * framebuffer)267 _cogl_framebuffer_get_modelview_entry (CoglFramebuffer *framebuffer)
268 {
269   CoglMatrixStack *modelview_stack =
270     _cogl_framebuffer_get_modelview_stack (framebuffer);
271   return modelview_stack->last_entry;
272 }
273 
274 static inline CoglMatrixEntry *
_cogl_framebuffer_get_projection_entry(CoglFramebuffer * framebuffer)275 _cogl_framebuffer_get_projection_entry (CoglFramebuffer *framebuffer)
276 {
277   CoglMatrixStack *projection_stack =
278     _cogl_framebuffer_get_projection_stack (framebuffer);
279   return projection_stack->last_entry;
280 }
281 
282 gboolean
283 _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
284                                            int x,
285                                            int y,
286                                            CoglReadPixelsFlags source,
287                                            CoglBitmap *bitmap,
288                                            GError **error);
289 
290 /*
291  * _cogl_framebuffer_get_stencil_bits:
292  * @framebuffer: a pointer to a #CoglFramebuffer
293  *
294  * Retrieves the number of stencil bits of @framebuffer
295  *
296  * Return value: the number of bits
297  *
298  * Since: 2.0
299  * Stability: unstable
300  */
301 COGL_EXPORT int
302 _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
303 
304 CoglJournal *
305 cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer);
306 
307 CoglFramebufferDriver *
308 cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer);
309 
310 /**
311  * cogl_framebuffer_is_y_flipped:
312  * @framebuffer: a #CoglFramebuffer
313  *
314  * Returns %TRUE if the Y coordinate 0 means the bottom of the framebuffer, and
315  * %FALSE if the Y coordinate means the top.
316  */
317 gboolean
318 cogl_framebuffer_is_y_flipped (CoglFramebuffer *framebuffer);
319 
320 #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
321