cogl: rename CoglMaterial -> CoglPipeline

This applies an API naming change that's been deliberated over for a
while now which is to rename CoglMaterial to CoglPipeline.

For now the new pipeline API is marked as experimental and public
headers continue to talk about materials not pipelines. The CoglMaterial
API is now maintained in terms of the cogl_pipeline API internally.
Currently this API is targeting Cogl 2.0 so we will have time to
integrate it properly with other upcoming Cogl 2.0 work.

The basic reasons for the rename are:
- That the term "material" implies to many people that they are
  constrained to fragment processing; perhaps as some kind of high-level
  texture abstraction.
    - In Clutter they get exposed by ClutterTexture actors which may be
      re-inforcing this misconception.
- When comparing how other frameworks use the term material, a material
  sometimes describes a multi-pass fragment processing technique which
  isn't the case in Cogl.
- In code, "CoglPipeline" will hopefully be a much more self documenting
  summary of what these objects represent; a full GPU pipeline
  configuration including, for example, vertex processing, fragment
  processing and blending.
- When considering the API documentation story, at some point we need a
  document introducing developers to how the "GPU pipeline" works so it
  should become intuitive that CoglPipeline maps back to that
  description of the GPU pipeline.
- This is consistent in terminology and concept to OpenGL 4's new
  pipeline object which is a container for program objects.

Note: The cogl-material.[ch] files have been renamed to
cogl-material-compat.[ch] because otherwise git doesn't seem to treat
the change as a moving the old cogl-material.c->cogl-pipeline.c and so
we loose all our git-blame history.
This commit is contained in:
Robert Bragg 2010-10-27 18:54:57 +01:00
parent 959af183b1
commit 8034dc87d4
45 changed files with 5305 additions and 3554 deletions

View File

@ -60,7 +60,8 @@ cogl_public_h = \
$(srcdir)/cogl-buffer.h \
$(srcdir)/cogl-color.h \
$(srcdir)/cogl-fixed.h \
$(srcdir)/cogl-material.h \
$(srcdir)/cogl-material-compat.h \
$(srcdir)/cogl-pipeline.h \
$(srcdir)/cogl-vector.h \
$(srcdir)/cogl-matrix.h \
$(srcdir)/cogl-offscreen.h \
@ -225,16 +226,17 @@ cogl_sources_c = \
$(srcdir)/cogl-matrix-private.h \
$(srcdir)/cogl-matrix-stack.c \
$(srcdir)/cogl-matrix-stack.h \
$(srcdir)/cogl-material.c \
$(srcdir)/cogl-material-private.h \
$(srcdir)/cogl-material-opengl.c \
$(srcdir)/cogl-material-opengl-private.h \
$(srcdir)/cogl-material-glsl.c \
$(srcdir)/cogl-material-glsl-private.h \
$(srcdir)/cogl-material-arbfp.c \
$(srcdir)/cogl-material-arbfp-private.h \
$(srcdir)/cogl-material-fixed.c \
$(srcdir)/cogl-material-fixed-private.h \
$(srcdir)/cogl-pipeline.c \
$(srcdir)/cogl-pipeline-private.h \
$(srcdir)/cogl-pipeline-opengl.c \
$(srcdir)/cogl-pipeline-opengl-private.h \
$(srcdir)/cogl-pipeline-glsl.c \
$(srcdir)/cogl-pipeline-glsl-private.h \
$(srcdir)/cogl-pipeline-arbfp.c \
$(srcdir)/cogl-pipeline-arbfp-private.h \
$(srcdir)/cogl-pipeline-fixed.c \
$(srcdir)/cogl-pipeline-fixed-private.h \
$(srcdir)/cogl-material-compat.c \
$(srcdir)/cogl-program.c \
$(srcdir)/cogl-program-private.h \
$(srcdir)/cogl-blend-string.c \

View File

@ -41,7 +41,7 @@
#include "cogl-texture-driver.h"
#include "cogl-rectangle-map.h"
#include "cogl-journal-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-atlas.h"
#include <stdlib.h>
@ -87,17 +87,17 @@ _cogl_atlas_texture_reorganize_foreach_cb (const CoglRectangleMapEntry *entry,
void *rectangle_data,
void *user_data)
{
/* Notify cogl-material.c that the texture's underlying GL texture
/* Notify cogl-pipeline.c that the texture's underlying GL texture
* storage is changing so it knows it may need to bind a new texture
* if the CoglTexture is reused with the same texture unit. */
_cogl_material_texture_storage_change_notify (rectangle_data);
_cogl_pipeline_texture_storage_change_notify (rectangle_data);
}
static void
_cogl_atlas_texture_reorganize_cb (void *data)
{
CoglAtlas *atlas;
/* We don't know if any materials may currently be referenced in
/* We don't know if any pipelines may currently be referenced in
* the journal that depend on the current underlying GL texture
* storage so we flush the journal before migrating.
*
@ -274,7 +274,7 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
{
COGL_NOTE (ATLAS, "Migrating texture out of the atlas");
/* We don't know if any materials may currently be referenced in
/* We don't know if any pipelines may currently be referenced in
* the journal that depend on the current underlying GL texture
* storage so we flush the journal before migrating.
*
@ -283,10 +283,10 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
*/
_cogl_journal_flush ();
/* Notify cogl-material.c that the texture's underlying GL texture
/* Notify cogl-pipeline.c that the texture's underlying GL texture
* storage is changing so it knows it may need to bind a new texture
* if the CoglTexture is reused with the same texture unit. */
_cogl_material_texture_storage_change_notify (atlas_tex);
_cogl_pipeline_texture_storage_change_notify (atlas_tex);
cogl_handle_unref (atlas_tex->sub_texture);

View File

@ -35,7 +35,7 @@
#include "cogl-texture-private.h"
#include "cogl-texture-2d-private.h"
#include "cogl-texture-driver.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-debug.h"
#include <stdlib.h>

View File

@ -31,7 +31,7 @@
#include <glib.h>
#include "cogl.h"
#include "cogl-object.h"
#include "cogl-object-private.h"
#include "cogl-buffer.h"
G_BEGIN_DECLS

View File

@ -308,8 +308,8 @@ add_stencil_clip_rectangle (float x_1,
_cogl_framebuffer_flush_state (framebuffer, 0);
/* temporarily swap in our special stenciling material */
cogl_push_source (ctx->stencil_material);
/* temporarily swap in our special stenciling pipeline */
cogl_push_source (ctx->stencil_pipeline);
if (first)
{
@ -367,7 +367,7 @@ add_stencil_clip_rectangle (float x_1,
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
/* restore the original source material */
/* restore the original source pipeline */
cogl_pop_source ();
}

View File

@ -32,8 +32,8 @@
#include "cogl-context.h"
#include "cogl-journal-private.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-path-private.h"
@ -103,8 +103,8 @@ cogl_create_context (void)
_cogl_create_context_winsys (_context);
_cogl_material_init_default_material ();
_cogl_material_init_default_layers ();
_cogl_pipeline_init_default_pipeline ();
_cogl_pipeline_init_default_layers ();
_context->enable_flags = 0;
@ -122,15 +122,15 @@ cogl_create_context (void)
_context->texture_units =
g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
/* See cogl-material.c for more details about why we leave texture unit 1
/* See cogl-pipeline.c for more details about why we leave texture unit 1
* active by default... */
_context->active_texture_unit = 1;
GE (glActiveTexture (GL_TEXTURE1));
_context->legacy_fog_state.enabled = FALSE;
_context->simple_material = cogl_material_new ();
_context->texture_material = cogl_material_new ();
_context->simple_pipeline = cogl_pipeline_new ();
_context->texture_pipeline = cogl_pipeline_new ();
_context->arbfp_source_buffer = g_string_new ("");
_context->source_stack = NULL;
@ -146,13 +146,13 @@ cogl_create_context (void)
_context->polygon_vertices = g_array_new (FALSE, FALSE, sizeof (float));
_context->current_material = NULL;
_context->current_material_changes_since_flush = 0;
_context->current_material_skip_gl_color = FALSE;
_context->current_pipeline = NULL;
_context->current_pipeline_changes_since_flush = 0;
_context->current_pipeline_skip_gl_color = FALSE;
_context->material0_nodes =
_context->pipeline0_nodes =
g_array_sized_new (FALSE, FALSE, sizeof (CoglHandle), 20);
_context->material1_nodes =
_context->pipeline1_nodes =
g_array_sized_new (FALSE, FALSE, sizeof (CoglHandle), 20);
_cogl_bitmask_init (&_context->texcoord_arrays_enabled);
@ -165,7 +165,7 @@ cogl_create_context (void)
_context->current_program = COGL_INVALID_HANDLE;
_context->current_use_program_type = COGL_MATERIAL_PROGRAM_TYPE_FIXED;
_context->current_use_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED;
_context->current_gl_program = 0;
_context->gl_blend_enable_cache = FALSE;
@ -195,7 +195,7 @@ cogl_create_context (void)
_context->dirty_gl_viewport = TRUE;
_context->current_path = _cogl_path_new ();
_context->stencil_material = cogl_material_new ();
_context->stencil_pipeline = cogl_pipeline_new ();
_context->in_begin_gl_block = FALSE;
@ -207,7 +207,7 @@ cogl_create_context (void)
_context->rectangle_short_indices = NULL;
_context->rectangle_short_indices_len = 0;
_context->texture_download_material = COGL_INVALID_HANDLE;
_context->texture_download_pipeline = COGL_INVALID_HANDLE;
/* The default for GL_ALPHA_TEST is to always pass which is equivalent to
* the test being disabled therefore we assume that for all drivers there
@ -235,8 +235,8 @@ cogl_create_context (void)
0, /* auto calc row stride */
default_texture_data);
cogl_push_source (_context->simple_material);
_cogl_material_flush_gl_state (_context->simple_material, FALSE);
cogl_push_source (_context->simple_pipeline);
_cogl_pipeline_flush_gl_state (_context->simple_pipeline, FALSE);
_cogl_enable (enable_flags);
_cogl_flush_face_winding ();
@ -246,7 +246,7 @@ cogl_create_context (void)
unless GL_COORD_REPLACE is enabled for an individual
layer. Therefore it seems like it should be ok to just leave it
enabled all the time instead of having to have a set property on
each material to track whether any layers have point sprite
each pipeline to track whether any layers have point sprite
coords enabled */
if (cogl_features_available (COGL_FEATURE_POINT_SPRITE))
GE (glEnable (GL_POINT_SPRITE));
@ -275,10 +275,10 @@ _cogl_destroy_context (void)
if (_context->default_gl_texture_rect_tex)
cogl_handle_unref (_context->default_gl_texture_rect_tex);
if (_context->simple_material)
cogl_handle_unref (_context->simple_material);
if (_context->texture_material)
cogl_handle_unref (_context->texture_material);
if (_context->simple_pipeline)
cogl_handle_unref (_context->simple_pipeline);
if (_context->texture_pipeline)
cogl_handle_unref (_context->texture_pipeline);
if (_context->journal)
g_array_free (_context->journal, TRUE);
@ -300,8 +300,8 @@ _cogl_destroy_context (void)
if (_context->rectangle_short_indices)
cogl_object_unref (_context->rectangle_short_indices);
if (_context->default_material)
cogl_handle_unref (_context->default_material);
if (_context->default_pipeline)
cogl_handle_unref (_context->default_pipeline);
if (_context->dummy_layer_dependant)
cogl_handle_unref (_context->dummy_layer_dependant);

View File

@ -38,7 +38,7 @@
#include "cogl-primitives.h"
#include "cogl-clip-stack.h"
#include "cogl-matrix-stack.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-buffer-private.h"
#include "cogl-bitmask.h"
#include "cogl-atlas.h"
@ -57,7 +57,7 @@ typedef struct
CoglFeatureFlagsPrivate feature_flags_private;
gboolean features_cached;
CoglHandle default_material;
CoglHandle default_pipeline;
CoglHandle default_layer_0;
CoglHandle default_layer_n;
CoglHandle dummy_layer_dependant;
@ -80,11 +80,11 @@ typedef struct
GArray *texture_units;
int active_texture_unit;
CoglMaterialFogState legacy_fog_state;
CoglPipelineFogState legacy_fog_state;
/* Materials */
CoglMaterial *simple_material; /* used for set_source_color */
CoglMaterial *texture_material; /* used for set_source_texture */
CoglPipeline *simple_pipeline; /* used for set_source_color */
CoglPipeline *texture_pipeline; /* used for set_source_texture */
GString *arbfp_source_buffer;
GList *source_stack;
@ -105,13 +105,13 @@ typedef struct
GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */
CoglMaterial *current_material;
unsigned long current_material_changes_since_flush;
gboolean current_material_skip_gl_color;
unsigned long current_material_age;
CoglPipeline *current_pipeline;
unsigned long current_pipeline_changes_since_flush;
gboolean current_pipeline_skip_gl_color;
unsigned long current_pipeline_age;
GArray *material0_nodes;
GArray *material1_nodes;
GArray *pipeline0_nodes;
GArray *pipeline1_nodes;
/* Bitmask of texture coordinates arrays that are enabled */
CoglBitmask texcoord_arrays_enabled;
@ -143,7 +143,7 @@ typedef struct
/* Primitives */
CoglHandle current_path;
CoglMaterial *stencil_material;
CoglPipeline *stencil_pipeline;
/* Pre-generated VBOs containing indices to generate GL_TRIANGLES
out of a vertex array of quads */
@ -157,7 +157,7 @@ typedef struct
gboolean in_begin_gl_block;
CoglMaterial *texture_download_material;
CoglPipeline *texture_download_pipeline;
CoglAtlas *atlas;
@ -176,7 +176,7 @@ typedef struct
/* Fragment processing programs */
CoglHandle current_program;
CoglMaterialProgramType current_use_program_type;
CoglPipelineProgramType current_use_program_type;
GLuint current_gl_program;
/* List of types that will be considered a subclass of CoglTexture in

View File

@ -470,7 +470,7 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
* To avoid an error with drivers that do consider this a problem we
* explicitly set non mipmapped filters here. These will later be reset when
* the texture is actually used for rendering according to the filters set on
* the corresponding CoglMaterial.
* the corresponding CoglPipeline.
*/
_cogl_texture_set_filters (texhandle, GL_NEAREST, GL_NEAREST);

View File

@ -31,21 +31,21 @@
* later flush the journal we aim to batch data, and gl draw calls. */
typedef struct _CoglJournalEntry
{
CoglHandle material;
CoglPipeline *pipeline;
int n_layers;
CoglMatrix model_view;
/* XXX: These entries are pretty big now considering the padding in
* CoglMaterialFlushOptions and CoglMatrix, so we might need to optimize this
* CoglPipelineFlushOptions and CoglMatrix, so we might need to optimize this
* later. */
} CoglJournalEntry;
void
_cogl_journal_log_quad (const float *position,
CoglHandle material,
CoglPipeline *pipeline,
int n_layers,
guint32 fallback_layers,
GLuint layer0_override_texture,
const CoglMaterialWrapModeOverrides *
const CoglPipelineWrapModeOverrides *
wrap_mode_overrides,
const float *tex_coords,
unsigned int tex_coords_len);

View File

@ -31,8 +31,8 @@
#include "cogl-context.h"
#include "cogl-journal-private.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-profile.h"
@ -49,7 +49,7 @@
* 4 RGBA GLubytes,
* 2 GLfloats per tex coord * n_layers
*
* Where n_layers corresponds to the number of material layers enabled
* Where n_layers corresponds to the number of pipeline layers enabled
*
* To avoid frequent changes in the stride of our vertex data we always pad
* n_layers to be >= 2
@ -85,7 +85,7 @@ typedef struct _CoglJournalFlushState
#endif
CoglMatrixStack *modelview_stack;
CoglMaterial *source;
CoglPipeline *source;
} CoglJournalFlushState;
typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start,
@ -184,7 +184,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
CoglJournalFlushState *state = data;
CoglVertexAttribute **attributes;
COGL_STATIC_TIMER (time_flush_modelview_and_entries,
"flush: material+entries", /* parent */
"flush: pipeline+entries", /* parent */
"flush: modelview+entries",
"The time spent flushing modelview + entries",
0 /* no application private data */);
@ -239,15 +239,15 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
*/
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_RECTANGLES))
{
static CoglHandle outline = COGL_INVALID_HANDLE;
static CoglPipeline *outline = NULL;
guint8 color_intensity;
int i;
CoglVertexAttribute *loop_attributes[2];
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
if (outline == COGL_INVALID_HANDLE)
outline = cogl_material_new ();
if (outline == NULL)
outline = cogl_pipeline_new ();
/* The least significant three bits represent the three
components so that the order of colours goes red, green,
@ -257,7 +257,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
of 24 colours. If there are more than 24 batches on the stage
then it will wrap around */
color_intensity = 0xff - 0x33 * (ctxt->journal_rectangles_color >> 3);
cogl_material_set_color4ub (outline,
cogl_pipeline_set_color4ub (outline,
(ctxt->journal_rectangles_color & 1) ?
color_intensity : 0,
(ctxt->journal_rectangles_color & 2) ?
@ -313,27 +313,27 @@ compare_entry_modelviews (CoglJournalEntry *entry0,
}
/* At this point we have a run of quads that we know have compatible
* materials, but they may not all have the same modelview matrix */
* pipelines, but they may not all have the same modelview matrix */
static void
_cogl_journal_flush_material_and_entries (CoglJournalEntry *batch_start,
_cogl_journal_flush_pipeline_and_entries (CoglJournalEntry *batch_start,
int batch_len,
void *data)
{
CoglJournalFlushState *state = data;
COGL_STATIC_TIMER (time_flush_material_entries,
"flush: texcoords+material+entries", /* parent */
"flush: material+entries",
"The time spent flushing material + entries",
COGL_STATIC_TIMER (time_flush_pipeline_entries,
"flush: texcoords+pipeline+entries", /* parent */
"flush: pipeline+entries",
"The time spent flushing pipeline + entries",
0 /* no application private data */);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
COGL_TIMER_START (_cogl_uprof_context, time_flush_material_entries);
COGL_TIMER_START (_cogl_uprof_context, time_flush_pipeline_entries);
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
g_print ("BATCHING: material batch len = %d\n", batch_len);
g_print ("BATCHING: pipeline batch len = %d\n", batch_len);
state->source = batch_start->material;
state->source = batch_start->pipeline;
/* If we haven't transformed the quads in software then we need to also break
* up batches according to changes in the modelview matrix... */
@ -348,20 +348,20 @@ _cogl_journal_flush_material_and_entries (CoglJournalEntry *batch_start,
else
_cogl_journal_flush_modelview_and_entries (batch_start, batch_len, data);
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_material_entries);
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_pipeline_entries);
}
static gboolean
compare_entry_materials (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
{
/* batch rectangles using compatible materials */
/* batch rectangles using compatible pipelines */
/* XXX: _cogl_material_equal may give false negatives since it avoids
/* XXX: _cogl_pipeline_equal may give false negatives since it avoids
* deep comparisons as an optimization. It aims to compare enough so
* that we that we are able to batch the 90% common cases, but may not
* look at less common differences. */
if (_cogl_material_equal (entry0->material,
entry1->material,
if (_cogl_pipeline_equal (entry0->pipeline,
entry1->pipeline,
TRUE))
return TRUE;
else
@ -379,16 +379,16 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries (
{
CoglJournalFlushState *state = data;
int i;
COGL_STATIC_TIMER (time_flush_texcoord_material_entries,
"flush: vbo+texcoords+material+entries", /* parent */
"flush: texcoords+material+entries",
"The time spent flushing texcoord offsets + material "
COGL_STATIC_TIMER (time_flush_texcoord_pipeline_entries,
"flush: vbo+texcoords+pipeline+entries", /* parent */
"flush: texcoords+pipeline+entries",
"The time spent flushing texcoord offsets + pipeline "
"+ entries",
0 /* no application private data */);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
COGL_TIMER_START (_cogl_uprof_context, time_flush_texcoord_material_entries);
COGL_TIMER_START (_cogl_uprof_context, time_flush_texcoord_pipeline_entries);
/* NB: attributes 0 and 1 are position and color */
@ -444,10 +444,10 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries (
batch_and_call (batch_start,
batch_len,
compare_entry_materials,
_cogl_journal_flush_material_and_entries,
compare_entry_pipelines,
_cogl_journal_flush_pipeline_and_entries,
data);
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_material_entries);
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_pipeline_entries);
}
static gboolean
@ -470,17 +470,17 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
gsize stride;
int i;
CoglVertexAttribute **attribute_entry;
COGL_STATIC_TIMER (time_flush_vbo_texcoord_material_entries,
COGL_STATIC_TIMER (time_flush_vbo_texcoord_pipeline_entries,
"Journal Flush", /* parent */
"flush: vbo+texcoords+material+entries",
"flush: vbo+texcoords+pipeline+entries",
"The time spent flushing vbo + texcoord offsets + "
"material + entries",
"pipeline + entries",
0 /* no application private data */);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
COGL_TIMER_START (_cogl_uprof_context,
time_flush_vbo_texcoord_material_entries);
time_flush_vbo_texcoord_pipeline_entries);
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
g_print ("BATCHING: vbo offset batch len = %d\n", batch_len);
@ -529,7 +529,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
#endif
/* We only create new VertexAttributes when the stride within the
* VertexArray changes. (due to a change in the number of material layers)
* VertexArray changes. (due to a change in the number of pipeline layers)
* While the stride remains constant we walk forward through the above
* VertexArray using a vertex offset passed to cogl_draw_vertex_attributes
*/
@ -561,14 +561,14 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
g_print ("new vbo offset = %lu\n", (unsigned long)state->array_offset);
COGL_TIMER_STOP (_cogl_uprof_context,
time_flush_vbo_texcoord_material_entries);
time_flush_vbo_texcoord_pipeline_entries);
}
static gboolean
compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
{
/* Currently the only thing that affects the stride for our vertex arrays
* is the number of material layers. We need to update our VBO offsets
* is the number of pipeline layers. We need to update our VBO offsets
* whenever the stride changes. */
/* TODO: We should be padding the n_layers == 1 case as if it were
* n_layers == 2 so we can reduce the need to split batches. */
@ -605,7 +605,7 @@ upload_vertices (GArray *vertices, CoglJournalFlushState *state)
}
/* XXX NB: When _cogl_journal_flush() returns all state relating
* to materials, all glEnable flags and current matrix state
* to pipelines, all glEnable flags and current matrix state
* is undefined.
*/
void
@ -659,14 +659,14 @@ _cogl_journal_flush (void)
* Each time the stride of our vertex data changes we need to call
* gl{Vertex,Color}Pointer to inform GL of new VBO offsets.
* Currently the only thing that affects the stride of our vertex data
* is the number of material layers.
* 2) We split the entries explicitly by the number of material layers:
* is the number of pipeline layers.
* 2) We split the entries explicitly by the number of pipeline layers:
* We pad our vertex data when the number of layers is < 2 so that we
* can minimize changes in stride. Each time the number of layers
* changes we need to call glTexCoordPointer to inform GL of new VBO
* offsets.
* 3) We then split according to compatible Cogl materials:
* This is where we flush material state
* 3) We then split according to compatible Cogl pipelines:
* This is where we flush pipeline state
* 4) Finally we split according to modelview matrix changes:
* This is when we finally tell GL to draw something.
* Note: Splitting by modelview changes is skipped when are doing the
@ -684,7 +684,7 @@ _cogl_journal_flush (void)
{
CoglJournalEntry *entry =
&g_array_index (ctx->journal, CoglJournalEntry, i);
_cogl_material_journal_unref (entry->material);
_cogl_pipeline_journal_unref (entry->pipeline);
}
g_array_set_size (ctx->journal, 0);
@ -707,11 +707,11 @@ _cogl_journal_init (void)
void
_cogl_journal_log_quad (const float *position,
CoglHandle material,
CoglPipeline *pipeline,
int n_layers,
guint32 fallback_layers,
GLuint layer0_override_texture,
const CoglMaterialWrapModeOverrides *
const CoglPipelineWrapModeOverrides *
wrap_mode_overrides,
const float *tex_coords,
unsigned int tex_coords_len)
@ -726,8 +726,8 @@ _cogl_journal_log_quad (const float *position,
int next_entry;
guint32 disable_layers;
CoglJournalEntry *entry;
CoglHandle source;
CoglMaterialFlushOptions flush_options;
CoglPipeline *source;
CoglPipelineFlushOptions flush_options;
COGL_STATIC_TIMER (log_timer,
"Mainloop", /* parent */
"Journal Log",
@ -764,7 +764,7 @@ _cogl_journal_log_quad (const float *position,
/* FIXME: This is a hacky optimization, since it will break if we
* change the definition of CoglColor: */
_cogl_material_get_colorubv (material, c);
_cogl_pipeline_get_colorubv (pipeline, c);
src_c = c;
for (i = 0; i < 3; i++)
{
@ -846,49 +846,49 @@ _cogl_journal_log_quad (const float *position,
entry->n_layers = n_layers;
source = material;
source = pipeline;
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (material);
_cogl_material_apply_legacy_state (source);
source = cogl_pipeline_copy (pipeline);
_cogl_pipeline_apply_legacy_state (source);
}
flush_options.flags = 0;
if (G_UNLIKELY (cogl_material_get_n_layers (material) != n_layers))
if (G_UNLIKELY (cogl_pipeline_get_n_layers (pipeline) != n_layers))
{
disable_layers = (1 << n_layers) - 1;
disable_layers = ~disable_layers;
flush_options.disable_layers = disable_layers;
flush_options.flags |= COGL_MATERIAL_FLUSH_DISABLE_MASK;
flush_options.flags |= COGL_PIPELINE_FLUSH_DISABLE_MASK;
}
if (G_UNLIKELY (fallback_layers))
{
flush_options.fallback_layers = fallback_layers;
flush_options.flags |= COGL_MATERIAL_FLUSH_FALLBACK_MASK;
flush_options.flags |= COGL_PIPELINE_FLUSH_FALLBACK_MASK;
}
if (G_UNLIKELY (layer0_override_texture))
{
flush_options.flags |= COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE;
flush_options.flags |= COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE;
flush_options.layer0_override_texture = layer0_override_texture;
}
if (wrap_mode_overrides)
{
flush_options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
flush_options.flags |= COGL_PIPELINE_FLUSH_WRAP_MODE_OVERRIDES;
flush_options.wrap_mode_overrides = *wrap_mode_overrides;
}
if (G_UNLIKELY (flush_options.flags))
{
/* If we haven't already created a derived material... */
if (source == material)
source = cogl_material_copy (material);
_cogl_material_apply_overrides (source, &flush_options);
/* If we haven't already created a derived pipeline... */
if (source == pipeline)
source = cogl_pipeline_copy (pipeline);
_cogl_pipeline_apply_overrides (source, &flush_options);
}
entry->material = _cogl_material_journal_ref (source);
entry->pipeline = _cogl_pipeline_journal_ref (source);
if (G_UNLIKELY (source != material))
if (G_UNLIKELY (source != pipeline))
cogl_handle_unref (source);
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))

View File

@ -0,0 +1,495 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 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.h>
#include <cogl-material-compat.h>
#include <cogl-pipeline.h>
#include <cogl-pipeline-private.h>
#include <cogl-types.h>
#include <cogl-matrix.h>
#include <cogl-context.h>
CoglMaterial *
cogl_material_new (void)
{
return COGL_MATERIAL (cogl_pipeline_new ());
}
CoglMaterial *
cogl_material_copy (CoglMaterial *source)
{
return COGL_MATERIAL (cogl_pipeline_copy (COGL_PIPELINE (source)));
}
CoglHandle
cogl_material_ref (CoglHandle handle)
{
return cogl_object_ref (handle);
}
void
cogl_material_unref (CoglHandle handle)
{
cogl_object_unref (handle);
}
gboolean
cogl_is_material (CoglHandle handle)
{
return cogl_is_pipeline (handle);
}
void
cogl_material_set_color (CoglMaterial *material,
const CoglColor *color)
{
cogl_pipeline_set_color (COGL_PIPELINE (material), color);
}
void
cogl_material_set_color4ub (CoglMaterial *material,
guint8 red,
guint8 green,
guint8 blue,
guint8 alpha)
{
cogl_pipeline_set_color4ub (COGL_PIPELINE (material),
red, green, blue, alpha);
}
void
cogl_material_set_color4f (CoglMaterial *material,
float red,
float green,
float blue,
float alpha)
{
cogl_pipeline_set_color4f (COGL_PIPELINE (material),
red, green, blue, alpha);
}
void
cogl_material_get_color (CoglMaterial *material,
CoglColor *color)
{
cogl_pipeline_get_color (COGL_PIPELINE (material), color);
}
void
cogl_material_set_ambient (CoglMaterial *material,
const CoglColor *ambient)
{
cogl_pipeline_set_ambient (COGL_PIPELINE (material), ambient);
}
void
cogl_material_get_ambient (CoglMaterial *material,
CoglColor *ambient)
{
cogl_pipeline_get_ambient (COGL_PIPELINE (material), ambient);
}
void
cogl_material_set_diffuse (CoglMaterial *material,
const CoglColor *diffuse)
{
cogl_pipeline_set_diffuse (COGL_PIPELINE (material), diffuse);
}
void
cogl_material_get_diffuse (CoglMaterial *material,
CoglColor *diffuse)
{
cogl_pipeline_get_diffuse (COGL_PIPELINE (material), diffuse);
}
void
cogl_material_set_ambient_and_diffuse (CoglMaterial *material,
const CoglColor *color)
{
cogl_pipeline_set_ambient_and_diffuse (COGL_PIPELINE (material), color);
}
void
cogl_material_set_specular (CoglMaterial *material,
const CoglColor *specular)
{
cogl_pipeline_set_specular (COGL_PIPELINE (material), specular);
}
void
cogl_material_get_specular (CoglMaterial *material,
CoglColor *specular)
{
cogl_pipeline_get_specular (COGL_PIPELINE (material), specular);
}
void
cogl_material_set_shininess (CoglMaterial *material,
float shininess)
{
cogl_pipeline_set_shininess (COGL_PIPELINE (material), shininess);
}
float
cogl_material_get_shininess (CoglMaterial *material)
{
return cogl_pipeline_get_shininess (COGL_PIPELINE (material));
}
void
cogl_material_set_emission (CoglMaterial *material,
const CoglColor *emission)
{
cogl_pipeline_set_emission (COGL_PIPELINE (material), emission);
}
void
cogl_material_get_emission (CoglMaterial *material,
CoglColor *emission)
{
cogl_pipeline_get_emission (COGL_PIPELINE (material), emission);
}
void
cogl_material_set_alpha_test_function (CoglMaterial *material,
CoglMaterialAlphaFunc alpha_func,
float alpha_reference)
{
cogl_pipeline_set_alpha_test_function (COGL_PIPELINE (material),
alpha_func,
alpha_reference);
}
gboolean
cogl_material_set_blend (CoglMaterial *material,
const char *blend_string,
GError **error)
{
return cogl_pipeline_set_blend (COGL_PIPELINE (material),
blend_string,
error);
}
void
cogl_material_set_blend_constant (CoglMaterial *material,
const CoglColor *constant_color)
{
cogl_pipeline_set_blend_constant (COGL_PIPELINE (material), constant_color);
}
void
cogl_material_set_point_size (CoglMaterial *material,
float point_size)
{
cogl_pipeline_set_point_size (COGL_PIPELINE (material), point_size);
}
float
cogl_material_get_point_size (CoglMaterial *material)
{
return cogl_pipeline_get_point_size (COGL_PIPELINE (material));
}
CoglHandle
cogl_material_get_user_program (CoglMaterial *material)
{
return cogl_pipeline_get_user_program (COGL_PIPELINE (material));
}
void
cogl_material_set_user_program (CoglMaterial *material,
CoglHandle program)
{
cogl_pipeline_set_user_program (COGL_PIPELINE (material), program);
}
void
cogl_material_set_layer (CoglMaterial *material,
int layer_index,
CoglHandle texture)
{
cogl_pipeline_set_layer_texture (COGL_PIPELINE (material),
layer_index, texture);
}
void
cogl_material_remove_layer (CoglMaterial *material,
int layer_index)
{
cogl_pipeline_remove_layer (COGL_PIPELINE (material), layer_index);
}
gboolean
cogl_material_set_layer_combine (CoglMaterial *material,
int layer_index,
const char *blend_string,
GError **error)
{
return cogl_pipeline_set_layer_combine (COGL_PIPELINE (material),
layer_index,
blend_string,
error);
}
void
cogl_material_set_layer_combine_constant (CoglMaterial *material,
int layer_index,
const CoglColor *constant)
{
cogl_pipeline_set_layer_combine_constant (COGL_PIPELINE (material),
layer_index,
constant);
}
void
cogl_material_set_layer_matrix (CoglMaterial *material,
int layer_index,
const CoglMatrix *matrix)
{
cogl_pipeline_set_layer_matrix (COGL_PIPELINE (material),
layer_index, matrix);
}
G_CONST_RETURN GList *
cogl_material_get_layers (CoglMaterial *material)
{
return _cogl_pipeline_get_layers (COGL_PIPELINE (material));
}
int
cogl_material_get_n_layers (CoglMaterial *material)
{
return cogl_pipeline_get_n_layers (COGL_PIPELINE (material));
}
CoglMaterialLayerType
cogl_material_layer_get_type (CoglMaterialLayer *layer)
{
return COGL_MATERIAL_LAYER_TYPE_TEXTURE;
}
CoglHandle
cogl_material_layer_get_texture (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_texture (COGL_PIPELINE_LAYER (layer));
}
CoglMaterialFilter
cogl_material_layer_get_min_filter (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_min_filter (COGL_PIPELINE_LAYER (layer));
}
CoglMaterialFilter
cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_mag_filter (COGL_PIPELINE_LAYER (layer));
}
void
cogl_material_set_layer_filters (CoglMaterial *material,
int layer_index,
CoglMaterialFilter min_filter,
CoglMaterialFilter mag_filter)
{
cogl_pipeline_set_layer_filters (COGL_PIPELINE (material),
layer_index,
min_filter,
mag_filter);
}
gboolean
cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index,
gboolean enable,
GError **error)
{
CoglPipeline *pipeline = COGL_PIPELINE (material);
return cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline,
layer_index,
enable,
error);
}
gboolean
cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index)
{
CoglPipeline *pipeline = COGL_PIPELINE (material);
return cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline,
layer_index);
}
CoglMaterialWrapMode
cogl_material_get_layer_wrap_mode_s (CoglMaterial *material,
int layer_index)
{
return cogl_pipeline_get_layer_wrap_mode_s (COGL_PIPELINE (material),
layer_index);
}
void
cogl_material_set_layer_wrap_mode_s (CoglMaterial *material,
int layer_index,
CoglMaterialWrapMode mode)
{
cogl_pipeline_set_layer_wrap_mode_s (COGL_PIPELINE (material), layer_index,
mode);
}
CoglMaterialWrapMode
cogl_material_get_layer_wrap_mode_t (CoglMaterial *material,
int layer_index)
{
return cogl_pipeline_get_layer_wrap_mode_t (COGL_PIPELINE (material),
layer_index);
}
void
cogl_material_set_layer_wrap_mode_t (CoglMaterial *material,
int layer_index,
CoglMaterialWrapMode mode)
{
cogl_pipeline_set_layer_wrap_mode_t (COGL_PIPELINE (material), layer_index,
mode);
}
CoglMaterialWrapMode
cogl_material_get_layer_wrap_mode_p (CoglMaterial *material,
int layer_index)
{
return cogl_pipeline_get_layer_wrap_mode_p (COGL_PIPELINE (material),
layer_index);
}
void
cogl_material_set_layer_wrap_mode_p (CoglMaterial *material,
int layer_index,
CoglMaterialWrapMode mode)
{
cogl_pipeline_set_layer_wrap_mode_p (COGL_PIPELINE (material), layer_index,
mode);
}
void
cogl_material_set_layer_wrap_mode (CoglMaterial *material,
int layer_index,
CoglMaterialWrapMode mode)
{
cogl_pipeline_set_layer_wrap_mode (COGL_PIPELINE (material), layer_index,
mode);
}
CoglMaterialWrapMode
cogl_material_layer_get_wrap_mode_s (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_wrap_mode_s (COGL_PIPELINE_LAYER (layer));
}
CoglMaterialWrapMode
cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_wrap_mode_t (COGL_PIPELINE_LAYER (layer));
}
CoglMaterialWrapMode
cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer)
{
return _cogl_pipeline_layer_get_wrap_mode_p (COGL_PIPELINE_LAYER (layer));
}
void
cogl_material_set_depth_test_enabled (CoglMaterial *material,
gboolean enable)
{
cogl_pipeline_set_depth_test_enabled (COGL_PIPELINE (material), enable);
}
gboolean
cogl_material_get_depth_test_enabled (CoglMaterial *material)
{
return cogl_pipeline_get_depth_test_enabled (COGL_PIPELINE (material));
}
void
cogl_material_set_depth_writing_enabled (CoglMaterial *material,
gboolean enable)
{
cogl_pipeline_set_depth_writing_enabled (COGL_PIPELINE (material), enable);
}
gboolean
cogl_material_get_depth_writing_enabled (CoglMaterial *material)
{
return cogl_pipeline_get_depth_writing_enabled (COGL_PIPELINE (material));
}
void
cogl_material_set_depth_test_function (CoglMaterial *material,
CoglDepthTestFunction function)
{
cogl_pipeline_set_depth_test_function (COGL_PIPELINE (material), function);
}
CoglDepthTestFunction
cogl_material_get_depth_test_function (CoglMaterial *material)
{
return cogl_pipeline_get_depth_test_function (COGL_PIPELINE (material));
}
gboolean
cogl_material_set_depth_range (CoglMaterial *material,
float near_val,
float far_val,
GError **error)
{
return cogl_pipeline_set_depth_range (COGL_PIPELINE (material),
near_val, far_val, error);
}
void
cogl_material_get_depth_range (CoglMaterial *material,
float *near_val,
float *far_val)
{
cogl_pipeline_get_depth_range (COGL_PIPELINE (material), near_val, far_val);
}
void
cogl_material_foreach_layer (CoglMaterial *material,
CoglMaterialLayerCallback callback,
void *user_data)
{
cogl_pipeline_foreach_layer (COGL_PIPELINE (material),
(CoglPipelineLayerCallback)callback, user_data);
}

