/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008,2009,2010,2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* .
*
*
*
* Authors:
* Robert Bragg
*/
#ifndef __COGL_PIPELINE_LAYER_PRIVATE_H
#define __COGL_PIPELINE_LAYER_PRIVATE_H
#include "cogl-pipeline.h"
#include "cogl-node-private.h"
#include "cogl-texture.h"
#include "cogl-matrix.h"
#include "cogl-pipeline-layer-state.h"
#include "cogl-internal.h"
#include
/* This isn't defined in the GLES headers */
#ifndef GL_CLAMP_TO_BORDER
#define GL_CLAMP_TO_BORDER 0x812d
#endif
#ifndef GL_MIRRORED_REPEAT
#define GL_MIRRORED_REPEAT 0x8370
#endif
typedef struct _CoglPipelineLayer CoglPipelineLayer;
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
/* GL_ALWAYS is just used here as a value that is known not to clash
* with any valid GL wrap modes.
*
* XXX: keep the values in sync with the CoglPipelineWrapMode enum
* so no conversion is actually needed.
*/
typedef enum _CoglPipelineWrapModeInternal
{
COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
COGL_PIPELINE_WRAP_MODE_INTERNAL_MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS
} CoglPipelineWrapModeInternal;
/* XXX: should I rename these as
* COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ?
*/
typedef enum
{
/* sparse state */
COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
/* note: layers don't currently have any non-sparse state */
COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT,
COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT
} CoglPipelineLayerStateIndex;
/* XXX: If you add or remove state groups here you may need to update
* some of the state masks following this enum too!
*
* FIXME: perhaps it would be better to rename this enum to
* CoglPipelineLayerStateGroup to better convey the fact that a single
* enum here can map to multiple properties.
*/
typedef enum
{
COGL_PIPELINE_LAYER_STATE_UNIT =
1L<big_state.
*/
/* Layers represent their state in a tree structure where some of
* the state relating to a given pipeline or layer may actually be
* owned by one if is ancestors in the tree. We have a common data
* type to track the tree heirachy so we can share code... */
CoglNode _parent;
/* Some layers have a pipeline owner, which is to say that the layer
* is referenced in that pipelines->layer_differences list. A layer
* doesn't always have an owner and may simply be an ancestor for
* other layers that keeps track of some shared state. */
CoglPipeline *owner;
/* The lowest index is blended first then others on top */
int index;
/* A mask of which state groups are different in this layer
* in comparison to its parent. */
unsigned long differences;
/* Common differences
*
* As a basic way to reduce memory usage we divide the layer
* state into two groups; the minimal state modified in 90% of
* all layers and the rest, so that the second group can
* be allocated dynamically when required.
*/
/* Each layer is directly associated with a single texture unit */
int unit_index;
/* The texture for this layer, or NULL for an empty
* layer */
CoglTexture *texture;
GLenum target;
CoglPipelineFilter mag_filter;
CoglPipelineFilter min_filter;
CoglPipelineWrapModeInternal wrap_mode_s;
CoglPipelineWrapModeInternal wrap_mode_t;
CoglPipelineWrapModeInternal wrap_mode_p;
/* Infrequent differences aren't currently tracked in
* a separate, dynamically allocated structure as they are
* for pipelines... */
CoglPipelineLayerBigState *big_state;
/* bitfields */
/* Determines if layer->big_state is valid */
unsigned int has_big_state:1;
};
typedef gboolean
(*CoglPipelineLayerStateComparitor) (CoglPipelineLayer *authority0,
CoglPipelineLayer *authority1);
void
_cogl_pipeline_init_default_layers (void);
static inline CoglPipelineLayer *
_cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer)
{
CoglNode *parent_node = COGL_NODE (layer)->parent;
return COGL_PIPELINE_LAYER (parent_node);
}
CoglPipelineLayer *
_cogl_pipeline_layer_copy (CoglPipelineLayer *layer);
void
_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer,
unsigned long differences,
CoglPipelineLayer **authorities);
gboolean
_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
CoglPipelineLayer *layer1,
unsigned long differences_mask,
CoglPipelineEvalFlags flags);
CoglPipelineLayer *
_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
CoglPipelineLayer *layer,
CoglPipelineLayerState change);
void
_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer);
gboolean
_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer);
gboolean
_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline,
int layer_index);
/*
* Calls the pre_paint method on the layer texture if there is
* one. This will determine whether mipmaps are needed based on the
* filter settings.
*/
void
_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr);
void
_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer,
CoglPipelineWrapModeInternal *wrap_mode_s,
CoglPipelineWrapModeInternal *wrap_mode_t,
CoglPipelineWrapModeInternal *wrap_mode_r);
void
_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer,
CoglPipelineFilter *min_filter,
CoglPipelineFilter *mag_filter);
void
_cogl_pipeline_get_layer_filters (CoglPipeline *pipeline,
int layer_index,
CoglPipelineFilter *min_filter,
CoglPipelineFilter *mag_filter);
typedef enum {
COGL_PIPELINE_LAYER_TYPE_TEXTURE
} CoglPipelineLayerType;
CoglPipelineLayerType
_cogl_pipeline_layer_get_type (CoglPipelineLayer *layer);
CoglTexture *
_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
CoglTexture *
_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
CoglPipelineFilter
_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);
CoglPipelineFilter
_cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer);
CoglPipelineWrapMode
_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer);
CoglPipelineWrapMode
_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer);
CoglPipelineWrapMode
_cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer);
unsigned long
_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0,
CoglPipelineLayer *layer1);
CoglPipelineLayer *
_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer,
unsigned long difference);
CoglTexture *
_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
int
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
gboolean
_cogl_pipeline_layer_needs_combine_separate
(CoglPipelineLayer *combine_authority);
#endif /* __COGL_PIPELINE_LAYER_PRIVATE_H */