4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2008,2009,2010,2011 Intel Corporation.
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.
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.
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/>.
25 * Robert Bragg <robert@linux.intel.com>
28 #ifndef __COGL_PIPELINE_LAYER_PRIVATE_H
29 #define __COGL_PIPELINE_LAYER_PRIVATE_H
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"
41 /* This isn't defined in the GLES headers */
42 #ifndef GL_CLAMP_TO_BORDER
43 #define GL_CLAMP_TO_BORDER 0x812d
45 #ifndef GL_MIRRORED_REPEAT
46 #define GL_MIRRORED_REPEAT 0x8370
49 typedef struct _CoglPipelineLayer CoglPipelineLayer;
50 #define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
52 /* GL_ALWAYS is just used here as a value that is known not to clash
53 * with any valid GL wrap modes.
55 * XXX: keep the values in sync with the CoglPipelineWrapMode enum
56 * so no conversion is actually needed.
58 typedef enum _CoglPipelineWrapModeInternal
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;
67 /* XXX: should I rename these as
68 * COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ?
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,
85 /* note: layers don't currently have any non-sparse state */
87 COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT,
88 COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT
89 } CoglPipelineLayerStateIndex;
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!
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.
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,
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,
118 COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS =
119 1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
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,
126 /* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
128 } CoglPipelineLayerState;
131 * Various special masks that tag state-groups in different ways...
134 #define COGL_PIPELINE_LAYER_STATE_ALL \
135 ((1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1)
137 #define COGL_PIPELINE_LAYER_STATE_ALL_SPARSE \
138 COGL_PIPELINE_LAYER_STATE_ALL
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)
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)
155 #define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN \
156 COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS
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;
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;
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;
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];
200 CoglPipelineCombineFunc texture_combine_alpha_func;
201 CoglPipelineCombineSource texture_combine_alpha_src[3];
202 CoglPipelineCombineOp texture_combine_alpha_op[3];
204 float texture_combine_constant[4];
206 /* The texture matrix dscribes how to transform texture coordinates */
209 gboolean point_sprite_coords;
211 CoglPipelineSnippetList vertex_snippets;
212 CoglPipelineSnippetList fragment_snippets;
213 } CoglPipelineLayerBigState;
215 struct _CoglPipelineLayer
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.
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.
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... */
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. */
243 /* The lowest index is blended first then others on top */
246 /* A mask of which state groups are different in this layer
247 * in comparison to its parent. */
248 unsigned long differences;
250 /* Common differences
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.
258 /* Each layer is directly associated with a single texture unit */
261 /* The texture for this layer, or NULL for an empty
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
268 CoglTextureType texture_type;
270 CoglPipelineFilter mag_filter;
271 CoglPipelineFilter min_filter;
273 CoglPipelineWrapModeInternal wrap_mode_s;
274 CoglPipelineWrapModeInternal wrap_mode_t;
275 CoglPipelineWrapModeInternal wrap_mode_p;
277 /* Infrequent differences aren't currently tracked in
278 * a separate, dynamically allocated structure as they are
279 * for pipelines... */
280 CoglPipelineLayerBigState *big_state;
284 /* Determines if layer->big_state is valid */
285 unsigned int has_big_state:1;
290 (*CoglPipelineLayerStateComparitor) (CoglPipelineLayer *authority0,
291 CoglPipelineLayer *authority1);
296 _cogl_pipeline_init_default_layers (void);
298 static inline CoglPipelineLayer *
299 _cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer)
301 CoglNode *parent_node = COGL_NODE (layer)->parent;
302 return COGL_PIPELINE_LAYER (parent_node);
306 _cogl_pipeline_layer_copy (CoglPipelineLayer *layer);
309 _cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer,
310 unsigned long differences,
311 CoglPipelineLayer **authorities);
314 _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
315 CoglPipelineLayer *layer1,
316 unsigned long differences_mask,
317 CoglPipelineEvalFlags flags);
320 _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
321 CoglPipelineLayer *layer,
322 CoglPipelineLayerState change);
325 _cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer);
328 _cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer);
331 _cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline,
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
340 _cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr);
343 _cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer,
344 CoglPipelineWrapModeInternal *wrap_mode_s,
345 CoglPipelineWrapModeInternal *wrap_mode_t,
346 CoglPipelineWrapModeInternal *wrap_mode_r);
349 _cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer,
350 CoglPipelineFilter *min_filter,
351 CoglPipelineFilter *mag_filter);
354 _cogl_pipeline_get_layer_filters (CoglPipeline *pipeline,
356 CoglPipelineFilter *min_filter,
357 CoglPipelineFilter *mag_filter);
360 COGL_PIPELINE_LAYER_TYPE_TEXTURE
361 } CoglPipelineLayerType;
363 CoglPipelineLayerType
364 _cogl_pipeline_layer_get_type (CoglPipelineLayer *layer);
367 _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
370 _cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
373 _cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer);
376 _cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);
379 _cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer);
382 _cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer);
385 _cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer);
388 _cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer);
391 _cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0,
392 CoglPipelineLayer *layer1);
395 _cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer,
396 unsigned long difference);
399 _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
402 _cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
405 _cogl_pipeline_layer_needs_combine_separate
406 (CoglPipelineLayer *combine_authority);
408 #endif /* __COGL_PIPELINE_LAYER_PRIVATE_H */