View File

@ -76,13 +76,14 @@ typedef struct _CoglMaterialLayer CoglMaterialLayer;
* average or simply using the nearest texel.
*/
typedef enum {
COGL_MATERIAL_FILTER_NEAREST = GL_NEAREST,
COGL_MATERIAL_FILTER_LINEAR = GL_LINEAR,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
COGL_MATERIAL_FILTER_NEAREST = 0x2600,
COGL_MATERIAL_FILTER_LINEAR = 0x2601,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701,
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702,
COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703
} CoglMaterialFilter;
/* NB: these values come from the equivalents in gl.h */
/**
* CoglMaterialWrapMode:
@ -119,10 +120,11 @@ typedef enum {
* enum so no conversion is actually needed.
*/
typedef enum {
COGL_MATERIAL_WRAP_MODE_REPEAT = GL_REPEAT,
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
COGL_MATERIAL_WRAP_MODE_AUTOMATIC = GL_ALWAYS
COGL_MATERIAL_WRAP_MODE_REPEAT = 0x2901,
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE = 0x812F,
COGL_MATERIAL_WRAP_MODE_AUTOMATIC = 0x0207
} CoglMaterialWrapMode;
/* NB: these values come from the equivalents in gl.h */
/**
* cogl_material_new:
@ -468,14 +470,14 @@ cogl_material_get_emission (CoglMaterial *material,
* determines how the comparison is done.
*/
typedef enum {
COGL_MATERIAL_ALPHA_FUNC_NEVER = GL_NEVER,
COGL_MATERIAL_ALPHA_FUNC_LESS = GL_LESS,
COGL_MATERIAL_ALPHA_FUNC_EQUAL = GL_EQUAL,
COGL_MATERIAL_ALPHA_FUNC_LEQUAL = GL_LEQUAL,
COGL_MATERIAL_ALPHA_FUNC_GREATER = GL_GREATER,
COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL = GL_NOTEQUAL,
COGL_MATERIAL_ALPHA_FUNC_GEQUAL = GL_GEQUAL,
COGL_MATERIAL_ALPHA_FUNC_ALWAYS = GL_ALWAYS
COGL_MATERIAL_ALPHA_FUNC_NEVER = 0x0200,
COGL_MATERIAL_ALPHA_FUNC_LESS = 0x0201,
COGL_MATERIAL_ALPHA_FUNC_EQUAL = 0x0202,
COGL_MATERIAL_ALPHA_FUNC_LEQUAL = 0x0203,
COGL_MATERIAL_ALPHA_FUNC_GREATER = 0x0204,
COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL = 0x0205,
COGL_MATERIAL_ALPHA_FUNC_GEQUAL = 0x0206,
COGL_MATERIAL_ALPHA_FUNC_ALWAYS = 0x0207
} CoglMaterialAlphaFunc;
/**
@ -619,8 +621,8 @@ cogl_material_set_blend_constant (CoglMaterial *material,
* Since: 1.4
*/
void
cogl_material_set_point_size (CoglHandle material,
float point_size);
cogl_material_set_point_size (CoglMaterial *material,
float point_size);
/**
* cogl_material_get_point_size:
@ -634,7 +636,7 @@ cogl_material_set_point_size (CoglHandle material,
* Since: 1.4
*/
float
cogl_material_get_point_size (CoglHandle material);
cogl_material_get_point_size (CoglMaterial *material);
/**
* cogl_material_get_user_program:
@ -1189,52 +1191,6 @@ cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer);
CoglMaterialWrapMode
cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer);
/* XXX: should this be CoglMaterialDepthTestFunction?
* It makes it very verbose but would be consistent with
* CoglMaterialWrapMode */
/**
* CoglDepthTestFunction:
* @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes.
* @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth
* value is less than the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth
* value is equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth
* value is less or equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth
* value is greater than the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth
* value is not equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth
* value greater than or equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes.
*
* When using depth testing one of these functions is used to compare
* the depth of an incoming fragment against the depth value currently
* stored in the depth buffer. The function is changed using
* cogl_material_set_depth_test_function().
*
* The test is only done when depth testing is explicitly enabled. (See
* cogl_material_set_depth_test_enabled())
*/
typedef enum
{
COGL_DEPTH_TEST_FUNCTION_NEVER = GL_NEVER,
COGL_DEPTH_TEST_FUNCTION_LESS = GL_LESS,
COGL_DEPTH_TEST_FUNCTION_EQUAL = GL_EQUAL,
COGL_DEPTH_TEST_FUNCTION_LEQUAL = GL_LEQUAL,
COGL_DEPTH_TEST_FUNCTION_GREATER = GL_GREATER,
COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = GL_NOTEQUAL,
COGL_DEPTH_TEST_FUNCTION_GEQUAL = GL_GEQUAL,
COGL_DEPTH_TEST_FUNCTION_ALWAYS = GL_ALWAYS
} CoglDepthTestFunction;
/* XXX: to avoid having to split this into a separate include that can
* in #included internally without needing the
* COGL_ENABLE_EXPERIMENTAL_API define this isn't guarded. It's still
* considered experimental but it's guarded instead by the fact that
* there's no corresponding API. */
#ifdef COGL_ENABLE_EXPERIMENTAL_API
/**

View File

@ -1,957 +0,0 @@
/*
* 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_MATERIAL_PRIVATE_H
#define __COGL_MATERIAL_PRIVATE_H
#include "cogl.h"
#include "cogl-material.h"
#include "cogl-matrix.h"
#include "cogl-handle.h"
#include "cogl-profile.h"
#include <glib.h>
#if defined (HAVE_COGL_GL)
/* NB: material->backend is currently a 3bit unsigned int bitfield */
#define COGL_MATERIAL_BACKEND_GLSL 0
#define COGL_MATERIAL_BACKEND_GLSL_MASK (1L<<0)
#define COGL_MATERIAL_BACKEND_ARBFP 1
#define COGL_MATERIAL_BACKEND_ARBFP_MASK (1L<<1)
#define COGL_MATERIAL_BACKEND_FIXED 2
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<2)
#define COGL_MATERIAL_N_BACKENDS 3
#elif defined (HAVE_COGL_GLES2)
#define COGL_MATERIAL_BACKEND_GLSL 0
#define COGL_MATERIAL_BACKEND_GLSL_MASK (1L<<0)
#define COGL_MATERIAL_BACKEND_FIXED 1
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<1)
#define COGL_MATERIAL_N_BACKENDS 2
#else /* HAVE_COGL_GLES */
#define COGL_MATERIAL_BACKEND_FIXED 0
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<0)
#define COGL_MATERIAL_N_BACKENDS 1
#endif
#define COGL_MATERIAL_BACKEND_DEFAULT 0
#define COGL_MATERIAL_BACKEND_UNDEFINED 3
typedef enum
{
COGL_MATERIAL_LAYER_STATE_UNIT = 1L<<0,
COGL_MATERIAL_LAYER_STATE_TEXTURE = 1L<<1,
COGL_MATERIAL_LAYER_STATE_FILTERS = 1L<<2,
COGL_MATERIAL_LAYER_STATE_WRAP_MODES = 1L<<3,
COGL_MATERIAL_LAYER_STATE_COMBINE = 1L<<4,
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
COGL_MATERIAL_LAYER_STATE_USER_MATRIX = 1L<<6,
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS = 1L<<7,
/* COGL_MATERIAL_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
COGL_MATERIAL_LAYER_STATE_ALL_SPARSE =
COGL_MATERIAL_LAYER_STATE_UNIT |
COGL_MATERIAL_LAYER_STATE_TEXTURE |
COGL_MATERIAL_LAYER_STATE_FILTERS |
COGL_MATERIAL_LAYER_STATE_WRAP_MODES |
COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX |
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS,
COGL_MATERIAL_LAYER_STATE_NEEDS_BIG_STATE =
COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX |
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS,
} CoglMaterialLayerState;
typedef struct
{
/* The texture combine state determines how the color of individual
* texture fragments are calculated. */
GLint texture_combine_rgb_func;
GLint texture_combine_rgb_src[3];
GLint texture_combine_rgb_op[3];
GLint texture_combine_alpha_func;
GLint texture_combine_alpha_src[3];
GLint 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;
} CoglMaterialLayerBigState;
/* Materials and layers represent their state in a tree structure where
* some of the state relating to a given material 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... */
typedef struct _CoglMaterialNode CoglMaterialNode;
struct _CoglMaterialNode
{
/* the parent in terms of class hierarchy, so anything inheriting
* from CoglMaterialNode also inherits from CoglObject. */
CoglObject _parent;
/* The parent material/layer */
CoglMaterialNode *parent;
/* TRUE if the node took a strong reference on its parent. Weak
* materials for instance don't take a reference on their parent. */
gboolean has_parent_reference;
/* As an optimization for creating leaf node materials/layers (the
* most common) we don't require any list node allocations to link
* to a single descendant. */
CoglMaterialNode *first_child;
/* Determines if node->first_child and node->children are
* initialized pointers. */
gboolean has_children;
/* Materials and layers are sparse structures defined as a diff
* against their parent and may have multiple children which depend
* on them to define the values of properties which they don't
* change. */
GList *children;
};
#define COGL_MATERIAL_NODE(X) ((CoglMaterialNode *)(X))
typedef void (*CoglMaterialNodeUnparentVFunc) (CoglMaterialNode *node);
typedef gboolean (*CoglMaterialNodeChildCallback) (CoglMaterialNode *child,
void *user_data);
void
_cogl_material_node_foreach_child (CoglMaterialNode *node,
CoglMaterialNodeChildCallback callback,
void *user_data);
struct _CoglMaterialLayer
{
/* XXX: Please think twice about adding members that *have* be
* initialized during a _cogl_material_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 materials or
* if the state can be shared among many derived materials 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 material 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... */
CoglMaterialNode _parent;
/* Some layers have a material owner, which is to say that the layer
* is referenced in that materials->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. */
CoglMaterial *owner;
/* The lowest index is blended first then others on top */
int index;
/* Different material backends (GLSL/ARBfp/Fixed Function) may
* want to associate private data with a layer...
*
* NB: we have per backend pointers because a layer may be
* associated with multiple materials with different backends.
*/
void *backend_priv[COGL_MATERIAL_N_BACKENDS];
/* 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 COGL_INVALID_HANDLE for an empty
* layer */
CoglHandle texture;
gboolean texture_overridden;
/* If ->texture_overridden == TRUE then the texture is instead
* defined by these... */
GLuint slice_gl_texture;
GLenum slice_gl_target;
CoglMaterialFilter mag_filter;
CoglMaterialFilter min_filter;
CoglMaterialWrapMode wrap_mode_s;
CoglMaterialWrapMode wrap_mode_t;
CoglMaterialWrapMode wrap_mode_p;
/* Infrequent differences aren't currently tracked in
* a separate, dynamically allocated structure as they are
* for materials... */
CoglMaterialLayerBigState *big_state;
/* bitfields */
/* Determines if layer->big_state is valid */
unsigned int has_big_state:1;
};
/* Used in material->differences masks and for notifying material
* state changes... */
typedef enum _CoglMaterialState
{
COGL_MATERIAL_STATE_COLOR = 1L<<0,
COGL_MATERIAL_STATE_BLEND_ENABLE = 1L<<1,
COGL_MATERIAL_STATE_LAYERS = 1L<<2,
COGL_MATERIAL_STATE_LIGHTING = 1L<<3,
COGL_MATERIAL_STATE_ALPHA_FUNC = 1L<<4,
COGL_MATERIAL_STATE_BLEND = 1L<<5,
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
COGL_MATERIAL_STATE_DEPTH = 1L<<7,
COGL_MATERIAL_STATE_FOG = 1L<<8,
COGL_MATERIAL_STATE_POINT_SIZE = 1L<<9,
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<10,
COGL_MATERIAL_STATE_ALL_SPARSE =
COGL_MATERIAL_STATE_COLOR |
COGL_MATERIAL_STATE_BLEND_ENABLE |
COGL_MATERIAL_STATE_LAYERS |
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER |
COGL_MATERIAL_STATE_DEPTH |
COGL_MATERIAL_STATE_FOG |
COGL_MATERIAL_STATE_POINT_SIZE,
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
COGL_MATERIAL_STATE_COLOR |
COGL_MATERIAL_STATE_BLEND_ENABLE |
COGL_MATERIAL_STATE_LAYERS |
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER,
COGL_MATERIAL_STATE_NEEDS_BIG_STATE =
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER |
COGL_MATERIAL_STATE_DEPTH |
COGL_MATERIAL_STATE_FOG |
COGL_MATERIAL_STATE_POINT_SIZE
} CoglMaterialState;
typedef enum
{
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_AMBIENT = 1,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_DIFFUSE,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SPECULAR,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_EMISSION,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SHININESS
} CoglMaterialLightingStateProperty;
typedef struct
{
/* Standard OpenGL lighting model attributes */
float ambient[4];
float diffuse[4];
float specular[4];
float emission[4];
float shininess;
} CoglMaterialLightingState;
typedef struct
{
/* Determines what fragments are discarded based on their alpha */
CoglMaterialAlphaFunc alpha_func;
GLfloat alpha_func_reference;
} CoglMaterialAlphaFuncState;
typedef enum _CoglMaterialBlendEnable
{
/* XXX: we want to detect users mistakenly using TRUE or FALSE
* so start the enum at 2. */
COGL_MATERIAL_BLEND_ENABLE_ENABLED = 2,
COGL_MATERIAL_BLEND_ENABLE_DISABLED,
COGL_MATERIAL_BLEND_ENABLE_AUTOMATIC
} CoglMaterialBlendEnable;
typedef struct
{
/* Determines how this material is blended with other primitives */
#ifndef HAVE_COGL_GLES
GLenum blend_equation_rgb;
GLenum blend_equation_alpha;
GLint blend_src_factor_alpha;
GLint blend_dst_factor_alpha;
CoglColor blend_constant;
#endif
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
} CoglMaterialBlendState;
typedef struct
{
gboolean depth_test_enabled;
CoglDepthTestFunction depth_test_function;
gboolean depth_writing_enabled;
float depth_range_near;
float depth_range_far;
} CoglMaterialDepthState;
typedef struct
{
gboolean enabled;
CoglColor color;
CoglFogMode mode;
float density;
float z_near;
float z_far;
} CoglMaterialFogState;
typedef struct
{
CoglMaterialLightingState lighting_state;
CoglMaterialAlphaFuncState alpha_state;
CoglMaterialBlendState blend_state;
CoglHandle user_program;
CoglMaterialDepthState depth_state;
CoglMaterialFogState fog_state;
float point_size;
} CoglMaterialBigState;
typedef enum
{
COGL_MATERIAL_FLAG_DIRTY_LAYERS_CACHE = 1L<<0,
COGL_MATERIAL_FLAG_DIRTY_GET_LAYERS_LIST = 1L<<1
} CoglMaterialFlag;
typedef struct
{
CoglMaterial *owner;
CoglMaterialLayer *layer;
} CoglMaterialLayerCacheEntry;
/*
* CoglMaterialDestroyCallback
* @material: The #CoglMaterial that has been destroyed
* @user_data: The private data associated with the callback
*
* Notifies when a weak material has been destroyed because one
* of its ancestors has been freed or modified.
*/
typedef void (*CoglMaterialDestroyCallback)(CoglMaterial *material,
void *user_data);
struct _CoglMaterial
{
/* XXX: Please think twice about adding members that *have* be
* initialized during a cogl_material_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 materials or
* if the state can be shared among many derived materials instead.
* This will determine if the state should be added directly to this
* structure which will increase the memory overhead for *all*
* materials 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 material 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... */
CoglMaterialNode _parent;
/* We need to track if a material is referenced in the journal
* because we can't allow modification to these materials without
* flushing the journal first */
unsigned long journal_ref_count;
/* When weak materials are destroyed the user is notified via this
* callback */
CoglMaterialDestroyCallback destroy_callback;
/* When notifying that a weak material has been destroyed this
* private data is passed to the above callback */
void *destroy_data;
/* A mask of which sparse state groups are different in this
* material in comparison to its parent. */
unsigned long differences;
/* The fragment processing backends can associate private data with a
* material. */
void *backend_privs[COGL_MATERIAL_N_BACKENDS];
/* Whenever a material is modified we increment the age. There's no
* guarantee that it won't wrap but it can nevertheless be a
* convenient mechanism to determine when a material has been
* changed to you can invalidate some some associated cache that
* depends on the old state. */
unsigned long age;
/* This is the primary color of the material.
*
* This is a sparse property, ref COGL_MATERIAL_STATE_COLOR */
CoglColor color;
/* A material may be made up with multiple layers used to combine
* textures together.
*
* This is sparse state, ref COGL_MATERIAL_STATE_LAYERS */
GList *layer_differences;
unsigned int n_layers;
/* As a basic way to reduce memory usage we divide the material
* state into two groups; the minimal state modified in 90% of
* all materials and the rest, so that the second group can
* be allocated dynamically when required... */
CoglMaterialBigState *big_state;
/* For debugging purposes it's possible to associate a static const
* string with a material which can be an aid when trying to trace
* where the material originates from */
const char *static_breadcrumb;
/* Cached state... */
/* A cached, complete list of the layers this material depends
* on sorted by layer->unit_index. */
CoglMaterialLayer **layers_cache;
/* To avoid a separate ->layers_cache allocation for common
* materials with only a few layers... */
CoglMaterialLayer *short_layers_cache[3];
/* The deprecated cogl_material_get_layers() API returns a
* const GList of layers, which we track here... */
GList *deprecated_get_layers_list;
/* XXX: consider adding an authorities cache to speed up sparse
* property value lookups:
* CoglMaterial *authorities_cache[COGL_MATERIAL_N_SPARSE_PROPERTIES];
* and corresponding authorities_cache_dirty:1 bitfield
*/
/* bitfields */
/* A material can have private data associated with it for multiple
* fragment processing backends. Although only one backend is
* associated with a material the backends may want to cache private
* state with the ancestors of other materials and those ancestors
* could currently be associated with different backends.
*
* Each set bit indicates if the correspondong ->backend_privs[]
* entry is valid.
*/
unsigned int backend_priv_set_mask:COGL_MATERIAL_N_BACKENDS;
/* Weak materials don't count as dependants on their parents which
* means that the parent material can be modified without
* considering how the modifications may affect the weak material.
*/
unsigned int is_weak:1;
/* Determines if material->big_state is valid */
unsigned int has_big_state:1;
/* By default blending is enabled automatically depending on the
* unlit color, the lighting colors or the texture format. The user
* can override this to explicitly enable or disable blending.
*
* This is a sparse property */
unsigned int blend_enable:3;
/* There are many factors that can determine if we need to enable
* blending, this holds our final decision */
unsigned int real_blend_enable:1;
unsigned int layers_cache_dirty:1;
unsigned int deprecated_get_layers_list_dirty:1;
/* For debugging purposes it's possible to associate a static const
* string with a material which can be an aid when trying to trace
* where the material originates from */
unsigned int has_static_breadcrumb:1;
/* There are multiple fragment processing backends for CoglMaterial,
* glsl, arbfp and fixed. This identifies the backend being used for
* the material and any private state the backend has associated
* with the material. */
unsigned int backend:3;
};
typedef struct _CoglMaterialBackend
{
int (*get_max_texture_units) (void);
gboolean (*start) (CoglMaterial *material,
int n_layers,
unsigned long materials_difference);
gboolean (*add_layer) (CoglMaterial *material,
CoglMaterialLayer *layer,
unsigned long layers_difference);
gboolean (*passthrough) (CoglMaterial *material);
gboolean (*end) (CoglMaterial *material,
unsigned long materials_difference);
void (*material_pre_change_notify) (CoglMaterial *material,
CoglMaterialState change,
const CoglColor *new_color);
void (*material_set_parent_notify) (CoglMaterial *material);
void (*layer_pre_change_notify) (CoglMaterial *owner,
CoglMaterialLayer *layer,
CoglMaterialLayerState change);
void (*free_priv) (CoglMaterial *material);
void (*free_layer_priv) (CoglMaterialLayer *layer);
} CoglMaterialBackend;
typedef enum
{
COGL_MATERIAL_PROGRAM_TYPE_GLSL = 1,
COGL_MATERIAL_PROGRAM_TYPE_ARBFP,
COGL_MATERIAL_PROGRAM_TYPE_FIXED
} CoglMaterialProgramType;
extern const CoglMaterialBackend *
_cogl_material_backends[COGL_MATERIAL_N_BACKENDS];
void
_cogl_material_init_default_material (void);
void
_cogl_material_init_default_layers (void);
/*
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl materials for filling.
*
* Normally you shouldn't need to use this API directly, but if you need to
* developing a custom/specialised primitive - probably using raw OpenGL - then
* this API aims to expose enough of the material internals to support being
* able to fill your geometry according to a given Cogl material.
*/
gboolean
_cogl_material_get_real_blend_enabled (CoglMaterial *material);
gboolean
_cogl_material_layer_has_user_matrix (CoglMaterialLayer *layer);
/*
* 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_material_layer_pre_paint (CoglMaterialLayer *layerr);
/*
* 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_material_pre_paint_for_layer (CoglMaterial *material,
int layer_id);
/*
* CoglMaterialFlushFlag:
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: The fallback_layers member is set to
* a guint32 mask of the layers that can't be supported with the user
* supplied texture and need to be replaced with fallback textures. (1 =
* fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: The disable_layers member is set to
* a guint32 mask of the layers that you want to completly disable
* texturing for (1 = fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is
* set to a GLuint OpenGL texture name to override the texture used for
* layer 0 of the material. This is intended for dealing with sliced
* textures where you will need to point to each of the texture slices in
* turn when drawing your geometry. Passing a value of 0 is the same as
* not passing the option at all.
* @COGL_MATERIAL_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the
* material don't call glColor.
* @COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES: Specifies that a bitmask
* of overrides for the wrap modes for some or all layers is
* given.
*/
typedef enum _CoglMaterialFlushFlag
{
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1L<<0,
COGL_MATERIAL_FLUSH_DISABLE_MASK = 1L<<1,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE = 1L<<2,
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR = 1L<<3,
COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES = 1L<<4
} CoglMaterialFlushFlag;
/* 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 CoglMaterialWrapMode enum
* so no conversion is actually needed.
*/
typedef enum _CoglMaterialWrapModeInternal
{
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS
} CoglMaterialWrapModeInternal;
typedef enum _CoglMaterialWrapModeOverride
{
COGL_MATERIAL_WRAP_MODE_OVERRIDE_NONE = 0,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT =
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE =
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER =
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER,
} CoglMaterialWrapModeOverride;
/* There can't be more than 32 layers because we need to fit a bitmask
of the layers into a guint32 */
#define COGL_MATERIAL_MAX_LAYERS 32
typedef struct _CoglMaterialWrapModeOverrides
{
struct
{
CoglMaterialWrapModeOverride s;
CoglMaterialWrapModeOverride t;
CoglMaterialWrapModeOverride p;
} values[COGL_MATERIAL_MAX_LAYERS];
} CoglMaterialWrapModeOverrides;
/*
* CoglMaterialFlushOptions:
*
*/
typedef struct _CoglMaterialFlushOptions
{
CoglMaterialFlushFlag flags;
guint32 fallback_layers;
guint32 disable_layers;
GLuint layer0_override_texture;
CoglMaterialWrapModeOverrides wrap_mode_overrides;
} CoglMaterialFlushOptions;
int
_cogl_get_max_texture_image_units (void);
void
_cogl_use_program (GLuint gl_program, CoglMaterialProgramType type);
unsigned int
_cogl_get_n_args_for_combine_func (GLint func);
/*
* _cogl_material_weak_copy:
* @material: A #CoglMaterial object
* @callback: A callback to notify when your weak material is destroyed
* @user_data: Private data to pass to your given callback.
*
* Returns a weak copy of the given source @material. Unlike a normal
* copy no internal reference is taken on the source @material and you
* can expect that later modifications of the source material (or in
* fact any other material) can result in the weak material being
* destroyed.
*
* To understand this better its good to know a bit about the internal
* design of #CoglMaterial...
*
* Internally #CoglMaterial<!-- -->s are represented as a graph of
* property diff's, where each node is a diff of properties that gets
* applied on top of its parent. Copying a material creates an empty
* diff and a child->parent relationship between the empty diff and
* the source @material, parent.
*
* Because of this internal graph design a single #CoglMaterial may
* indirectly depend on a chain of ancestors to fully define all of
* its properties. Because a node depends on its ancestors it normally
* owns a reference to its parent to stop it from being freed. Also if
* you try to modify a material with children we internally use a
* copy-on-write mechanism to ensure that you don't indirectly change
* the properties those children.
*
* Weak materials avoid the use of copy-on-write to preserve the
* integrity of weak dependants and instead weak dependants are
* simply destroyed allowing the parent to be modified directly. Also
* because weak materials don't own a reference to their parent they
* won't stop the source @material from being freed when the user
* releases their reference on it.
*
* Because weak materials don't own a reference on their parent they
* are the recommended mechanism for creating derived materials that you
* want to cache as a private property of the original material
* because they won't result in a circular dependency.
*
* An example use case:
*
* Consider for example you are implementing a custom primitive that is
* not compatible with certain source materials. To handle this you
* implement a validation stage that given an arbitrary material as
* input will create a derived material that is suitable for drawing
* your primitive.
*
* Because you don't want to have to repeat this validation every time
* the same incompatible material is given as input you want to cache
* the result as a private property of the original material. If the
* derived material were created using cogl_material_copy that would
* create a circular dependency so the original material can never be
* freed.
*
* If you instead create a weak copy you won't stop the original material
* from being freed if it's no longer needed, and you will instead simply
* be notified that your weak material has been destroyed.
*
* This is the recommended coding pattern for validating an input
* material and caching a derived result:
* |[
* static CoglUserDataKey _cogl_my_cache_key;
*
* typedef struct {
* CoglMaterial *validated_source;
* } MyValidatedMaterialCache;
*
* static void
* destroy_cache_cb (CoglObject *object, void *user_data)
* {
* g_slice_free (MyValidatedMaterialCache, user_data);
* }
*
* static void
* invalidate_cache_cb (CoglMaterial *destroyed, void *user_data)
* {
* MyValidatedMaterialCache *cache = user_data;
* cogl_object_unref (cache->validated_source);
* cache->validated_source = NULL;
* }
*
* static CoglMaterial *
* get_validated_material (CoglMaterial *source)
* {
* MyValidatedMaterialCache *cache =
* cogl_object_get_user_data (COGL_OBJECT (source),
* &_cogl_my_cache_key);
* if (G_UNLIKELY (cache == NULL))
* {
* cache = g_slice_new (MyValidatedMaterialCache);
* cogl_object_set_user_data (COGL_OBJECT (source),
* &_cogl_my_cache_key,
* cache, destroy_cache_cb);
* cache->validated_source = source;
* }
*
* if (G_UNLIKELY (cache->validated_source == NULL))
* {
* cache->validated_source = source;
*
* /&nbsp;* Start validating source... *&nbsp;/
*
* /&nbsp;* If you find you need to change something... *&nbsp;/
* if (cache->validated_source == source)
* cache->validated_source =
* cogl_material_weak_copy (source,
* invalidate_cache_cb,
* cache);
*
* /&nbsp;* Modify cache->validated_source *&nbsp;/
* }
*
* return cache->validated_source;
* }
* ]|
*/
CoglMaterial *
_cogl_material_weak_copy (CoglMaterial *material,
CoglMaterialDestroyCallback callback,
void *user_data);
void
_cogl_material_set_backend (CoglMaterial *material, int backend);
CoglMaterial *
_cogl_material_get_parent (CoglMaterial *material);
void
_cogl_material_get_colorubv (CoglMaterial *material,
guint8 *color);
unsigned long
_cogl_material_compare_differences (CoglMaterial *material0,
CoglMaterial *material1);
gboolean
_cogl_material_equal (CoglMaterial *material0,
CoglMaterial *material1,
gboolean skip_gl_color);
CoglMaterial *
_cogl_material_journal_ref (CoglMaterial *material);
void
_cogl_material_journal_unref (CoglMaterial *material);
void
_cogl_material_layer_get_wrap_modes (CoglMaterialLayer *layer,
CoglMaterialWrapModeInternal *wrap_mode_s,
CoglMaterialWrapModeInternal *wrap_mode_t,
CoglMaterialWrapModeInternal *wrap_mode_r);
void
_cogl_material_layer_get_filters (CoglMaterialLayer *layer,
CoglMaterialFilter *min_filter,
CoglMaterialFilter *mag_filter);
void
_cogl_material_get_layer_filters (CoglMaterial *material,
int layer_index,
CoglMaterialFilter *min_filter,
CoglMaterialFilter *mag_filter);
CoglMaterialFilter
_cogl_material_get_layer_min_filter (CoglMaterial *material,
int layer_index);
CoglMaterialFilter
_cogl_material_get_layer_mag_filter (CoglMaterial *material,
int layer_index);
void
_cogl_material_texture_storage_change_notify (CoglHandle texture);
void
_cogl_material_apply_legacy_state (CoglMaterial *material);
void
_cogl_material_apply_overrides (CoglMaterial *material,
CoglMaterialFlushOptions *options);
CoglMaterialBlendEnable
_cogl_material_get_blend_enabled (CoglMaterial *material);
void
_cogl_material_set_blend_enabled (CoglMaterial *material,
CoglMaterialBlendEnable enable);
void
_cogl_material_set_static_breadcrumb (CoglMaterial *material,
const char *breadcrumb);
unsigned long
_cogl_material_get_age (CoglMaterial *material);
CoglMaterial *
_cogl_material_get_authority (CoglMaterial *material,
unsigned long difference);
unsigned long
_cogl_material_layer_compare_differences (CoglMaterialLayer *layer0,
CoglMaterialLayer *layer1);
CoglMaterialLayer *
_cogl_material_layer_get_authority (CoglMaterialLayer *layer,
unsigned long difference);
CoglHandle
_cogl_material_layer_get_texture (CoglMaterialLayer *layer);
CoglHandle
_cogl_material_get_layer_texture (CoglMaterial *material,
int layer_index);
typedef gboolean (*CoglMaterialInternalLayerCallback) (CoglMaterialLayer *layer,
void *user_data);
void
_cogl_material_foreach_layer_internal (CoglMaterial *material,
CoglMaterialInternalLayerCallback callback,
void *user_data);
int
_cogl_material_layer_get_unit_index (CoglMaterialLayer *layer);
void
_cogl_material_get_layer_combine_constant (CoglMaterial *material,
int layer_index,
float *constant);
void
_cogl_material_prune_to_n_layers (CoglMaterial *material, int n);
#endif /* __COGL_MATERIAL_PRIVATE_H */

