mirror of
https://github.com/brl/mutter.git
synced 2025-01-25 19:08:56 +00:00
pipeline: Split more code out from cogl-pipeline.c
This splits out the core CoglPipelineLayer support code from cogl-pipeline.c into cogl-pipeline-layer.c; it splits out the debugging code for dumping a pipeline to a .dot file into cogl-pipeline-debug.c and it splits the CoglPipelineNode support which is shared between CoglPipeline and CoglPipelineLayer into cogl-node.c. Note: cogl-pipeline-layer.c only contains the layer code directly relating to CoglPipelineLayer objects; it does not contain any _cogl_pipeline API relating to how CoglPipeline tracks and manipulates layers.
This commit is contained in:
parent
77a7add50e
commit
d4459e2d42
@ -244,12 +244,18 @@ cogl_sources_c = \
|
|||||||
$(srcdir)/cogl-matrix-stack.h \
|
$(srcdir)/cogl-matrix-stack.h \
|
||||||
$(srcdir)/cogl-depth-state.c \
|
$(srcdir)/cogl-depth-state.c \
|
||||||
$(srcdir)/cogl-depth-state-private.h \
|
$(srcdir)/cogl-depth-state-private.h \
|
||||||
|
$(srcdir)/cogl-node.c \
|
||||||
|
$(srcdir)/cogl-node-private.h \
|
||||||
$(srcdir)/cogl-pipeline.c \
|
$(srcdir)/cogl-pipeline.c \
|
||||||
$(srcdir)/cogl-pipeline-private.h \
|
$(srcdir)/cogl-pipeline-private.h \
|
||||||
|
$(srcdir)/cogl-pipeline-layer.c \
|
||||||
|
$(srcdir)/cogl-pipeline-layer-private.h \
|
||||||
$(srcdir)/cogl-pipeline-state.c \
|
$(srcdir)/cogl-pipeline-state.c \
|
||||||
$(srcdir)/cogl-pipeline-layer-state-private.h \
|
$(srcdir)/cogl-pipeline-layer-state-private.h \
|
||||||
$(srcdir)/cogl-pipeline-layer-state.c \
|
$(srcdir)/cogl-pipeline-layer-state.c \
|
||||||
$(srcdir)/cogl-pipeline-state-private.h \
|
$(srcdir)/cogl-pipeline-state-private.h \
|
||||||
|
$(srcdir)/cogl-pipeline-debug.c \
|
||||||
|
$(srcdir)/cogl-pipeline-debug-private.h \
|
||||||
$(srcdir)/cogl-pipeline-opengl.c \
|
$(srcdir)/cogl-pipeline-opengl.c \
|
||||||
$(srcdir)/cogl-pipeline-opengl-private.h \
|
$(srcdir)/cogl-pipeline-opengl-private.h \
|
||||||
$(srcdir)/cogl-pipeline-fragend-glsl.c \
|
$(srcdir)/cogl-pipeline-fragend-glsl.c \
|
||||||
|
@ -131,6 +131,14 @@ typedef enum
|
|||||||
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT = 1L<<1
|
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT = 1L<<1
|
||||||
} CoglPrivateFeatureFlags;
|
} CoglPrivateFeatureFlags;
|
||||||
|
|
||||||
|
/* Sometimes when evaluating pipelines, either during comparisons or
|
||||||
|
* if calculating a hash value we need to tweak the evaluation
|
||||||
|
* semantics */
|
||||||
|
typedef enum _CoglPipelineEvalFlags
|
||||||
|
{
|
||||||
|
COGL_PIPELINE_EVAL_FLAG_NONE = 0
|
||||||
|
} CoglPipelineEvalFlags;
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_check_extension (const char *name, const char *ext);
|
_cogl_check_extension (const char *name, const char *ext);
|
||||||
|
|
||||||
|
85
cogl/cogl-node-private.h
Normal file
85
cogl/cogl-node-private.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008,2009,2010 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_NODE_PRIVATE_H
|
||||||
|
#define __COGL_NODE_PRIVATE_H
|
||||||
|
|
||||||
|
#include "cogl-object-private.h"
|
||||||
|
#include "cogl-queue.h"
|
||||||
|
|
||||||
|
typedef struct _CoglNode CoglNode;
|
||||||
|
|
||||||
|
COGL_LIST_HEAD (CoglNodeList, CoglNode);
|
||||||
|
|
||||||
|
/* Pipelines and 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... */
|
||||||
|
struct _CoglNode
|
||||||
|
{
|
||||||
|
/* the parent in terms of class hierarchy, so anything inheriting
|
||||||
|
* from CoglNode also inherits from CoglObject. */
|
||||||
|
CoglObject _parent;
|
||||||
|
|
||||||
|
/* The parent pipeline/layer */
|
||||||
|
CoglNode *parent;
|
||||||
|
|
||||||
|
/* The list entry here contains pointers to the node's siblings */
|
||||||
|
COGL_LIST_ENTRY (CoglNode) list_node;
|
||||||
|
|
||||||
|
/* List of children */
|
||||||
|
CoglNodeList children;
|
||||||
|
|
||||||
|
/* TRUE if the node took a strong reference on its parent. Weak
|
||||||
|
* pipelines for instance don't take a reference on their parent. */
|
||||||
|
gboolean has_parent_reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define COGL_NODE(X) ((CoglNode *)(X))
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_init (CoglNode *node);
|
||||||
|
|
||||||
|
typedef void (*CoglNodeUnparentVFunc) (CoglNode *node);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_set_parent_real (CoglNode *node,
|
||||||
|
CoglNode *parent,
|
||||||
|
CoglNodeUnparentVFunc unparent,
|
||||||
|
gboolean take_strong_reference);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_unparent_real (CoglNode *node);
|
||||||
|
|
||||||
|
typedef gboolean (*CoglNodeChildCallback) (CoglNode *child, void *user_data);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_foreach_child (CoglNode *node,
|
||||||
|
CoglNodeChildCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
#endif /* __COGL_NODE_PRIVATE_H */
|
103
cogl/cogl-node.c
Normal file
103
cogl/cogl-node.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008,2009,2010 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl-node-private.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_init (CoglNode *node)
|
||||||
|
{
|
||||||
|
node->parent = NULL;
|
||||||
|
COGL_LIST_INIT (&node->children);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_set_parent_real (CoglNode *node,
|
||||||
|
CoglNode *parent,
|
||||||
|
CoglNodeUnparentVFunc unparent,
|
||||||
|
gboolean take_strong_reference)
|
||||||
|
{
|
||||||
|
/* NB: the old parent may indirectly be keeping the new parent alive
|
||||||
|
* so we have to ref the new parent before unrefing the old.
|
||||||
|
*
|
||||||
|
* Note: we take a reference here regardless of
|
||||||
|
* take_strong_reference because weak children may need special
|
||||||
|
* handling when the parent disposes itself which relies on a
|
||||||
|
* consistent link to all weak nodes. Once the node is linked to its
|
||||||
|
* parent then we remove the reference at the end if
|
||||||
|
* take_strong_reference == FALSE. */
|
||||||
|
cogl_object_ref (parent);
|
||||||
|
|
||||||
|
if (node->parent)
|
||||||
|
unparent (node);
|
||||||
|
|
||||||
|
COGL_LIST_INSERT_HEAD (&parent->children, node, list_node);
|
||||||
|
|
||||||
|
node->parent = parent;
|
||||||
|
node->has_parent_reference = take_strong_reference;
|
||||||
|
|
||||||
|
/* Now that there is a consistent parent->child link we can remove
|
||||||
|
* the parent reference if no reference was requested. If it turns
|
||||||
|
* out that the new parent was only being kept alive by the old
|
||||||
|
* parent then it will be disposed of here. */
|
||||||
|
if (!take_strong_reference)
|
||||||
|
cogl_object_unref (parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_unparent_real (CoglNode *node)
|
||||||
|
{
|
||||||
|
CoglNode *parent = node->parent;
|
||||||
|
|
||||||
|
if (parent == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_return_if_fail (!COGL_LIST_EMPTY (&parent->children));
|
||||||
|
|
||||||
|
COGL_LIST_REMOVE (node, list_node);
|
||||||
|
|
||||||
|
if (node->has_parent_reference)
|
||||||
|
cogl_object_unref (parent);
|
||||||
|
|
||||||
|
node->parent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_node_foreach_child (CoglNode *node,
|
||||||
|
CoglNodeChildCallback callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglNode *child, *next;
|
||||||
|
|
||||||
|
COGL_LIST_FOREACH_SAFE (child, &node->children, list_node, next)
|
||||||
|
callback (child, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
284
cogl/cogl-pipeline-debug.c
Normal file
284
cogl/cogl-pipeline-debug.c
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl-context-private.h"
|
||||||
|
#include "cogl-pipeline-private.h"
|
||||||
|
#include "cogl-pipeline-layer-private.h"
|
||||||
|
#include "cogl-node-private.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int parent_id;
|
||||||
|
int *node_id_ptr;
|
||||||
|
GString *graph;
|
||||||
|
int indent;
|
||||||
|
} PrintDebugState;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dump_layer_cb (CoglNode *node, void *user_data)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node);
|
||||||
|
PrintDebugState *state = user_data;
|
||||||
|
int layer_id = *state->node_id_ptr;
|
||||||
|
PrintDebugState state_out;
|
||||||
|
GString *changes_label;
|
||||||
|
gboolean changes = FALSE;
|
||||||
|
|
||||||
|
if (state->parent_id >= 0)
|
||||||
|
g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n",
|
||||||
|
state->indent, "",
|
||||||
|
layer->_parent.parent,
|
||||||
|
layer);
|
||||||
|
|
||||||
|
g_string_append_printf (state->graph,
|
||||||
|
"%*slayer%p [label=\"layer=0x%p\\n"
|
||||||
|
"ref count=%d\" "
|
||||||
|
"color=\"blue\"];\n",
|
||||||
|
state->indent, "",
|
||||||
|
layer,
|
||||||
|
layer,
|
||||||
|
COGL_OBJECT (layer)->ref_count);
|
||||||
|
|
||||||
|
changes_label = g_string_new ("");
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"%*slayer%p -> layer_state%d [weight=100];\n"
|
||||||
|
"%*slayer_state%d [shape=box label=\"",
|
||||||
|
state->indent, "",
|
||||||
|
layer,
|
||||||
|
layer_id,
|
||||||
|
state->indent, "",
|
||||||
|
layer_id);
|
||||||
|
|
||||||
|
if (layer->differences & COGL_PIPELINE_LAYER_STATE_UNIT)
|
||||||
|
{
|
||||||
|
changes = TRUE;
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"\\lunit=%u\\n",
|
||||||
|
layer->unit_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
|
||||||
|
{
|
||||||
|
changes = TRUE;
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"\\ltexture=%p\\n",
|
||||||
|
layer->texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes)
|
||||||
|
{
|
||||||
|
g_string_append_printf (changes_label, "\"];\n");
|
||||||
|
g_string_append (state->graph, changes_label->str);
|
||||||
|
g_string_free (changes_label, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
state_out.parent_id = layer_id;
|
||||||
|
|
||||||
|
state_out.node_id_ptr = state->node_id_ptr;
|
||||||
|
(*state_out.node_id_ptr)++;
|
||||||
|
|
||||||
|
state_out.graph = state->graph;
|
||||||
|
state_out.indent = state->indent + 2;
|
||||||
|
|
||||||
|
_cogl_pipeline_node_foreach_child (COGL_NODE (layer),
|
||||||
|
dump_layer_cb,
|
||||||
|
&state_out);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dump_layer_ref_cb (CoglPipelineLayer *layer, void *data)
|
||||||
|
{
|
||||||
|
PrintDebugState *state = data;
|
||||||
|
int pipeline_id = *state->node_id_ptr;
|
||||||
|
|
||||||
|
g_string_append_printf (state->graph,
|
||||||
|
"%*spipeline_state%d -> layer%p;\n",
|
||||||
|
state->indent, "",
|
||||||
|
pipeline_id,
|
||||||
|
layer);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dump_pipeline_cb (CoglNode *node, void *user_data)
|
||||||
|
{
|
||||||
|
CoglPipeline *pipeline = COGL_PIPELINE (node);
|
||||||
|
PrintDebugState *state = user_data;
|
||||||
|
int pipeline_id = *state->node_id_ptr;
|
||||||
|
PrintDebugState state_out;
|
||||||
|
GString *changes_label;
|
||||||
|
gboolean changes = FALSE;
|
||||||
|
gboolean layers = FALSE;
|
||||||
|
|
||||||
|
if (state->parent_id >= 0)
|
||||||
|
g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n",
|
||||||
|
state->indent, "",
|
||||||
|
state->parent_id,
|
||||||
|
pipeline_id);
|
||||||
|
|
||||||
|
g_string_append_printf (state->graph,
|
||||||
|
"%*spipeline%d [label=\"pipeline=0x%p\\n"
|
||||||
|
"ref count=%d\\n"
|
||||||
|
"breadcrumb=\\\"%s\\\"\" color=\"red\"];\n",
|
||||||
|
state->indent, "",
|
||||||
|
pipeline_id,
|
||||||
|
pipeline,
|
||||||
|
COGL_OBJECT (pipeline)->ref_count,
|
||||||
|
pipeline->has_static_breadcrumb ?
|
||||||
|
pipeline->static_breadcrumb : "NULL");
|
||||||
|
|
||||||
|
changes_label = g_string_new ("");
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"%*spipeline%d -> pipeline_state%d [weight=100];\n"
|
||||||
|
"%*spipeline_state%d [shape=box label=\"",
|
||||||
|
state->indent, "",
|
||||||
|
pipeline_id,
|
||||||
|
pipeline_id,
|
||||||
|
state->indent, "",
|
||||||
|
pipeline_id);
|
||||||
|
|
||||||
|
|
||||||
|
if (pipeline->differences & COGL_PIPELINE_STATE_COLOR)
|
||||||
|
{
|
||||||
|
changes = TRUE;
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"\\lcolor=0x%02X%02X%02X%02X\\n",
|
||||||
|
cogl_color_get_red_byte (&pipeline->color),
|
||||||
|
cogl_color_get_green_byte (&pipeline->color),
|
||||||
|
cogl_color_get_blue_byte (&pipeline->color),
|
||||||
|
cogl_color_get_alpha_byte (&pipeline->color));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipeline->differences & COGL_PIPELINE_STATE_BLEND)
|
||||||
|
{
|
||||||
|
const char *blend_enable_name;
|
||||||
|
|
||||||
|
changes = TRUE;
|
||||||
|
|
||||||
|
switch (pipeline->blend_enable)
|
||||||
|
{
|
||||||
|
case COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC:
|
||||||
|
blend_enable_name = "AUTO";
|
||||||
|
break;
|
||||||
|
case COGL_PIPELINE_BLEND_ENABLE_ENABLED:
|
||||||
|
blend_enable_name = "ENABLED";
|
||||||
|
break;
|
||||||
|
case COGL_PIPELINE_BLEND_ENABLE_DISABLED:
|
||||||
|
blend_enable_name = "DISABLED";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
blend_enable_name = "UNKNOWN";
|
||||||
|
}
|
||||||
|
g_string_append_printf (changes_label,
|
||||||
|
"\\lblend=%s\\n",
|
||||||
|
blend_enable_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
||||||
|
{
|
||||||
|
changes = TRUE;
|
||||||
|
layers = TRUE;
|
||||||
|
g_string_append_printf (changes_label, "\\ln_layers=%d\\n",
|
||||||
|
pipeline->n_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes)
|
||||||
|
{
|
||||||
|
g_string_append_printf (changes_label, "\"];\n");
|
||||||
|
g_string_append (state->graph, changes_label->str);
|
||||||
|
g_string_free (changes_label, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layers)
|
||||||
|
{
|
||||||
|
g_list_foreach (pipeline->layer_differences,
|
||||||
|
(GFunc)dump_layer_ref_cb,
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state_out.parent_id = pipeline_id;
|
||||||
|
|
||||||
|
state_out.node_id_ptr = state->node_id_ptr;
|
||||||
|
(*state_out.node_id_ptr)++;
|
||||||
|
|
||||||
|
state_out.graph = state->graph;
|
||||||
|
state_out.indent = state->indent + 2;
|
||||||
|
|
||||||
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
||||||
|
dump_pipeline_cb,
|
||||||
|
&state_out);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_debug_dump_pipelines_dot_file (const char *filename)
|
||||||
|
{
|
||||||
|
GString *graph;
|
||||||
|
PrintDebugState layer_state;
|
||||||
|
PrintDebugState pipeline_state;
|
||||||
|
int layer_id = 0;
|
||||||
|
int pipeline_id = 0;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
if (!ctx->default_pipeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
graph = g_string_new ("");
|
||||||
|
g_string_append_printf (graph, "digraph {\n");
|
||||||
|
|
||||||
|
layer_state.graph = graph;
|
||||||
|
layer_state.parent_id = -1;
|
||||||
|
layer_state.node_id_ptr = &layer_id;
|
||||||
|
layer_state.indent = 0;
|
||||||
|
dump_layer_cb (ctx->default_layer_0, &layer_state);
|
||||||
|
|
||||||
|
pipeline_state.graph = graph;
|
||||||
|
pipeline_state.parent_id = -1;
|
||||||
|
pipeline_state.node_id_ptr = &pipeline_id;
|
||||||
|
pipeline_state.indent = 0;
|
||||||
|
dump_pipeline_cb (ctx->default_pipeline, &pipeline_state);
|
||||||
|
|
||||||
|
g_string_append_printf (graph, "}\n");
|
||||||
|
|
||||||
|
if (filename)
|
||||||
|
g_file_set_contents (filename, graph->str, -1, NULL);
|
||||||
|
else
|
||||||
|
g_print ("%s", graph->str);
|
||||||
|
|
||||||
|
g_string_free (graph, TRUE);
|
||||||
|
}
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "cogl-debug.h"
|
#include "cogl-debug.h"
|
||||||
#include "cogl-pipeline-private.h"
|
#include "cogl-pipeline-private.h"
|
||||||
|
#include "cogl-pipeline-layer-private.h"
|
||||||
|
|
||||||
#ifdef COGL_PIPELINE_FRAGEND_ARBFP
|
#ifdef COGL_PIPELINE_FRAGEND_ARBFP
|
||||||
|
|
||||||
@ -709,7 +710,7 @@ _cogl_pipeline_fragend_arbfp_add_layer (CoglPipeline *pipeline,
|
|||||||
if (!shader_state->source)
|
if (!shader_state->source)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!_cogl_pipeline_need_texture_combine_separate (combine_authority))
|
if (!_cogl_pipeline_layer_needs_combine_separate (combine_authority))
|
||||||
{
|
{
|
||||||
append_masked_combine (pipeline,
|
append_masked_combine (pipeline,
|
||||||
layer,
|
layer,
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "cogl-pipeline-private.h"
|
#include "cogl-pipeline-private.h"
|
||||||
|
#include "cogl-pipeline-layer-private.h"
|
||||||
#include "cogl-shader-private.h"
|
#include "cogl-shader-private.h"
|
||||||
#include "cogl-blend-string.h"
|
#include "cogl-blend-string.h"
|
||||||
|
|
||||||
@ -730,7 +731,7 @@ ensure_layer_generated (CoglPipeline *pipeline,
|
|||||||
" vec4 layer%i;\n",
|
" vec4 layer%i;\n",
|
||||||
layer_index);
|
layer_index);
|
||||||
|
|
||||||
if (!_cogl_pipeline_need_texture_combine_separate (combine_authority) ||
|
if (!_cogl_pipeline_layer_needs_combine_separate (combine_authority) ||
|
||||||
/* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function
|
/* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function
|
||||||
* since if you use it, it overrides your ALPHA function...
|
* since if you use it, it overrides your ALPHA function...
|
||||||
*/
|
*/
|
||||||
|
380
cogl/cogl-pipeline-layer-private.h
Normal file
380
cogl/cogl-pipeline-layer-private.h
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <glib.h>
|
||||||
|
|
||||||
|
/* This isn't defined in the GLES headers */
|
||||||
|
#ifndef GL_CLAMP_TO_BORDER
|
||||||
|
#define GL_CLAMP_TO_BORDER 0x812d
|
||||||
|
#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_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<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_FILTERS =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_WRAP_MODES =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
||||||
|
|
||||||
|
COGL_PIPELINE_LAYER_STATE_COMBINE =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_USER_MATRIX =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
||||||
|
|
||||||
|
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS =
|
||||||
|
1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
||||||
|
|
||||||
|
/* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
|
||||||
|
|
||||||
|
} CoglPipelineLayerState;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various special masks that tag state-groups in different ways...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define COGL_PIPELINE_LAYER_STATE_ALL \
|
||||||
|
((1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1)
|
||||||
|
|
||||||
|
#define COGL_PIPELINE_LAYER_STATE_ALL_SPARSE \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_ALL
|
||||||
|
|
||||||
|
#define COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE \
|
||||||
|
(COGL_PIPELINE_LAYER_STATE_COMBINE | \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT | \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_USER_MATRIX | \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS)
|
||||||
|
|
||||||
|
#define COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY \
|
||||||
|
(COGL_PIPELINE_LAYER_STATE_FILTERS | \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_WRAP_MODES | \
|
||||||
|
COGL_PIPELINE_LAYER_STATE_COMBINE)
|
||||||
|
|
||||||
|
#define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN 0
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* These are the same values as GL */
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_ADD = 0x0104,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED = 0x8574,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_SUBTRACT = 0x84E7,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE = 0x8575,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_REPLACE = 0x1E01,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_MODULATE = 0x2100,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB = 0x86AE,
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA = 0x86AF
|
||||||
|
} CoglPipelineCombineFunc;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* These are the same values as GL */
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE = 0x1702,
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_CONSTANT = 0x8576,
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR = 0x8577,
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS = 0x8578,
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 = 0x84C0
|
||||||
|
} CoglPipelineCombineSource;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* These are the same values as GL */
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_COLOR = 0x0300,
|
||||||
|
COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR = 0x0301,
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA = 0x0302,
|
||||||
|
COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA = 0x0303
|
||||||
|
} CoglPipelineCombineOp;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* The texture combine state determines how the color of individual
|
||||||
|
* texture fragments are calculated. */
|
||||||
|
CoglPipelineCombineFunc texture_combine_rgb_func;
|
||||||
|
CoglPipelineCombineSource texture_combine_rgb_src[3];
|
||||||
|
CoglPipelineCombineOp texture_combine_rgb_op[3];
|
||||||
|
|
||||||
|
CoglPipelineCombineFunc texture_combine_alpha_func;
|
||||||
|
CoglPipelineCombineSource texture_combine_alpha_src[3];
|
||||||
|
CoglPipelineCombineOp texture_combine_alpha_op[3];
|
||||||
|
|
||||||
|
float texture_combine_constant[4];
|
||||||
|
|
||||||
|
/* The texture matrix dscribes how to transform texture coordinates */
|
||||||
|
CoglMatrix matrix;
|
||||||
|
|
||||||
|
gboolean point_sprite_coords;
|
||||||
|
|
||||||
|
} CoglPipelineLayerBigState;
|
||||||
|
|
||||||
|
struct _CoglPipelineLayer
|
||||||
|
{
|
||||||
|
/* XXX: Please think twice about adding members that *have* be
|
||||||
|
* initialized during a _cogl_pipeline_layer_copy. We are aiming
|
||||||
|
* to have copies be as cheap as possible and copies may be
|
||||||
|
* done by the primitives APIs which means they may happen
|
||||||
|
* in performance critical code paths.
|
||||||
|
*
|
||||||
|
* XXX: If you are extending the state we track please consider if
|
||||||
|
* the state is expected to vary frequently across many pipelines or
|
||||||
|
* if the state can be shared among many derived pipelines instead.
|
||||||
|
* This will determine if the state should be added directly to this
|
||||||
|
* structure which will increase the memory overhead for *all*
|
||||||
|
* layers or if instead it can go under ->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 */
|
@ -28,11 +28,22 @@
|
|||||||
#ifndef __COGL_PIPELINE_LAYER_STATE_PRIVATE_H
|
#ifndef __COGL_PIPELINE_LAYER_STATE_PRIVATE_H
|
||||||
#define __COGL_PIPELINE_LAYER_STATE_PRIVATE_H
|
#define __COGL_PIPELINE_LAYER_STATE_PRIVATE_H
|
||||||
|
|
||||||
|
#include "cogl-pipeline-layer-state.h"
|
||||||
|
#include "cogl-pipeline-private.h"
|
||||||
|
|
||||||
CoglPipelineLayer *
|
CoglPipelineLayer *
|
||||||
_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner,
|
_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner,
|
||||||
CoglPipelineLayer *layer,
|
CoglPipelineLayer *layer,
|
||||||
int unit_index);
|
int unit_index);
|
||||||
|
|
||||||
|
CoglPipelineFilter
|
||||||
|
_cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline,
|
||||||
|
int layer_index);
|
||||||
|
|
||||||
|
CoglPipelineFilter
|
||||||
|
_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline,
|
||||||
|
int layer_index);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0,
|
_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0,
|
||||||
CoglPipelineLayer *authority1,
|
CoglPipelineLayer *authority1,
|
||||||
|
798
cogl/cogl-pipeline-layer.c
Normal file
798
cogl/cogl-pipeline-layer.c
Normal file
@ -0,0 +1,798 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008,2009,2010 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl-pipeline.h"
|
||||||
|
#include "cogl-pipeline-layer-private.h"
|
||||||
|
#include "cogl-pipeline-layer-state-private.h"
|
||||||
|
#include "cogl-pipeline-layer-state.h"
|
||||||
|
#include "cogl-node-private.h"
|
||||||
|
#include "cogl-pipeline-opengl-private.h"
|
||||||
|
#include "cogl-context-private.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pipeline_layer_free (CoglPipelineLayer *layer);
|
||||||
|
|
||||||
|
/* This type was made deprecated before the cogl_is_pipeline_layer
|
||||||
|
function was ever exposed in the public headers so there's no need
|
||||||
|
to make the cogl_is_pipeline_layer function public. We use INTERNAL
|
||||||
|
so that the cogl_is_* function won't get defined */
|
||||||
|
COGL_OBJECT_INTERNAL_DEFINE (PipelineLayer, pipeline_layer);
|
||||||
|
|
||||||
|
|
||||||
|
CoglPipelineLayer *
|
||||||
|
_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer,
|
||||||
|
unsigned long difference)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *authority = layer;
|
||||||
|
while (!(authority->differences & difference))
|
||||||
|
authority = _cogl_pipeline_layer_get_parent (authority);
|
||||||
|
return authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *authority =
|
||||||
|
_cogl_pipeline_layer_get_authority (layer, COGL_PIPELINE_LAYER_STATE_UNIT);
|
||||||
|
return authority->unit_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *combine_authority =
|
||||||
|
_cogl_pipeline_layer_get_authority (layer,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_COMBINE);
|
||||||
|
CoglPipelineLayerBigState *big_state = combine_authority->big_state;
|
||||||
|
CoglPipelineLayer *tex_authority;
|
||||||
|
|
||||||
|
/* has_alpha maintains the alpha status for the GL_PREVIOUS layer */
|
||||||
|
|
||||||
|
/* For anything but the default texture combine we currently just
|
||||||
|
* assume it may result in an alpha value < 1
|
||||||
|
*
|
||||||
|
* FIXME: we could do better than this. */
|
||||||
|
if (big_state->texture_combine_alpha_func !=
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_MODULATE ||
|
||||||
|
big_state->texture_combine_alpha_src[0] !=
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS ||
|
||||||
|
big_state->texture_combine_alpha_op[0] !=
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA ||
|
||||||
|
big_state->texture_combine_alpha_src[1] !=
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE ||
|
||||||
|
big_state->texture_combine_alpha_op[1] !=
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NB: A layer may have a combine mode set on it but not yet
|
||||||
|
* have an associated texture which would mean we'd fallback
|
||||||
|
* to the default texture which doesn't have an alpha component
|
||||||
|
*/
|
||||||
|
tex_authority =
|
||||||
|
_cogl_pipeline_layer_get_authority (layer,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA);
|
||||||
|
if (tex_authority->texture &&
|
||||||
|
cogl_texture_get_format (tex_authority->texture) & COGL_A_BIT)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func)
|
||||||
|
{
|
||||||
|
switch (func)
|
||||||
|
{
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_REPLACE:
|
||||||
|
return 1;
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_MODULATE:
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_ADD:
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED:
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT:
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB:
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA:
|
||||||
|
return 2;
|
||||||
|
case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE:
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pipeline_layer_init_multi_property_sparse_state (
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayerState change)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *authority;
|
||||||
|
|
||||||
|
/* Nothing to initialize in these cases since they are all comprised
|
||||||
|
* of one member which we expect to immediately be overwritten. */
|
||||||
|
if (!(change & COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
authority = _cogl_pipeline_layer_get_authority (layer, change);
|
||||||
|
|
||||||
|
switch (change)
|
||||||
|
{
|
||||||
|
/* XXX: avoid using a default: label so we get a warning if we
|
||||||
|
* don't explicitly handle a newly defined state-group here. */
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_UNIT:
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET:
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA:
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS:
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_USER_MATRIX:
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT:
|
||||||
|
g_return_if_reached ();
|
||||||
|
|
||||||
|
/* XXX: technically we could probably even consider these as
|
||||||
|
* single property state-groups from the pov that currently the
|
||||||
|
* corresponding property setters always update all of the values
|
||||||
|
* at the same time. */
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_FILTERS:
|
||||||
|
layer->min_filter = authority->min_filter;
|
||||||
|
layer->mag_filter = authority->mag_filter;
|
||||||
|
break;
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_WRAP_MODES:
|
||||||
|
layer->wrap_mode_s = authority->wrap_mode_s;
|
||||||
|
layer->wrap_mode_t = authority->wrap_mode_t;
|
||||||
|
layer->wrap_mode_p = authority->wrap_mode_p;
|
||||||
|
break;
|
||||||
|
case COGL_PIPELINE_LAYER_STATE_COMBINE:
|
||||||
|
{
|
||||||
|
int n_args;
|
||||||
|
int i;
|
||||||
|
CoglPipelineLayerBigState *src_big_state = authority->big_state;
|
||||||
|
CoglPipelineLayerBigState *dest_big_state = layer->big_state;
|
||||||
|
GLint func = src_big_state->texture_combine_rgb_func;
|
||||||
|
|
||||||
|
dest_big_state->texture_combine_rgb_func = func;
|
||||||
|
n_args = _cogl_get_n_args_for_combine_func (func);
|
||||||
|
for (i = 0; i < n_args; i++)
|
||||||
|
{
|
||||||
|
dest_big_state->texture_combine_rgb_src[i] =
|
||||||
|
src_big_state->texture_combine_rgb_src[i];
|
||||||
|
dest_big_state->texture_combine_rgb_op[i] =
|
||||||
|
src_big_state->texture_combine_rgb_op[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
func = src_big_state->texture_combine_alpha_func;
|
||||||
|
dest_big_state->texture_combine_alpha_func = func;
|
||||||
|
n_args = _cogl_get_n_args_for_combine_func (func);
|
||||||
|
for (i = 0; i < n_args; i++)
|
||||||
|
{
|
||||||
|
dest_big_state->texture_combine_alpha_src[i] =
|
||||||
|
src_big_state->texture_combine_alpha_src[i];
|
||||||
|
dest_big_state->texture_combine_alpha_op[i] =
|
||||||
|
src_big_state->texture_combine_alpha_op[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NB: If a layer has descendants we can't modify the layer
|
||||||
|
* NB: If the layer is owned and the owner has descendants we can't
|
||||||
|
* modify the layer.
|
||||||
|
*
|
||||||
|
* This function will allocate a new derived layer if you are trying
|
||||||
|
* to change the state of a layer with dependants (as described above)
|
||||||
|
* so you must always check the return value.
|
||||||
|
*
|
||||||
|
* If a new layer is returned it will be owned by required_owner.
|
||||||
|
* (NB: a layer is always modified with respect to a pipeline - the
|
||||||
|
* "required_owner")
|
||||||
|
*
|
||||||
|
* required_owner can only by NULL for new, currently unowned layers
|
||||||
|
* with no dependants.
|
||||||
|
*/
|
||||||
|
CoglPipelineLayer *
|
||||||
|
_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayerState change)
|
||||||
|
{
|
||||||
|
CoglTextureUnit *unit;
|
||||||
|
|
||||||
|
/* Identify the case where the layer is new with no owner or
|
||||||
|
* dependants and so we don't need to do anything. */
|
||||||
|
if (COGL_LIST_EMPTY (&COGL_NODE (layer)->children) &&
|
||||||
|
layer->owner == NULL)
|
||||||
|
goto init_layer_state;
|
||||||
|
|
||||||
|
/* We only allow a NULL required_owner for new layers */
|
||||||
|
g_return_val_if_fail (required_owner != NULL, layer);
|
||||||
|
|
||||||
|
/* Chain up:
|
||||||
|
* A modification of a layer is indirectly also a modification of
|
||||||
|
* its owner so first make sure to flush the journal of any
|
||||||
|
* references to the current owner state and if necessary perform
|
||||||
|
* a copy-on-write for the required_owner if it has dependants.
|
||||||
|
*/
|
||||||
|
_cogl_pipeline_pre_change_notify (required_owner,
|
||||||
|
COGL_PIPELINE_STATE_LAYERS,
|
||||||
|
NULL,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
/* Unlike pipelines; layers are simply considered immutable once
|
||||||
|
* they have dependants - either direct children, or another
|
||||||
|
* pipeline as an owner.
|
||||||
|
*/
|
||||||
|
if (!COGL_LIST_EMPTY (&COGL_NODE (layer)->children) ||
|
||||||
|
layer->owner != required_owner)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer);
|
||||||
|
if (layer->owner == required_owner)
|
||||||
|
_cogl_pipeline_remove_layer_difference (required_owner, layer, FALSE);
|
||||||
|
_cogl_pipeline_add_layer_difference (required_owner, new, FALSE);
|
||||||
|
cogl_object_unref (new);
|
||||||
|
layer = new;
|
||||||
|
goto init_layer_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: At this point we know there is only one pipeline dependant on
|
||||||
|
* this layer (required_owner), and there are no other layers
|
||||||
|
* dependant on this layer so it's ok to modify it. */
|
||||||
|
|
||||||
|
_cogl_pipeline_fragend_layer_change_notify (required_owner, layer, change);
|
||||||
|
_cogl_pipeline_vertend_layer_change_notify (required_owner, layer, change);
|
||||||
|
_cogl_pipeline_progend_layer_change_notify (required_owner, layer, change);
|
||||||
|
|
||||||
|
/* If the layer being changed is the same as the last layer we
|
||||||
|
* flushed to the corresponding texture unit then we keep a track of
|
||||||
|
* the changes so we can try to minimize redundant OpenGL calls if
|
||||||
|
* the same layer is flushed again.
|
||||||
|
*/
|
||||||
|
unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer));
|
||||||
|
if (unit->layer == layer)
|
||||||
|
unit->layer_changes_since_flush |= change;
|
||||||
|
|
||||||
|
init_layer_state:
|
||||||
|
|
||||||
|
if (required_owner)
|
||||||
|
required_owner->age++;
|
||||||
|
|
||||||
|
if (change & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE &&
|
||||||
|
!layer->has_big_state)
|
||||||
|
{
|
||||||
|
layer->big_state = g_slice_new (CoglPipelineLayerBigState);
|
||||||
|
layer->has_big_state = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: conceptually we have just been notified that a single
|
||||||
|
* property value is about to change, but since some state-groups
|
||||||
|
* contain multiple properties and 'layer' is about to take over
|
||||||
|
* being the authority for the property's corresponding state-group
|
||||||
|
* we need to maintain the integrity of the other property values
|
||||||
|
* too.
|
||||||
|
*
|
||||||
|
* To ensure this we handle multi-property state-groups by copying
|
||||||
|
* all the values from the old-authority to the new...
|
||||||
|
*
|
||||||
|
* We don't have to worry about non-sparse property groups since
|
||||||
|
* we never take over being an authority for such properties so
|
||||||
|
* they automatically maintain integrity.
|
||||||
|
*/
|
||||||
|
if (change & COGL_PIPELINE_LAYER_STATE_ALL_SPARSE &&
|
||||||
|
!(layer->differences & change))
|
||||||
|
{
|
||||||
|
_cogl_pipeline_layer_init_multi_property_sparse_state (layer, change);
|
||||||
|
layer->differences |= change;
|
||||||
|
}
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pipeline_layer_unparent (CoglNode *layer)
|
||||||
|
{
|
||||||
|
/* Chain up */
|
||||||
|
_cogl_pipeline_node_unparent_real (layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pipeline_layer_set_parent (CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayer *parent)
|
||||||
|
{
|
||||||
|
/* Chain up */
|
||||||
|
_cogl_pipeline_node_set_parent_real (COGL_NODE (layer),
|
||||||
|
COGL_NODE (parent),
|
||||||
|
_cogl_pipeline_layer_unparent,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPipelineLayer *
|
||||||
|
_cogl_pipeline_layer_copy (CoglPipelineLayer *src)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *layer = g_slice_new (CoglPipelineLayer);
|
||||||
|
|
||||||
|
_cogl_pipeline_node_init (COGL_NODE (layer));
|
||||||
|
|
||||||
|
layer->owner = NULL;
|
||||||
|
layer->index = src->index;
|
||||||
|
layer->differences = 0;
|
||||||
|
layer->has_big_state = FALSE;
|
||||||
|
|
||||||
|
_cogl_pipeline_layer_set_parent (layer, src);
|
||||||
|
|
||||||
|
return _cogl_pipeline_layer_object_new (layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: This is duplicated logic; the same as for
|
||||||
|
* _cogl_pipeline_prune_redundant_ancestry it would be nice to find a
|
||||||
|
* way to consolidate these functions! */
|
||||||
|
void
|
||||||
|
_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *new_parent = _cogl_pipeline_layer_get_parent (layer);
|
||||||
|
|
||||||
|
/* walk up past ancestors that are now redundant and potentially
|
||||||
|
* reparent the layer. */
|
||||||
|
while (_cogl_pipeline_layer_get_parent (new_parent) &&
|
||||||
|
(new_parent->differences | layer->differences) ==
|
||||||
|
layer->differences)
|
||||||
|
new_parent = _cogl_pipeline_layer_get_parent (new_parent);
|
||||||
|
|
||||||
|
_cogl_pipeline_layer_set_parent (layer, new_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the mask of differences between two layers.
|
||||||
|
*
|
||||||
|
* XXX: If layers and pipelines could both be cast to a common Tree
|
||||||
|
* type of some kind then we could have a unified
|
||||||
|
* compare_differences() function.
|
||||||
|
*/
|
||||||
|
unsigned long
|
||||||
|
_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0,
|
||||||
|
CoglPipelineLayer *layer1)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *node0;
|
||||||
|
CoglPipelineLayer *node1;
|
||||||
|
int len0;
|
||||||
|
int len1;
|
||||||
|
int len0_index;
|
||||||
|
int len1_index;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
CoglPipelineLayer *common_ancestor = NULL;
|
||||||
|
unsigned long layers_difference = 0;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, 0);
|
||||||
|
|
||||||
|
/* Algorithm:
|
||||||
|
*
|
||||||
|
* 1) Walk the ancestors of each layer to the root node, adding a
|
||||||
|
* pointer to each ancester node to two GArrays:
|
||||||
|
* ctx->pipeline0_nodes, and ctx->pipeline1_nodes.
|
||||||
|
*
|
||||||
|
* 2) Compare the arrays to find the nodes where they stop to
|
||||||
|
* differ.
|
||||||
|
*
|
||||||
|
* 3) For each array now iterate from index 0 to the first node of
|
||||||
|
* difference ORing that nodes ->difference mask into the final
|
||||||
|
* pipeline_differences mask.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_array_set_size (ctx->pipeline0_nodes, 0);
|
||||||
|
g_array_set_size (ctx->pipeline1_nodes, 0);
|
||||||
|
for (node0 = layer0; node0; node0 = _cogl_pipeline_layer_get_parent (node0))
|
||||||
|
g_array_append_vals (ctx->pipeline0_nodes, &node0, 1);
|
||||||
|
for (node1 = layer1; node1; node1 = _cogl_pipeline_layer_get_parent (node1))
|
||||||
|
g_array_append_vals (ctx->pipeline1_nodes, &node1, 1);
|
||||||
|
|
||||||
|
len0 = ctx->pipeline0_nodes->len;
|
||||||
|
len1 = ctx->pipeline1_nodes->len;
|
||||||
|
/* There's no point looking at the last entries since we know both
|
||||||
|
* layers must have the same default layer as their root node. */
|
||||||
|
len0_index = len0 - 2;
|
||||||
|
len1_index = len1 - 2;
|
||||||
|
count = MIN (len0, len1) - 1;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
node0 = g_array_index (ctx->pipeline0_nodes,
|
||||||
|
CoglPipelineLayer *, len0_index--);
|
||||||
|
node1 = g_array_index (ctx->pipeline1_nodes,
|
||||||
|
CoglPipelineLayer *, len1_index--);
|
||||||
|
if (node0 != node1)
|
||||||
|
{
|
||||||
|
common_ancestor = _cogl_pipeline_layer_get_parent (node0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't already find the first the common_ancestor ancestor
|
||||||
|
* that's because one pipeline is a direct descendant of the other
|
||||||
|
* and in this case the first common ancestor is the last node we
|
||||||
|
* looked at. */
|
||||||
|
if (!common_ancestor)
|
||||||
|
common_ancestor = node0;
|
||||||
|
|
||||||
|
count = len0 - 1;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
node0 = g_array_index (ctx->pipeline0_nodes, CoglPipelineLayer *, i);
|
||||||
|
if (node0 == common_ancestor)
|
||||||
|
break;
|
||||||
|
layers_difference |= node0->differences;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = len1 - 1;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
node1 = g_array_index (ctx->pipeline1_nodes, CoglPipelineLayer *, i);
|
||||||
|
if (node1 == common_ancestor)
|
||||||
|
break;
|
||||||
|
layers_difference |= node1->differences;
|
||||||
|
}
|
||||||
|
|
||||||
|
return layers_difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
layer_state_equal (CoglPipelineLayerStateIndex state_index,
|
||||||
|
CoglPipelineLayer **authorities0,
|
||||||
|
CoglPipelineLayer **authorities1,
|
||||||
|
CoglPipelineLayerStateComparitor comparitor)
|
||||||
|
{
|
||||||
|
return comparitor (authorities0[state_index], authorities1[state_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer,
|
||||||
|
unsigned long differences,
|
||||||
|
CoglPipelineLayer **authorities)
|
||||||
|
{
|
||||||
|
unsigned long remaining = differences;
|
||||||
|
CoglPipelineLayer *authority = layer;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned long found = authority->differences & remaining;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (found == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; TRUE; i++)
|
||||||
|
{
|
||||||
|
unsigned long state = (1L<<i);
|
||||||
|
|
||||||
|
if (state & found)
|
||||||
|
authorities[i] = authority;
|
||||||
|
else if (state > found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining &= ~found;
|
||||||
|
if (remaining == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while ((authority = _cogl_pipeline_layer_get_parent (authority)));
|
||||||
|
|
||||||
|
g_assert (remaining == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
|
||||||
|
CoglPipelineLayer *layer1,
|
||||||
|
unsigned long differences_mask,
|
||||||
|
CoglPipelineEvalFlags flags)
|
||||||
|
{
|
||||||
|
unsigned long layers_difference;
|
||||||
|
CoglPipelineLayer *authorities0[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT];
|
||||||
|
CoglPipelineLayer *authorities1[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT];
|
||||||
|
|
||||||
|
if (layer0 == layer1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
layers_difference =
|
||||||
|
_cogl_pipeline_layer_compare_differences (layer0, layer1);
|
||||||
|
|
||||||
|
/* Only compare the sparse state groups requested by the caller... */
|
||||||
|
layers_difference &= differences_mask;
|
||||||
|
|
||||||
|
_cogl_pipeline_layer_resolve_authorities (layer0,
|
||||||
|
layers_difference,
|
||||||
|
authorities0);
|
||||||
|
_cogl_pipeline_layer_resolve_authorities (layer1,
|
||||||
|
layers_difference,
|
||||||
|
authorities1);
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET)
|
||||||
|
{
|
||||||
|
CoglPipelineLayerStateIndex state_index =
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX;
|
||||||
|
if (!_cogl_pipeline_layer_texture_target_equal (authorities0[state_index],
|
||||||
|
authorities1[state_index],
|
||||||
|
flags))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
|
||||||
|
{
|
||||||
|
CoglPipelineLayerStateIndex state_index =
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX;
|
||||||
|
if (!_cogl_pipeline_layer_texture_data_equal (authorities0[state_index],
|
||||||
|
authorities1[state_index],
|
||||||
|
flags))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_combine_state_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_combine_constant_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_FILTERS &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_filters_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_WRAP_MODES &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_wrap_modes_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_user_matrix_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS &&
|
||||||
|
!layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
||||||
|
authorities0, authorities1,
|
||||||
|
_cogl_pipeline_layer_point_sprite_coords_equal))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_pipeline_layer_free (CoglPipelineLayer *layer)
|
||||||
|
{
|
||||||
|
_cogl_pipeline_layer_unparent (COGL_NODE (layer));
|
||||||
|
|
||||||
|
if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA &&
|
||||||
|
layer->texture != NULL)
|
||||||
|
cogl_object_unref (layer->texture);
|
||||||
|
|
||||||
|
if (layer->differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE)
|
||||||
|
g_slice_free (CoglPipelineLayerBigState, layer->big_state);
|
||||||
|
|
||||||
|
g_slice_free (CoglPipelineLayer, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_init_default_layers (void)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *layer = g_slice_new0 (CoglPipelineLayer);
|
||||||
|
CoglPipelineLayerBigState *big_state =
|
||||||
|
g_slice_new0 (CoglPipelineLayerBigState);
|
||||||
|
CoglPipelineLayer *new;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
_cogl_pipeline_node_init (COGL_NODE (layer));
|
||||||
|
|
||||||
|
layer->index = 0;
|
||||||
|
|
||||||
|
layer->differences = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE;
|
||||||
|
|
||||||
|
layer->unit_index = 0;
|
||||||
|
|
||||||
|
layer->texture = NULL;
|
||||||
|
layer->target = 0;
|
||||||
|
|
||||||
|
layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||||
|
layer->min_filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||||
|
|
||||||
|
layer->wrap_mode_s = COGL_PIPELINE_WRAP_MODE_AUTOMATIC;
|
||||||
|
layer->wrap_mode_t = COGL_PIPELINE_WRAP_MODE_AUTOMATIC;
|
||||||
|
layer->wrap_mode_p = COGL_PIPELINE_WRAP_MODE_AUTOMATIC;
|
||||||
|
|
||||||
|
layer->big_state = big_state;
|
||||||
|
layer->has_big_state = TRUE;
|
||||||
|
|
||||||
|
/* Choose the same default combine mode as OpenGL:
|
||||||
|
* RGBA = MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */
|
||||||
|
big_state->texture_combine_rgb_func =
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_MODULATE;
|
||||||
|
big_state->texture_combine_rgb_src[0] =
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS;
|
||||||
|
big_state->texture_combine_rgb_src[1] =
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE;
|
||||||
|
big_state->texture_combine_rgb_op[0] =
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_COLOR;
|
||||||
|
big_state->texture_combine_rgb_op[1] =
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_COLOR;
|
||||||
|
big_state->texture_combine_alpha_func =
|
||||||
|
COGL_PIPELINE_COMBINE_FUNC_MODULATE;
|
||||||
|
big_state->texture_combine_alpha_src[0] =
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS;
|
||||||
|
big_state->texture_combine_alpha_src[1] =
|
||||||
|
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE;
|
||||||
|
big_state->texture_combine_alpha_op[0] =
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA;
|
||||||
|
big_state->texture_combine_alpha_op[1] =
|
||||||
|
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA;
|
||||||
|
|
||||||
|
big_state->point_sprite_coords = FALSE;
|
||||||
|
|
||||||
|
cogl_matrix_init_identity (&big_state->matrix);
|
||||||
|
|
||||||
|
ctx->default_layer_0 = _cogl_pipeline_layer_object_new (layer);
|
||||||
|
|
||||||
|
/* TODO: we should make default_layer_n comprise of two
|
||||||
|
* descendants of default_layer_0:
|
||||||
|
* - the first descendant should change the texture combine
|
||||||
|
* to what we expect is most commonly used for multitexturing
|
||||||
|
* - the second should revert the above change.
|
||||||
|
*
|
||||||
|
* why? the documentation for how a new layer is initialized
|
||||||
|
* doesn't say that layers > 0 have different defaults so unless
|
||||||
|
* we change the documentation we can't use different defaults,
|
||||||
|
* but if the user does what we expect and changes the
|
||||||
|
* texture combine then we can revert the authority to the
|
||||||
|
* first descendant which means we can maximize the number
|
||||||
|
* of layers with a common ancestor.
|
||||||
|
*
|
||||||
|
* The main problem will be that we'll need to disable the
|
||||||
|
* optimizations for flattening the ancestry when we make
|
||||||
|
* the second descendant which reverts the state.
|
||||||
|
*/
|
||||||
|
ctx->default_layer_n = _cogl_pipeline_layer_copy (layer);
|
||||||
|
new = _cogl_pipeline_set_layer_unit (NULL, ctx->default_layer_n, 1);
|
||||||
|
g_assert (new == ctx->default_layer_n);
|
||||||
|
/* Since we passed a newly allocated layer we don't expect that
|
||||||
|
* _set_layer_unit() will have to allocate *another* layer. */
|
||||||
|
|
||||||
|
/* Finally we create a dummy dependant for ->default_layer_n which
|
||||||
|
* effectively ensures that ->default_layer_n and ->default_layer_0
|
||||||
|
* remain immutable.
|
||||||
|
*/
|
||||||
|
ctx->dummy_layer_dependant =
|
||||||
|
_cogl_pipeline_layer_copy (ctx->default_layer_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layer)
|
||||||
|
{
|
||||||
|
CoglPipelineLayer *texture_authority;
|
||||||
|
|
||||||
|
texture_authority =
|
||||||
|
_cogl_pipeline_layer_get_authority (layer,
|
||||||
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA);
|
||||||
|
|
||||||
|
if (texture_authority->texture != NULL)
|
||||||
|
{
|
||||||
|
CoglTexturePrePaintFlags flags = 0;
|
||||||
|
CoglPipelineFilter min_filter;
|
||||||
|
CoglPipelineFilter mag_filter;
|
||||||
|
|
||||||
|
_cogl_pipeline_layer_get_filters (layer, &min_filter, &mag_filter);
|
||||||
|
|
||||||
|
if (min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST
|
||||||
|
|| min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST
|
||||||
|
|| min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR
|
||||||
|
|| min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR)
|
||||||
|
flags |= COGL_TEXTURE_NEEDS_MIPMAP;
|
||||||
|
|
||||||
|
_cogl_texture_pre_paint (texture_authority->texture, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determines if we need to handle the RGB and A texture combining
|
||||||
|
* separately or is the same function used for both channel masks and
|
||||||
|
* with the same arguments...
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_pipeline_layer_needs_combine_separate
|
||||||
|
(CoglPipelineLayer *combine_authority)
|
||||||
|
{
|
||||||
|
CoglPipelineLayerBigState *big_state = combine_authority->big_state;
|
||||||
|
int n_args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (big_state->texture_combine_rgb_func !=
|
||||||
|
big_state->texture_combine_alpha_func)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
n_args = _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func);
|
||||||
|
|
||||||
|
for (i = 0; i < n_args; i++)
|
||||||
|
{
|
||||||
|
if (big_state->texture_combine_rgb_src[i] !=
|
||||||
|
big_state->texture_combine_alpha_src[i])
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can allow some variation of the source operands without
|
||||||
|
* needing a separation...
|
||||||
|
*
|
||||||
|
* "A = REPLACE (CONSTANT[A])" + either of the following...
|
||||||
|
* "RGB = REPLACE (CONSTANT[RGB])"
|
||||||
|
* "RGB = REPLACE (CONSTANT[A])"
|
||||||
|
*
|
||||||
|
* can be combined as:
|
||||||
|
* "RGBA = REPLACE (CONSTANT)" or
|
||||||
|
* "RGBA = REPLACE (CONSTANT[A])" or
|
||||||
|
*
|
||||||
|
* And "A = REPLACE (1-CONSTANT[A])" + either of the following...
|
||||||
|
* "RGB = REPLACE (1-CONSTANT)" or
|
||||||
|
* "RGB = REPLACE (1-CONSTANT[A])"
|
||||||
|
*
|
||||||
|
* can be combined as:
|
||||||
|
* "RGBA = REPLACE (1-CONSTANT)" or
|
||||||
|
* "RGBA = REPLACE (1-CONSTANT[A])"
|
||||||
|
*/
|
||||||
|
switch (big_state->texture_combine_alpha_op[i])
|
||||||
|
{
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
switch (big_state->texture_combine_rgb_op[i])
|
||||||
|
{
|
||||||
|
case GL_SRC_COLOR:
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
switch (big_state->texture_combine_rgb_op[i])
|
||||||
|
{
|
||||||
|
case GL_ONE_MINUS_SRC_COLOR:
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE; /* impossible */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008,2009,2010 Intel Corporation.
|
* Copyright (C) 2008,2009,2010,2011 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -28,19 +28,17 @@
|
|||||||
#ifndef __COGL_PIPELINE_PRIVATE_H
|
#ifndef __COGL_PIPELINE_PRIVATE_H
|
||||||
#define __COGL_PIPELINE_PRIVATE_H
|
#define __COGL_PIPELINE_PRIVATE_H
|
||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl-node-private.h"
|
||||||
|
#include "cogl-pipeline-layer-private.h"
|
||||||
#include "cogl-pipeline.h"
|
#include "cogl-pipeline.h"
|
||||||
#include "cogl-matrix.h"
|
#include "cogl-matrix.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-profile.h"
|
#include "cogl-profile.h"
|
||||||
#include "cogl-queue.h"
|
#include "cogl-queue.h"
|
||||||
|
#include "cogl-internal.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct _CoglPipelineLayer CoglPipelineLayer;
|
|
||||||
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
|
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GL
|
#ifdef HAVE_COGL_GL
|
||||||
|
|
||||||
#define COGL_PIPELINE_FRAGEND_ARBFP 0
|
#define COGL_PIPELINE_FRAGEND_ARBFP 0
|
||||||
@ -149,268 +147,6 @@ typedef struct _CoglPipelineLayer CoglPipelineLayer;
|
|||||||
#define COGL_PIPELINE_N_PROGENDS 0
|
#define COGL_PIPELINE_N_PROGENDS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_FILTERS =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
|
|
||||||
|
|
||||||
COGL_PIPELINE_LAYER_STATE_COMBINE =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX,
|
|
||||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX,
|
|
||||||
|
|
||||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS =
|
|
||||||
1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX,
|
|
||||||
|
|
||||||
/* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
|
|
||||||
|
|
||||||
} CoglPipelineLayerState;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Various special masks that tag state-groups in different ways...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_LAYER_STATE_ALL \
|
|
||||||
((1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1)
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_LAYER_STATE_ALL_SPARSE \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_ALL
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE \
|
|
||||||
(COGL_PIPELINE_LAYER_STATE_COMBINE | \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT | \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_USER_MATRIX | \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS)
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY \
|
|
||||||
(COGL_PIPELINE_LAYER_STATE_FILTERS | \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_WRAP_MODES | \
|
|
||||||
COGL_PIPELINE_LAYER_STATE_COMBINE)
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN 0
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/* These are the same values as GL */
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_ADD = 0x0104,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED = 0x8574,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_SUBTRACT = 0x84E7,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE = 0x8575,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_REPLACE = 0x1E01,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_MODULATE = 0x2100,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB = 0x86AE,
|
|
||||||
COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA = 0x86AF
|
|
||||||
} CoglPipelineCombineFunc;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/* These are the same values as GL */
|
|
||||||
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE = 0x1702,
|
|
||||||
COGL_PIPELINE_COMBINE_SOURCE_CONSTANT = 0x8576,
|
|
||||||
COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR = 0x8577,
|
|
||||||
COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS = 0x8578,
|
|
||||||
COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 = 0x84C0
|
|
||||||
} CoglPipelineCombineSource;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/* These are the same values as GL */
|
|
||||||
COGL_PIPELINE_COMBINE_OP_SRC_COLOR = 0x0300,
|
|
||||||
COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR = 0x0301,
|
|
||||||
COGL_PIPELINE_COMBINE_OP_SRC_ALPHA = 0x0302,
|
|
||||||
COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA = 0x0303
|
|
||||||
} CoglPipelineCombineOp;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* The texture combine state determines how the color of individual
|
|
||||||
* texture fragments are calculated. */
|
|
||||||
CoglPipelineCombineFunc texture_combine_rgb_func;
|
|
||||||
CoglPipelineCombineSource texture_combine_rgb_src[3];
|
|
||||||
CoglPipelineCombineOp texture_combine_rgb_op[3];
|
|
||||||
|
|
||||||
CoglPipelineCombineFunc texture_combine_alpha_func;
|
|
||||||
CoglPipelineCombineSource texture_combine_alpha_src[3];
|
|
||||||
CoglPipelineCombineOp texture_combine_alpha_op[3];
|
|
||||||
|
|
||||||
float texture_combine_constant[4];
|
|
||||||
|
|
||||||
/* The texture matrix dscribes how to transform texture coordinates */
|
|
||||||
CoglMatrix matrix;
|
|
||||||
|
|
||||||
gboolean point_sprite_coords;
|
|
||||||
|
|
||||||
} CoglPipelineLayerBigState;
|
|
||||||
|
|
||||||
typedef struct _CoglPipelineNode CoglPipelineNode;
|
|
||||||
|
|
||||||
COGL_LIST_HEAD (CoglPipelineNodeList, CoglPipelineNode);
|
|
||||||
|
|
||||||
/* Materials and 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... */
|
|
||||||
struct _CoglPipelineNode
|
|
||||||
{
|
|
||||||
/* the parent in terms of class hierarchy, so anything inheriting
|
|
||||||
* from CoglPipelineNode also inherits from CoglObject. */
|
|
||||||
CoglObject _parent;
|
|
||||||
|
|
||||||
/* The parent pipeline/layer */
|
|
||||||
CoglPipelineNode *parent;
|
|
||||||
|
|
||||||
/* The list entry here contains pointers to the node's siblings */
|
|
||||||
COGL_LIST_ENTRY (CoglPipelineNode) list_node;
|
|
||||||
|
|
||||||
/* List of children */
|
|
||||||
CoglPipelineNodeList children;
|
|
||||||
|
|
||||||
/* TRUE if the node took a strong reference on its parent. Weak
|
|
||||||
* pipelines for instance don't take a reference on their parent. */
|
|
||||||
gboolean has_parent_reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define COGL_PIPELINE_NODE(X) ((CoglPipelineNode *)(X))
|
|
||||||
|
|
||||||
typedef void (*CoglPipelineNodeUnparentVFunc) (CoglPipelineNode *node);
|
|
||||||
|
|
||||||
typedef gboolean (*CoglPipelineNodeChildCallback) (CoglPipelineNode *child,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_pipeline_node_foreach_child (CoglPipelineNode *node,
|
|
||||||
CoglPipelineNodeChildCallback callback,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
/* This isn't defined in the GLES headers */
|
|
||||||
#ifndef GL_CLAMP_TO_BORDER
|
|
||||||
#define GL_CLAMP_TO_BORDER 0x812d
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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_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;
|
|
||||||
|
|
||||||
struct _CoglPipelineLayer
|
|
||||||
{
|
|
||||||
/* XXX: Please think twice about adding members that *have* be
|
|
||||||
* initialized during a _cogl_pipeline_layer_copy. We are aiming
|
|
||||||
* to have copies be as cheap as possible and copies may be
|
|
||||||
* done by the primitives APIs which means they may happen
|
|
||||||
* in performance critical code paths.
|
|
||||||
*
|
|
||||||
* XXX: If you are extending the state we track please consider if
|
|
||||||
* the state is expected to vary frequently across many pipelines or
|
|
||||||
* if the state can be shared among many derived pipelines instead.
|
|
||||||
* This will determine if the state should be added directly to this
|
|
||||||
* structure which will increase the memory overhead for *all*
|
|
||||||
* layers or if instead it can go under ->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... */
|
|
||||||
CoglPipelineNode _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;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* XXX: should I rename these as
|
/* XXX: should I rename these as
|
||||||
* COGL_PIPELINE_STATE_INDEX_XYZ... ?
|
* COGL_PIPELINE_STATE_INDEX_XYZ... ?
|
||||||
*/
|
*/
|
||||||
@ -636,14 +372,6 @@ typedef struct
|
|||||||
CoglPipelineLayer *layer;
|
CoglPipelineLayer *layer;
|
||||||
} CoglPipelineLayerCacheEntry;
|
} CoglPipelineLayerCacheEntry;
|
||||||
|
|
||||||
/* Sometimes when evaluating pipelines, either during comparisons or
|
|
||||||
* if calculating a hash value we need to tweak the evaluation
|
|
||||||
* semantics */
|
|
||||||
typedef enum _CoglPipelineEvalFlags
|
|
||||||
{
|
|
||||||
COGL_PIPELINE_EVAL_FLAG_NONE = 0
|
|
||||||
} CoglPipelineEvalFlags;
|
|
||||||
|
|
||||||
typedef struct _CoglPipelineHashState
|
typedef struct _CoglPipelineHashState
|
||||||
{
|
{
|
||||||
unsigned long layer_differences;
|
unsigned long layer_differences;
|
||||||
@ -682,7 +410,7 @@ struct _CoglPipeline
|
|||||||
* the state relating to a given pipeline or layer may actually be
|
* 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
|
* 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... */
|
* type to track the tree heirachy so we can share code... */
|
||||||
CoglPipelineNode _parent;
|
CoglNode _parent;
|
||||||
|
|
||||||
/* We need to track if a pipeline is referenced in the journal
|
/* We need to track if a pipeline is referenced in the journal
|
||||||
* because we can't allow modification to these pipelines without
|
* because we can't allow modification to these pipelines without
|
||||||
@ -863,13 +591,10 @@ _cogl_pipeline_progends[];
|
|||||||
void
|
void
|
||||||
_cogl_pipeline_init_default_pipeline (void);
|
_cogl_pipeline_init_default_pipeline (void);
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_pipeline_init_default_layers (void);
|
|
||||||
|
|
||||||
static inline CoglPipeline *
|
static inline CoglPipeline *
|
||||||
_cogl_pipeline_get_parent (CoglPipeline *pipeline)
|
_cogl_pipeline_get_parent (CoglPipeline *pipeline)
|
||||||
{
|
{
|
||||||
CoglPipelineNode *parent_node = COGL_PIPELINE_NODE (pipeline)->parent;
|
CoglNode *parent_node = COGL_NODE (pipeline)->parent;
|
||||||
return COGL_PIPELINE (parent_node);
|
return COGL_PIPELINE (parent_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,11 +611,6 @@ _cogl_pipeline_get_authority (CoglPipeline *pipeline,
|
|||||||
typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0,
|
typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0,
|
||||||
CoglPipeline *authority1);
|
CoglPipeline *authority1);
|
||||||
|
|
||||||
typedef gboolean
|
|
||||||
(*CoglPipelineLayerStateComparitor) (CoglPipelineLayer *authority0,
|
|
||||||
CoglPipelineLayer *authority1);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_update_authority (CoglPipeline *pipeline,
|
_cogl_pipeline_update_authority (CoglPipeline *pipeline,
|
||||||
CoglPipeline *authority,
|
CoglPipeline *authority,
|
||||||
@ -916,21 +636,6 @@ _cogl_pipeline_get_layer (CoglPipeline *pipeline,
|
|||||||
gboolean
|
gboolean
|
||||||
_cogl_is_pipeline_layer (void *object);
|
_cogl_is_pipeline_layer (void *object);
|
||||||
|
|
||||||
static inline CoglPipelineLayer *
|
|
||||||
_cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer)
|
|
||||||
{
|
|
||||||
CoglPipelineNode *parent_node = COGL_PIPELINE_NODE (layer)->parent;
|
|
||||||
return COGL_PIPELINE_LAYER (parent_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
CoglPipelineLayer *
|
|
||||||
_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
|
|
||||||
CoglPipelineLayer *layer,
|
|
||||||
CoglPipelineLayerState change);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority,
|
_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority,
|
||||||
CoglPipelineLayer *layer);
|
CoglPipelineLayer *layer);
|
||||||
@ -949,18 +654,6 @@ _cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority,
|
|||||||
gboolean
|
gboolean
|
||||||
_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline);
|
_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calls the pre_paint method on the layer texture if there is
|
* Calls the pre_paint method on the layer texture if there is
|
||||||
* one. This will determine whether mipmaps are needed based on the
|
* one. This will determine whether mipmaps are needed based on the
|
||||||
@ -1181,14 +874,6 @@ _cogl_pipeline_journal_ref (CoglPipeline *pipeline);
|
|||||||
void
|
void
|
||||||
_cogl_pipeline_journal_unref (CoglPipeline *pipeline);
|
_cogl_pipeline_journal_unref (CoglPipeline *pipeline);
|
||||||
|
|
||||||
CoglPipelineFilter
|
|
||||||
_cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline,
|
|
||||||
int layer_index);
|
|
||||||
|
|
||||||
CoglPipelineFilter
|
|
||||||
_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline,
|
|
||||||
int layer_index);
|
|
||||||
|
|
||||||
const CoglMatrix *
|
const CoglMatrix *
|
||||||
_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline,
|
_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline,
|
||||||
int layer_index);
|
int layer_index);
|
||||||
@ -1224,6 +909,16 @@ CoglPipeline *
|
|||||||
_cogl_pipeline_get_authority (CoglPipeline *pipeline,
|
_cogl_pipeline_get_authority (CoglPipeline *pipeline,
|
||||||
unsigned long difference);
|
unsigned long difference);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
gboolean inc_n_layers);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
gboolean dec_n_layers);
|
||||||
|
|
||||||
CoglPipeline *
|
CoglPipeline *
|
||||||
_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline,
|
_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline,
|
||||||
CoglPipelineState pipeline_state,
|
CoglPipelineState pipeline_state,
|
||||||
@ -1249,62 +944,6 @@ _cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n);
|
|||||||
const GList *
|
const GList *
|
||||||
_cogl_pipeline_get_layers (CoglPipeline *pipeline);
|
_cogl_pipeline_get_layers (CoglPipeline *pipeline);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer,
|
typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
@ -1313,9 +952,6 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
|
|||||||
CoglPipelineInternalLayerCallback callback,
|
CoglPipelineInternalLayerCallback callback,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
int
|
|
||||||
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_pipeline_need_texture_combine_separate
|
_cogl_pipeline_need_texture_combine_separate
|
||||||
(CoglPipelineLayer *combine_authority);
|
(CoglPipelineLayer *combine_authority);
|
||||||
@ -1326,11 +962,26 @@ _cogl_pipeline_init_state_hash_functions (void);
|
|||||||
void
|
void
|
||||||
_cogl_pipeline_init_layer_state_hash_functions (void);
|
_cogl_pipeline_init_layer_state_hash_functions (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_fragend_layer_change_notify (CoglPipeline *owner,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayerState change);
|
||||||
|
|
||||||
CoglPipelineLayerState
|
CoglPipelineLayerState
|
||||||
_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context);
|
_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context);
|
||||||
|
|
||||||
CoglPipelineState
|
CoglPipelineState
|
||||||
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context);
|
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_vertend_layer_change_notify (CoglPipeline *owner,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayerState change);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_progend_layer_change_notify (CoglPipeline *owner,
|
||||||
|
CoglPipelineLayer *layer,
|
||||||
|
CoglPipelineLayerState change);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_PRIVATE_H */
|
#endif /* __COGL_PIPELINE_PRIVATE_H */
|
||||||
|
|
||||||
|
1161
cogl/cogl-pipeline.c
1161
cogl/cogl-pipeline.c
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,10 @@
|
|||||||
#ifndef __COGL_PIPELINE_H__
|
#ifndef __COGL_PIPELINE_H__
|
||||||
#define __COGL_PIPELINE_H__
|
#define __COGL_PIPELINE_H__
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#include <cogl/cogl-types.h>
|
#include <cogl/cogl-types.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#ifdef COGL_ENABLE_EXPERIMENTAL_API
|
#ifdef COGL_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +47,6 @@ G_BEGIN_DECLS
|
|||||||
* performs fragment processing including depth testing and texture
|
* performs fragment processing including depth testing and texture
|
||||||
* mapping. Finally it blends the result with the framebuffer.
|
* mapping. Finally it blends the result with the framebuffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _CoglPipeline CoglPipeline;
|
typedef struct _CoglPipeline CoglPipeline;
|
||||||
|
|
||||||
#define COGL_PIPELINE(OBJECT) ((CoglPipeline *)OBJECT)
|
#define COGL_PIPELINE(OBJECT) ((CoglPipeline *)OBJECT)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#if defined (COGL_ENABLE_EXPERIMENTAL_API)
|
#if defined (COGL_ENABLE_EXPERIMENTAL_API)
|
||||||
#include <cogl/cogl-pixel-buffer.h>
|
#include <cogl/cogl-pixel-buffer.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cogl/cogl-bitmap.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -939,6 +939,8 @@ AC_SUBST(COGL_GL_HEADER_INCLUDES)
|
|||||||
|
|
||||||
AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1],
|
AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1],
|
||||||
[Can use Cogl 2.0 API internally])
|
[Can use Cogl 2.0 API internally])
|
||||||
|
AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_API], [1],
|
||||||
|
[Can use experimental API internally])
|
||||||
|
|
||||||
AC_SUBST(COGL_DEP_CFLAGS)
|
AC_SUBST(COGL_DEP_CFLAGS)
|
||||||
AC_SUBST(COGL_DEP_LIBS)
|
AC_SUBST(COGL_DEP_LIBS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user