cleanup specfile for packaging
[profile/ivi/cogl.git] / cogl / cogl-pipeline-layer-private.h
1 /*
2  * Cogl
3  *
4  * An object oriented GL/GLES Abstraction/Utility Layer
5  *
6  * Copyright (C) 2008,2009,2010,2011 Intel Corporation.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see
20  * <http://www.gnu.org/licenses/>.
21  *
22  *
23  *
24  * Authors:
25  *   Robert Bragg <robert@linux.intel.com>
26  */
27
28 #ifndef __COGL_PIPELINE_LAYER_PRIVATE_H
29 #define __COGL_PIPELINE_LAYER_PRIVATE_H
30
31 #include "cogl-pipeline.h"
32 #include "cogl-node-private.h"
33 #include "cogl-texture.h"
34 #include "cogl-matrix.h"
35 #include "cogl-pipeline-layer-state.h"
36 #include "cogl-internal.h"
37 #include "cogl-pipeline-snippet-private.h"
38
39 #include <glib.h>
40
41 /* This isn't defined in the GLES headers */
42 #ifndef GL_CLAMP_TO_BORDER
43 #define GL_CLAMP_TO_BORDER 0x812d
44 #endif
45 #ifndef GL_MIRRORED_REPEAT
46 #define GL_MIRRORED_REPEAT 0x8370
47 #endif
48
49 typedef struct _CoglPipelineLayer     CoglPipelineLayer;
50 #define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
51
52 /* GL_ALWAYS is just used here as a value that is known not to clash
53  * with any valid GL wrap modes.
54  *
55  * XXX: keep the values in sync with the CoglPipelineWrapMode enum
56  * so no conversion is actually needed.
57  */
58 typedef enum _CoglPipelineWrapModeInternal
59 {
60   COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
61   COGL_PIPELINE_WRAP_MODE_INTERNAL_MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
62   COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
63   COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
64   COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS
65 } CoglPipelineWrapModeInternal;
66
67 /* XXX: should I rename these as
68  * COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ?
69  */
70 typedef enum
71 {
72   /* sparse state */
73   COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
74   COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
75   COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
76   COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
77   COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
78   COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
79   COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
80   COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
81   COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
82   COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX,
83   COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX,
84
85   /* note: layers don't currently have any non-sparse state */
86
87   COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT,
88   COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT
89 } CoglPipelineLayerStateIndex;
90
91 /* XXX: If you add or remove state groups here you may need to update
92  * some of the state masks following this enum too!
93  *
94  * FIXME: perhaps it would be better to rename this enum to
95  * CoglPipelineLayerStateGroup to better convey the fact that a single
96  * enum here can map to multiple properties.
97  */
98 typedef enum
99 {
100   COGL_PIPELINE_LAYER_STATE_UNIT =
101     1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
102   COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE =
103     1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
104   COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
105     1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
106   COGL_PIPELINE_LAYER_STATE_FILTERS =
107     1L<<COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
108   COGL_PIPELINE_LAYER_STATE_WRAP_MODES =
109     1L<<COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
110
111   COGL_PIPELINE_LAYER_STATE_COMBINE =
112     1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
113   COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT =
114     1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
115   COGL_PIPELINE_LAYER_STATE_USER_MATRIX =
116     1L<<COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
117
118   COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS =
119     1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
120
121   COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS =
122     1L<<COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX,
123   COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS =
124     1L<<COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX,
125
126   /* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN   = 1L<<8, */
127
128 } CoglPipelineLayerState;
129
130 /*
131  * Various special masks that tag state-groups in different ways...
132  */
133
134 #define COGL_PIPELINE_LAYER_STATE_ALL \
135   ((1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1)
136
137 #define COGL_PIPELINE_LAYER_STATE_ALL_SPARSE \
138   COGL_PIPELINE_LAYER_STATE_ALL
139
140 #define COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE \
141   (COGL_PIPELINE_LAYER_STATE_COMBINE | \
142    COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT | \
143    COGL_PIPELINE_LAYER_STATE_USER_MATRIX | \
144    COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS | \
145    COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS | \
146    COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS)
147
148 #define COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY \
149   (COGL_PIPELINE_LAYER_STATE_FILTERS | \
150    COGL_PIPELINE_LAYER_STATE_WRAP_MODES | \
151    COGL_PIPELINE_LAYER_STATE_COMBINE | \
152    COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS | \
153    COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS)
154
155 #define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN \
156   COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS
157
158 typedef enum
159 {
160   /* These are the same values as GL */
161   COGL_PIPELINE_COMBINE_FUNC_ADD         = 0x0104,
162   COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED  = 0x8574,
163   COGL_PIPELINE_COMBINE_FUNC_SUBTRACT    = 0x84E7,
164   COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE = 0x8575,
165   COGL_PIPELINE_COMBINE_FUNC_REPLACE     = 0x1E01,
166   COGL_PIPELINE_COMBINE_FUNC_MODULATE    = 0x2100,
167   COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB    = 0x86AE,
168   COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA   = 0x86AF
169 } CoglPipelineCombineFunc;
170
171 typedef enum
172 {
173   /* Note that these numbers are deliberately not the same as the GL
174      numbers so that we can reserve all numbers > TEXTURE0 to store
175      very large layer numbers */
176   COGL_PIPELINE_COMBINE_SOURCE_TEXTURE,
177   COGL_PIPELINE_COMBINE_SOURCE_CONSTANT,
178   COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR,
179   COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS,
180   COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0
181 } CoglPipelineCombineSource;
182
183 typedef enum
184 {
185   /* These are the same values as GL */
186   COGL_PIPELINE_COMBINE_OP_SRC_COLOR           = 0x0300,
187   COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR = 0x0301,
188   COGL_PIPELINE_COMBINE_OP_SRC_ALPHA           = 0x0302,
189   COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA = 0x0303
190 } CoglPipelineCombineOp;
191
192 typedef struct
193 {
194   /* The texture combine state determines how the color of individual
195    * texture fragments are calculated. */
196   CoglPipelineCombineFunc texture_combine_rgb_func;
197   CoglPipelineCombineSource texture_combine_rgb_src[3];
198   CoglPipelineCombineOp texture_combine_rgb_op[3];
199
200   CoglPipelineCombineFunc texture_combine_alpha_func;
201   CoglPipelineCombineSource texture_combine_alpha_src[3];
202   CoglPipelineCombineOp texture_combine_alpha_op[3];
203
204   float texture_combine_constant[4];
205
206   /* The texture matrix dscribes how to transform texture coordinates */
207   CoglMatrix matrix;
208
209   gboolean point_sprite_coords;
210
211   CoglPipelineSnippetList vertex_snippets;
212   CoglPipelineSnippetList fragment_snippets;
213 } CoglPipelineLayerBigState;
214
215 struct _CoglPipelineLayer
216 {
217   /* XXX: Please think twice about adding members that *have* be
218    * initialized during a _cogl_pipeline_layer_copy. We are aiming
219    * to have copies be as cheap as possible and copies may be
220    * done by the primitives APIs which means they may happen
221    * in performance critical code paths.
222    *
223    * XXX: If you are extending the state we track please consider if
224    * the state is expected to vary frequently across many pipelines or
225    * if the state can be shared among many derived pipelines instead.
226    * This will determine if the state should be added directly to this
227    * structure which will increase the memory overhead for *all*
228    * layers or if instead it can go under ->big_state.
229    */
230
231   /* Layers represent their state in a tree structure where some of
232    * the state relating to a given pipeline or layer may actually be
233    * owned by one if is ancestors in the tree. We have a common data
234    * type to track the tree heirachy so we can share code... */
235   CoglNode _parent;
236
237   /* Some layers have a pipeline owner, which is to say that the layer
238    * is referenced in that pipelines->layer_differences list.  A layer
239    * doesn't always have an owner and may simply be an ancestor for
240    * other layers that keeps track of some shared state. */
241   CoglPipeline      *owner;
242
243   /* The lowest index is blended first then others on top */
244   int                index;
245
246   /* A mask of which state groups are different in this layer
247    * in comparison to its parent. */
248   unsigned long             differences;
249
250   /* Common differences
251    *
252    * As a basic way to reduce memory usage we divide the layer
253    * state into two groups; the minimal state modified in 90% of
254    * all layers and the rest, so that the second group can
255    * be allocated dynamically when required.
256    */
257
258   /* Each layer is directly associated with a single texture unit */
259   int                        unit_index;
260
261   /* The texture for this layer, or NULL for an empty
262    * layer */
263   CoglTexture               *texture;
264   /* The type of the texture. This is always set even if the texture
265      is NULL and it will be used to determine what type of texture
266      lookups to use in any shaders generated by the pipeline
267      backends. */
268   CoglTextureType            texture_type;
269
270   CoglPipelineFilter         mag_filter;
271   CoglPipelineFilter         min_filter;
272
273   CoglPipelineWrapModeInternal wrap_mode_s;
274   CoglPipelineWrapModeInternal wrap_mode_t;
275   CoglPipelineWrapModeInternal wrap_mode_p;
276
277   /* Infrequent differences aren't currently tracked in
278    * a separate, dynamically allocated structure as they are
279    * for pipelines... */
280   CoglPipelineLayerBigState *big_state;
281
282   /* bitfields */
283
284   /* Determines if layer->big_state is valid */
285   unsigned int          has_big_state:1;
286
287 };
288
289 typedef gboolean
290 (*CoglPipelineLayerStateComparitor) (CoglPipelineLayer *authority0,
291                                      CoglPipelineLayer *authority1);
292
293
294
295 void
296 _cogl_pipeline_init_default_layers (void);
297
298 static inline CoglPipelineLayer *
299 _cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer)
300 {
301   CoglNode *parent_node = COGL_NODE (layer)->parent;
302   return COGL_PIPELINE_LAYER (parent_node);
303 }
304
305 CoglPipelineLayer *
306 _cogl_pipeline_layer_copy (CoglPipelineLayer *layer);
307
308 void
309 _cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer,
310                                           unsigned long differences,
311                                           CoglPipelineLayer **authorities);
312
313 gboolean
314 _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
315                             CoglPipelineLayer *layer1,
316                             unsigned long differences_mask,
317                             CoglPipelineEvalFlags flags);
318
319 CoglPipelineLayer *
320 _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
321                                         CoglPipelineLayer *layer,
322                                         CoglPipelineLayerState change);
323
324 void
325 _cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer);
326
327 gboolean
328 _cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer);
329
330 gboolean
331 _cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline,
332                                       int layer_index);
333
334 /*
335  * Calls the pre_paint method on the layer texture if there is
336  * one. This will determine whether mipmaps are needed based on the
337  * filter settings.
338  */
339 void
340 _cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr);
341
342 void
343 _cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer,
344                                      CoglPipelineWrapModeInternal *wrap_mode_s,
345                                      CoglPipelineWrapModeInternal *wrap_mode_t,
346                                      CoglPipelineWrapModeInternal *wrap_mode_r);
347
348 void
349 _cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer,
350                                   CoglPipelineFilter *min_filter,
351                                   CoglPipelineFilter *mag_filter);
352
353 void
354 _cogl_pipeline_get_layer_filters (CoglPipeline *pipeline,
355                                   int layer_index,
356                                   CoglPipelineFilter *min_filter,
357                                   CoglPipelineFilter *mag_filter);
358
359 typedef enum {
360   COGL_PIPELINE_LAYER_TYPE_TEXTURE
361 } CoglPipelineLayerType;
362
363 CoglPipelineLayerType
364 _cogl_pipeline_layer_get_type (CoglPipelineLayer *layer);
365
366 CoglTexture *
367 _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
368
369 CoglTexture *
370 _cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
371
372 CoglTextureType
373 _cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer);
374
375 CoglPipelineFilter
376 _cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);
377
378 CoglPipelineFilter
379 _cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer);
380
381 CoglPipelineWrapMode
382 _cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer);
383
384 CoglPipelineWrapMode
385 _cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer);
386
387 CoglPipelineWrapMode
388 _cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer);
389
390 unsigned long
391 _cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0,
392                                           CoglPipelineLayer *layer1);
393
394 CoglPipelineLayer *
395 _cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer,
396                                     unsigned long difference);
397
398 CoglTexture *
399 _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
400
401 int
402 _cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
403
404 gboolean
405 _cogl_pipeline_layer_needs_combine_separate
406                                        (CoglPipelineLayer *combine_authority);
407
408 #endif /* __COGL_PIPELINE_LAYER_PRIVATE_H */