View File

@ -30,8 +30,8 @@
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-journal-private.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-path-private.h"
#include "cogl-texture-private.h"
@ -181,8 +181,8 @@ _cogl_path_stroke_nodes (void)
unsigned int path_start = 0;
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
CoglPathData *data;
CoglMaterial *copy = NULL;
CoglMaterial *source;
CoglPipeline *copy = NULL;
CoglPipeline *source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -191,7 +191,7 @@ _cogl_path_stroke_nodes (void)
_cogl_journal_flush ();
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the material state) when flushing the clip stack, so should
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
@ -199,26 +199,26 @@ _cogl_path_stroke_nodes (void)
if (G_UNLIKELY (ctx->legacy_state_set))
{
CoglMaterial *users_source = cogl_get_source ();
copy = cogl_material_copy (users_source);
_cogl_material_apply_legacy_state (copy);
CoglPipeline *users_source = cogl_get_source ();
copy = cogl_pipeline_copy (users_source);
_cogl_pipeline_apply_legacy_state (copy);
source = copy;
}
else
source = cogl_get_source ();
if (cogl_material_get_n_layers (source) != 0)
if (cogl_pipeline_get_n_layers (source) != 0)
{
/* If we haven't already created a derivative material... */
/* If we haven't already created a derivative pipeline... */
if (!copy)
copy = cogl_material_copy (source);
_cogl_material_prune_to_n_layers (copy, 0);
copy = cogl_pipeline_copy (source);
_cogl_pipeline_prune_to_n_layers (copy, 0);
source = copy;
}
cogl_push_source (source);
_cogl_material_flush_gl_state (source, FALSE);
_cogl_pipeline_flush_gl_state (source, FALSE);
/* Disable all client texture coordinate arrays */
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
@ -304,14 +304,14 @@ _cogl_path_fill_nodes (CoglPath *path)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* If any of the layers of the current material contain sliced
/* If any of the layers of the current pipeline contain sliced
textures or textures with waste then it won't work to draw the
path directly. Instead we can use draw the texture as a quad
clipped to the stencil buffer. */
for (l = cogl_material_get_layers (cogl_get_source ()); l; l = l->next)
for (l = _cogl_pipeline_get_layers (cogl_get_source ()); l; l = l->next)
{
CoglHandle layer = l->data;
CoglHandle texture = cogl_material_layer_get_texture (layer);
CoglHandle texture = _cogl_pipeline_layer_get_texture (layer);
if (texture != COGL_INVALID_HANDLE &&
(cogl_texture_is_sliced (texture) ||
@ -365,14 +365,14 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
_cogl_journal_flush ();
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the material state) when flushing the clip stack, so should
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (framebuffer, 0);
/* Just setup a simple material that doesn't use texturing... */
cogl_push_source (ctx->stencil_material);
/* Just setup a simple pipeline that doesn't use texturing... */
cogl_push_source (ctx->stencil_pipeline);
_cogl_material_flush_gl_state (ctx->stencil_material, FALSE);
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE);
_cogl_enable (enable_flags);
@ -461,7 +461,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
GE (glStencilFunc (GL_EQUAL, 0x1, 0x1));
GE (glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
/* restore the original material */
/* restore the original pipeline */
cogl_pop_source ();
}

View File

@ -25,12 +25,12 @@
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_ARBFP_PRIVATE_H
#define __COGL_MATERIAL_ARBFP_PRIVATE_H
#ifndef __COGL_PIPELINE_ARBFP_PRIVATE_H
#define __COGL_PIPELINE_ARBFP_PRIVATE_H
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
extern const CoglMaterialBackend _cogl_material_arbfp_backend;
extern const CoglPipelineBackend _cogl_pipeline_arbfp_backend;
#endif /* __COGL_MATERIAL_ARBFP_PRIVATE_H */
#endif /* __COGL_PIPELINE_ARBFP_PRIVATE_H */

View File

@ -30,9 +30,9 @@
#endif
#include "cogl-debug.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#ifdef COGL_MATERIAL_BACKEND_ARBFP
#ifdef COGL_PIPELINE_BACKEND_ARBFP
#include "cogl.h"
#include "cogl-internal.h"
@ -51,7 +51,7 @@
#include <string.h>
/*
* GL/GLES compatability defines for material thingies:
* GL/GLES compatability defines for pipeline thingies:
*/
#ifdef HAVE_COGL_GLES2
@ -94,17 +94,17 @@ typedef struct _ArbfpProgramState
is used to detect when we need to flush all of the uniforms */
unsigned int user_program_age;
/* We need to track the last material that an ARBfp program was used
/* We need to track the last pipeline that an ARBfp program was used
* with so know if we need to update any program.local parameters. */
CoglMaterial *last_used_for_material;
CoglPipeline *last_used_for_pipeline;
} ArbfpProgramState;
typedef struct _CoglMaterialBackendARBfpPrivate
typedef struct _CoglPipelineBackendARBfpPrivate
{
ArbfpProgramState *arbfp_program_state;
} CoglMaterialBackendARBfpPrivate;
} CoglPipelineBackendARBfpPrivate;
const CoglMaterialBackend _cogl_material_arbfp_backend;
const CoglPipelineBackend _cogl_pipeline_arbfp_backend;
static ArbfpProgramState *
@ -146,7 +146,7 @@ arbfp_program_state_unref (ArbfpProgramState *state)
}
static int
_cogl_material_backend_arbfp_get_max_texture_units (void)
_cogl_pipeline_backend_arbfp_get_max_texture_units (void)
{
return _cogl_get_max_texture_image_units ();
}
@ -154,11 +154,11 @@ _cogl_material_backend_arbfp_get_max_texture_units (void)
typedef struct
{
int i;
CoglMaterialLayer **layers;
CoglPipelineLayer **layers;
} AddLayersToArrayState;
static gboolean
add_layer_to_array_cb (CoglMaterialLayer *layer,
add_layer_to_array_cb (CoglPipelineLayer *layer,
void *user_data)
{
AddLayersToArrayState *state = user_data;
@ -167,36 +167,36 @@ add_layer_to_array_cb (CoglMaterialLayer *layer,
}
static gboolean
layers_arbfp_would_differ (CoglMaterialLayer **material0_layers,
CoglMaterialLayer **material1_layers,
layers_arbfp_would_differ (CoglPipelineLayer **pipeline0_layers,
CoglPipelineLayer **pipeline1_layers,
int n_layers)
{
int i;
/* The layer state that affects arbfp codegen... */
unsigned long arbfp_codegen_modifiers =
COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_UNIT;
COGL_PIPELINE_LAYER_STATE_COMBINE |
COGL_PIPELINE_LAYER_STATE_UNIT;
for (i = 0; i < n_layers; i++)
{
CoglMaterialLayer *layer0 = material0_layers[i];
CoglMaterialLayer *layer1 = material1_layers[i];
CoglPipelineLayer *layer0 = pipeline0_layers[i];
CoglPipelineLayer *layer1 = pipeline1_layers[i];
unsigned long layer_differences;
if (layer0 == layer1)
continue;
layer_differences =
_cogl_material_layer_compare_differences (layer0, layer1);
_cogl_pipeline_layer_compare_differences (layer0, layer1);
if (layer_differences & arbfp_codegen_modifiers)
{
/* When it comes to texture differences the only thing that
* affects the arbfp is the target enum... */
if (layer_differences == COGL_MATERIAL_LAYER_STATE_TEXTURE)
if (layer_differences == COGL_PIPELINE_LAYER_STATE_TEXTURE)
{
CoglHandle tex0 = _cogl_material_layer_get_texture (layer0);
CoglHandle tex1 = _cogl_material_layer_get_texture (layer1);
CoglHandle tex0 = _cogl_pipeline_layer_get_texture (layer0);
CoglHandle tex1 = _cogl_pipeline_layer_get_texture (layer1);
GLenum gl_target0;
GLenum gl_target1;
@ -213,37 +213,37 @@ layers_arbfp_would_differ (CoglMaterialLayer **material0_layers,
}
/* This tries to find the oldest ancestor whos state would generate
* the same arbfp program as the current material. This is a simple
* the same arbfp program as the current pipeline. This is a simple
* mechanism for reducing the number of arbfp programs we have to
* generate.
*/
static CoglMaterial *
find_arbfp_authority (CoglMaterial *material, CoglHandle user_program)
static CoglPipeline *
find_arbfp_authority (CoglPipeline *pipeline, CoglHandle user_program)
{
CoglMaterial *authority0;
CoglMaterial *authority1;
CoglPipeline *authority0;
CoglPipeline *authority1;
int n_layers;
CoglMaterialLayer **authority0_layers;
CoglMaterialLayer **authority1_layers;
CoglPipelineLayer **authority0_layers;
CoglPipelineLayer **authority1_layers;
/* XXX: we'll need to update this when we add fog support to the
* arbfp codegen */
if (user_program != COGL_INVALID_HANDLE)
return material;
return pipeline;
/* Find the first material that modifies state that affects the
/* Find the first pipeline that modifies state that affects the
* arbfp codegen... */
authority0 = _cogl_material_get_authority (material,
COGL_MATERIAL_STATE_LAYERS);
authority0 = _cogl_pipeline_get_authority (pipeline,
COGL_PIPELINE_STATE_LAYERS);
/* Find the next ancestor after that, that also modifies state
* affecting arbfp codegen... */
if (_cogl_material_get_parent (authority0))
if (_cogl_pipeline_get_parent (authority0))
{
authority1 =
_cogl_material_get_authority (_cogl_material_get_parent (authority0),
COGL_MATERIAL_STATE_LAYERS);
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0),
COGL_PIPELINE_STATE_LAYERS);
}
else
return authority0;
@ -258,18 +258,18 @@ find_arbfp_authority (CoglMaterial *material, CoglHandle user_program)
return authority0;
authority0_layers =
g_alloca (sizeof (CoglMaterialLayer *) * n_layers);
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
state.i = 0;
state.layers = authority0_layers;
_cogl_material_foreach_layer_internal (authority0,
_cogl_pipeline_foreach_layer_internal (authority0,
add_layer_to_array_cb,
&state);
authority1_layers =
g_alloca (sizeof (CoglMaterialLayer *) * n_layers);
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
state.i = 0;
state.layers = authority1_layers;
_cogl_material_foreach_layer_internal (authority1,
_cogl_pipeline_foreach_layer_internal (authority1,
add_layer_to_array_cb,
&state);
@ -280,13 +280,13 @@ find_arbfp_authority (CoglMaterial *material, CoglHandle user_program)
/* Find the next ancestor after that, that also modifies state
* affecting arbfp codegen... */
if (!_cogl_material_get_parent (authority1))
if (!_cogl_pipeline_get_parent (authority1))
break;
authority0 = authority1;
authority1 =
_cogl_material_get_authority (_cogl_material_get_parent (authority1),
COGL_MATERIAL_STATE_LAYERS);
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1),
COGL_PIPELINE_STATE_LAYERS);
if (authority1 == authority0)
break;
}
@ -294,44 +294,44 @@ find_arbfp_authority (CoglMaterial *material, CoglHandle user_program)
return authority1;
}
static CoglMaterialBackendARBfpPrivate *
get_arbfp_priv (CoglMaterial *material)
static CoglPipelineBackendARBfpPrivate *
get_arbfp_priv (CoglPipeline *pipeline)
{
if (!(material->backend_priv_set_mask & COGL_MATERIAL_BACKEND_ARBFP_MASK))
if (!(pipeline->backend_priv_set_mask & COGL_PIPELINE_BACKEND_ARBFP_MASK))
return NULL;
return material->backend_privs[COGL_MATERIAL_BACKEND_ARBFP];
return pipeline->backend_privs[COGL_PIPELINE_BACKEND_ARBFP];
}
static void
set_arbfp_priv (CoglMaterial *material, CoglMaterialBackendARBfpPrivate *priv)
set_arbfp_priv (CoglPipeline *pipeline, CoglPipelineBackendARBfpPrivate *priv)
{
if (priv)
{
material->backend_privs[COGL_MATERIAL_BACKEND_ARBFP] = priv;
material->backend_priv_set_mask |= COGL_MATERIAL_BACKEND_ARBFP_MASK;
pipeline->backend_privs[COGL_PIPELINE_BACKEND_ARBFP] = priv;
pipeline->backend_priv_set_mask |= COGL_PIPELINE_BACKEND_ARBFP_MASK;
}
else
material->backend_priv_set_mask &= ~COGL_MATERIAL_BACKEND_ARBFP_MASK;
pipeline->backend_priv_set_mask &= ~COGL_PIPELINE_BACKEND_ARBFP_MASK;
}
static ArbfpProgramState *
get_arbfp_program_state (CoglMaterial *material)
get_arbfp_program_state (CoglPipeline *pipeline)
{
CoglMaterialBackendARBfpPrivate *priv = get_arbfp_priv (material);
CoglPipelineBackendARBfpPrivate *priv = get_arbfp_priv (pipeline);
if (!priv)
return NULL;
return priv->arbfp_program_state;
}
static gboolean
_cogl_material_backend_arbfp_start (CoglMaterial *material,
_cogl_pipeline_backend_arbfp_start (CoglPipeline *pipeline,
int n_layers,
unsigned long materials_difference)
unsigned long pipelines_difference)
{
CoglMaterialBackendARBfpPrivate *priv;
CoglMaterial *authority;
CoglMaterialBackendARBfpPrivate *authority_priv;
CoglPipelineBackendARBfpPrivate *priv;
CoglPipeline *authority;
CoglPipelineBackendARBfpPrivate *authority_priv;
CoglHandle user_program;
_COGL_GET_CONTEXT (ctx, FALSE);
@ -346,18 +346,18 @@ _cogl_material_backend_arbfp_start (CoglMaterial *material,
if (ctx->legacy_fog_state.enabled)
return FALSE;
user_program = cogl_material_get_user_program (material);
user_program = cogl_pipeline_get_user_program (pipeline);
if (user_program != COGL_INVALID_HANDLE &&
_cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_ARBFP)
return FALSE;
/* Now lookup our ARBfp backend private state (allocating if
* necessary) */
priv = get_arbfp_priv (material);
priv = get_arbfp_priv (pipeline);
if (!priv)
{
priv = g_slice_new0 (CoglMaterialBackendARBfpPrivate);
set_arbfp_priv (material, priv);
priv = g_slice_new0 (CoglPipelineBackendARBfpPrivate);
set_arbfp_priv (pipeline, priv);
}
/* If we have a valid arbfp_program_state pointer then we are all
@ -367,17 +367,17 @@ _cogl_material_backend_arbfp_start (CoglMaterial *material,
/* If we don't have an associated arbfp program yet then find the
* arbfp-authority (the oldest ancestor whose state will result in
* the same program being generated as for this material).
* the same program being generated as for this pipeline).
*
* We always make sure to associate new programs with the
* arbfp-authority to maximize the chance that other materials can
* arbfp-authority to maximize the chance that other pipelines can
* share it.
*/
authority = find_arbfp_authority (material, user_program);
authority = find_arbfp_authority (pipeline, user_program);
authority_priv = get_arbfp_priv (authority);
if (!authority_priv)
{
authority_priv = g_slice_new0 (CoglMaterialBackendARBfpPrivate);
authority_priv = g_slice_new0 (CoglPipelineBackendARBfpPrivate);
set_arbfp_priv (authority, authority_priv);
}
@ -416,10 +416,10 @@ _cogl_material_backend_arbfp_start (CoglMaterial *material,
}
}
/* Finally, if the material isn't actually its own arbfp-authority
/* Finally, if the pipeline isn't actually its own arbfp-authority
* then steal a reference to the program state associated with the
* arbfp-authority... */
if (authority != material)
if (authority != pipeline)
priv->arbfp_program_state =
arbfp_program_state_ref (authority_priv->arbfp_program_state);
@ -431,9 +431,9 @@ _cogl_material_backend_arbfp_start (CoglMaterial *material,
* with the same arguments...
*/
static gboolean
need_texture_combine_separate (CoglMaterialLayer *combine_authority)
need_texture_combine_separate (CoglPipelineLayer *combine_authority)
{
CoglMaterialLayerBigState *big_state = combine_authority->big_state;
CoglPipelineLayerBigState *big_state = combine_authority->big_state;
int n_args;
int i;
@ -539,18 +539,18 @@ setup_texture_source (ArbfpProgramState *arbfp_program_state,
}
}
typedef enum _CoglMaterialBackendARBfpArgType
typedef enum _CoglPipelineBackendARBfpArgType
{
COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE,
COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_CONSTANT,
COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_TEXTURE
} CoglMaterialBackendARBfpArgType;
COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE,
COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_CONSTANT,
COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_TEXTURE
} CoglPipelineBackendARBfpArgType;
typedef struct _CoglMaterialBackendARBfpArg
typedef struct _CoglPipelineBackendARBfpArg
{
const char *name;
CoglMaterialBackendARBfpArgType type;
CoglPipelineBackendARBfpArgType type;
/* for type = TEXTURE */
int texture_unit;
@ -561,22 +561,22 @@ typedef struct _CoglMaterialBackendARBfpArg
const char *swizzle;
} CoglMaterialBackendARBfpArg;
} CoglPipelineBackendARBfpArg;
static void
append_arg (GString *source, const CoglMaterialBackendARBfpArg *arg)
append_arg (GString *source, const CoglPipelineBackendARBfpArg *arg)
{
switch (arg->type)
{
case COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_TEXTURE:
case COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_TEXTURE:
g_string_append_printf (source, "texel%d%s",
arg->texture_unit, arg->swizzle);
break;
case COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_CONSTANT:
case COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_CONSTANT:
g_string_append_printf (source, "program.local[%d]%s",
arg->constant_id, arg->swizzle);
break;
case COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE:
case COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE:
g_string_append_printf (source, "%s%s",
arg->name, arg->swizzle);
break;
@ -585,17 +585,17 @@ append_arg (GString *source, const CoglMaterialBackendARBfpArg *arg)
/* Note: we are trying to avoid duplicating strings during codegen
* which is why we have the slightly awkward
* CoglMaterialBackendARBfpArg mechanism. */
* CoglPipelineBackendARBfpArg mechanism. */
static void
setup_arg (CoglMaterial *material,
CoglMaterialLayer *layer,
setup_arg (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
CoglBlendStringChannelMask mask,
int arg_index,
GLint src,
GLint op,
CoglMaterialBackendARBfpArg *arg)
CoglPipelineBackendARBfpArg *arg)
{
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (material);
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline);
static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" };
GLenum gl_target;
CoglHandle texture;
@ -603,42 +603,42 @@ setup_arg (CoglMaterial *material,
switch (src)
{
case GL_TEXTURE:
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_TEXTURE;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_TEXTURE;
arg->name = "texel%d";
arg->texture_unit = _cogl_material_layer_get_unit_index (layer);
texture = _cogl_material_layer_get_texture (layer);
arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer);
texture = _cogl_pipeline_layer_get_texture (layer);
cogl_texture_get_gl_texture (texture, NULL, &gl_target);
setup_texture_source (arbfp_program_state, arg->texture_unit, gl_target);
break;
case GL_CONSTANT:
{
int unit_index = _cogl_material_layer_get_unit_index (layer);
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
UnitState *unit_state = &arbfp_program_state->unit_state[unit_index];
unit_state->constant_id = arbfp_program_state->next_constant_id++;
unit_state->dirty_combine_constant = TRUE;
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_CONSTANT;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_CONSTANT;
arg->name = "program.local[%d]";
arg->constant_id = unit_state->constant_id;
break;
}
case GL_PRIMARY_COLOR:
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->name = "fragment.color.primary";
break;
case GL_PREVIOUS:
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
if (_cogl_material_layer_get_unit_index (layer) == 0)
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
if (_cogl_pipeline_layer_get_unit_index (layer) == 0)
arg->name = "fragment.color.primary";
else
arg->name = "output";
break;
default: /* GL_TEXTURE0..N */
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_TEXTURE;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_TEXTURE;
arg->name = "texture[%d]";
arg->texture_unit = src - GL_TEXTURE0;
texture = _cogl_material_layer_get_texture (layer);
texture = _cogl_pipeline_layer_get_texture (layer);
cogl_texture_get_gl_texture (texture, NULL, &gl_target);
setup_texture_source (arbfp_program_state, arg->texture_unit, gl_target);
}
@ -655,7 +655,7 @@ setup_arg (CoglMaterial *material,
arg_index);
append_arg (arbfp_program_state->source, arg);
g_string_append_printf (arbfp_program_state->source, ";\n");
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->name = tmp_name[arg_index];
arg->swizzle = "";
break;
@ -676,7 +676,7 @@ setup_arg (CoglMaterial *material,
g_string_append_printf (arbfp_program_state->source, ".a;\n");
else
g_string_append_printf (arbfp_program_state->source, ";\n");
arg->type = COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->type = COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_SIMPLE;
arg->name = tmp_name[arg_index];
break;
default:
@ -686,8 +686,8 @@ setup_arg (CoglMaterial *material,
}
static gboolean
backend_arbfp_args_equal (CoglMaterialBackendARBfpArg *arg0,
CoglMaterialBackendARBfpArg *arg1)
backend_arbfp_args_equal (CoglPipelineBackendARBfpArg *arg0,
CoglPipelineBackendARBfpArg *arg1)
{
if (arg0->type != arg1->type)
return FALSE;
@ -696,13 +696,13 @@ backend_arbfp_args_equal (CoglMaterialBackendARBfpArg *arg0,
strcmp (arg0->name, arg1->name) != 0)
return FALSE;
if (arg0->type == COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_TEXTURE &&
if (arg0->type == COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_TEXTURE &&
arg0->texture_unit != arg1->texture_unit)
return FALSE;
/* Note we don't have to check the target; a texture unit can only
* have one target enabled at a time. */
if (arg0->type == COGL_MATERIAL_BACKEND_ARBFP_ARG_TYPE_CONSTANT &&
if (arg0->type == COGL_PIPELINE_BACKEND_ARBFP_ARG_TYPE_CONSTANT &&
arg0->constant_id != arg0->constant_id)
return FALSE;
@ -714,13 +714,13 @@ backend_arbfp_args_equal (CoglMaterialBackendARBfpArg *arg0,
}
static void
append_function (CoglMaterial *material,
append_function (CoglPipeline *pipeline,
CoglBlendStringChannelMask mask,
GLint function,
CoglMaterialBackendARBfpArg *args,
CoglPipelineBackendARBfpArg *args,
int n_args)
{
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (material);
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline);
const char *mask_name;
switch (mask)
@ -852,8 +852,8 @@ append_function (CoglMaterial *material,
}
static void
append_masked_combine (CoglMaterial *arbfp_authority,
CoglMaterialLayer *layer,
append_masked_combine (CoglPipeline *arbfp_authority,
CoglPipelineLayer *layer,
CoglBlendStringChannelMask mask,
GLint function,
GLint *src,
@ -861,7 +861,7 @@ append_masked_combine (CoglMaterial *arbfp_authority,
{
int i;
int n_args;
CoglMaterialBackendARBfpArg args[3];
CoglPipelineBackendARBfpArg args[3];
n_args = _cogl_get_n_args_for_combine_func (function);
@ -884,15 +884,15 @@ append_masked_combine (CoglMaterial *arbfp_authority,
}
static gboolean
_cogl_material_backend_arbfp_add_layer (CoglMaterial *material,
CoglMaterialLayer *layer,
_cogl_pipeline_backend_arbfp_add_layer (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
unsigned long layers_difference)
{
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (material);
CoglMaterialLayer *combine_authority =
_cogl_material_layer_get_authority (layer,
COGL_MATERIAL_LAYER_STATE_COMBINE);
CoglMaterialLayerBigState *big_state = combine_authority->big_state;
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline);
CoglPipelineLayer *combine_authority =
_cogl_pipeline_layer_get_authority (layer,
COGL_PIPELINE_LAYER_STATE_COMBINE);
CoglPipelineLayerBigState *big_state = combine_authority->big_state;
/* Notes...
*
@ -928,7 +928,7 @@ _cogl_material_backend_arbfp_add_layer (CoglMaterial *material,
if (!need_texture_combine_separate (combine_authority))
{
append_masked_combine (material,
append_masked_combine (pipeline,
layer,
COGL_BLEND_STRING_CHANNEL_MASK_RGBA,
big_state->texture_combine_rgb_func,
@ -940,7 +940,7 @@ _cogl_material_backend_arbfp_add_layer (CoglMaterial *material,
/* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function
* since if you use it, it overrides your ALPHA function...
*/
append_masked_combine (material,
append_masked_combine (pipeline,
layer,
COGL_BLEND_STRING_CHANNEL_MASK_RGBA,
big_state->texture_combine_rgb_func,
@ -949,13 +949,13 @@ _cogl_material_backend_arbfp_add_layer (CoglMaterial *material,
}
else
{
append_masked_combine (material,
append_masked_combine (pipeline,
layer,
COGL_BLEND_STRING_CHANNEL_MASK_RGB,
big_state->texture_combine_rgb_func,
big_state->texture_combine_rgb_src,
big_state->texture_combine_rgb_op);
append_masked_combine (material,
append_masked_combine (pipeline,
layer,
COGL_BLEND_STRING_CHANNEL_MASK_ALPHA,
big_state->texture_combine_alpha_func,
@ -967,9 +967,9 @@ _cogl_material_backend_arbfp_add_layer (CoglMaterial *material,
}
gboolean
_cogl_material_backend_arbfp_passthrough (CoglMaterial *material)
_cogl_pipeline_backend_arbfp_passthrough (CoglPipeline *pipeline)
{
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (material);
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline);
if (!arbfp_program_state->source)
return TRUE;
@ -987,7 +987,7 @@ typedef struct _UpdateConstantsState
} UpdateConstantsState;
static gboolean
update_constants_cb (CoglMaterial *material,
update_constants_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
@ -1000,7 +1000,7 @@ update_constants_cb (CoglMaterial *material,
if (state->update_all || unit_state->dirty_combine_constant)
{
float constant[4];
_cogl_material_get_layer_combine_constant (material,
_cogl_pipeline_get_layer_combine_constant (pipeline,
layer_index,
constant);
GE (glProgramLocalParameter4fv (GL_FRAGMENT_PROGRAM_ARB,
@ -1012,10 +1012,10 @@ update_constants_cb (CoglMaterial *material,
}
static gboolean
_cogl_material_backend_arbfp_end (CoglMaterial *material,
unsigned long materials_difference)
_cogl_pipeline_backend_arbfp_end (CoglPipeline *pipeline,
unsigned long pipelines_difference)
{
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (material);
ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline);
GLuint gl_program;
_COGL_GET_CONTEXT (ctx, FALSE);
@ -1036,7 +1036,7 @@ _cogl_material_backend_arbfp_end (CoglMaterial *material,
g_string_append (arbfp_program_state->source, "END\n");
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_SHOW_SOURCE))
g_message ("material program:\n%s", arbfp_program_state->source->str);
g_message ("pipeline program:\n%s", arbfp_program_state->source->str);
GE (glGenPrograms (1, &arbfp_program_state->gl_program));
@ -1072,18 +1072,18 @@ _cogl_material_backend_arbfp_end (CoglMaterial *material,
gl_program = arbfp_program_state->gl_program;
GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, gl_program));
_cogl_use_program (0, COGL_MATERIAL_PROGRAM_TYPE_ARBFP);
_cogl_use_program (0, COGL_PIPELINE_PROGRAM_TYPE_ARBFP);
if (arbfp_program_state->user_program == COGL_INVALID_HANDLE)
{
UpdateConstantsState state;
state.unit = 0;
state.arbfp_program_state = arbfp_program_state;
/* If this arbfp program was last used with a different material
/* If this arbfp program was last used with a different pipeline
* then we need to ensure we update all program.local params */
state.update_all =
material != arbfp_program_state->last_used_for_material;
cogl_material_foreach_layer (material,
pipeline != arbfp_program_state->last_used_for_pipeline;
cogl_pipeline_foreach_layer (pipeline,
update_constants_cb,
&state);
}
@ -1101,22 +1101,22 @@ _cogl_material_backend_arbfp_end (CoglMaterial *material,
arbfp_program_state->user_program_age = program->age;
}
/* We need to track what material used this arbfp program last since
/* We need to track what pipeline used this arbfp program last since
* we will need to update program.local params when switching
* between different materials. */
arbfp_program_state->last_used_for_material = material;
* between different pipelines. */
arbfp_program_state->last_used_for_pipeline = pipeline;
return TRUE;
}
static void
dirty_arbfp_program_state (CoglMaterial *material)
dirty_arbfp_program_state (CoglPipeline *pipeline)
{
CoglMaterialBackendARBfpPrivate *priv;
CoglPipelineBackendARBfpPrivate *priv;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
priv = get_arbfp_priv (material);
priv = get_arbfp_priv (pipeline);
if (!priv)
return;
@ -1128,40 +1128,40 @@ dirty_arbfp_program_state (CoglMaterial *material)
}
static void
_cogl_material_backend_arbfp_material_pre_change_notify (
CoglMaterial *material,
CoglMaterialState change,
_cogl_pipeline_backend_arbfp_pipeline_pre_change_notify (
CoglPipeline *pipeline,
CoglPipelineState change,
const CoglColor *new_color)
{
static const unsigned long fragment_op_changes =
COGL_MATERIAL_STATE_LAYERS |
COGL_MATERIAL_STATE_USER_SHADER;
/* TODO: COGL_MATERIAL_STATE_FOG */
COGL_PIPELINE_STATE_LAYERS |
COGL_PIPELINE_STATE_USER_SHADER;
/* TODO: COGL_PIPELINE_STATE_FOG */
if (!(change & fragment_op_changes))
return;
dirty_arbfp_program_state (material);
dirty_arbfp_program_state (pipeline);
}
/* NB: layers are considered immutable once they have any dependants
* so although multiple materials can end up depending on a single
* so although multiple pipelines can end up depending on a single
* static layer, we can guarantee that if a layer is being *changed*
* then it can only have one material depending on it.
* then it can only have one pipeline depending on it.
*
* XXX: Don't forget this is *pre* change, we can't read the new value
* yet!
*/
static void
_cogl_material_backend_arbfp_layer_pre_change_notify (
CoglMaterial *owner,
CoglMaterialLayer *layer,
CoglMaterialLayerState change)
_cogl_pipeline_backend_arbfp_layer_pre_change_notify (
CoglPipeline *owner,
CoglPipelineLayer *layer,
CoglPipelineLayerState change)
{
CoglMaterialBackendARBfpPrivate *priv;
CoglPipelineBackendARBfpPrivate *priv;
static const unsigned long not_fragment_op_changes =
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_TEXTURE;
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT |
COGL_PIPELINE_LAYER_STATE_TEXTURE;
priv = get_arbfp_priv (owner);
if (!priv)
@ -1173,11 +1173,11 @@ _cogl_material_backend_arbfp_layer_pre_change_notify (
return;
}
if (change & COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT)
if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT)
{
ArbfpProgramState *arbfp_program_state =
get_arbfp_program_state (owner);
int unit_index = _cogl_material_layer_get_unit_index (layer);
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
arbfp_program_state->unit_state[unit_index].dirty_combine_constant = TRUE;
}
@ -1188,31 +1188,31 @@ _cogl_material_backend_arbfp_layer_pre_change_notify (
}
static void
_cogl_material_backend_arbfp_free_priv (CoglMaterial *material)
_cogl_pipeline_backend_arbfp_free_priv (CoglPipeline *pipeline)
{
CoglMaterialBackendARBfpPrivate *priv = get_arbfp_priv (material);
CoglPipelineBackendARBfpPrivate *priv = get_arbfp_priv (pipeline);
if (priv)
{
if (priv->arbfp_program_state)
arbfp_program_state_unref (priv->arbfp_program_state);
g_slice_free (CoglMaterialBackendARBfpPrivate, priv);
set_arbfp_priv (material, NULL);
g_slice_free (CoglPipelineBackendARBfpPrivate, priv);
set_arbfp_priv (pipeline, NULL);
}
}
const CoglMaterialBackend _cogl_material_arbfp_backend =
const CoglPipelineBackend _cogl_pipeline_arbfp_backend =
{
_cogl_material_backend_arbfp_get_max_texture_units,
_cogl_material_backend_arbfp_start,
_cogl_material_backend_arbfp_add_layer,
_cogl_material_backend_arbfp_passthrough,
_cogl_material_backend_arbfp_end,
_cogl_material_backend_arbfp_material_pre_change_notify,
_cogl_pipeline_backend_arbfp_get_max_texture_units,
_cogl_pipeline_backend_arbfp_start,
_cogl_pipeline_backend_arbfp_add_layer,
_cogl_pipeline_backend_arbfp_passthrough,
_cogl_pipeline_backend_arbfp_end,
_cogl_pipeline_backend_arbfp_pipeline_pre_change_notify,
NULL,
_cogl_material_backend_arbfp_layer_pre_change_notify,
_cogl_material_backend_arbfp_free_priv,
_cogl_pipeline_backend_arbfp_layer_pre_change_notify,
_cogl_pipeline_backend_arbfp_free_priv,
NULL
};
#endif /* COGL_MATERIAL_BACKEND_ARBFP */
#endif /* COGL_PIPELINE_BACKEND_ARBFP */

View File

@ -25,12 +25,12 @@
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_FIXED_PRIVATE_H
#define __COGL_MATERIAL_FIXED_PRIVATE_H
#ifndef __COGL_PIPELINE_FIXED_PRIVATE_H
#define __COGL_PIPELINE_FIXED_PRIVATE_H
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
extern const CoglMaterialBackend _cogl_material_fixed_backend;
extern const CoglPipelineBackend _cogl_pipeline_fixed_backend;
#endif /* __COGL_MATERIAL_FIXED_PRIVATE_H */
#endif /* __COGL_PIPELINE_FIXED_PRIVATE_H */

View File

@ -29,10 +29,10 @@
#include "config.h"
#endif
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#ifdef COGL_MATERIAL_BACKEND_FIXED
#ifdef COGL_PIPELINE_BACKEND_FIXED
#include "cogl.h"
#include "cogl-internal.h"
@ -51,10 +51,10 @@
#include "../gles/cogl-gles2-wrapper.h"
#endif
const CoglMaterialBackend _cogl_material_fixed_backend;
const CoglPipelineBackend _cogl_pipeline_fixed_backend;
static int
_cogl_material_backend_fixed_get_max_texture_units (void)
_cogl_pipeline_backend_fixed_get_max_texture_units (void)
{
_COGL_GET_CONTEXT (ctx, 0);
@ -71,21 +71,21 @@ _cogl_material_backend_fixed_get_max_texture_units (void)
}
static gboolean
_cogl_material_backend_fixed_start (CoglMaterial *material,
_cogl_pipeline_backend_fixed_start (CoglPipeline *pipeline,
int n_layers,
unsigned long materials_difference)
unsigned long pipelines_difference)
{
_cogl_use_program (0, COGL_MATERIAL_PROGRAM_TYPE_FIXED);
_cogl_use_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED);
return TRUE;
}
static gboolean
_cogl_material_backend_fixed_add_layer (CoglMaterial *material,
CoglMaterialLayer *layer,
_cogl_pipeline_backend_fixed_add_layer (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
unsigned long layers_difference)
{
CoglTextureUnit *unit =
_cogl_get_texture_unit (_cogl_material_layer_get_unit_index (layer));
_cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer));
int unit_index = unit->index;
int n_rgb_func_args;
int n_alpha_func_args;
@ -100,12 +100,12 @@ _cogl_material_backend_fixed_add_layer (CoglMaterial *material,
*/
_cogl_set_active_texture_unit (unit_index);
if (layers_difference & COGL_MATERIAL_LAYER_STATE_COMBINE)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE)
{
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer,
COGL_MATERIAL_LAYER_STATE_COMBINE);
CoglMaterialLayerBigState *big_state = authority->big_state;
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer,
COGL_PIPELINE_LAYER_STATE_COMBINE);
CoglPipelineLayerBigState *big_state = authority->big_state;
GE (glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
@ -168,12 +168,12 @@ _cogl_material_backend_fixed_add_layer (CoglMaterial *material,
}
}
if (layers_difference & COGL_MATERIAL_LAYER_STATE_COMBINE)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE)
{
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer,
COGL_MATERIAL_LAYER_STATE_COMBINE);
CoglMaterialLayerBigState *big_state = authority->big_state;
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer,
COGL_PIPELINE_LAYER_STATE_COMBINE);
CoglPipelineLayerBigState *big_state = authority->big_state;
GE (glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
big_state->texture_combine_constant));
@ -183,14 +183,14 @@ _cogl_material_backend_fixed_add_layer (CoglMaterial *material,
}
static gboolean
_cogl_material_backend_fixed_end (CoglMaterial *material,
unsigned long materials_difference)
_cogl_pipeline_backend_fixed_end (CoglPipeline *pipeline,
unsigned long pipelines_difference)
{
if (materials_difference & COGL_MATERIAL_STATE_FOG)
if (pipelines_difference & COGL_PIPELINE_STATE_FOG)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_FOG);
CoglMaterialFogState *fog_state = &authority->big_state->fog_state;
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG);
CoglPipelineFogState *fog_state = &authority->big_state->fog_state;
if (fog_state->enabled)
{
@ -244,18 +244,18 @@ _cogl_material_backend_fixed_end (CoglMaterial *material,
return TRUE;
}
const CoglMaterialBackend _cogl_material_fixed_backend =
const CoglPipelineBackend _cogl_pipeline_fixed_backend =
{
_cogl_material_backend_fixed_get_max_texture_units,
_cogl_material_backend_fixed_start,
_cogl_material_backend_fixed_add_layer,
_cogl_pipeline_backend_fixed_get_max_texture_units,
_cogl_pipeline_backend_fixed_start,
_cogl_pipeline_backend_fixed_add_layer,
NULL, /* passthrough */
_cogl_material_backend_fixed_end,
NULL, /* material_change_notify */
NULL, /* material_set_parent_notify */
_cogl_pipeline_backend_fixed_end,
NULL, /* pipeline_change_notify */
NULL, /* pipeline_set_parent_notify */
NULL, /* layer_change_notify */
NULL /* free_priv */
};
#endif /* COGL_MATERIAL_BACKEND_FIXED */
#endif /* COGL_PIPELINE_BACKEND_FIXED */

View File

@ -25,12 +25,12 @@
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_GLSL_PRIVATE_H
#define __COGL_MATERIAL_GLSL_PRIVATE_H
#ifndef __COGL_PIPELINE_GLSL_PRIVATE_H
#define __COGL_PIPELINE_GLSL_PRIVATE_H
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
extern const CoglMaterialBackend _cogl_material_glsl_backend;
extern const CoglPipelineBackend _cogl_pipeline_glsl_backend;
#endif /* __COGL_MATERIAL_GLSL_PRIVATE_H */
#endif /* __COGL_PIPELINE_GLSL_PRIVATE_H */

View File

@ -29,10 +29,10 @@
#include "config.h"
#endif
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-shader-private.h"
#ifdef COGL_MATERIAL_BACKEND_GLSL
#ifdef COGL_PIPELINE_BACKEND_GLSL
#include "cogl.h"
#include "cogl-internal.h"
@ -56,7 +56,7 @@
#include <glib.h>
/*
* GL/GLES compatability defines for material thingies:
* GL/GLES compatability defines for pipeline thingies:
*/
#ifdef HAVE_COGL_GLES2
@ -87,15 +87,15 @@ typedef struct _GlslProgramState
#endif
} GlslProgramState;
typedef struct _CoglMaterialBackendGlslPrivate
typedef struct _CoglPipelineBackendGlslPrivate
{
GlslProgramState *glsl_program_state;
} CoglMaterialBackendGlslPrivate;
} CoglPipelineBackendGlslPrivate;
const CoglMaterialBackend _cogl_material_glsl_backend;
const CoglPipelineBackend _cogl_pipeline_glsl_backend;
static int
_cogl_material_backend_glsl_get_max_texture_units (void)
_cogl_pipeline_backend_glsl_get_max_texture_units (void)
{
return _cogl_get_max_texture_image_units ();
}
@ -152,56 +152,56 @@ glsl_program_state_unref (GlslProgramState *state)
}
/* This tries to find the oldest ancestor whos state would generate
* the same glsl program as the current material. This is a simple
* the same glsl program as the current pipeline. This is a simple
* mechanism for reducing the number of glsl programs we have to
* generate.
*/
static CoglMaterial *
find_glsl_authority (CoglMaterial *material, CoglHandle user_program)
static CoglPipeline *
find_glsl_authority (CoglPipeline *pipeline, CoglHandle user_program)
{
/* Find the first material that modifies the user shader */
return _cogl_material_get_authority (material,
COGL_MATERIAL_STATE_USER_SHADER);
/* Find the first pipeline that modifies the user shader */
return _cogl_pipeline_get_authority (pipeline,
COGL_PIPELINE_STATE_USER_SHADER);
}
static CoglMaterialBackendGlslPrivate *
get_glsl_priv (CoglMaterial *material)
static CoglPipelineBackendGlslPrivate *
get_glsl_priv (CoglPipeline *pipeline)
{
if (!(material->backend_priv_set_mask & COGL_MATERIAL_BACKEND_GLSL_MASK))
if (!(pipeline->backend_priv_set_mask & COGL_PIPELINE_BACKEND_GLSL_MASK))
return NULL;
return material->backend_privs[COGL_MATERIAL_BACKEND_GLSL];
return pipeline->backend_privs[COGL_PIPELINE_BACKEND_GLSL];
}
static void
set_glsl_priv (CoglMaterial *material, CoglMaterialBackendGlslPrivate *priv)
set_glsl_priv (CoglPipeline *pipeline, CoglPipelineBackendGlslPrivate *priv)
{
if (priv)
{
material->backend_privs[COGL_MATERIAL_BACKEND_GLSL] = priv;
material->backend_priv_set_mask |= COGL_MATERIAL_BACKEND_GLSL_MASK;
pipeline->backend_privs[COGL_PIPELINE_BACKEND_GLSL] = priv;
pipeline->backend_priv_set_mask |= COGL_PIPELINE_BACKEND_GLSL_MASK;
}
else
material->backend_priv_set_mask &= ~COGL_MATERIAL_BACKEND_GLSL_MASK;
pipeline->backend_priv_set_mask &= ~COGL_PIPELINE_BACKEND_GLSL_MASK;
}
static GlslProgramState *
get_glsl_program_state (CoglMaterial *material)
get_glsl_program_state (CoglPipeline *pipeline)
{
CoglMaterialBackendGlslPrivate *priv = get_glsl_priv (material);
CoglPipelineBackendGlslPrivate *priv = get_glsl_priv (pipeline);
if (!priv)
return NULL;
return priv->glsl_program_state;
}
static void
dirty_glsl_program_state (CoglMaterial *material)
dirty_glsl_program_state (CoglPipeline *pipeline)
{
CoglMaterialBackendGlslPrivate *priv;
CoglPipelineBackendGlslPrivate *priv;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
priv = get_glsl_priv (material);
priv = get_glsl_priv (pipeline);
if (!priv)
return;
@ -250,13 +250,13 @@ link_program (GLint gl_program)
}
static gboolean
_cogl_material_backend_glsl_start (CoglMaterial *material,
_cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
int n_layers,
unsigned long materials_difference)
unsigned long pipelines_difference)
{
CoglMaterialBackendGlslPrivate *priv;
CoglMaterial *authority;
CoglMaterialBackendGlslPrivate *authority_priv;
CoglPipelineBackendGlslPrivate *priv;
CoglPipeline *authority;
CoglPipelineBackendGlslPrivate *authority_priv;
CoglProgram *user_program;
GLuint gl_program;
GSList *l;
@ -266,18 +266,18 @@ _cogl_material_backend_glsl_start (CoglMaterial *material,
if (!cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
return FALSE;
user_program = cogl_material_get_user_program (material);
user_program = cogl_pipeline_get_user_program (pipeline);
if (user_program == COGL_INVALID_HANDLE ||
_cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_GLSL)
return FALSE; /* XXX: change me when we support code generation here */
/* Now lookup our glsl backend private state (allocating if
* necessary) */
priv = get_glsl_priv (material);
priv = get_glsl_priv (pipeline);
if (!priv)
{
priv = g_slice_new0 (CoglMaterialBackendGlslPrivate);
set_glsl_priv (material, priv);
priv = g_slice_new0 (CoglPipelineBackendGlslPrivate);
set_glsl_priv (pipeline, priv);
}
/* If we already have a valid GLSL program then we don't need to
@ -299,17 +299,17 @@ _cogl_material_backend_glsl_start (CoglMaterial *material,
{
/* If we don't have an associated glsl program yet then find the
* glsl-authority (the oldest ancestor whose state will result in
* the same program being generated as for this material).
* the same program being generated as for this pipeline).
*
* We always make sure to associate new programs with the
* glsl-authority to maximize the chance that other materials can
* glsl-authority to maximize the chance that other pipelines can
* share it.
*/
authority = find_glsl_authority (material, user_program);
authority = find_glsl_authority (pipeline, user_program);
authority_priv = get_glsl_priv (authority);
if (!authority_priv)
{
authority_priv = g_slice_new0 (CoglMaterialBackendGlslPrivate);
authority_priv = g_slice_new0 (CoglPipelineBackendGlslPrivate);
set_glsl_priv (authority, authority_priv);
}
@ -322,10 +322,10 @@ _cogl_material_backend_glsl_start (CoglMaterial *material,
glsl_program_state_new (n_layers);
authority_priv->glsl_program_state = glsl_program_state;
/* If the material isn't actually its own glsl-authority
/* If the pipeline isn't actually its own glsl-authority
* then take a reference to the program state associated
* with the glsl-authority... */
if (authority != material)
if (authority != pipeline)
priv->glsl_program_state =
glsl_program_state_ref (authority_priv->glsl_program_state);
}
@ -359,24 +359,24 @@ _cogl_material_backend_glsl_start (CoglMaterial *material,
}
gboolean
_cogl_material_backend_glsl_add_layer (CoglMaterial *material,
CoglMaterialLayer *layer,
_cogl_pipeline_backend_glsl_add_layer (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
unsigned long layers_difference)
{
return TRUE;
}
gboolean
_cogl_material_backend_glsl_passthrough (CoglMaterial *material)
_cogl_pipeline_backend_glsl_passthrough (CoglPipeline *pipeline)
{
return TRUE;
}
gboolean
_cogl_material_backend_glsl_end (CoglMaterial *material,
unsigned long materials_difference)
_cogl_pipeline_backend_glsl_end (CoglPipeline *pipeline,
unsigned long pipelines_difference)
{
GlslProgramState *glsl_program_state = get_glsl_program_state (material);
GlslProgramState *glsl_program_state = get_glsl_program_state (pipeline);
GLuint gl_program;
gboolean gl_program_changed;
@ -396,10 +396,10 @@ _cogl_material_backend_glsl_end (CoglMaterial *material,
gl_program_changed = TRUE;
}
#else
_cogl_use_program (gl_program, COGL_MATERIAL_PROGRAM_TYPE_GLSL);
_cogl_use_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL);
#endif
_cogl_program_flush_uniforms (cogl_material_get_user_program (material),
_cogl_program_flush_uniforms (cogl_pipeline_get_user_program (pipeline),
gl_program, gl_program_changed);
glsl_program_state->gl_program_changed = FALSE;
@ -408,45 +408,45 @@ _cogl_material_backend_glsl_end (CoglMaterial *material,
}
static void
_cogl_material_backend_glsl_pre_change_notify (CoglMaterial *material,
CoglMaterialState change,
_cogl_pipeline_backend_glsl_pre_change_notify (CoglPipeline *pipeline,
CoglPipelineState change,
const CoglColor *new_color)
{
static const unsigned long glsl_op_changes =
COGL_MATERIAL_STATE_USER_SHADER;
COGL_PIPELINE_STATE_USER_SHADER;
if (!(change & glsl_op_changes))
return;
dirty_glsl_program_state (material);
dirty_glsl_program_state (pipeline);
}
static void
_cogl_material_backend_glsl_free_priv (CoglMaterial *material)
_cogl_pipeline_backend_glsl_free_priv (CoglPipeline *pipeline)
{
CoglMaterialBackendGlslPrivate *priv = get_glsl_priv (material);
CoglPipelineBackendGlslPrivate *priv = get_glsl_priv (pipeline);
if (priv)
{
if (priv->glsl_program_state)
glsl_program_state_unref (priv->glsl_program_state);
g_slice_free (CoglMaterialBackendGlslPrivate, priv);
set_glsl_priv (material, NULL);
g_slice_free (CoglPipelineBackendGlslPrivate, priv);
set_glsl_priv (pipeline, NULL);
}
}
const CoglMaterialBackend _cogl_material_glsl_backend =
const CoglPipelineBackend _cogl_pipeline_glsl_backend =
{
_cogl_material_backend_glsl_get_max_texture_units,
_cogl_material_backend_glsl_start,
_cogl_material_backend_glsl_add_layer,
_cogl_material_backend_glsl_passthrough,
_cogl_material_backend_glsl_end,
_cogl_material_backend_glsl_pre_change_notify,
NULL, /* material_set_parent_notify */
_cogl_pipeline_backend_glsl_get_max_texture_units,
_cogl_pipeline_backend_glsl_start,
_cogl_pipeline_backend_glsl_add_layer,
_cogl_pipeline_backend_glsl_passthrough,
_cogl_pipeline_backend_glsl_end,
_cogl_pipeline_backend_glsl_pre_change_notify,
NULL, /* pipeline_set_parent_notify */
NULL, /* layer_pre_change_notify */
_cogl_material_backend_glsl_free_priv,
_cogl_pipeline_backend_glsl_free_priv,
NULL /* free_layer_priv */
};
#endif /* COGL_MATERIAL_BACKEND_GLSL */
#endif /* COGL_PIPELINE_BACKEND_GLSL */

View File

@ -25,15 +25,16 @@
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_OPENGL_PRIVATE_H
#define __COGL_MATERIAL_OPENGL_PRIVATE_H
#ifndef __COGL_PIPELINE_OPENGL_PRIVATE_H
#define __COGL_PIPELINE_OPENGL_PRIVATE_H
#include "cogl.h"
#include "cogl-pipeline-private.h"
#include "cogl-matrix-stack.h"
/*
* cogl-material.c owns the GPU's texture unit state so we have some
* cogl-pipeline.c owns the GPU's texture unit state so we have some
* private structures for describing the current state of a texture
* unit that we track in a per context array (ctx->texture_units) that
* grows according to the largest texture unit used so far...
@ -41,7 +42,7 @@
* Roughly speaking the members in this structure are of two kinds:
* either they are a low level reflection of the state we send to
* OpenGL or they are for high level meta data assoicated with the
* texture unit when flushing CoglMaterialLayers that is typically
* texture unit when flushing CoglPipelineLayers that is typically
* used to optimize subsequent re-flushing of the same layer.
*
* The low level members are at the top, and the high level members
@ -79,7 +80,7 @@ typedef struct _CoglTextureUnit
* to track when the unit->gl_texture state is out of sync with the GL
* texture object really bound too (GL_TEXTURE0+unit->index).
*
* XXX: as a further optimization cogl-material.c uses a convention
* XXX: as a further optimization cogl-pipeline.c uses a convention
* of always using texture unit 1 for these transient bindings so we
* can assume this is only ever TRUE for unit 1.
*/
@ -93,14 +94,14 @@ typedef struct _CoglTextureUnit
* Higher level layer state associated with the unit...
*/
/* The CoglMaterialLayer whos state was flushed to update this
/* The CoglPipelineLayer whos state was flushed to update this
* texture unit last.
*
* This will be set to NULL if the layer is modified or freed which
* means when we come to flush a layer; if this pointer is still
* valid and == to the layer being flushed we don't need to update
* any texture unit state. */
CoglMaterialLayer *layer;
CoglPipelineLayer *layer;
/* To help minimize the state changes required we track the
* difference flags associated with the layer whos state was last
@ -114,12 +115,12 @@ typedef struct _CoglTextureUnit
unsigned long layer_changes_since_flush;
/* Whenever a CoglTexture's internal GL texture storage changes
* cogl-material.c is notified with a call to
* _cogl_material_texture_storage_change_notify which inturn sets
* cogl-pipeline.c is notified with a call to
* _cogl_pipeline_texture_storage_change_notify which inturn sets
* this to TRUE for each texture unit that it is currently bound
* too. When we later come to flush some material state then we will
* too. When we later come to flush some pipeline state then we will
* always check this to potentially force an update of the texture
* state even if the material hasn't changed. */
* state even if the pipeline hasn't changed. */
gboolean texture_storage_changed;
} CoglTextureUnit;
@ -148,8 +149,8 @@ void
_cogl_gl_use_program_wrapper (CoglHandle program);
void
_cogl_material_flush_gl_state (CoglMaterial *material,
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
gboolean skip_gl_state);
#endif /* __COGL_MATERIAL_OPENGL_PRIVATE_H */
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */

View File

@ -32,26 +32,26 @@
#include "cogl.h"
#include "cogl-debug.h"
#include "cogl-material-opengl-private.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-context.h"
#include "cogl-texture-private.h"
#ifdef COGL_MATERIAL_BACKEND_GLSL
#include "cogl-material-glsl-private.h"
#ifdef COGL_PIPELINE_BACKEND_GLSL
#include "cogl-pipeline-glsl-private.h"
#endif
#ifdef COGL_MATERIAL_BACKEND_ARBFP
#include "cogl-material-arbfp-private.h"
#ifdef COGL_PIPELINE_BACKEND_ARBFP
#include "cogl-pipeline-arbfp-private.h"
#endif
#ifdef COGL_MATERIAL_BACKEND_FIXED
#include "cogl-material-fixed-private.h"
#ifdef COGL_PIPELINE_BACKEND_FIXED
#include "cogl-pipeline-fixed-private.h"
#endif
#include <glib.h>
#include <string.h>
/*
* GL/GLES compatability defines for material thingies:
* GL/GLES compatability defines for pipeline thingies:
*/
#ifdef HAVE_COGL_GLES2
@ -258,7 +258,7 @@ _cogl_delete_gl_texture (GLuint gl_texture)
* if it is reused again with the same texture unit.
*/
void
_cogl_material_texture_storage_change_notify (CoglHandle texture)
_cogl_pipeline_texture_storage_change_notify (CoglHandle texture)
{
int i;
@ -270,7 +270,7 @@ _cogl_material_texture_storage_change_notify (CoglHandle texture)
&g_array_index (ctx->texture_units, CoglTextureUnit, i);
if (unit->layer &&
_cogl_material_layer_get_texture (unit->layer) == texture)
_cogl_pipeline_layer_get_texture (unit->layer) == texture)
unit->texture_storage_changed = TRUE;
/* NB: the texture may be bound to multiple texture units so
@ -279,7 +279,7 @@ _cogl_material_texture_storage_change_notify (CoglHandle texture)
}
void
_cogl_use_program (GLuint gl_program, CoglMaterialProgramType type)
_cogl_use_program (GLuint gl_program, CoglPipelineProgramType type)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -289,18 +289,18 @@ _cogl_use_program (GLuint gl_program, CoglMaterialProgramType type)
/* ... disable the old type */
switch (ctx->current_use_program_type)
{
case COGL_MATERIAL_PROGRAM_TYPE_GLSL:
case COGL_PIPELINE_PROGRAM_TYPE_GLSL:
GE( glUseProgram (0) );
ctx->current_gl_program = 0;
break;
case COGL_MATERIAL_PROGRAM_TYPE_ARBFP:
case COGL_PIPELINE_PROGRAM_TYPE_ARBFP:
#ifdef HAVE_COGL_GL
GE( glDisable (GL_FRAGMENT_PROGRAM_ARB) );
#endif
break;
case COGL_MATERIAL_PROGRAM_TYPE_FIXED:
case COGL_PIPELINE_PROGRAM_TYPE_FIXED:
/* don't need to to anything */
break;
}
@ -308,22 +308,22 @@ _cogl_use_program (GLuint gl_program, CoglMaterialProgramType type)
/* ... and enable the new type */
switch (type)
{
case COGL_MATERIAL_PROGRAM_TYPE_ARBFP:
case COGL_PIPELINE_PROGRAM_TYPE_ARBFP:
#ifdef HAVE_COGL_GL
GE( glEnable (GL_FRAGMENT_PROGRAM_ARB) );
#endif
break;
case COGL_MATERIAL_PROGRAM_TYPE_GLSL:
case COGL_MATERIAL_PROGRAM_TYPE_FIXED:
case COGL_PIPELINE_PROGRAM_TYPE_GLSL:
case COGL_PIPELINE_PROGRAM_TYPE_FIXED:
/* don't need to to anything */
break;
}
}
if (type == COGL_MATERIAL_PROGRAM_TYPE_GLSL)
if (type == COGL_PIPELINE_PROGRAM_TYPE_GLSL)
{
#ifdef COGL_MATERIAL_BACKEND_GLSL
#ifdef COGL_PIPELINE_BACKEND_GLSL
if (ctx->current_gl_program != gl_program)
{
@ -345,18 +345,18 @@ _cogl_use_program (GLuint gl_program, CoglMaterialProgramType type)
g_warning ("Unexpected use of GLSL backend!");
#endif /* COGL_MATERIAL_BACKEND_GLSL */
#endif /* COGL_PIPELINE_BACKEND_GLSL */
}
#ifndef COGL_MATERIAL_BACKEND_ARBFP
else if (type == COGL_MATERIAL_PROGRAM_TYPE_ARBFP)
#ifndef COGL_PIPELINE_BACKEND_ARBFP
else if (type == COGL_PIPELINE_PROGRAM_TYPE_ARBFP)
g_warning ("Unexpected use of ARBFP backend!");
#endif /* COGL_MATERIAL_BACKEND_ARBFP */
#endif /* COGL_PIPELINE_BACKEND_ARBFP */
ctx->current_use_program_type = type;
}
#if defined (COGL_MATERIAL_BACKEND_GLSL) || \
defined (COGL_MATERIAL_BACKEND_ARBFP)
#if defined (COGL_PIPELINE_BACKEND_GLSL) || \
defined (COGL_PIPELINE_BACKEND_ARBFP)
int
_cogl_get_max_texture_image_units (void)
{
@ -376,7 +376,7 @@ _cogl_get_max_texture_image_units (void)
#endif
static void
_cogl_material_layer_get_texture_info (CoglMaterialLayer *layer,
_cogl_pipeline_layer_get_texture_info (CoglPipelineLayer *layer,
CoglHandle *texture,
GLuint *gl_texture,
GLuint *gl_target)
@ -409,7 +409,7 @@ blend_factor_uses_constant (GLenum blend_factor)
#endif
static void
flush_depth_state (CoglMaterialDepthState *depth_state)
flush_depth_state (CoglPipelineDepthState *depth_state)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -444,22 +444,22 @@ flush_depth_state (CoglMaterialDepthState *depth_state)
}
static void
_cogl_material_flush_color_blend_alpha_depth_state (
CoglMaterial *material,
unsigned long materials_difference,
_cogl_pipeline_flush_color_blend_alpha_depth_state (
CoglPipeline *pipeline,
unsigned long pipelines_difference,
gboolean skip_gl_color)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!skip_gl_color)
{
if ((materials_difference & COGL_MATERIAL_STATE_COLOR) ||
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
/* Assume if we were previously told to skip the color, then
* the current color needs updating... */
ctx->current_material_skip_gl_color)
ctx->current_pipeline_skip_gl_color)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_COLOR);
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);
GE (glColor4ub (cogl_color_get_red_byte (&authority->color),
cogl_color_get_green_byte (&authority->color),
cogl_color_get_blue_byte (&authority->color),
@ -467,11 +467,11 @@ _cogl_material_flush_color_blend_alpha_depth_state (
}
}
if (materials_difference & COGL_MATERIAL_STATE_LIGHTING)
if (pipelines_difference & COGL_PIPELINE_STATE_LIGHTING)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_LIGHTING);
CoglMaterialLightingState *lighting_state =
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING);
CoglPipelineLightingState *lighting_state =
&authority->big_state->lighting_state;
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, lighting_state->ambient));
@ -482,11 +482,11 @@ _cogl_material_flush_color_blend_alpha_depth_state (
&lighting_state->shininess));
}
if (materials_difference & COGL_MATERIAL_STATE_BLEND)
if (pipelines_difference & COGL_PIPELINE_STATE_BLEND)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_BLEND);
CoglMaterialBlendState *blend_state =
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND);
CoglPipelineBlendState *blend_state =
&authority->big_state->blend_state;
#if defined (HAVE_COGL_GLES2)
@ -541,11 +541,11 @@ _cogl_material_flush_color_blend_alpha_depth_state (
blend_state->blend_dst_factor_rgb));
}
if (materials_difference & COGL_MATERIAL_STATE_ALPHA_FUNC)
if (pipelines_difference & COGL_PIPELINE_STATE_ALPHA_FUNC)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_ALPHA_FUNC);
CoglMaterialAlphaFuncState *alpha_state =
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC);
CoglPipelineAlphaFuncState *alpha_state =
&authority->big_state->alpha_state;
/* NB: Currently the Cogl defines are compatible with the GL ones: */
@ -553,11 +553,11 @@ _cogl_material_flush_color_blend_alpha_depth_state (
alpha_state->alpha_func_reference));
}
if (materials_difference & COGL_MATERIAL_STATE_DEPTH)
if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
CoglMaterialDepthState *depth_state = &authority->big_state->depth_state;
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
CoglPipelineDepthState *depth_state = &authority->big_state->depth_state;
if (depth_state->depth_test_enabled)
{
@ -575,10 +575,10 @@ _cogl_material_flush_color_blend_alpha_depth_state (
}
}
if (materials_difference & COGL_MATERIAL_STATE_POINT_SIZE)
if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE)
{
CoglMaterial *authority =
_cogl_material_get_authority (material, COGL_MATERIAL_STATE_POINT_SIZE);
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE);
if (ctx->point_size_cache != authority->big_state->point_size)
{
@ -587,15 +587,15 @@ _cogl_material_flush_color_blend_alpha_depth_state (
}
}
if (material->real_blend_enable != ctx->gl_blend_enable_cache)
if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache)
{
if (material->real_blend_enable)
if (pipeline->real_blend_enable)
GE (glEnable (GL_BLEND));
else
GE (glDisable (GL_BLEND));
/* XXX: we shouldn't update any other blend state if blending
* is disabled! */
ctx->gl_blend_enable_cache = material->real_blend_enable;
ctx->gl_blend_enable_cache = pipeline->real_blend_enable;
}
}
@ -627,12 +627,12 @@ typedef struct
{
int i;
unsigned long *layer_differences;
} CoglMaterialFlushLayerState;
} CoglPipelineFlushLayerState;
static gboolean
flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
{
CoglMaterialFlushLayerState *flush_state = user_data;
CoglPipelineFlushLayerState *flush_state = user_data;
int unit_index = flush_state->i;
CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index);
unsigned long layers_difference =
@ -654,16 +654,16 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
return FALSE;
}
if (layers_difference & COGL_MATERIAL_LAYER_STATE_TEXTURE)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE)
{
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer,
COGL_MATERIAL_LAYER_STATE_TEXTURE);
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer,
COGL_PIPELINE_LAYER_STATE_TEXTURE);
CoglHandle texture = NULL;
GLuint gl_texture;
GLenum gl_target;
_cogl_material_layer_get_texture_info (authority,
_cogl_pipeline_layer_get_texture_info (authority,
&texture,
&gl_texture,
&gl_target);
@ -679,7 +679,7 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
*
* Because texture unit 1 is a bit special we actually defer any
* necessary glBindTexture for it until the end of
* _cogl_material_flush_gl_state().
* _cogl_pipeline_flush_gl_state().
*
* NB: we get notified whenever glDeleteTextures is used (see
* _cogl_delete_gl_texture()) where we invalidate
@ -740,11 +740,11 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
}
}
if (layers_difference & COGL_MATERIAL_LAYER_STATE_USER_MATRIX)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX)
{
CoglMaterialLayerState state = COGL_MATERIAL_LAYER_STATE_USER_MATRIX;
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer, state);
CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX;
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer, state);
_cogl_matrix_stack_set (unit->matrix_stack,
&authority->big_state->matrix);
@ -752,12 +752,12 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
_cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE);
}
if (layers_difference & COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS)
{
CoglMaterialState change = COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS;
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer, change);
CoglMaterialLayerBigState *big_state = authority->big_state;
CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer, change);
CoglPipelineLayerBigState *big_state = authority->big_state;
_cogl_set_active_texture_unit (unit_index);
@ -778,22 +778,22 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
}
static void
_cogl_material_flush_common_gl_state (CoglMaterial *material,
unsigned long materials_difference,
_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline,
unsigned long pipelines_difference,
unsigned long *layer_differences,
gboolean skip_gl_color)
{
CoglMaterialFlushLayerState state;
CoglPipelineFlushLayerState state;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_material_flush_color_blend_alpha_depth_state (material,
materials_difference,
_cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline,
pipelines_difference,
skip_gl_color);
state.i = 0;
state.layer_differences = layer_differences;
_cogl_material_foreach_layer_internal (material,
_cogl_pipeline_foreach_layer_internal (pipeline,
flush_layers_common_gl_state_cb,
&state);
@ -808,16 +808,16 @@ _cogl_material_flush_common_gl_state (CoglMaterial *material,
* since the actual texture being used may have been overridden.
*/
static void
_cogl_material_layer_forward_wrap_modes (CoglMaterialLayer *layer,
_cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer,
CoglHandle texture)
{
CoglMaterialWrapModeInternal wrap_mode_s, wrap_mode_t, wrap_mode_p;
CoglPipelineWrapModeInternal wrap_mode_s, wrap_mode_t, wrap_mode_p;
GLenum gl_wrap_mode_s, gl_wrap_mode_t, gl_wrap_mode_p;
if (texture == COGL_INVALID_HANDLE)
return;
_cogl_material_layer_get_wrap_modes (layer,
_cogl_pipeline_layer_get_wrap_modes (layer,
&wrap_mode_s,
&wrap_mode_t,
&wrap_mode_p);
@ -833,17 +833,17 @@ _cogl_material_layer_forward_wrap_modes (CoglMaterialLayer *layer,
will break if the application tries to use different modes in
different layers using the same texture. */
if (wrap_mode_s == COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC)
if (wrap_mode_s == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC)
gl_wrap_mode_s = GL_CLAMP_TO_EDGE;
else
gl_wrap_mode_s = wrap_mode_s;
if (wrap_mode_t == COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC)
if (wrap_mode_t == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC)
gl_wrap_mode_t = GL_CLAMP_TO_EDGE;
else
gl_wrap_mode_t = wrap_mode_t;
if (wrap_mode_p == COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC)
if (wrap_mode_p == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC)
gl_wrap_mode_p = GL_CLAMP_TO_EDGE;
else
gl_wrap_mode_p = wrap_mode_p;
@ -857,7 +857,7 @@ _cogl_material_layer_forward_wrap_modes (CoglMaterialLayer *layer,
/* OpenGL associates the min/mag filters and repeat modes with the
* texture object not the texture unit so we always have to re-assert
* the filter and repeat modes whenever we use a texture since it may
* be referenced by multiple materials with different modes.
* be referenced by multiple pipelines with different modes.
*
* XXX: GL_ARB_sampler_objects fixes this in OpenGL so we should
* eventually look at using this extension when available.
@ -879,14 +879,14 @@ foreach_texture_unit_update_filter_and_wrap_modes (void)
if (unit->layer)
{
CoglHandle texture = _cogl_material_layer_get_texture (unit->layer);
CoglMaterialFilter min;
CoglMaterialFilter mag;
CoglHandle texture = _cogl_pipeline_layer_get_texture (unit->layer);
CoglPipelineFilter min;
CoglPipelineFilter mag;
_cogl_material_layer_get_filters (unit->layer, &min, &mag);
_cogl_pipeline_layer_get_filters (unit->layer, &min, &mag);
_cogl_texture_set_filters (texture, min, mag);
_cogl_material_layer_forward_wrap_modes (unit->layer, texture);
_cogl_pipeline_layer_forward_wrap_modes (unit->layer, texture);
}
}
}
@ -895,12 +895,12 @@ typedef struct
{
int i;
unsigned long *layer_differences;
} CoglMaterialCompareLayersState;
} CoglPipelineCompareLayersState;
static gboolean
compare_layer_differences_cb (CoglMaterialLayer *layer, void *user_data)
compare_layer_differences_cb (CoglPipelineLayer *layer, void *user_data)
{
CoglMaterialCompareLayersState *state = user_data;
CoglPipelineCompareLayersState *state = user_data;
CoglTextureUnit *unit = _cogl_get_texture_unit (state->i);
if (unit->layer == layer)
@ -909,21 +909,21 @@ compare_layer_differences_cb (CoglMaterialLayer *layer, void *user_data)
{
state->layer_differences[state->i] = unit->layer_changes_since_flush;
state->layer_differences[state->i] |=
_cogl_material_layer_compare_differences (layer, unit->layer);
_cogl_pipeline_layer_compare_differences (layer, unit->layer);
}
else
state->layer_differences[state->i] = COGL_MATERIAL_LAYER_STATE_ALL_SPARSE;
state->layer_differences[state->i] = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE;
/* XXX: There is always a possibility that a CoglTexture's
* underlying GL texture storage has been changed since it was last
* bound to a texture unit which is why we have a callback into
* _cogl_material_texture_storage_change_notify whenever a textures
* _cogl_pipeline_texture_storage_change_notify whenever a textures
* underlying GL texture storage changes which will set the
* unit->texture_intern_changed flag. If we see that's been set here
* then we force an update of the texture state...
*/
if (unit->texture_storage_changed)
state->layer_differences[state->i] |= COGL_MATERIAL_LAYER_STATE_TEXTURE;
state->layer_differences[state->i] |= COGL_PIPELINE_LAYER_STATE_TEXTURE;
state->i++;
@ -932,22 +932,22 @@ compare_layer_differences_cb (CoglMaterialLayer *layer, void *user_data)
typedef struct
{
const CoglMaterialBackend *backend;
CoglMaterial *material;
const CoglPipelineBackend *backend;
CoglPipeline *pipeline;
unsigned long *layer_differences;
gboolean error_adding_layer;
gboolean added_layer;
} CoglMaterialBackendAddLayerState;
} CoglPipelineBackendAddLayerState;
static gboolean
backend_add_layer_cb (CoglMaterialLayer *layer,
backend_add_layer_cb (CoglPipelineLayer *layer,
void *user_data)
{
CoglMaterialBackendAddLayerState *state = user_data;
const CoglMaterialBackend *backend = state->backend;
CoglMaterial *material = state->material;
int unit_index = _cogl_material_layer_get_unit_index (layer);
CoglPipelineBackendAddLayerState *state = user_data;
const CoglPipelineBackend *backend = state->backend;
CoglPipeline *pipeline = state->pipeline;
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index);
_COGL_GET_CONTEXT (ctx, FALSE);
@ -971,7 +971,7 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
/* Either generate per layer code snippets or setup the
* fixed function glTexEnv for each layer... */
if (G_LIKELY (backend->add_layer (material,
if (G_LIKELY (backend->add_layer (pipeline,
layer,
state->layer_differences[unit_index])))
state->added_layer = TRUE;
@ -985,10 +985,10 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
}
/*
* _cogl_material_flush_gl_state:
* _cogl_pipeline_flush_gl_state:
*
* Details of override options:
* ->fallback_mask: is a bitmask of the material layers that need to be
* ->fallback_mask: is a bitmask of the pipeline layers that need to be
* replaced with the default, fallback textures. The fallback textures are
* fully transparent textures so they hopefully wont contribute to the
* texture combining.
@ -999,7 +999,7 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
* have a fighting chance of looking close to their originally intended
* result.
*
* ->disable_mask: is a bitmask of the material layers that will simply have
* ->disable_mask: is a bitmask of the pipeline layers that will simply have
* texturing disabled. It's only really intended for disabling all layers
* > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB
* and at some point the remaining bits flip to 1. It might work to disable
@ -1016,7 +1016,7 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
* 0.
*
* The intention of this is for any primitives that supports sliced textures.
* The code will can iterate each of the slices and re-flush the material
* The code will can iterate each of the slices and re-flush the pipeline
* forcing the GL texture of each slice in turn.
*
* ->wrap_mode_overrides: overrides the wrap modes set on each
@ -1035,16 +1035,16 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
* isn't ideal, and can't be used with CoglVertexBuffers.
*/
void
_cogl_material_flush_gl_state (CoglMaterial *material,
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
gboolean skip_gl_color)
{
unsigned long materials_difference;
unsigned long pipelines_difference;
int n_layers;
unsigned long *layer_differences;
int i;
CoglTextureUnit *unit1;
COGL_STATIC_TIMER (material_flush_timer,
COGL_STATIC_TIMER (pipeline_flush_timer,
"Mainloop", /* parent */
"Material Flush",
"The time spent flushing material state",
@ -1052,37 +1052,37 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
COGL_TIMER_START (_cogl_uprof_context, material_flush_timer);
COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer);
if (ctx->current_material == material)
if (ctx->current_pipeline == pipeline)
{
/* Bail out asap if we've been asked to re-flush the already current
* material and we can see the material hasn't changed */
if (ctx->current_material_age == material->age)
* pipeline and we can see the pipeline hasn't changed */
if (ctx->current_pipeline_age == pipeline->age)
goto done;
materials_difference = ctx->current_material_changes_since_flush;
pipelines_difference = ctx->current_pipeline_changes_since_flush;
}
else if (ctx->current_material)
else if (ctx->current_pipeline)
{
materials_difference = ctx->current_material_changes_since_flush;
materials_difference |=
_cogl_material_compare_differences (ctx->current_material,
material);
pipelines_difference = ctx->current_pipeline_changes_since_flush;
pipelines_difference |=
_cogl_pipeline_compare_differences (ctx->current_pipeline,
pipeline);
}
else
materials_difference = COGL_MATERIAL_STATE_ALL_SPARSE;
pipelines_difference = COGL_PIPELINE_STATE_ALL_SPARSE;
/* Get a layer_differences mask for each layer to be flushed */
n_layers = cogl_material_get_n_layers (material);
n_layers = cogl_pipeline_get_n_layers (pipeline);
if (n_layers)
{
CoglMaterialCompareLayersState state;
CoglPipelineCompareLayersState state;
layer_differences = g_alloca (sizeof (unsigned long *) * n_layers);
memset (layer_differences, 0, sizeof (layer_differences));
state.i = 0;
state.layer_differences = layer_differences;
_cogl_material_foreach_layer_internal (material,
_cogl_pipeline_foreach_layer_internal (pipeline,
compare_layer_differences_cb,
&state);
}
@ -1090,7 +1090,7 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
layer_differences = NULL;
/* First flush everything that's the same regardless of which
* material backend is being used...
* pipeline backend is being used...
*
* 1) top level state:
* glColor (or skip if a vertex attribute is being used for color)
@ -1103,51 +1103,51 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
* enable/disable target
* flush user matrix
*
* Note: After _cogl_material_flush_common_gl_state you can expect
* Note: After _cogl_pipeline_flush_common_gl_state you can expect
* all state of the layers corresponding texture unit to be
* updated.
*/
_cogl_material_flush_common_gl_state (material,
materials_difference,
_cogl_pipeline_flush_common_gl_state (pipeline,
pipelines_difference,
layer_differences,
skip_gl_color);
/* Now flush the fragment processing state according to the current
* fragment processing backend.
*
* Note: Some of the backends may not support the current material
* Note: Some of the backends may not support the current pipeline
* configuration and in that case it will report an error and we
* will fallback to a different backend.
*
* NB: if material->backend != COGL_MATERIAL_BACKEND_UNDEFINED then
* we have previously managed to successfully flush this material
* NB: if pipeline->backend != COGL_PIPELINE_BACKEND_UNDEFINED then
* we have previously managed to successfully flush this pipeline
* with the given backend so we will simply use that to avoid
* fallback code paths.
*/
if (material->backend == COGL_MATERIAL_BACKEND_UNDEFINED)
_cogl_material_set_backend (material, COGL_MATERIAL_BACKEND_DEFAULT);
if (pipeline->backend == COGL_PIPELINE_BACKEND_UNDEFINED)
_cogl_pipeline_set_backend (pipeline, COGL_PIPELINE_BACKEND_DEFAULT);
for (i = material->backend;
i < G_N_ELEMENTS (_cogl_material_backends);
i++, _cogl_material_set_backend (material, i))
for (i = pipeline->backend;
i < G_N_ELEMENTS (_cogl_pipeline_backends);
i++, _cogl_pipeline_set_backend (pipeline, i))
{
const CoglMaterialBackend *backend = _cogl_material_backends[i];
CoglMaterialBackendAddLayerState state;
const CoglPipelineBackend *backend = _cogl_pipeline_backends[i];
CoglPipelineBackendAddLayerState state;
/* E.g. For backends generating code they can setup their
* scratch buffers here... */
if (G_UNLIKELY (!backend->start (material,
if (G_UNLIKELY (!backend->start (pipeline,
n_layers,
materials_difference)))
pipelines_difference)))
continue;
state.backend = backend;
state.material = material;
state.pipeline = pipeline;
state.layer_differences = layer_differences;
state.error_adding_layer = FALSE;
state.added_layer = FALSE;
_cogl_material_foreach_layer_internal (material,
_cogl_pipeline_foreach_layer_internal (pipeline,
backend_add_layer_cb,
&state);
@ -1156,34 +1156,34 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
if (!state.added_layer &&
backend->passthrough &&
G_UNLIKELY (!backend->passthrough (material)))
G_UNLIKELY (!backend->passthrough (pipeline)))
continue;
/* For backends generating code they may compile and link their
* programs here, update any uniforms and tell OpenGL to use
* that program.
*/
if (G_UNLIKELY (!backend->end (material, materials_difference)))
if (G_UNLIKELY (!backend->end (pipeline, pipelines_difference)))
continue;
break;
}
/* FIXME: This reference is actually resulting in lots of
* copy-on-write reparenting because one-shot materials end up
* copy-on-write reparenting because one-shot pipelines end up
* living for longer than necessary and so any later modification of
* the parent will cause a copy-on-write.
*
* XXX: The issue should largely go away when we switch to using
* weak materials for overrides.
* weak pipelines for overrides.
*/
cogl_object_ref (material);
if (ctx->current_material != NULL)
cogl_object_unref (ctx->current_material);
ctx->current_material = material;
ctx->current_material_changes_since_flush = 0;
ctx->current_material_skip_gl_color = skip_gl_color;
ctx->current_material_age = material->age;
cogl_object_ref (pipeline);
if (ctx->current_pipeline != NULL)
cogl_object_unref (ctx->current_pipeline);
ctx->current_pipeline = pipeline;
ctx->current_pipeline_changes_since_flush = 0;
ctx->current_pipeline_skip_gl_color = skip_gl_color;
ctx->current_pipeline_age = pipeline->age;
done:
@ -1191,12 +1191,12 @@ done:
* modes with the texture objects not the texture units... */
foreach_texture_unit_update_filter_and_wrap_modes ();
/* If this material has more than one layer then we always need
/* If this pipeline has more than one layer then we always need
* to make sure we rebind the texture for unit 1.
*
* NB: various components of Cogl may temporarily bind arbitrary
* textures to texture unit 1 so they can query and modify texture
* object parameters. cogl-material.c (See
* object parameters. cogl-pipeline.c (See
* _cogl_bind_gl_texture_transient)
*/
unit1 = _cogl_get_texture_unit (1);
@ -1207,6 +1207,6 @@ done:
unit1->dirty_gl_texture = FALSE;
}
COGL_TIMER_STOP (_cogl_uprof_context, material_flush_timer);
COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer);
}

View File

@ -0,0 +1,993 @@
/*
* 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_PIPELINE_PRIVATE_H
#define __COGL_PIPELINE_PRIVATE_H
#include "cogl.h"
#include "cogl-pipeline.h"
#include "cogl-matrix.h"
#include "cogl-object-private.h"
#include "cogl-profile.h"
#include <glib.h>
typedef struct _CoglPipelineLayer CoglPipelineLayer;
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
#if defined (HAVE_COGL_GL)
/* NB: pipeline->backend is currently a 3bit unsigned int bitfield */
#define COGL_PIPELINE_BACKEND_GLSL 0
#define COGL_PIPELINE_BACKEND_GLSL_MASK (1L<<0)
#define COGL_PIPELINE_BACKEND_ARBFP 1
#define COGL_PIPELINE_BACKEND_ARBFP_MASK (1L<<1)
#define COGL_PIPELINE_BACKEND_FIXED 2
#define COGL_PIPELINE_BACKEND_FIXED_MASK (1L<<2)
#define COGL_PIPELINE_N_BACKENDS 3
#elif defined (HAVE_COGL_GLES2)
#define COGL_PIPELINE_BACKEND_GLSL 0
#define COGL_PIPELINE_BACKEND_GLSL_MASK (1L<<0)
#define COGL_PIPELINE_BACKEND_FIXED 1
#define COGL_PIPELINE_BACKEND_FIXED_MASK (1L<<1)
#define COGL_PIPELINE_N_BACKENDS 2
#else /* HAVE_COGL_GLES */
#define COGL_PIPELINE_BACKEND_FIXED 0
#define COGL_PIPELINE_BACKEND_FIXED_MASK (1L<<0)
#define COGL_PIPELINE_N_BACKENDS 1
#endif
#define COGL_PIPELINE_BACKEND_DEFAULT 0
#define COGL_PIPELINE_BACKEND_UNDEFINED 3
typedef enum
{
COGL_PIPELINE_LAYER_STATE_UNIT = 1L<<0,
COGL_PIPELINE_LAYER_STATE_TEXTURE = 1L<<1,
COGL_PIPELINE_LAYER_STATE_FILTERS = 1L<<2,
COGL_PIPELINE_LAYER_STATE_WRAP_MODES = 1L<<3,
COGL_PIPELINE_LAYER_STATE_COMBINE = 1L<<4,
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
COGL_PIPELINE_LAYER_STATE_USER_MATRIX = 1L<<6,
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS = 1L<<7,
/* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
COGL_PIPELINE_LAYER_STATE_ALL_SPARSE =
COGL_PIPELINE_LAYER_STATE_UNIT |
COGL_PIPELINE_LAYER_STATE_TEXTURE |
COGL_PIPELINE_LAYER_STATE_FILTERS |
COGL_PIPELINE_LAYER_STATE_WRAP_MODES |
COGL_PIPELINE_LAYER_STATE_COMBINE |
COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT |
COGL_PIPELINE_LAYER_STATE_USER_MATRIX |
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS,
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,
} CoglPipelineLayerState;
typedef struct
{
/* The texture combine state determines how the color of individual
* texture fragments are calculated. */
GLint texture_combine_rgb_func;
GLint texture_combine_rgb_src[3];
GLint texture_combine_rgb_op[3];
GLint texture_combine_alpha_func;
GLint texture_combine_alpha_src[3];
GLint 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;
/* 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... */
typedef struct _CoglPipelineNode CoglPipelineNode;
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;
/* 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;
/* As an optimization for creating leaf node pipelines/layers (the
* most common) we don't require any list node allocations to link
* to a single descendant. */
CoglPipelineNode *first_child;
/* Determines if node->first_child and node->children are
* initialized pointers. */
gboolean has_children;
/* Materials and layers are sparse structures defined as a diff
* against their parent and may have multiple children which depend
* on them to define the values of properties which they don't
* change. */
GList *children;
};
#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);
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;
/* Different pipeline backends (GLSL/ARBfp/Fixed Function) may
* want to associate private data with a layer...
*
* NB: we have per backend pointers because a layer may be
* associated with multiple pipelines with different backends.
*/
void *backend_priv[COGL_PIPELINE_N_BACKENDS];
/* 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 COGL_INVALID_HANDLE for an empty
* layer */
CoglHandle texture;
gboolean texture_overridden;
/* If ->texture_overridden == TRUE then the texture is instead
* defined by these... */
GLuint slice_gl_texture;
GLenum slice_gl_target;
CoglPipelineFilter mag_filter;
CoglPipelineFilter min_filter;
CoglPipelineWrapMode wrap_mode_s;
CoglPipelineWrapMode wrap_mode_t;
CoglPipelineWrapMode 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;
};
/* Used in pipeline->differences masks and for notifying pipeline
* state changes... */
typedef enum _CoglPipelineState
{
COGL_PIPELINE_STATE_COLOR = 1L<<0,
COGL_PIPELINE_STATE_BLEND_ENABLE = 1L<<1,
COGL_PIPELINE_STATE_LAYERS = 1L<<2,
COGL_PIPELINE_STATE_LIGHTING = 1L<<3,
COGL_PIPELINE_STATE_ALPHA_FUNC = 1L<<4,
COGL_PIPELINE_STATE_BLEND = 1L<<5,
COGL_PIPELINE_STATE_USER_SHADER = 1L<<6,
COGL_PIPELINE_STATE_DEPTH = 1L<<7,
COGL_PIPELINE_STATE_FOG = 1L<<8,
COGL_PIPELINE_STATE_POINT_SIZE = 1L<<9,
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE = 1L<<10,
COGL_PIPELINE_STATE_ALL_SPARSE =
COGL_PIPELINE_STATE_COLOR |
COGL_PIPELINE_STATE_BLEND_ENABLE |
COGL_PIPELINE_STATE_LAYERS |
COGL_PIPELINE_STATE_LIGHTING |
COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_BLEND |
COGL_PIPELINE_STATE_USER_SHADER |
COGL_PIPELINE_STATE_DEPTH |
COGL_PIPELINE_STATE_FOG |
COGL_PIPELINE_STATE_POINT_SIZE,
COGL_PIPELINE_STATE_AFFECTS_BLENDING =
COGL_PIPELINE_STATE_COLOR |
COGL_PIPELINE_STATE_BLEND_ENABLE |
COGL_PIPELINE_STATE_LAYERS |
COGL_PIPELINE_STATE_LIGHTING |
COGL_PIPELINE_STATE_BLEND |
COGL_PIPELINE_STATE_USER_SHADER,
COGL_PIPELINE_STATE_NEEDS_BIG_STATE =
COGL_PIPELINE_STATE_LIGHTING |
COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_BLEND |
COGL_PIPELINE_STATE_USER_SHADER |
COGL_PIPELINE_STATE_DEPTH |
COGL_PIPELINE_STATE_FOG |
COGL_PIPELINE_STATE_POINT_SIZE
} CoglPipelineState;
typedef enum
{
COGL_PIPELINE_LIGHTING_STATE_PROPERTY_AMBIENT = 1,
COGL_PIPELINE_LIGHTING_STATE_PROPERTY_DIFFUSE,
COGL_PIPELINE_LIGHTING_STATE_PROPERTY_SPECULAR,
COGL_PIPELINE_LIGHTING_STATE_PROPERTY_EMISSION,
COGL_PIPELINE_LIGHTING_STATE_PROPERTY_SHININESS
} CoglPipelineLightingStateProperty;
typedef struct
{
/* Standard OpenGL lighting model attributes */
float ambient[4];
float diffuse[4];
float specular[4];
float emission[4];
float shininess;
} CoglPipelineLightingState;
typedef struct
{
/* Determines what fragments are discarded based on their alpha */
CoglPipelineAlphaFunc alpha_func;
GLfloat alpha_func_reference;
} CoglPipelineAlphaFuncState;
typedef enum _CoglPipelineBlendEnable
{
/* XXX: we want to detect users mistakenly using TRUE or FALSE
* so start the enum at 2. */
COGL_PIPELINE_BLEND_ENABLE_ENABLED = 2,
COGL_PIPELINE_BLEND_ENABLE_DISABLED,
COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC
} CoglPipelineBlendEnable;
typedef struct
{
/* Determines how this pipeline is blended with other primitives */
#ifndef HAVE_COGL_GLES
GLenum blend_equation_rgb;
GLenum blend_equation_alpha;
GLint blend_src_factor_alpha;
GLint blend_dst_factor_alpha;
CoglColor blend_constant;
#endif
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
} CoglPipelineBlendState;
typedef struct
{
gboolean depth_test_enabled;
CoglDepthTestFunction depth_test_function;
gboolean depth_writing_enabled;
float depth_range_near;
float depth_range_far;
} CoglPipelineDepthState;
typedef struct
{
gboolean enabled;
CoglColor color;
CoglFogMode mode;
float density;
float z_near;
float z_far;
} CoglPipelineFogState;
typedef struct
{
CoglPipelineLightingState lighting_state;
CoglPipelineAlphaFuncState alpha_state;
CoglPipelineBlendState blend_state;
CoglHandle user_program;
CoglPipelineDepthState depth_state;
CoglPipelineFogState fog_state;
float point_size;
} CoglPipelineBigState;
typedef enum
{
COGL_PIPELINE_FLAG_DIRTY_LAYERS_CACHE = 1L<<0,
COGL_PIPELINE_FLAG_DIRTY_GET_LAYERS_LIST = 1L<<1
} CoglPipelineFlag;
typedef struct
{
CoglPipeline *owner;
CoglPipelineLayer *layer;
} CoglPipelineLayerCacheEntry;
/*
* CoglPipelineDestroyCallback
* @pipeline: The #CoglPipeline that has been destroyed
* @user_data: The private data associated with the callback
*
* Notifies when a weak pipeline has been destroyed because one
* of its ancestors has been freed or modified.
*/
typedef void (*CoglPipelineDestroyCallback)(CoglPipeline *pipeline,
void *user_data);
struct _CoglPipeline
{
/* XXX: Please think twice about adding members that *have* be
* initialized during a cogl_pipeline_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*
* pipelines 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;
/* We need to track if a pipeline is referenced in the journal
* because we can't allow modification to these pipelines without
* flushing the journal first */
unsigned long journal_ref_count;
/* When weak pipelines are destroyed the user is notified via this
* callback */
CoglPipelineDestroyCallback destroy_callback;
/* When notifying that a weak pipeline has been destroyed this
* private data is passed to the above callback */
void *destroy_data;
/* A mask of which sparse state groups are different in this
* pipeline in comparison to its parent. */
unsigned long differences;
/* The fragment processing backends can associate private data with a
* pipeline. */
void *backend_privs[COGL_PIPELINE_N_BACKENDS];
/* Whenever a pipeline is modified we increment the age. There's no
* guarantee that it won't wrap but it can nevertheless be a
* convenient mechanism to determine when a pipeline has been
* changed to you can invalidate some some associated cache that
* depends on the old state. */
unsigned long age;
/* This is the primary color of the pipeline.
*
* This is a sparse property, ref COGL_PIPELINE_STATE_COLOR */
CoglColor color;
/* A pipeline may be made up with multiple layers used to combine
* textures together.
*
* This is sparse state, ref COGL_PIPELINE_STATE_LAYERS */
GList *layer_differences;
unsigned int n_layers;
/* As a basic way to reduce memory usage we divide the pipeline
* state into two groups; the minimal state modified in 90% of
* all pipelines and the rest, so that the second group can
* be allocated dynamically when required... */
CoglPipelineBigState *big_state;
/* For debugging purposes it's possible to associate a static const
* string with a pipeline which can be an aid when trying to trace
* where the pipeline originates from */
const char *static_breadcrumb;
/* Cached state... */
/* A cached, complete list of the layers this pipeline depends
* on sorted by layer->unit_index. */
CoglPipelineLayer **layers_cache;
/* To avoid a separate ->layers_cache allocation for common
* pipelines with only a few layers... */
CoglPipelineLayer *short_layers_cache[3];
/* The deprecated cogl_pipeline_get_layers() API returns a
* const GList of layers, which we track here... */
GList *deprecated_get_layers_list;
/* XXX: consider adding an authorities cache to speed up sparse
* property value lookups:
* CoglPipeline *authorities_cache[COGL_PIPELINE_N_SPARSE_PROPERTIES];
* and corresponding authorities_cache_dirty:1 bitfield
*/
/* bitfields */
/* A pipeline can have private data associated with it for multiple
* fragment processing backends. Although only one backend is
* associated with a pipeline the backends may want to cache private
* state with the ancestors of other pipelines and those ancestors
* could currently be associated with different backends.
*
* Each set bit indicates if the correspondong ->backend_privs[]
* entry is valid.
*/
unsigned int backend_priv_set_mask:COGL_PIPELINE_N_BACKENDS;
/* Weak pipelines don't count as dependants on their parents which
* means that the parent pipeline can be modified without
* considering how the modifications may affect the weak pipeline.
*/
unsigned int is_weak:1;
/* Determines if pipeline->big_state is valid */
unsigned int has_big_state:1;
/* By default blending is enabled automatically depending on the
* unlit color, the lighting colors or the texture format. The user
* can override this to explicitly enable or disable blending.
*
* This is a sparse property */
unsigned int blend_enable:3;
/* There are many factors that can determine if we need to enable
* blending, this holds our final decision */
unsigned int real_blend_enable:1;
unsigned int layers_cache_dirty:1;
unsigned int deprecated_get_layers_list_dirty:1;
/* For debugging purposes it's possible to associate a static const
* string with a pipeline which can be an aid when trying to trace
* where the pipeline originates from */
unsigned int has_static_breadcrumb:1;
/* There are multiple fragment processing backends for CoglPipeline,
* glsl, arbfp and fixed. This identifies the backend being used for
* the pipeline and any private state the backend has associated
* with the pipeline. */
unsigned int backend:3;
};
typedef struct _CoglPipelineBackend
{
int (*get_max_texture_units) (void);
gboolean (*start) (CoglPipeline *pipeline,
int n_layers,
unsigned long pipelines_difference);
gboolean (*add_layer) (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
unsigned long layers_difference);
gboolean (*passthrough) (CoglPipeline *pipeline);
gboolean (*end) (CoglPipeline *pipeline,
unsigned long pipelines_difference);
void (*pipeline_pre_change_notify) (CoglPipeline *pipeline,
CoglPipelineState change,
const CoglColor *new_color);
void (*pipeline_set_parent_notify) (CoglPipeline *pipeline);
void (*layer_pre_change_notify) (CoglPipeline *owner,
CoglPipelineLayer *layer,
CoglPipelineLayerState change);
void (*free_priv) (CoglPipeline *pipeline);
void (*free_layer_priv) (CoglPipelineLayer *layer);
} CoglPipelineBackend;
typedef enum
{
COGL_PIPELINE_PROGRAM_TYPE_GLSL = 1,
COGL_PIPELINE_PROGRAM_TYPE_ARBFP,
COGL_PIPELINE_PROGRAM_TYPE_FIXED
} CoglPipelineProgramType;
extern const CoglPipelineBackend *
_cogl_pipeline_backends[COGL_PIPELINE_N_BACKENDS];
void
_cogl_pipeline_init_default_pipeline (void);
void
_cogl_pipeline_init_default_layers (void);
/*
* SECTION:cogl-pipeline-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl pipelines for filling.
*
* Normally you shouldn't need to use this API directly, but if you need to
* developing a custom/specialised primitive - probably using raw OpenGL - then
* this API aims to expose enough of the pipeline internals to support being
* able to fill your geometry according to a given Cogl pipeline.
*/
gboolean
_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline);
gboolean
_cogl_pipeline_layer_has_user_matrix (CoglPipelineLayer *layer);
/*
* 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
* one. This will determine whether mipmaps are needed based on the
* filter settings.
*/
void
_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline,
int layer_id);
/*
* CoglPipelineFlushFlag:
* @COGL_PIPELINE_FLUSH_FALLBACK_MASK: The fallback_layers member is set to
* a guint32 mask of the layers that can't be supported with the user
* supplied texture and need to be replaced with fallback textures. (1 =
* fallback, and the least significant bit = layer 0)
* @COGL_PIPELINE_FLUSH_DISABLE_MASK: The disable_layers member is set to
* a guint32 mask of the layers that you want to completly disable
* texturing for (1 = fallback, and the least significant bit = layer 0)
* @COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is
* set to a GLuint OpenGL texture name to override the texture used for
* layer 0 of the pipeline. This is intended for dealing with sliced
* textures where you will need to point to each of the texture slices in
* turn when drawing your geometry. Passing a value of 0 is the same as
* not passing the option at all.
* @COGL_PIPELINE_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the
* pipeline don't call glColor.
* @COGL_PIPELINE_FLUSH_WRAP_MODE_OVERRIDES: Specifies that a bitmask
* of overrides for the wrap modes for some or all layers is
* given.
*/
typedef enum _CoglPipelineFlushFlag
{
COGL_PIPELINE_FLUSH_FALLBACK_MASK = 1L<<0,
COGL_PIPELINE_FLUSH_DISABLE_MASK = 1L<<1,
COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE = 1L<<2,
COGL_PIPELINE_FLUSH_SKIP_GL_COLOR = 1L<<3,
COGL_PIPELINE_FLUSH_WRAP_MODE_OVERRIDES = 1L<<4
} CoglPipelineFlushFlag;
/* 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;
typedef enum _CoglPipelineWrapModeOverride
{
COGL_PIPELINE_WRAP_MODE_OVERRIDE_NONE = 0,
COGL_PIPELINE_WRAP_MODE_OVERRIDE_REPEAT =
COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT,
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE =
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE,
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER =
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER,
} CoglPipelineWrapModeOverride;
/* There can't be more than 32 layers because we need to fit a bitmask
of the layers into a guint32 */
#define COGL_PIPELINE_MAX_LAYERS 32
typedef struct _CoglPipelineWrapModeOverrides
{
struct
{
CoglPipelineWrapModeOverride s;
CoglPipelineWrapModeOverride t;
CoglPipelineWrapModeOverride p;
} values[COGL_PIPELINE_MAX_LAYERS];
} CoglPipelineWrapModeOverrides;
/*
* CoglPipelineFlushOptions:
*
*/
typedef struct _CoglPipelineFlushOptions
{
CoglPipelineFlushFlag flags;
guint32 fallback_layers;
guint32 disable_layers;
GLuint layer0_override_texture;
CoglPipelineWrapModeOverrides wrap_mode_overrides;
} CoglPipelineFlushOptions;
int
_cogl_get_max_texture_image_units (void);
void
_cogl_use_program (GLuint gl_program, CoglPipelineProgramType type);
unsigned int
_cogl_get_n_args_for_combine_func (GLint func);
/*
* _cogl_pipeline_weak_copy:
* @pipeline: A #CoglPipeline object
* @callback: A callback to notify when your weak pipeline is destroyed
* @user_data: Private data to pass to your given callback.
*
* Returns a weak copy of the given source @pipeline. Unlike a normal
* copy no internal reference is taken on the source @pipeline and you
* can expect that later modifications of the source pipeline (or in
* fact any other pipeline) can result in the weak pipeline being
* destroyed.
*
* To understand this better its good to know a bit about the internal
* design of #CoglPipeline...
*
* Internally #CoglPipeline<!-- -->s are represented as a graph of
* property diff's, where each node is a diff of properties that gets
* applied on top of its parent. Copying a pipeline creates an empty
* diff and a child->parent relationship between the empty diff and
* the source @pipeline, parent.
*
* Because of this internal graph design a single #CoglPipeline may
* indirectly depend on a chain of ancestors to fully define all of
* its properties. Because a node depends on its ancestors it normally
* owns a reference to its parent to stop it from being freed. Also if
* you try to modify a pipeline with children we internally use a
* copy-on-write mechanism to ensure that you don't indirectly change
* the properties those children.
*
* Weak pipelines avoid the use of copy-on-write to preserve the
* integrity of weak dependants and instead weak dependants are
* simply destroyed allowing the parent to be modified directly. Also
* because weak pipelines don't own a reference to their parent they
* won't stop the source @pipeline from being freed when the user
* releases their reference on it.
*
* Because weak pipelines don't own a reference on their parent they
* are the recommended mechanism for creating derived pipelines that you
* want to cache as a private property of the original pipeline
* because they won't result in a circular dependency.
*
* An example use case:
*
* Consider for example you are implementing a custom primitive that is
* not compatible with certain source pipelines. To handle this you
* implement a validation stage that given an arbitrary pipeline as
* input will create a derived pipeline that is suitable for drawing
* your primitive.
*
* Because you don't want to have to repeat this validation every time
* the same incompatible pipeline is given as input you want to cache
* the result as a private property of the original pipeline. If the
* derived pipeline were created using cogl_pipeline_copy that would
* create a circular dependency so the original pipeline can never be
* freed.
*
* If you instead create a weak copy you won't stop the original pipeline
* from being freed if it's no longer needed, and you will instead simply
* be notified that your weak pipeline has been destroyed.
*
* This is the recommended coding pattern for validating an input
* pipeline and caching a derived result:
* |[
* static CoglUserDataKey _cogl_my_cache_key;
*
* typedef struct {
* CoglPipeline *validated_source;
* } MyValidatedMaterialCache;
*
* static void
* destroy_cache_cb (CoglObject *object, void *user_data)
* {
* g_slice_free (MyValidatedMaterialCache, user_data);
* }
*
* static void
* invalidate_cache_cb (CoglPipeline *destroyed, void *user_data)
* {
* MyValidatedMaterialCache *cache = user_data;
* cogl_object_unref (cache->validated_source);
* cache->validated_source = NULL;
* }
*
* static CoglPipeline *
* get_validated_pipeline (CoglPipeline *source)
* {
* MyValidatedMaterialCache *cache =
* cogl_object_get_user_data (COGL_OBJECT (source),
* &_cogl_my_cache_key);
* if (G_UNLIKELY (cache == NULL))
* {
* cache = g_slice_new (MyValidatedMaterialCache);
* cogl_object_set_user_data (COGL_OBJECT (source),
* &_cogl_my_cache_key,
* cache, destroy_cache_cb);
* cache->validated_source = source;
* }
*
* if (G_UNLIKELY (cache->validated_source == NULL))
* {
* cache->validated_source = source;
*
* /&nbsp;* Start validating source... *&nbsp;/
*
* /&nbsp;* If you find you need to change something... *&nbsp;/
* if (cache->validated_source == source)
* cache->validated_source =
* cogl_pipeline_weak_copy (source,
* invalidate_cache_cb,
* cache);
*
* /&nbsp;* Modify cache->validated_source *&nbsp;/
* }
*
* return cache->validated_source;
* }
* ]|
*/
CoglPipeline *
_cogl_pipeline_weak_copy (CoglPipeline *pipeline,
CoglPipelineDestroyCallback callback,
void *user_data);
void
_cogl_pipeline_set_backend (CoglPipeline *pipeline, int backend);
CoglPipeline *
_cogl_pipeline_get_parent (CoglPipeline *pipeline);
void
_cogl_pipeline_get_colorubv (CoglPipeline *pipeline,
guint8 *color);
unsigned long
_cogl_pipeline_compare_differences (CoglPipeline *pipeline0,
CoglPipeline *pipeline1);
gboolean
_cogl_pipeline_equal (CoglPipeline *pipeline0,
CoglPipeline *pipeline1,
gboolean skip_gl_color);
CoglPipeline *
_cogl_pipeline_journal_ref (CoglPipeline *pipeline);
void
_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);
void
_cogl_pipeline_texture_storage_change_notify (CoglHandle texture);
void
_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline);
void
_cogl_pipeline_apply_overrides (CoglPipeline *pipeline,
CoglPipelineFlushOptions *options);
CoglPipelineBlendEnable
_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline);
void
_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline,
CoglPipelineBlendEnable enable);
void
_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline,
const char *breadcrumb);
unsigned long
_cogl_pipeline_get_age (CoglPipeline *pipeline);
CoglPipeline *
_cogl_pipeline_get_authority (CoglPipeline *pipeline,
unsigned long difference);
CoglHandle
_cogl_pipeline_get_layer_texture (CoglPipeline *pipeline,
int layer_index);
void
_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline,
int layer_index,
float *constant);
void
_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n);
/*
* API to support the deprecate cogl_pipeline_layer_xyz functions...
*/
G_CONST_RETURN GList *
_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);
CoglHandle
_cogl_pipeline_layer_get_texture (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);
CoglHandle
_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer,
void *user_data);
void
_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
CoglPipelineInternalLayerCallback callback,
void *user_data);
int
_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer);
#endif /* __COGL_PIPELINE_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,8 @@
#include "cogl-context.h"
#include "cogl-journal-private.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-vertex-attribute-private.h"
@ -49,7 +49,7 @@
typedef struct _TextureSlicedQuadState
{
CoglHandle material;
CoglPipeline *pipeline;
float tex_virtual_origin_x;
float tex_virtual_origin_y;
float quad_origin_x;
@ -60,7 +60,7 @@ typedef struct _TextureSlicedQuadState
float quad_len_y;
gboolean flipped_x;
gboolean flipped_y;
CoglMaterialWrapModeOverrides *wrap_mode_overrides;
CoglPipelineWrapModeOverrides *wrap_mode_overrides;
} TextureSlicedQuadState;
typedef struct _TextureSlicedPolygonState
@ -114,10 +114,10 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
subtexture_coords[0], subtexture_coords[1],
subtexture_coords[2], subtexture_coords[3]);
/* FIXME: when the wrap mode becomes part of the material we need to
/* FIXME: when the wrap mode becomes part of the pipeline we need to
* be able to override the wrap mode when logging a quad. */
_cogl_journal_log_quad (quad_coords,
state->material,
state->pipeline,
1, /* one layer */
0, /* don't need to use fallbacks */
gl_handle, /* replace the layer0 texture */
@ -141,18 +141,18 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
*/
/* TODO: support multitexturing */
static void
_cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
CoglHandle material,
gboolean clamp_s,
gboolean clamp_t,
const float *position,
float tx_1,
float ty_1,
float tx_2,
float ty_2)
_cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
CoglPipeline *pipeline,
gboolean clamp_s,
gboolean clamp_t,
const float *position,
float tx_1,
float ty_1,
float tx_2,
float ty_2)
{
TextureSlicedQuadState state;
CoglMaterialWrapModeOverrides wrap_mode_overrides;
CoglPipelineWrapModeOverrides wrap_mode_overrides;
gboolean tex_virtual_flipped_x;
gboolean tex_virtual_flipped_y;
gboolean quad_flipped_x;
@ -182,7 +182,7 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
(position[2] - position[0]) *
(tx_1 - old_tx_1) / (old_tx_2 - old_tx_1)),
position[3] };
_cogl_texture_quad_multiple_primitives (tex_handle, material,
_cogl_texture_quad_multiple_primitives (tex_handle, pipeline,
FALSE, clamp_t,
tmp_position,
tx_1, ty_1, tx_1, ty_2);
@ -197,7 +197,7 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
(position[2] - position[0]) *
(tx_2 - old_tx_1) / (old_tx_2 - old_tx_1)),
position[1], position[2], position[3] };
_cogl_texture_quad_multiple_primitives (tex_handle, material,
_cogl_texture_quad_multiple_primitives (tex_handle, pipeline,
FALSE, clamp_t,
tmp_position,
tx_2, ty_1, tx_2, ty_2);
@ -229,7 +229,7 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
(position[1] +
(position[3] - position[1]) *
(ty_1 - old_ty_1) / (old_ty_2 - old_ty_1)) };
_cogl_texture_quad_multiple_primitives (tex_handle, material,
_cogl_texture_quad_multiple_primitives (tex_handle, pipeline,
clamp_s, FALSE,
tmp_position,
tx_1, ty_1, tx_2, ty_1);
@ -245,7 +245,7 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
(position[3] - position[1]) *
(ty_2 - old_ty_1) / (old_ty_2 - old_ty_1)),
position[2], position[3] };
_cogl_texture_quad_multiple_primitives (tex_handle, material,
_cogl_texture_quad_multiple_primitives (tex_handle, pipeline,
clamp_s, FALSE,
tmp_position,
tx_1, ty_2, tx_2, ty_2);
@ -266,23 +266,23 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
otherwise it might pull in edge pixels from the other side. By
default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need
to override if the wrap mode is repeat */
first_layer = cogl_material_get_layers (material)->data;
if (cogl_material_layer_get_wrap_mode_s (first_layer) ==
COGL_MATERIAL_WRAP_MODE_REPEAT)
first_layer = _cogl_pipeline_get_layers (pipeline)->data;
if (_cogl_pipeline_layer_get_wrap_mode_s (first_layer) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
state.wrap_mode_overrides = &wrap_mode_overrides;
wrap_mode_overrides.values[0].s =
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
}
if (cogl_material_layer_get_wrap_mode_t (first_layer) ==
COGL_MATERIAL_WRAP_MODE_REPEAT)
if (_cogl_pipeline_layer_get_wrap_mode_t (first_layer) ==
COGL_PIPELINE_WRAP_MODE_REPEAT)
{
state.wrap_mode_overrides = &wrap_mode_overrides;
wrap_mode_overrides.values[0].t =
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
COGL_PIPELINE_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE;
}
state.material = material;
state.pipeline = pipeline;
/* Get together the data we need to transform the virtual texture
* coordinates of each slice into quad coordinates...
@ -348,21 +348,21 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
* require repeating.
*/
static gboolean
_cogl_multitexture_quad_single_primitive (const float *position,
CoglHandle material,
guint32 fallback_layers,
const float *user_tex_coords,
int user_tex_coords_len)
_cogl_multitexture_quad_single_primitive (const float *position,
CoglPipeline *pipeline,
guint32 fallback_layers,
const float *user_tex_coords,
int user_tex_coords_len)
{
int n_layers = cogl_material_get_n_layers (material);
int n_layers = cogl_pipeline_get_n_layers (pipeline);
float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers);
const GList *layers;
GList *tmp;
int i;
CoglMaterialWrapModeOverrides wrap_mode_overrides;
CoglPipelineWrapModeOverrides wrap_mode_overrides;
/* This will be set to point to wrap_mode_overrides when an override
is needed */
CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL;
CoglPipelineWrapModeOverrides *wrap_mode_overrides_p = NULL;
_COGL_GET_CONTEXT (ctx, FALSE);
@ -371,7 +371,7 @@ _cogl_multitexture_quad_single_primitive (const float *position,
/*
* Validate the texture coordinates for this rectangle.
*/
layers = cogl_material_get_layers (material);
layers = _cogl_pipeline_get_layers (pipeline);
for (tmp = (GList *)layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
{
CoglHandle layer = (CoglHandle)tmp->data;
@ -381,10 +381,10 @@ _cogl_multitexture_quad_single_primitive (const float *position,
float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
CoglTransformResult transform_result;
tex_handle = cogl_material_layer_get_texture (layer);
tex_handle = _cogl_pipeline_layer_get_texture (layer);
/* COGL_INVALID_HANDLE textures are handled by
* _cogl_material_flush_gl_state */
* _cogl_pipeline_flush_gl_state */
if (tex_handle == COGL_INVALID_HANDLE)
continue;
@ -456,25 +456,25 @@ _cogl_multitexture_quad_single_primitive (const float *position,
the full texture is drawn with GL_LINEAR filter mode */
if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
{
if (cogl_material_layer_get_wrap_mode_s (layer) ==
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
if (_cogl_pipeline_layer_get_wrap_mode_s (layer) ==
COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
wrap_mode_overrides.values[i].s
= COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
= COGL_PIPELINE_WRAP_MODE_OVERRIDE_REPEAT;
wrap_mode_overrides_p = &wrap_mode_overrides;
}
if (cogl_material_layer_get_wrap_mode_t (layer) ==
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
if (_cogl_pipeline_layer_get_wrap_mode_t (layer) ==
COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
wrap_mode_overrides.values[i].t
= COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT;
= COGL_PIPELINE_WRAP_MODE_OVERRIDE_REPEAT;
wrap_mode_overrides_p = &wrap_mode_overrides;
}
}
}
_cogl_journal_log_quad (position,
material,
pipeline,
n_layers,
fallback_layers,
0, /* don't replace the layer0 texture */
@ -497,7 +497,7 @@ _cogl_rectangles_with_multitexture_coords (
struct _CoglMutiTexturedRect *rects,
int n_rects)
{
CoglMaterial *material;
CoglPipeline *pipeline;
const GList *layers;
int n_layers;
const GList *tmp;
@ -507,13 +507,13 @@ _cogl_rectangles_with_multitexture_coords (
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
material = cogl_get_source ();
pipeline = cogl_get_source ();
layers = cogl_material_get_layers (material);
n_layers = cogl_material_get_n_layers (material);
layers = _cogl_pipeline_get_layers (pipeline);
n_layers = cogl_pipeline_get_n_layers (pipeline);
/*
* Validate all the layers of the current source material...
* Validate all the layers of the current source pipeline...
*/
for (tmp = layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
@ -521,10 +521,6 @@ _cogl_rectangles_with_multitexture_coords (
CoglHandle layer = tmp->data;
CoglHandle tex_handle;
if (cogl_material_layer_get_type (layer)
!= COGL_MATERIAL_LAYER_TYPE_TEXTURE)
continue;
/* We need to ensure the mipmaps are ready before deciding
* anything else about the texture because the texture storage
* could completely change if it needs to be migrated out of the
@ -535,42 +531,42 @@ _cogl_rectangles_with_multitexture_coords (
* underlying texture storage. We could add two mechanisms to
* generalize this a bit...
*
* 1) add a _cogl_material_layer_update_storage() function that
* 1) add a _cogl_pipeline_layer_update_storage() function that
* would for instance consider if mipmapping is necessary and
* potentially migrate the texture from an atlas.
*
* 2) allow setting of transient primitive-flags on a material
* 2) allow setting of transient primitive-flags on a pipeline
* that may affect the outcome of _update_storage(). One flag
* could indicate that we expect to sample beyond the bounds of
* the texture border.
*
* flags = COGL_MATERIAL_PRIMITIVE_FLAG_VALID_BORDERS;
* _cogl_material_layer_assert_primitive_flags (layer, flags)
* _cogl_material_layer_update_storage (layer)
* flags = COGL_PIPELINE_PRIMITIVE_FLAG_VALID_BORDERS;
* _cogl_pipeline_layer_assert_primitive_flags (layer, flags)
* _cogl_pipeline_layer_update_storage (layer)
* enqueue primitive in journal
*
* when the primitive is dequeued and drawn we should:
* _cogl_material_flush_gl_state (material)
* _cogl_pipeline_flush_gl_state (pipeline)
* draw primitive
* _cogl_material_unassert_primitive_flags (layer, flags);
* _cogl_pipeline_unassert_primitive_flags (layer, flags);
*
* _cogl_material_layer_update_storage should take into
* _cogl_pipeline_layer_update_storage should take into
* consideration all the asserted primitive requirements. (E.g.
* there could be multiple primitives in the journal - or in a
* renderlist in the future - that need mipmaps or that need
* valid contents beyond their borders (for cogl_polygon)
* meaning they can't work with textures in an atas, so
* _cogl_material_layer_update_storage would pass on these
* _cogl_pipeline_layer_update_storage would pass on these
* requirements to the texture atlas backend which would make
* sure the referenced texture is migrated out of the atlas and
* mipmaps are generated.)
*/
_cogl_material_layer_pre_paint (layer);
_cogl_pipeline_layer_pre_paint (layer);
tex_handle = cogl_material_layer_get_texture (layer);
tex_handle = _cogl_pipeline_layer_get_texture (layer);
/* COGL_INVALID_HANDLE textures are handled by
* _cogl_material_flush_gl_state */
* _cogl_pipeline_flush_gl_state */
if (tex_handle == COGL_INVALID_HANDLE)
continue;
@ -593,7 +589,7 @@ _cogl_rectangles_with_multitexture_coords (
{
static gboolean warning_seen = FALSE;
if (!warning_seen)
g_warning ("Skipping layers 1..n of your material since "
g_warning ("Skipping layers 1..n of your pipeline since "
"the first layer is sliced. We don't currently "
"support any multi-texturing with sliced "
"textures but assume layer 0 is the most "
@ -606,7 +602,7 @@ _cogl_rectangles_with_multitexture_coords (
{
static gboolean warning_seen = FALSE;
if (!warning_seen)
g_warning ("Skipping layer %d of your material consisting of "
g_warning ("Skipping layer %d of your pipeline consisting of "
"a sliced texture (unsuported for multi texturing)",
i);
warning_seen = TRUE;
@ -622,12 +618,12 @@ _cogl_rectangles_with_multitexture_coords (
* waste or if using GL_TEXTURE_RECTANGLE_ARB) then we don't support
* multi texturing since we don't know if the result will end up trying
* to texture from the waste area. */
if (_cogl_material_layer_has_user_matrix (layer)
if (_cogl_pipeline_layer_has_user_matrix (layer)
&& !_cogl_texture_can_hardware_repeat (tex_handle))
{
static gboolean warning_seen = FALSE;
if (!warning_seen)
g_warning ("Skipping layer %d of your material since a custom "
g_warning ("Skipping layer %d of your pipeline since a custom "
"texture matrix was given for a texture that can't be "
"repeated using the GPU and the result may try to "
"sample beyond the bounds of the texture ",
@ -656,7 +652,7 @@ _cogl_rectangles_with_multitexture_coords (
{
gboolean success =
_cogl_multitexture_quad_single_primitive (rects[i].position,
material,
pipeline,
fallback_layers,
rects[i].tex_coords,
rects[i].tex_coords_len);
@ -671,25 +667,25 @@ _cogl_rectangles_with_multitexture_coords (
/* If multitexturing failed or we are drawing with a sliced texture
* then we only support a single layer so we pluck out the texture
* from the first material layer... */
layers = cogl_material_get_layers (material);
* from the first pipeline layer... */
layers = _cogl_pipeline_get_layers (pipeline);
first_layer = layers->data;
tex_handle = cogl_material_layer_get_texture (first_layer);
tex_handle = _cogl_pipeline_layer_get_texture (first_layer);
if (rects[i].tex_coords)
tex_coords = rects[i].tex_coords;
else
tex_coords = default_tex_coords;
clamp_s = (cogl_material_layer_get_wrap_mode_s (first_layer) ==
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);
clamp_t = (cogl_material_layer_get_wrap_mode_t (first_layer) ==
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);
clamp_s = (_cogl_pipeline_layer_get_wrap_mode_s (first_layer) ==
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
clamp_t = (_cogl_pipeline_layer_get_wrap_mode_t (first_layer) ==
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
COGL_NOTE (DRAW, "Drawing Tex Quad (Multi-Prim Mode)");
_cogl_texture_quad_multiple_primitives (tex_handle,
material,
pipeline,
clamp_s, clamp_t,
rects[i].position,
tex_coords[0],
@ -832,7 +828,7 @@ typedef struct _AppendTexCoordsState
} AppendTexCoordsState;
gboolean
append_tex_coord_attributes_cb (CoglMaterial *material,
append_tex_coord_attributes_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
@ -845,9 +841,9 @@ append_tex_coord_attributes_cb (CoglMaterial *material,
ty = state->vertices_in[state->vertex].ty;
/* COGL_INVALID_HANDLE textures will be handled in
* _cogl_material_flush_layers_gl_state but there is no need to worry
* _cogl_pipeline_flush_layers_gl_state but there is no need to worry
* about scaling texture coordinates in this case */
tex_handle = _cogl_material_get_layer_texture (material, layer_index);
tex_handle = _cogl_pipeline_get_layer_texture (pipeline, layer_index);
if (tex_handle != COGL_INVALID_HANDLE)
_cogl_texture_transform_coords_to_gl (tex_handle, &tx, &ty);
@ -863,40 +859,40 @@ append_tex_coord_attributes_cb (CoglMaterial *material,
typedef struct _ValidateState
{
CoglMaterial *original_material;
CoglMaterial *material;
CoglPipeline *original_pipeline;
CoglPipeline *pipeline;
} ValidateState;
gboolean
validate_layer_cb (CoglMaterial *material,
validate_layer_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
ValidateState *state = user_data;
/* By default COGL_MATERIAL_WRAP_MODE_AUTOMATIC becomes
/* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes
* GL_CLAMP_TO_EDGE but we want the polygon API to use GL_REPEAT to
* maintain compatibility with previous releases
*/
if (cogl_material_get_layer_wrap_mode_s (material, layer_index) ==
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) ==
COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
if (state->original_material == state->material)
state->material = cogl_material_copy (material);
if (state->original_pipeline == state->pipeline)
state->pipeline = cogl_pipeline_copy (pipeline);
cogl_material_set_layer_wrap_mode_s (state->material, layer_index,
COGL_MATERIAL_WRAP_MODE_REPEAT);
cogl_pipeline_set_layer_wrap_mode_s (state->pipeline, layer_index,
COGL_PIPELINE_WRAP_MODE_REPEAT);
}
if (cogl_material_get_layer_wrap_mode_t (material, layer_index) ==
COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) ==
COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
if (state->original_material == state->material)
state->material = cogl_material_copy (material);
if (state->original_pipeline == state->pipeline)
state->pipeline = cogl_pipeline_copy (pipeline);
cogl_material_set_layer_wrap_mode_t (state->material, layer_index,
COGL_MATERIAL_WRAP_MODE_REPEAT);
cogl_pipeline_set_layer_wrap_mode_t (state->pipeline, layer_index,
COGL_PIPELINE_WRAP_MODE_REPEAT);
}
return TRUE;
@ -907,7 +903,7 @@ cogl_polygon (const CoglTextureVertex *vertices,
unsigned int n_vertices,
gboolean use_color)
{
CoglMaterial *material;
CoglPipeline *pipeline;
ValidateState validate_state;
int n_layers;
int n_attributes;
@ -920,16 +916,16 @@ cogl_polygon (const CoglTextureVertex *vertices,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
material = cogl_get_source ();
pipeline = cogl_get_source ();
validate_state.original_material = material;
validate_state.material = material;
cogl_material_foreach_layer (material,
validate_state.original_pipeline = pipeline;
validate_state.pipeline = pipeline;
cogl_pipeline_foreach_layer (pipeline,
validate_layer_cb,
&validate_state);
material = validate_state.material;
pipeline = validate_state.pipeline;
n_layers = cogl_material_get_n_layers (material);
n_layers = cogl_pipeline_get_n_layers (pipeline);
n_attributes = 1 + n_layers + (use_color ? 1 : 0);
attributes = g_alloca (sizeof (CoglVertexAttribute *) * (n_attributes + 1));
@ -1008,7 +1004,7 @@ cogl_polygon (const CoglTextureVertex *vertices,
append_tex_coords_state.vertex = i;
append_tex_coords_state.layer = 0;
append_tex_coords_state.vertices_out = v;
cogl_material_foreach_layer (material,
cogl_pipeline_foreach_layer (pipeline,
append_tex_coord_attributes_cb,
&append_tex_coords_state);
@ -1031,7 +1027,7 @@ cogl_polygon (const CoglTextureVertex *vertices,
(const guint8 *)v,
ctx->polygon_vertices->len * sizeof (float));
cogl_push_source (material);
cogl_push_source (pipeline);
cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_FAN,
0, n_vertices,

View File

@ -25,7 +25,7 @@
#define __COGL_TEXTURE_2D_H
#include "cogl-handle.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-texture-private.h"
#define COGL_TEXTURE_2D(tex) ((CoglTexture2D *) tex)

View File

@ -26,7 +26,7 @@
#include "cogl-bitmap-private.h"
#include "cogl-handle.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-texture-private.h"
#define COGL_TEXTURE_2D_SLICED(tex) ((CoglTexture2DSliced *)tex)

View File

@ -44,7 +44,7 @@
#include "cogl-handle.h"
#include "cogl-spans.h"
#include "cogl-journal-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <string.h>
#include <stdlib.h>

View File

@ -37,7 +37,7 @@
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-journal-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <string.h>
#include <math.h>

View File

@ -26,7 +26,7 @@
#define __COGL_TEXTURE_3D_PRIVATE_H
#include "cogl-handle.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-texture-private.h"
#define COGL_TEXTURE_3D(tex) ((CoglTexture3D *) tex)
@ -73,7 +73,7 @@ _cogl_handle_texture_3d_get_type (void);
* be used. The default blending equations of Cogl expect premultiplied
* color data; the main use of passing a non-premultiplied format here
* is if you have non-premultiplied source data and are going to adjust
* the blend mode (see cogl_material_set_blend()) or use the data for
* the blend mode (see cogl_pipeline_set_blend()) or use the data for
* something other than straight blending.
* @error: A GError return location.
*

View File

@ -35,8 +35,8 @@
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-journal-private.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <string.h>
#include <math.h>

View File

@ -26,7 +26,7 @@
#include "cogl-bitmap-private.h"
#include "cogl-handle.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#define COGL_TEXTURE(tex) ((CoglTexture *)(tex))
@ -145,7 +145,7 @@ typedef enum _CoglTextureChangeFlags
/* Whenever the internals of a texture are changed such that the
* underlying GL textures that represent the CoglTexture change then
* we notify cogl-material.c via
* _cogl_material_texture_pre_change_notify
* _cogl_pipeline_texture_pre_change_notify
*/
COGL_TEXTURE_CHANGE_GL_TEXTURES

View File

@ -25,7 +25,7 @@
#define __COGL_TEXTURE_RECTANGLE_H
#include "cogl-handle.h"
#include "cogl-material-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-texture-private.h"
#define COGL_TEXTURE_RECTANGLE(tex) ((CoglTextureRectangle *) tex)

View File

@ -37,7 +37,7 @@
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-journal-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <string.h>
#include <math.h>

View File

@ -44,7 +44,7 @@
#include "cogl-texture-rectangle-private.h"
#include "cogl-sub-texture-private.h"
#include "cogl-atlas-texture-private.h"
#include "cogl-material.h"
#include "cogl-pipeline.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-primitives.h"
@ -276,7 +276,7 @@ _cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride)
GE( glPixelStorei (GL_PACK_ALIGNMENT, 1) );
}
/* FIXME: wrap modes should be set on materials not textures */
/* FIXME: wrap modes should be set on pipelines not textures */
void
_cogl_texture_set_wrap_mode_parameters (CoglHandle handle,
GLenum wrap_mode_s,
@ -1084,26 +1084,26 @@ _cogl_texture_draw_and_read (CoglHandle handle,
/* Direct copy operation */
if (ctx->texture_download_material == COGL_INVALID_HANDLE)
if (ctx->texture_download_pipeline == COGL_INVALID_HANDLE)
{
ctx->texture_download_material = cogl_material_new ();
cogl_material_set_blend (ctx->texture_download_material,
ctx->texture_download_pipeline = cogl_pipeline_new ();
cogl_pipeline_set_blend (ctx->texture_download_pipeline,
"RGBA = ADD (SRC_COLOR, 0)",
NULL);
}
cogl_push_source (ctx->texture_download_material);
cogl_push_source (ctx->texture_download_pipeline);
cogl_material_set_layer (ctx->texture_download_material, 0, handle);
cogl_pipeline_set_layer_texture (ctx->texture_download_pipeline, 0, handle);
cogl_material_set_layer_combine (ctx->texture_download_material,
cogl_pipeline_set_layer_combine (ctx->texture_download_pipeline,
0, /* layer */
"RGBA = REPLACE (TEXTURE)",
NULL);
cogl_material_set_layer_filters (ctx->texture_download_material, 0,
COGL_MATERIAL_FILTER_NEAREST,
COGL_MATERIAL_FILTER_NEAREST);
cogl_pipeline_set_layer_filters (ctx->texture_download_pipeline, 0,
COGL_PIPELINE_FILTER_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
do_texture_draw_and_read (handle, target_bmp, viewport);
@ -1145,7 +1145,7 @@ _cogl_texture_draw_and_read (CoglHandle handle,
NULL);
/* Draw alpha values into RGB channels */
cogl_material_set_layer_combine (ctx->texture_download_material,
cogl_pipeline_set_layer_combine (ctx->texture_download_pipeline,
0, /* layer */
"RGBA = REPLACE (TEXTURE[A])",
NULL);
@ -1175,7 +1175,7 @@ _cogl_texture_draw_and_read (CoglHandle handle,
_cogl_matrix_stack_pop (modelview_stack);
_cogl_matrix_stack_pop (projection_stack);
/* restore the original material */
/* restore the original pipeline */
cogl_pop_source ();
return TRUE;

View File

@ -243,11 +243,11 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
* %COGL_FEATURE_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_TEXTURE_NPOT_REPEAT
* features to know if the hardware supports npot texture mipmaps
* or repeat modes other than
* %COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE respectively.
* %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively.
* @COGL_FEATURE_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in
* conjuntion with non power of two textures.
* @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than
* %COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE are supported by the
* %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the
* hardware.
* @COGL_FEATURE_POINT_SPRITE: Whether
* cogl_material_set_layer_point_sprite_coords_enabled() is supported.
@ -448,7 +448,7 @@ cogl_blend_string_error_quark (void);
* %COGL_FEATURE_TEXTURE_NPOT is not advertised.</para></listitem>
* <listitem><para>The GPU can not handle the configuration you have
* requested. An example might be if you try to use too many texture
* layers in a single #CoglMaterial</para></listitem>
* layers in a single #CoglPipeline</para></listitem>
* <listitem><para>The driver does not support some
* configuration.</para></listiem>
* </itemizedlist>
@ -513,6 +513,52 @@ typedef enum {
/* NB: The above definitions are taken from gl.h equivalents */
/* XXX: should this be CoglMaterialDepthTestFunction?
* It makes it very verbose but would be consistent with
* CoglMaterialWrapMode */
/**
* CoglDepthTestFunction:
* @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes.
* @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth
* value is less than the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth
* value is equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth
* value is less or equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth
* value is greater than the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth
* value is not equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth
* value greater than or equal to the value currently in the depth buffer.
* @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes.
*
* When using depth testing one of these functions is used to compare
* the depth of an incoming fragment against the depth value currently
* stored in the depth buffer. The function is changed using
* cogl_material_set_depth_test_function().
*
* The test is only done when depth testing is explicitly enabled. (See
* cogl_material_set_depth_test_enabled())
*/
typedef enum
{
COGL_DEPTH_TEST_FUNCTION_NEVER = 0x0200,
COGL_DEPTH_TEST_FUNCTION_LESS = 0x0201,
COGL_DEPTH_TEST_FUNCTION_EQUAL = 0x0202,
COGL_DEPTH_TEST_FUNCTION_LEQUAL = 0x0203,
COGL_DEPTH_TEST_FUNCTION_GREATER = 0x0204,
COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = 0x0205,
COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206,
COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207
} CoglDepthTestFunction;
/* XXX: Note these types are only referenced by experimental API so
* although they aren't explicitly guarded they are implicitly
* experimental too. */
/* NB: The above definitions are taken from gl.h equivalents */
G_END_DECLS
#endif /* __COGL_TYPES_H__ */

View File

@ -32,7 +32,7 @@
#include "cogl-fixed.h"
#include "cogl-internal.h"
#include "cogl-material.h"
#include "cogl-pipeline.h"
#include "cogl-offscreen.h"
#include "cogl-shader.h"
#include "cogl-texture.h"

View File

@ -34,9 +34,9 @@
#include "cogl-journal-private.h"
#include "cogl-vertex-attribute.h"
#include "cogl-vertex-attribute-private.h"
#include "cogl-material.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-texture-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-indices-private.h"
@ -365,22 +365,22 @@ _cogl_vertex_attribute_free (CoglVertexAttribute *attribute)
typedef struct
{
int unit;
CoglMaterialFlushOptions options;
CoglPipelineFlushOptions options;
guint32 fallback_layers;
} ValidateLayerState;
static gboolean
validate_layer_cb (CoglMaterial *material,
validate_layer_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
CoglHandle texture =
_cogl_material_get_layer_texture (material, layer_index);
_cogl_pipeline_get_layer_texture (pipeline, layer_index);
ValidateLayerState *state = user_data;
gboolean status = TRUE;
/* invalid textures will be handled correctly in
* _cogl_material_flush_layers_gl_state */
* _cogl_pipeline_flush_layers_gl_state */
if (texture == COGL_INVALID_HANDLE)
goto validated;
@ -394,7 +394,7 @@ validate_layer_cb (CoglMaterial *material,
* could completely change if it needs to be migrated out of the
* atlas and will affect how we validate the layer.
*/
_cogl_material_pre_paint_for_layer (material, layer_index);
_cogl_pipeline_pre_paint_for_layer (pipeline, layer_index);
if (!_cogl_texture_can_hardware_repeat (texture))
{
@ -415,7 +415,7 @@ validate_layer_cb (CoglMaterial *material,
* matrix.
*/
state->fallback_layers |= (1 << state->unit);
state->options.flags |= COGL_MATERIAL_FLUSH_FALLBACK_MASK;
state->options.flags |= COGL_PIPELINE_FLUSH_FALLBACK_MASK;
}
validated:
@ -433,13 +433,13 @@ enable_gl_state (CoglVertexAttribute **attributes,
#endif
unsigned long enable_flags = 0;
gboolean skip_gl_color = FALSE;
CoglMaterial *source;
CoglMaterial *copy = NULL;
CoglPipeline *source;
CoglPipeline *copy = NULL;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the material state) when flushing the clip stack, so should
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
@ -471,12 +471,12 @@ enable_gl_state (CoglVertexAttribute **attributes,
attribute->stride,
base + attribute->offset));
if (!_cogl_material_get_real_blend_enabled (source))
if (!_cogl_pipeline_get_real_blend_enabled (source))
{
CoglMaterialBlendEnable blend_enable =
COGL_MATERIAL_BLEND_ENABLE_ENABLED;
copy = cogl_material_copy (source);
_cogl_material_set_blend_enabled (copy, blend_enable);
CoglPipelineBlendEnable blend_enable =
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
copy = cogl_pipeline_copy (source);
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
source = copy;
}
skip_gl_color = TRUE;
@ -533,27 +533,27 @@ enable_gl_state (CoglVertexAttribute **attributes,
if (G_UNLIKELY (state->options.flags))
{
/* If we haven't already created a derived material... */
/* If we haven't already created a derived pipeline... */
if (!copy)
{
copy = cogl_material_copy (source);
copy = cogl_pipeline_copy (source);
source = copy;
}
_cogl_material_apply_overrides (source, &state->options);
_cogl_pipeline_apply_overrides (source, &state->options);
/* TODO:
* overrides = cogl_material_get_data (material,
* overrides = cogl_pipeline_get_data (pipeline,
* last_overrides_key);
* if (overrides)
* {
* age = cogl_material_get_age (material);
* age = cogl_pipeline_get_age (pipeline);
* XXX: actually we also need to check for legacy_state
* and blending overrides for use of glColorPointer...
* if (overrides->ags != age ||
* memcmp (&overrides->options, &options,
* sizeof (options) != 0)
* {
* cogl_object_unref (overrides->weak_material);
* cogl_object_unref (overrides->weak_pipeline);
* g_slice_free (Overrides, overrides);
* overrides = NULL;
* }
@ -561,32 +561,32 @@ enable_gl_state (CoglVertexAttribute **attributes,
* if (!overrides)
* {
* overrides = g_slice_new (Overrides);
* overrides->weak_material =
* cogl_material_weak_copy (cogl_get_source ());
* _cogl_material_apply_overrides (overrides->weak_material,
* overrides->weak_pipeline =
* cogl_pipeline_weak_copy (cogl_get_source ());
* _cogl_pipeline_apply_overrides (overrides->weak_pipeline,
* &options);
*
* cogl_material_set_data (material, last_overrides_key,
* cogl_pipeline_set_data (pipeline, last_overrides_key,
* weak_overrides,
* free_overrides_cb,
* NULL);
* }
* source = overrides->weak_material;
* source = overrides->weak_pipeline;
*/
}
if (G_UNLIKELY (ctx->legacy_state_set))
{
/* If we haven't already created a derived material... */
/* If we haven't already created a derived pipeline... */
if (!copy)
{
copy = cogl_material_copy (source);
copy = cogl_pipeline_copy (source);
source = copy;
}
_cogl_material_apply_legacy_state (source);
_cogl_pipeline_apply_legacy_state (source);
}
_cogl_material_flush_gl_state (source, skip_gl_color);
_cogl_pipeline_flush_gl_state (source, skip_gl_color);
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -601,7 +601,7 @@ enable_gl_state (CoglVertexAttribute **attributes,
* just disable the things not needed after enabling state. */
static void
disable_gl_state (CoglVertexAttribute **attributes,
CoglMaterial *source)
CoglPipeline *source)
{
#ifdef MAY_HAVE_PROGRAMABLE_GL
GLuint generic_index = 0;
@ -655,7 +655,7 @@ _cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode,
CoglVertexAttribute **attributes,
ValidateLayerState *state)
{
CoglMaterial *source = enable_gl_state (attributes, state);
CoglPipeline *source = enable_gl_state (attributes, state);
GE (glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
@ -665,7 +665,7 @@ _cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode,
}
/* This can be used by the CoglJournal to draw attributes skiping
* the implicit journal flush and material validation. */
* the implicit journal flush and pipeline validation. */
void
_cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex,
@ -698,7 +698,7 @@ cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
state.options.flags = 0;
state.fallback_layers = 0;
cogl_material_foreach_layer (cogl_get_source (),
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
&state);
@ -758,7 +758,7 @@ _cogl_draw_indexed_vertex_attributes_array_real (CoglVerticesMode mode,
CoglVertexAttribute **attributes,
ValidateLayerState *state)
{
CoglMaterial *source = enable_gl_state (attributes, state);
CoglPipeline *source = enable_gl_state (attributes, state);
CoglBuffer *buffer;
void *base;
size_t array_offset;
@ -834,7 +834,7 @@ cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
state.options.flags = 0;
state.fallback_layers = 0;
cogl_material_foreach_layer (cogl_get_source (),
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
&state);

View File

@ -103,8 +103,8 @@
#include "cogl-handle.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-texture-private.h"
#include "cogl-material.h"
#include "cogl-material-private.h"
#include "cogl-pipeline.h"
#include "cogl-pipeline-private.h"
#include "cogl-primitives.h"
#include "cogl-framebuffer-private.h"
#include "cogl-journal-private.h"
@ -114,7 +114,7 @@
static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer);
static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices);
static CoglUserDataKey _cogl_vertex_buffer_material_priv_key;
static CoglUserDataKey _cogl_vertex_buffer_pipeline_priv_key;
COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer);
COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (vertex_buffer);
@ -1392,70 +1392,70 @@ cogl_vertex_buffer_submit (CoglHandle handle)
typedef struct
{
CoglMaterial *real_source;
CoglPipeline *real_source;
} VertexBufferMaterialPrivate;
static void
weak_override_source_destroyed_cb (CoglMaterial *material,
weak_override_source_destroyed_cb (CoglPipeline *pipeline,
void *user_data)
{
VertexBufferMaterialPrivate *material_priv = user_data;
material_priv->real_source = NULL;
VertexBufferMaterialPrivate *pipeline_priv = user_data;
pipeline_priv->real_source = NULL;
}
static gboolean
validate_layer_cb (CoglMaterial *material,
validate_layer_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
VertexBufferMaterialPrivate *material_priv = user_data;
CoglMaterial *source = material_priv->real_source;
VertexBufferMaterialPrivate *pipeline_priv = user_data;
CoglPipeline *source = pipeline_priv->real_source;
if (!cogl_material_get_layer_point_sprite_coords_enabled (source,
if (!cogl_pipeline_get_layer_point_sprite_coords_enabled (source,
layer_index))
{
CoglMaterialWrapMode wrap_s;
CoglMaterialWrapMode wrap_t;
CoglMaterialWrapMode wrap_p;
CoglPipelineWrapMode wrap_s;
CoglPipelineWrapMode wrap_t;
CoglPipelineWrapMode wrap_p;
gboolean need_override_source = FALSE;
/* By default COGL_MATERIAL_WRAP_MODE_AUTOMATIC becomes
/* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes
* GL_CLAMP_TO_EDGE but we want GL_REPEAT to maintain
* compatibility with older versions of Cogl so we'll override
* it. We don't want to do this for point sprites because in
* that case the whole texture is drawn so you would usually
* want clamp-to-edge.
*/
wrap_s = cogl_material_get_layer_wrap_mode_s (source, layer_index);
if (wrap_s == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
wrap_s = cogl_pipeline_get_layer_wrap_mode_s (source, layer_index);
if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
need_override_source = TRUE;
wrap_s = COGL_MATERIAL_WRAP_MODE_REPEAT;
wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT;
}
wrap_t = cogl_material_get_layer_wrap_mode_t (source, layer_index);
if (wrap_t == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
wrap_t = cogl_pipeline_get_layer_wrap_mode_t (source, layer_index);
if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
need_override_source = TRUE;
wrap_t = COGL_MATERIAL_WRAP_MODE_REPEAT;
wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT;
}
wrap_p = cogl_material_get_layer_wrap_mode_p (source, layer_index);
if (wrap_p == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
wrap_p = cogl_pipeline_get_layer_wrap_mode_p (source, layer_index);
if (wrap_p == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
{
need_override_source = TRUE;
wrap_p = COGL_MATERIAL_WRAP_MODE_REPEAT;
wrap_p = COGL_PIPELINE_WRAP_MODE_REPEAT;
}
if (need_override_source)
{
if (material_priv->real_source == material)
material_priv->real_source = source =
_cogl_material_weak_copy (material,
if (pipeline_priv->real_source == pipeline)
pipeline_priv->real_source = source =
_cogl_pipeline_weak_copy (pipeline,
weak_override_source_destroyed_cb,
material_priv);
pipeline_priv);
cogl_material_set_layer_wrap_mode_s (source, layer_index, wrap_s);
cogl_material_set_layer_wrap_mode_t (source, layer_index, wrap_t);
cogl_material_set_layer_wrap_mode_p (source, layer_index, wrap_p);
cogl_pipeline_set_layer_wrap_mode_s (source, layer_index, wrap_s);
cogl_pipeline_set_layer_wrap_mode_t (source, layer_index, wrap_t);
cogl_pipeline_set_layer_wrap_mode_p (source, layer_index, wrap_p);
}
}
@ -1463,7 +1463,7 @@ validate_layer_cb (CoglMaterial *material,
}
static void
destroy_material_priv_cb (void *user_data)
destroy_pipeline_priv_cb (void *user_data)
{
g_slice_free (VertexBufferMaterialPrivate, user_data);
}
@ -1475,8 +1475,8 @@ update_primitive_and_draw (CoglVertexBuffer *buffer,
int count,
CoglVertexBufferIndices *buffer_indices)
{
VertexBufferMaterialPrivate *material_priv;
CoglMaterial *users_source;
VertexBufferMaterialPrivate *pipeline_priv;
CoglPipeline *users_source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1492,27 +1492,27 @@ update_primitive_and_draw (CoglVertexBuffer *buffer,
cogl_vertex_buffer_submit_real (buffer);
users_source = cogl_get_source ();
material_priv =
pipeline_priv =
cogl_object_get_user_data (COGL_OBJECT (users_source),
&_cogl_vertex_buffer_material_priv_key);
if (G_UNLIKELY (!material_priv))
&_cogl_vertex_buffer_pipeline_priv_key);
if (G_UNLIKELY (!pipeline_priv))
{
material_priv = g_slice_new0 (VertexBufferMaterialPrivate);
pipeline_priv = g_slice_new0 (VertexBufferMaterialPrivate);
cogl_object_set_user_data (COGL_OBJECT (users_source),
&_cogl_vertex_buffer_material_priv_key,
material_priv,
destroy_material_priv_cb);
&_cogl_vertex_buffer_pipeline_priv_key,
pipeline_priv,
destroy_pipeline_priv_cb);
}
if (G_UNLIKELY (!material_priv->real_source))
if (G_UNLIKELY (!pipeline_priv->real_source))
{
material_priv->real_source = users_source;
cogl_material_foreach_layer (material_priv->real_source,
pipeline_priv->real_source = users_source;
cogl_pipeline_foreach_layer (pipeline_priv->real_source,
validate_layer_cb,
material_priv);
pipeline_priv);
}
cogl_push_source (material_priv->real_source);
cogl_push_source (pipeline_priv->real_source);
cogl_primitive_draw (buffer->primitive);

View File

@ -36,8 +36,8 @@
#include "cogl-internal.h"
#include "cogl-util.h"
#include "cogl-context.h"
#include "cogl-material-private.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-winsys.h"
#include "cogl-framebuffer-private.h"
#include "cogl-matrix-private.h"
@ -158,7 +158,7 @@ cogl_clear (const CoglColor *color, unsigned long buffers)
_cogl_journal_flush ();
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the material state) when flushing the clip stack, so should
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
@ -375,9 +375,9 @@ cogl_set_source_color (const CoglColor *color)
premultiplied = *color;
cogl_color_premultiply (&premultiplied);
cogl_material_set_color (ctx->simple_material, &premultiplied);
cogl_pipeline_set_color (ctx->simple_pipeline, &premultiplied);
cogl_set_source (ctx->simple_material);
cogl_set_source (ctx->simple_pipeline);
}
void
@ -585,7 +585,7 @@ cogl_read_pixels (int x,
result of the default blending operations for Cogl ends up
with premultiplied data in the framebuffer. However it is
possible for the framebuffer to be in whatever format
depending on what CoglMaterial is used to render to
depending on what CoglPipeline is used to render to
it. Eventually we may want to add a way for an application to
inform Cogl that the framebuffer is not premultiplied in case
it is being used for some special purpose. */
@ -740,20 +740,20 @@ cogl_begin_gl (void)
* projection matrix state
*
* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the material state) when flushing the clip stack, so should
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
/* Setup the state for the current material */
/* Setup the state for the current pipeline */
/* We considered flushing a specific, minimal material here to try and
/* We considered flushing a specific, minimal pipeline here to try and
* simplify the GL state, but decided to avoid special cases and second
* guessing what would be actually helpful.
*
* A user should instead call cogl_set_source_color4ub() before
* cogl_begin_gl() to simplify the state flushed.
*/
_cogl_material_flush_gl_state (cogl_get_source (), FALSE);
_cogl_pipeline_flush_gl_state (cogl_get_source (), FALSE);
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -945,17 +945,17 @@ _cogl_driver_error_quark (void)
typedef struct _CoglSourceState
{
CoglMaterial *material;
CoglPipeline *pipeline;
int push_count;
} CoglSourceState;
static void
_push_source_real (CoglMaterial *material)
_push_source_real (CoglPipeline *pipeline)
{
CoglSourceState *top = g_slice_new (CoglSourceState);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
top->material = cogl_object_ref (material);
top->pipeline = cogl_object_ref (pipeline);
top->push_count = 1;
ctx->source_stack = g_list_prepend (ctx->source_stack, top);
@ -963,29 +963,30 @@ _push_source_real (CoglMaterial *material)
/* FIXME: This should take a context pointer for Cogl 2.0 Technically
* we could make it so we can retrieve a context reference from the
* material, but this would not by symmetric with cogl_pop_source. */
* pipeline, but this would not by symmetric with cogl_pop_source. */
void
cogl_push_source (CoglMaterial *material)
cogl_push_source (void *material_or_pipeline)
{
CoglSourceState *top;
CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (cogl_is_material (material));
g_return_if_fail (cogl_is_pipeline (pipeline));
if (ctx->source_stack)
{
top = ctx->source_stack->data;
if (top->material == material)
if (top->pipeline == pipeline)
{
top->push_count++;
return;
}
else
_push_source_real (material);
_push_source_real (pipeline);
}
else
_push_source_real (material);
_push_source_real (pipeline);
}
/* FIXME: This needs to take a context pointer for Cogl 2.0 */
@ -1002,7 +1003,7 @@ cogl_pop_source (void)
top->push_count--;
if (top->push_count == 0)
{
cogl_object_unref (top->material);
cogl_object_unref (top->pipeline);
g_slice_free (CoglSourceState, top);
ctx->source_stack = g_list_delete_link (ctx->source_stack,
ctx->source_stack);
@ -1010,7 +1011,7 @@ cogl_pop_source (void)
}
/* FIXME: This needs to take a context pointer for Cogl 2.0 */
CoglMaterial *
void *
cogl_get_source (void)
{
CoglSourceState *top;
@ -1020,35 +1021,36 @@ cogl_get_source (void)
g_return_val_if_fail (ctx->source_stack, NULL);
top = ctx->source_stack->data;
return top->material;
return top->pipeline;
}
void
cogl_set_source (CoglMaterial *material)
cogl_set_source (void *material_or_pipeline)
{
CoglSourceState *top;
CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (cogl_is_material (material));
g_return_if_fail (cogl_is_pipeline (pipeline));
g_return_if_fail (ctx->source_stack);
top = ctx->source_stack->data;
if (top->material == material)
if (top->pipeline == pipeline)
return;
if (top->push_count == 1)
{
/* NB: top->material may be only thing keeping material
* alive currently so ref material first... */
cogl_object_ref (material);
cogl_object_unref (top->material);
top->material = material;
/* NB: top->pipeline may be only thing keeping pipeline
* alive currently so ref pipeline first... */
cogl_object_ref (pipeline);
cogl_object_unref (top->pipeline);
top->pipeline = pipeline;
}
else
{
top->push_count--;
cogl_push_source (material);
cogl_push_source (pipeline);
}
}
@ -1059,8 +1061,8 @@ cogl_set_source_texture (CoglHandle texture_handle)
g_return_if_fail (texture_handle != NULL);
cogl_material_set_layer (ctx->texture_material, 0, texture_handle);
cogl_set_source (ctx->texture_material);
cogl_pipeline_set_layer_texture (ctx->texture_pipeline, 0, texture_handle);
cogl_set_source (ctx->texture_pipeline);
}
void

View File

@ -35,7 +35,7 @@
#include <cogl/cogl-bitmap.h>
#include <cogl/cogl-color.h>
#include <cogl/cogl-fixed.h>
#include <cogl/cogl-material.h>
#include <cogl/cogl-material-compat.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-offscreen.h>
#include <cogl/cogl-primitives.h>
@ -59,6 +59,7 @@
#include <cogl/cogl-indices.h>
#include <cogl/cogl-vertex-attribute.h>
#include <cogl/cogl-primitive.h>
#include <cogl/cogl-pipeline.h>
#endif
G_BEGIN_DECLS
@ -589,7 +590,7 @@ cogl_clear (const CoglColor *color,
* Since: 1.0
*/
void
cogl_set_source (CoglMaterial *material);
cogl_set_source (void *material);
/**
* cogl_get_source:
@ -607,7 +608,7 @@ cogl_set_source (CoglMaterial *material);
*
* Since: 1.6
*/
CoglMaterial *
void *
cogl_get_source (void);
/**
@ -621,7 +622,7 @@ cogl_get_source (void);
* Since: 1.6
*/
void
cogl_push_source (CoglMaterial *material);
cogl_push_source (void *material);
/**
* cogl_pop_source:

View File

@ -36,11 +36,11 @@
#include "cogl-bitmap.h"
#include "cogl-bitmap-private.h"
#include "cogl-texture-private.h"
#include "cogl-material.h"
#include "cogl-pipeline.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-primitives.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <string.h>
#include <stdlib.h>

View File

@ -36,8 +36,8 @@
#include "cogl-bitmap.h"
#include "cogl-bitmap-private.h"
#include "cogl-texture-private.h"
#include "cogl-material.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline.h"
#include "cogl-pipeline-opengl-private.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-primitives.h"

View File

@ -43,7 +43,7 @@
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-xlib.h"
#include "cogl-material-opengl-private.h"
#include "cogl-pipeline-opengl-private.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -1066,10 +1066,10 @@ _cogl_texture_pixmap_x11_set_use_glx_texture (CoglTexturePixmapX11 *tex_pixmap,
{
if (tex_pixmap->use_glx_texture != new_value)
{
/* Notify cogl-material.c that the texture's underlying GL texture
/* Notify cogl-pipeline.c that the texture's underlying GL texture
* storage is changing so it knows it may need to bind a new texture
* if the CoglTexture is reused with the same texture unit. */
_cogl_material_texture_storage_change_notify (tex_pixmap);
_cogl_pipeline_texture_storage_change_notify (tex_pixmap);
tex_pixmap->use_glx_texture = new_value;
}