summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2012-01-08 02:59:04 +0000
committerRobert Bragg <robert@linux.intel.com>2012-02-09 13:09:15 +0000
commit92c306301492a619037a8d13c8da8e4c5c1ebf94 (patch)
tree138ca612fe2376d2fa281ecc63dd8a2025e5be28
parent0365f6cda3df89335d243548053d85aaf66f1630 (diff)
downloadcogl-92c306301492a619037a8d13c8da8e4c5c1ebf94.tar.gz
framebuffer: Add cogl_framebuffer draw methods
This adds cogl_framebuffer_ apis for drawing attributes and primitives that replace corresponding apis that depend on the default CoglContext. This is part of the on going effort to adapt the Cogl api so it no longer depends on a global context variable. All the new drawing functions also take an explicit pipeline argument since we are also aiming to avoid being a stateful api like Cairo and OpenGL. Being stateless makes it easier for orthogonal components to share access to the GPU. Being stateless should also minimize any impedance miss-match for those wanting to build higher level stateless apis on top of Cogl. Note: none of the legacy, global state options such as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or cogl_program_use() are supported by these new drawing apis and if set will simply be silently ignored. Reviewed-by: Neil Roberts <neil@linux.intel.com>
-rw-r--r--cogl-pango/cogl-pango-display-list.c4
-rw-r--r--cogl/cogl-attribute-private.h25
-rw-r--r--cogl/cogl-attribute.c512
-rw-r--r--cogl/cogl-attribute.h28
-rw-r--r--cogl/cogl-clip-stack.c45
-rw-r--r--cogl/cogl-framebuffer-private.h31
-rw-r--r--cogl/cogl-framebuffer.c487
-rw-r--r--cogl/cogl-framebuffer.h210
-rw-r--r--cogl/cogl-journal.c62
-rw-r--r--cogl/cogl-primitive.c28
-rw-r--r--cogl/cogl-primitive.h12
-rw-r--r--cogl/cogl-primitives-private.h4
-rw-r--r--cogl/cogl-primitives.c41
-rw-r--r--cogl/cogl-vertex-buffer.c11
-rw-r--r--cogl/cogl2-path.c29
-rw-r--r--doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-docs.xml.in5
-rw-r--r--doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt17
-rw-r--r--examples/cogl-crate.c12
-rw-r--r--examples/cogl-hello.c8
-rw-r--r--examples/cogl-msaa.c7
-rw-r--r--examples/cogl-sdl-hello.c8
-rw-r--r--examples/cogl-x11-foreign.c5
-rw-r--r--examples/cogland.c5
-rw-r--r--tests/conform/test-custom-attributes.c78
-rw-r--r--tests/conform/test-primitive.c8
25 files changed, 958 insertions, 724 deletions
diff --git a/cogl-pango/cogl-pango-display-list.c b/cogl-pango/cogl-pango-display-list.c
index 9cc0166f..005b4786 100644
--- a/cogl-pango/cogl-pango-display-list.c
+++ b/cogl-pango/cogl-pango-display-list.c
@@ -364,7 +364,9 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
cogl_object_unref (attributes[1]);
}
- cogl_primitive_draw (node->d.texture.primitive);
+ cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
+ cogl_get_source (),
+ node->d.texture.primitive);
}
static void
diff --git a/cogl/cogl-attribute-private.h b/cogl/cogl-attribute-private.h
index 68ed52d0..d977376f 100644
--- a/cogl/cogl-attribute-private.h
+++ b/cogl/cogl-attribute-private.h
@@ -69,13 +69,14 @@ typedef enum
COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0,
COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1,
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2,
+ COGL_DRAW_SKIP_LEGACY_STATE = 1 << 3,
/* By default the vertex attribute drawing code will assume that if
there is a color attribute array enabled then we can't determine
if the colors will be opaque so we need to enabling
blending. However when drawing from the journal we know what the
contents of the color array is so we can override this by passing
this flag. */
- COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3
+ COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 4
} CoglDrawFlags;
/* During CoglContext initialization we register the "cogl_color_in"
@@ -95,24 +96,14 @@ void
_cogl_attribute_immutable_unref (CoglAttribute *attribute);
void
-_cogl_draw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglAttribute **attributes,
- int n_attributes,
- CoglDrawFlags flags);
-
-void
-_cogl_draw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- CoglAttribute **attributes,
- int n_attributes,
- CoglDrawFlags flags);
+_cogl_attribute_disable_cached_arrays (void);
void
-_cogl_attribute_disable_cached_arrays (void);
+_cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglDrawFlags flags,
+ CoglAttribute **attributes,
+ int n_attributes);
#endif /* __COGL_ATTRIBUTE_PRIVATE_H */
diff --git a/cogl/cogl-attribute.c b/cogl/cogl-attribute.c
index e8654df8..ddc3596c 100644
--- a/cogl/cogl-attribute.c
+++ b/cogl/cogl-attribute.c
@@ -538,32 +538,31 @@ apply_attribute_enable_updates (CoglContext *context,
&changed_bits_state);
}
-static CoglPipeline *
-flush_state (CoglDrawFlags flags,
- CoglAttribute **attributes,
- int n_attributes,
- ValidateLayerState *state)
+void
+_cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglDrawFlags flags,
+ CoglAttribute **attributes,
+ int n_attributes)
{
- CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
int i;
gboolean skip_gl_color = FALSE;
- CoglPipeline *source = cogl_get_source ();
CoglPipeline *copy = NULL;
int n_tex_coord_attribs = 0;
-
- _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
+ ValidateLayerState layers_state;
+ CoglContext *ctx = framebuffer->context;
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
_cogl_journal_flush (framebuffer->journal, framebuffer);
- state->unit = 0;
- state->options.flags = 0;
- state->fallback_layers = 0;
+ layers_state.unit = 0;
+ layers_state.options.flags = 0;
+ layers_state.fallback_layers = 0;
if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION))
- cogl_pipeline_foreach_layer (cogl_get_source (),
+ cogl_pipeline_foreach_layer (pipeline,
validate_layer_cb,
- state);
+ &layers_state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
@@ -572,8 +571,8 @@ flush_state (CoglDrawFlags flags,
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
- _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
- _cogl_get_read_framebuffer (),
+ _cogl_framebuffer_flush_state (framebuffer,
+ framebuffer,
COGL_FRAMEBUFFER_STATE_ALL);
/* In cogl_read_pixels we have a fast-path when reading a single
@@ -590,13 +589,13 @@ flush_state (CoglDrawFlags flags,
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 &&
- !_cogl_pipeline_get_real_blend_enabled (source))
+ !_cogl_pipeline_get_real_blend_enabled (pipeline))
{
CoglPipelineBlendEnable blend_enable =
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
- copy = cogl_pipeline_copy (source);
+ copy = cogl_pipeline_copy (pipeline);
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
- source = copy;
+ pipeline = copy;
}
skip_gl_color = TRUE;
break;
@@ -609,15 +608,15 @@ flush_state (CoglDrawFlags flags,
break;
}
- if (G_UNLIKELY (state->options.flags))
+ if (G_UNLIKELY (layers_state.options.flags))
{
/* If we haven't already created a derived pipeline... */
if (!copy)
{
- copy = cogl_pipeline_copy (source);
- source = copy;
+ copy = cogl_pipeline_copy (pipeline);
+ pipeline = copy;
}
- _cogl_pipeline_apply_overrides (source, &state->options);
+ _cogl_pipeline_apply_overrides (pipeline, &layers_state.options);
/* TODO:
* overrides = cogl_pipeline_get_data (pipeline,
@@ -640,7 +639,7 @@ flush_state (CoglDrawFlags flags,
* {
* overrides = g_slice_new (Overrides);
* overrides->weak_pipeline =
- * cogl_pipeline_weak_copy (cogl_get_source ());
+ * cogl_pipeline_weak_copy (pipeline);
* _cogl_pipeline_apply_overrides (overrides->weak_pipeline,
* &options);
*
@@ -649,23 +648,24 @@ flush_state (CoglDrawFlags flags,
* free_overrides_cb,
* NULL);
* }
- * source = overrides->weak_pipeline;
+ * pipeline = overrides->weak_pipeline;
*/
}
- if (G_UNLIKELY (ctx->legacy_state_set) &&
+ if (G_UNLIKELY (!(flags & COGL_DRAW_SKIP_LEGACY_STATE)) &&
+ G_UNLIKELY (ctx->legacy_state_set) &&
_cogl_get_enable_legacy_state ())
{
/* If we haven't already created a derived pipeline... */
if (!copy)
{
- copy = cogl_pipeline_copy (source);
- source = copy;
+ copy = cogl_pipeline_copy (pipeline);
+ pipeline = copy;
}
- _cogl_pipeline_apply_legacy_state (source);
+ _cogl_pipeline_apply_legacy_state (pipeline);
}
- _cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs);
+ _cogl_pipeline_flush_gl_state (pipeline, skip_gl_color, n_tex_coord_attribs);
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
@@ -691,7 +691,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
- setup_generic_attribute (ctx, source, attribute, base);
+ setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@@ -706,7 +706,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
- setup_generic_attribute (ctx, source, attribute, base);
+ setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@@ -720,7 +720,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
- setup_generic_attribute (ctx, source, attribute, base);
+ setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@@ -738,7 +738,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
- setup_generic_attribute (ctx, source, attribute, base);
+ setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@@ -753,7 +753,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
#ifdef COGL_PIPELINE_PROGEND_GLSL
if (ctx->driver != COGL_DRIVER_GLES1)
- setup_generic_attribute (ctx, source, attribute, base);
+ setup_generic_attribute (ctx, pipeline, attribute, base);
#endif
break;
default:
@@ -763,9 +763,10 @@ flush_state (CoglDrawFlags flags,
_cogl_buffer_unbind (buffer);
}
- apply_attribute_enable_updates (ctx, source);
+ apply_attribute_enable_updates (ctx, pipeline);
- return source;
+ if (copy)
+ cogl_object_unref (copy);
}
void
@@ -782,440 +783,3 @@ _cogl_attribute_disable_cached_arrays (void)
* attributes. */
apply_attribute_enable_updates (ctx, NULL);
}
-
-#ifdef COGL_ENABLE_DEBUG
-static int
-get_index (void *indices,
- CoglIndicesType type,
- int _index)
-{
- if (!indices)
- return _index;
-
- switch (type)
- {
- case COGL_INDICES_TYPE_UNSIGNED_BYTE:
- return ((guint8 *)indices)[_index];
- case COGL_INDICES_TYPE_UNSIGNED_SHORT:
- return ((guint16 *)indices)[_index];
- case COGL_INDICES_TYPE_UNSIGNED_INT:
- return ((guint32 *)indices)[_index];
- }
-
- g_return_val_if_reached (0);
-}
-
-static void
-add_line (void *vertices,
- void *indices,
- CoglIndicesType indices_type,
- CoglAttribute *attribute,
- int start,
- int end,
- CoglVertexP3 *lines,
- int *n_line_vertices)
-{
- int start_index = get_index (indices, indices_type, start);
- int end_index = get_index (indices, indices_type, end);
- float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride);
- float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride);
- float *o = (float *)(&lines[*n_line_vertices]);
- int i;
-
- for (i = 0; i < attribute->n_components; i++)
- *(o++) = *(v0++);
- for (;i < 3; i++)
- *(o++) = 0;
-
- for (i = 0; i < attribute->n_components; i++)
- *(o++) = *(v1++);
- for (;i < 3; i++)
- *(o++) = 0;
-
- *n_line_vertices += 2;
-}
-
-static CoglVertexP3 *
-get_wire_lines (CoglAttribute *attribute,
- CoglVerticesMode mode,
- int n_vertices_in,
- int *n_vertices_out,
- CoglIndices *_indices)
-{
- CoglAttributeBuffer *attribute_buffer = cogl_attribute_get_buffer (attribute);
- void *vertices;
- CoglIndexBuffer *index_buffer;
- void *indices;
- CoglIndicesType indices_type;
- int i;
- int n_lines;
- CoglVertexP3 *out = NULL;
-
- vertices = cogl_buffer_map (COGL_BUFFER (attribute_buffer),
- COGL_BUFFER_ACCESS_READ, 0);
- if (_indices)
- {
- index_buffer = cogl_indices_get_buffer (_indices);
- indices = cogl_buffer_map (COGL_BUFFER (index_buffer),
- COGL_BUFFER_ACCESS_READ, 0);
- indices_type = cogl_indices_get_type (_indices);
- }
- else
- {
- index_buffer = NULL;
- indices = NULL;
- indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE;
- }
-
- *n_vertices_out = 0;
-
- if (mode == COGL_VERTICES_MODE_TRIANGLES &&
- (n_vertices_in % 3) == 0)
- {
- n_lines = n_vertices_in;
- out = g_new (CoglVertexP3, n_lines * 2);
- for (i = 0; i < n_vertices_in; i += 3)
- {
- add_line (vertices, indices, indices_type, attribute,
- i, i+1, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i+1, i+2, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i+2, i, out, n_vertices_out);
- }
- }
- else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN &&
- n_vertices_in >= 3)
- {
- n_lines = 2 * n_vertices_in - 3;
- out = g_new (CoglVertexP3, n_lines * 2);
-
- add_line (vertices, indices, indices_type, attribute,
- 0, 1, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- 1, 2, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- 0, 2, out, n_vertices_out);
-
- for (i = 3; i < n_vertices_in; i++)
- {
- add_line (vertices, indices, indices_type, attribute,
- i - 1, i, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- 0, i, out, n_vertices_out);
- }
- }
- else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP &&
- n_vertices_in >= 3)
- {
- n_lines = 2 * n_vertices_in - 3;
- out = g_new (CoglVertexP3, n_lines * 2);
-
- add_line (vertices, indices, indices_type, attribute,
- 0, 1, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- 1, 2, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- 0, 2, out, n_vertices_out);
-
- for (i = 3; i < n_vertices_in; i++)
- {
- add_line (vertices, indices, indices_type, attribute,
- i - 1, i, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i - 2, i, out, n_vertices_out);
- }
- }
- /* In the journal we are a bit sneaky and actually use GL_QUADS
- * which isn't actually a valid CoglVerticesMode! */
-#ifdef HAVE_COGL_GL
- else if (mode == GL_QUADS && (n_vertices_in % 4) == 0)
- {
- n_lines = n_vertices_in;
- out = g_new (CoglVertexP3, n_lines * 2);
-
- for (i = 0; i < n_vertices_in; i += 4)
- {
- add_line (vertices, indices, indices_type, attribute,
- i, i + 1, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i + 1, i + 2, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i + 2, i + 3, out, n_vertices_out);
- add_line (vertices, indices, indices_type, attribute,
- i + 3, i, out, n_vertices_out);
- }
- }
-#endif
-
- if (vertices != NULL)
- cogl_buffer_unmap (COGL_BUFFER (attribute_buffer));
-
- if (indices != NULL)
- cogl_buffer_unmap (COGL_BUFFER (index_buffer));
-
- return out;
-}
-
-static void
-draw_wireframe (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglAttribute **attributes,
- int n_attributes,
- CoglIndices *indices)
-{
- CoglAttribute *position = NULL;
- int i;
- int n_line_vertices;
- static CoglPipeline *wire_pipeline;
- CoglAttribute *wire_attribute[1];
- CoglVertexP3 *lines;
- CoglAttributeBuffer *attribute_buffer;
-
- for (i = 0; i < n_attributes; i++)
- {
- if (attributes[i]->name_state->name_id ==
- COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY)
- {
- position = attributes[i];
- break;
- }
- }
- if (!position)
- return;
-
- lines = get_wire_lines (position,
- mode,
- n_vertices,
- &n_line_vertices,
- indices);
- attribute_buffer =
- cogl_attribute_buffer_new (sizeof (CoglVertexP3) * n_line_vertices,
- lines);
- wire_attribute[0] =
- cogl_attribute_new (attribute_buffer, "cogl_position_in",
- sizeof (CoglVertexP3),
- 0,
- 3,
- COGL_ATTRIBUTE_TYPE_FLOAT);
- cogl_object_unref (attribute_buffer);
-
- if (!wire_pipeline)
- {
- wire_pipeline = cogl_pipeline_new ();
- cogl_pipeline_set_color4ub (wire_pipeline,
- 0x00, 0xff, 0x00, 0xff);
- }
-
- _cogl_push_source (wire_pipeline, FALSE);
-
- /* temporarily disable the wireframe to avoid recursion! */
- COGL_DEBUG_CLEAR_FLAG (COGL_DEBUG_WIREFRAME);
- _cogl_draw_attributes (COGL_VERTICES_MODE_LINES,
- 0,
- n_line_vertices,
- wire_attribute,
- 1,
- COGL_DRAW_SKIP_JOURNAL_FLUSH |
- COGL_DRAW_SKIP_PIPELINE_VALIDATION |
- COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
-
- COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME);
-
- cogl_pop_source ();
-
- cogl_object_unref (wire_attribute[0]);
-}
-#endif
-
-/* This can be called directly by the CoglJournal to draw attributes
- * skipping the implicit journal flush, the framebuffer flush and
- * pipeline validation. */
-void
-_cogl_draw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglAttribute **attributes,
- int n_attributes,
- CoglDrawFlags flags)
-{
- ValidateLayerState state;
- CoglPipeline *source;
-
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
- source = flush_state (flags, attributes, n_attributes, &state);
-
- GE (ctx, glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
-
- if (G_UNLIKELY (source != cogl_get_source ()))
- cogl_object_unref (source);
-
-#ifdef COGL_ENABLE_DEBUG
- if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
- draw_wireframe (mode, first_vertex, n_vertices,
- attributes, n_attributes, NULL);
-#endif
-}
-
-void
-cogl_draw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglAttribute **attributes,
- int n_attributes)
-{
- _cogl_draw_attributes (mode, first_vertex,
- n_vertices,
- attributes, n_attributes,
- 0 /* no flags */);
-}
-
-void
-cogl_vdraw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- ...)
-{
- va_list ap;
- int n_attributes;
- CoglAttribute *attribute;
- CoglAttribute **attributes;
- int i;
-
- va_start (ap, n_vertices);
- for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
- ;
- va_end (ap);
-
- attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
-
- va_start (ap, n_vertices);
- for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
- attributes[i] = attribute;
- va_end (ap);
-
- cogl_draw_attributes (mode, first_vertex, n_vertices,
- attributes, n_attributes);
-}
-
-static size_t
-sizeof_index_type (CoglIndicesType type)
-{
- switch (type)
- {
- case COGL_INDICES_TYPE_UNSIGNED_BYTE:
- return 1;
- case COGL_INDICES_TYPE_UNSIGNED_SHORT:
- return 2;
- case COGL_INDICES_TYPE_UNSIGNED_INT:
- return 4;
- }
- g_return_val_if_reached (0);
-}
-
-void
-_cogl_draw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- CoglAttribute **attributes,
- int n_attributes,
- CoglDrawFlags flags)
-{
- ValidateLayerState state;
- CoglPipeline *source;
- CoglBuffer *buffer;
- guint8 *base;
- size_t buffer_offset;
- size_t index_size;
- GLenum indices_gl_type = 0;
-
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
- source = flush_state (flags, attributes, n_attributes, &state);
-
- buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
- base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
- buffer_offset = cogl_indices_get_offset (indices);
- index_size = sizeof_index_type (cogl_indices_get_type (indices));
-
- switch (cogl_indices_get_type (indices))
- {
- case COGL_INDICES_TYPE_UNSIGNED_BYTE:
- indices_gl_type = GL_UNSIGNED_BYTE;
- break;
- case COGL_INDICES_TYPE_UNSIGNED_SHORT:
- indices_gl_type = GL_UNSIGNED_SHORT;
- break;
- case COGL_INDICES_TYPE_UNSIGNED_INT:
- indices_gl_type = GL_UNSIGNED_INT;
- break;
- }
-
- GE (ctx, glDrawElements ((GLenum)mode,
- n_vertices,
- indices_gl_type,
- base + buffer_offset + index_size * first_vertex));
-
- _cogl_buffer_unbind (buffer);
-
- if (G_UNLIKELY (source != cogl_get_source ()))
- cogl_object_unref (source);
-
-#ifdef COGL_ENABLE_DEBUG
- if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
- draw_wireframe (mode, first_vertex, n_vertices,
- attributes, n_attributes, indices);
-#endif
-}
-
-void
-cogl_draw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- CoglAttribute **attributes,
- int n_attributes)
-{
- _cogl_draw_indexed_attributes (mode, first_vertex,
- n_vertices, indices,
- attributes, n_attributes,
- 0 /* no flags */);
-}
-
-void
-cogl_vdraw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- ...)
-{
- va_list ap;
- int n_attributes;
- CoglAttribute **attributes;
- int i;
- CoglAttribute *attribute;
-
- va_start (ap, indices);
- for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
- ;
- va_end (ap);
-
- attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
-
- va_start (ap, indices);
- for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
- attributes[i] = attribute;
- va_end (ap);
-
- cogl_draw_indexed_attributes (mode,
- first_vertex,
- n_vertices,
- indices,
- attributes,
- n_attributes);
-}
-
-
diff --git a/cogl/cogl-attribute.h b/cogl/cogl-attribute.h
index c12990b9..a9ec03ef 100644
--- a/cogl/cogl-attribute.h
+++ b/cogl/cogl-attribute.h
@@ -213,34 +213,6 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
gboolean
cogl_is_attribute (void *object);
-void
-cogl_vdraw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- ...) G_GNUC_NULL_TERMINATED;
-
-void
-cogl_draw_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglAttribute **attributes,
- int n_attributes);
-
-void
-cogl_vdraw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- ...) G_GNUC_NULL_TERMINATED;
-
-void
-cogl_draw_indexed_attributes (CoglVerticesMode mode,
- int first_vertex,
- int n_vertices,
- CoglIndices *indices,
- CoglAttribute **attributes,
- int n_attributes);
-
G_END_DECLS
#endif /* __COGL_ATTRIBUTE_H__ */
diff --git a/cogl/cogl-clip-stack.c b/cogl/cogl-clip-stack.c
index 5cc49817..418debb2 100644
--- a/cogl/cogl-clip-stack.c
+++ b/cogl/cogl-clip-stack.c
@@ -218,9 +218,6 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
_cogl_framebuffer_get_projection_stack (framebuffer);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
- /* temporarily swap in our special stenciling pipeline */
- _cogl_push_source (ctx->stencil_pipeline, FALSE);
-
/* This can be called from the journal code which doesn't flush
the matrix stacks between calls so we need to ensure they're
flushed now */
@@ -239,7 +236,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( ctx, glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) );
- _cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
+ _cogl_rectangle_immediate (framebuffer,
+ ctx->stencil_pipeline,
+ x_1, y_1, x_2, y_2);
}
else
{
@@ -247,7 +246,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
rectangle */
GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) );
GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
- _cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
+ _cogl_rectangle_immediate (framebuffer,
+ ctx->stencil_pipeline,
+ x_1, y_1, x_2, y_2);
/* Subtract one from all pixels in the stencil buffer so that
only pixels where both the original stencil buffer and the
@@ -263,7 +264,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
_cogl_context_set_current_projection (ctx, projection_stack);
_cogl_context_set_current_modelview (ctx, modelview_stack);
- _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
+ _cogl_rectangle_immediate (framebuffer,
+ ctx->stencil_pipeline,
+ -1.0, -1.0, 1.0, 1.0);
_cogl_matrix_stack_pop (modelview_stack);
_cogl_matrix_stack_pop (projection_stack);
@@ -272,9 +275,6 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
/* Restore the stencil mode */
GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
-
- /* restore the original source pipeline */
- cogl_pop_source ();
}
typedef void (*SilhouettePaintCallback) (void *user_data);
@@ -302,9 +302,6 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
_cogl_context_set_current_projection (ctx, projection_stack);
_cogl_context_set_current_modelview (ctx, modelview_stack);
- /* Just setup a simple pipeline that doesn't use texturing... */
- _cogl_push_source (ctx->stencil_pipeline, FALSE);
-
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0);
GE( ctx, glEnable (GL_STENCIL_TEST) );
@@ -337,7 +334,9 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
/* Just clear the bounding box */
GE( ctx, glStencilMask (~(GLuint) 0) );
GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
- _cogl_rectangle_immediate (bounds_x1, bounds_y1,
+ _cogl_rectangle_immediate (framebuffer,
+ ctx->stencil_pipeline,
+ bounds_x1, bounds_y1,
bounds_x2, bounds_y2);
}
GE (ctx, glStencilMask (1));
@@ -364,8 +363,10 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
_cogl_matrix_stack_push (modelview_stack);
_cogl_matrix_stack_load_identity (modelview_stack);
- _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
- _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
+ _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline,
+ -1.0, -1.0, 1.0, 1.0);
+ _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline,
+ -1.0, -1.0, 1.0, 1.0);
_cogl_matrix_stack_pop (modelview_stack);
_cogl_matrix_stack_pop (projection_stack);
@@ -377,9 +378,6 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1));
GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
-
- /* restore the original pipeline */
- cogl_pop_source ();
}
static void
@@ -414,10 +412,13 @@ add_stencil_clip_path (CoglFramebuffer *framebuffer,
static void
paint_primitive_silhouette (void *user_data)
{
- _cogl_primitive_draw (user_data,
- COGL_DRAW_SKIP_JOURNAL_FLUSH |
- COGL_DRAW_SKIP_PIPELINE_VALIDATION |
- COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
+ _cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
+ cogl_get_source (),
+ user_data,
+ COGL_DRAW_SKIP_JOURNAL_FLUSH |
+ COGL_DRAW_SKIP_PIPELINE_VALIDATION |
+ COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
+ COGL_DRAW_SKIP_LEGACY_STATE);
}
void
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 7e1f97d7..137ba876 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -29,6 +29,7 @@
#include "cogl-clip-state-private.h"
#include "cogl-journal-private.h"
#include "cogl-winsys-private.h"
+#include "cogl-attribute-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
@@ -367,4 +368,34 @@ _cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer);
void
_cogl_framebuffer_unref (CoglFramebuffer *framebuffer);
+void
+_cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglPrimitive *primitive,
+ CoglDrawFlags flags);
+
+/* This can be called directly by the CoglJournal to draw attributes
+ * skipping the implicit journal flush, the framebuffer flush and
+ * pipeline validation. */
+void
+_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags);
+
+void
+_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags);
+
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index c82ad4f1..b3d17534 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -41,6 +41,7 @@
#include "cogl-winsys-private.h"
#include "cogl-pipeline-state-private.h"
#include "cogl-matrix-private.h"
+#include "cogl-primitive-private.h"
#ifndef GL_FRAMEBUFFER
#define GL_FRAMEBUFFER 0x8D40
@@ -2416,3 +2417,489 @@ _cogl_framebuffer_unref (CoglFramebuffer *framebuffer)
/* Chain-up */
_cogl_object_default_unref (framebuffer);
}
+
+#ifdef COGL_ENABLE_DEBUG
+static int
+get_index (void *indices,
+ CoglIndicesType type,
+ int _index)
+{
+ if (!indices)
+ return _index;
+
+ switch (type)
+ {
+ case COGL_INDICES_TYPE_UNSIGNED_BYTE:
+ return ((guint8 *)indices)[_index];
+ case COGL_INDICES_TYPE_UNSIGNED_SHORT:
+ return ((guint16 *)indices)[_index];
+ case COGL_INDICES_TYPE_UNSIGNED_INT:
+ return ((guint32 *)indices)[_index];
+ }
+
+ g_return_val_if_reached (0);
+}
+
+static void
+add_line (void *vertices,
+ void *indices,
+ CoglIndicesType indices_type,
+ CoglAttribute *attribute,
+ int start,
+ int end,
+ CoglVertexP3 *lines,
+ int *n_line_vertices)
+{
+ int start_index = get_index (indices, indices_type, start);
+ int end_index = get_index (indices, indices_type, end);
+ float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride);
+ float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride);
+ float *o = (float *)(&lines[*n_line_vertices]);
+ int i;
+
+ for (i = 0; i < attribute->n_components; i++)
+ *(o++) = *(v0++);
+ for (;i < 3; i++)
+ *(o++) = 0;
+
+ for (i = 0; i < attribute->n_components; i++)
+ *(o++) = *(v1++);
+ for (;i < 3; i++)
+ *(o++) = 0;
+
+ *n_line_vertices += 2;
+}
+
+static CoglVertexP3 *
+get_wire_lines (CoglAttribute *attribute,
+ CoglVerticesMode mode,
+ int n_vertices_in,
+ int *n_vertices_out,
+ CoglIndices *_indices)
+{
+ CoglAttributeBuffer *attribute_buffer = cogl_attribute_get_buffer (attribute);
+ void *vertices;
+ CoglIndexBuffer *index_buffer;
+ void *indices;
+ CoglIndicesType indices_type;
+ int i;
+ int n_lines;
+ CoglVertexP3 *out = NULL;
+
+ vertices = cogl_buffer_map (COGL_BUFFER (attribute_buffer),
+ COGL_BUFFER_ACCESS_READ, 0);
+ if (_indices)
+ {
+ index_buffer = cogl_indices_get_buffer (_indices);
+ indices = cogl_buffer_map (COGL_BUFFER (index_buffer),
+ COGL_BUFFER_ACCESS_READ, 0);
+ indices_type = cogl_indices_get_type (_indices);
+ }
+ else
+ {
+ index_buffer = NULL;
+ indices = NULL;
+ indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE;
+ }
+
+ *n_vertices_out = 0;
+
+ if (mode == COGL_VERTICES_MODE_TRIANGLES &&
+ (n_vertices_in % 3) == 0)
+ {
+ n_lines = n_vertices_in;
+ out = g_new (CoglVertexP3, n_lines * 2);
+ for (i = 0; i < n_vertices_in; i += 3)
+ {
+ add_line (vertices, indices, indices_type, attribute,
+ i, i+1, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i+1, i+2, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i+2, i, out, n_vertices_out);
+ }
+ }
+ else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN &&
+ n_vertices_in >= 3)
+ {
+ n_lines = 2 * n_vertices_in - 3;
+ out = g_new (CoglVertexP3, n_lines * 2);
+
+ add_line (vertices, indices, indices_type, attribute,
+ 0, 1, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ 1, 2, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ 0, 2, out, n_vertices_out);
+
+ for (i = 3; i < n_vertices_in; i++)
+ {
+ add_line (vertices, indices, indices_type, attribute,
+ i - 1, i, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ 0, i, out, n_vertices_out);
+ }
+ }
+ else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP &&
+ n_vertices_in >= 3)
+ {
+ n_lines = 2 * n_vertices_in - 3;
+ out = g_new (CoglVertexP3, n_lines * 2);
+
+ add_line (vertices, indices, indices_type, attribute,
+ 0, 1, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ 1, 2, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ 0, 2, out, n_vertices_out);
+
+ for (i = 3; i < n_vertices_in; i++)
+ {
+ add_line (vertices, indices, indices_type, attribute,
+ i - 1, i, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i - 2, i, out, n_vertices_out);
+ }
+ }
+ /* In the journal we are a bit sneaky and actually use GL_QUADS
+ * which isn't actually a valid CoglVerticesMode! */
+#ifdef HAVE_COGL_GL
+ else if (mode == GL_QUADS && (n_vertices_in % 4) == 0)
+ {
+ n_lines = n_vertices_in;
+ out = g_new (CoglVertexP3, n_lines * 2);
+
+ for (i = 0; i < n_vertices_in; i += 4)
+ {
+ add_line (vertices, indices, indices_type, attribute,
+ i, i + 1, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i + 1, i + 2, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i + 2, i + 3, out, n_vertices_out);
+ add_line (vertices, indices, indices_type, attribute,
+ i + 3, i, out, n_vertices_out);
+ }
+ }
+#endif
+
+ if (vertices != NULL)
+ cogl_buffer_unmap (COGL_BUFFER (attribute_buffer));
+
+ if (indices != NULL)
+ cogl_buffer_unmap (COGL_BUFFER (index_buffer));
+
+ return out;
+}
+
+static void
+draw_wireframe (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglIndices *indices)
+{
+ CoglAttribute *position = NULL;
+ int i;
+ int n_line_vertices;
+ static CoglPipeline *wire_pipeline;
+ CoglAttribute *wire_attribute[1];
+ CoglVertexP3 *lines;
+ CoglAttributeBuffer *attribute_buffer;
+
+ for (i = 0; i < n_attributes; i++)
+ {
+ if (attributes[i]->name_state->name_id ==
+ COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY)
+ {
+ position = attributes[i];
+ break;
+ }
+ }
+ if (!position)
+ return;
+
+ lines = get_wire_lines (position,
+ mode,
+ n_vertices,
+ &n_line_vertices,
+ indices);
+ attribute_buffer =
+ cogl_attribute_buffer_new (sizeof (CoglVertexP3) * n_line_vertices,
+ lines);
+ wire_attribute[0] =
+ cogl_attribute_new (attribute_buffer, "cogl_position_in",
+ sizeof (CoglVertexP3),
+ 0,
+ 3,
+ COGL_ATTRIBUTE_TYPE_FLOAT);
+ cogl_object_unref (attribute_buffer);
+
+ if (!wire_pipeline)
+ {
+ wire_pipeline = cogl_pipeline_new ();
+ cogl_pipeline_set_color4ub (wire_pipeline,
+ 0x00, 0xff, 0x00, 0xff);
+ }
+
+ /* temporarily disable the wireframe to avoid recursion! */
+ COGL_DEBUG_CLEAR_FLAG (COGL_DEBUG_WIREFRAME);
+ _cogl_framebuffer_draw_attributes (framebuffer,
+ wire_pipeline,
+ COGL_VERTICES_MODE_LINES,
+ 0,
+ n_line_vertices,
+ wire_attribute,
+ 1,
+ COGL_DRAW_SKIP_JOURNAL_FLUSH |
+ COGL_DRAW_SKIP_PIPELINE_VALIDATION |
+ COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
+ COGL_DRAW_SKIP_LEGACY_STATE);
+
+ COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME);
+
+ cogl_object_unref (wire_attribute[0]);
+}
+#endif
+
+/* This can be called directly by the CoglJournal to draw attributes
+ * skipping the implicit journal flush, the framebuffer flush and
+ * pipeline validation. */
+void
+_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags)
+{
+ _cogl_flush_attributes_state (framebuffer, pipeline, flags,
+ attributes, n_attributes);
+
+ GE (framebuffer->context,
+ glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
+
+#ifdef COGL_ENABLE_DEBUG
+ if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
+ draw_wireframe (framebuffer, pipeline,
+ mode, first_vertex, n_vertices,
+ attributes, n_attributes, NULL);
+#endif
+}
+
+void
+cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes)
+{
+ _cogl_framebuffer_draw_attributes (framebuffer,
+ pipeline,
+ mode,
+ first_vertex,
+ n_vertices,
+ attributes, n_attributes,
+ COGL_DRAW_SKIP_LEGACY_STATE);
+}
+
+void
+cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ ...)
+{
+ va_list ap;
+ int n_attributes;
+ CoglAttribute *attribute;
+ CoglAttribute **attributes;
+ int i;
+
+ va_start (ap, n_vertices);
+ for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
+ ;
+ va_end (ap);
+
+ attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
+
+ va_start (ap, n_vertices);
+ for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
+ attributes[i] = attribute;
+ va_end (ap);
+
+ _cogl_framebuffer_draw_attributes (framebuffer,
+ pipeline,
+ mode, first_vertex, n_vertices,
+ attributes, n_attributes,
+ COGL_DRAW_SKIP_LEGACY_STATE);
+}
+
+static size_t
+sizeof_index_type (CoglIndicesType type)
+{
+ switch (type)
+ {
+ case COGL_INDICES_TYPE_UNSIGNED_BYTE:
+ return 1;
+ case COGL_INDICES_TYPE_UNSIGNED_SHORT:
+ return 2;
+ case COGL_INDICES_TYPE_UNSIGNED_INT:
+ return 4;
+ }
+ g_return_val_if_reached (0);
+}
+
+void
+_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags)
+{
+ CoglBuffer *buffer;
+ guint8 *base;
+ size_t buffer_offset;
+ size_t index_size;
+ GLenum indices_gl_type = 0;
+
+ _cogl_flush_attributes_state (framebuffer, pipeline, flags,
+ attributes, n_attributes);
+
+ buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
+ base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
+ buffer_offset = cogl_indices_get_offset (indices);
+ index_size = sizeof_index_type (cogl_indices_get_type (indices));
+
+ switch (cogl_indices_get_type (indices))
+ {
+ case COGL_INDICES_TYPE_UNSIGNED_BYTE:
+ indices_gl_type = GL_UNSIGNED_BYTE;
+ break;
+ case COGL_INDICES_TYPE_UNSIGNED_SHORT:
+ indices_gl_type = GL_UNSIGNED_SHORT;
+ break;
+ case COGL_INDICES_TYPE_UNSIGNED_INT:
+ indices_gl_type = GL_UNSIGNED_INT;
+ break;
+ }
+
+ GE (framebuffer->context,
+ glDrawElements ((GLenum)mode,
+ n_vertices,
+ indices_gl_type,
+ base + buffer_offset + index_size * first_vertex));
+
+ _cogl_buffer_unbind (buffer);
+
+#ifdef COGL_ENABLE_DEBUG
+ if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
+ draw_wireframe (framebuffer, pipeline,
+ mode, first_vertex, n_vertices,
+ attributes, n_attributes, indices);
+#endif
+}
+
+void
+cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ CoglAttribute **attributes,
+ int n_attributes)
+{
+ _cogl_framebuffer_draw_indexed_attributes (framebuffer,
+ pipeline,
+ mode, first_vertex,
+ n_vertices, indices,
+ attributes, n_attributes,
+ COGL_DRAW_SKIP_LEGACY_STATE);
+}
+
+void
+cogl_vdraw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ ...)
+{
+ va_list ap;
+ int n_attributes;
+ CoglAttribute **attributes;
+ int i;
+ CoglAttribute *attribute;
+
+ va_start (ap, indices);
+ for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
+ ;
+ va_end (ap);
+
+ attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
+
+ va_start (ap, indices);
+ for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
+ attributes[i] = attribute;
+ va_end (ap);
+
+ _cogl_framebuffer_draw_indexed_attributes (framebuffer,
+ pipeline,
+ mode,
+ first_vertex,
+ n_vertices,
+ indices,
+ attributes,
+ n_attributes,
+ COGL_DRAW_SKIP_LEGACY_STATE);
+}
+
+void
+_cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglPrimitive *primitive,
+ CoglDrawFlags flags)
+{
+ if (primitive->indices)
+ _cogl_framebuffer_draw_indexed_attributes (framebuffer,
+ pipeline,
+ primitive->mode,
+ primitive->first_vertex,
+ primitive->n_vertices,
+ primitive->indices,
+ primitive->attributes,
+ primitive->n_attributes,
+ flags);
+ else
+ _cogl_framebuffer_draw_attributes (framebuffer,
+ pipeline,
+ primitive->mode,
+ primitive->first_vertex,
+ primitive->n_vertices,
+ primitive->attributes,
+ primitive->n_attributes,
+ flags);
+}
+
+void
+cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglPrimitive *primitive)
+{
+ _cogl_framebuffer_draw_primitive (framebuffer, pipeline, primitive,
+ COGL_DRAW_SKIP_LEGACY_STATE);
+}
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index 1c1d0bde..5579ad18 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -973,6 +973,216 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
float blue,
float alpha);
+/**
+ * cogl_framebuffer_draw_primitive:
+ * @framebuffer: A destination #CoglFramebuffer
+ * @pipeline: A #CoglPipeline state object
+ * @primitive: A #CoglPrimitive geometry object
+ *
+ * Draws the given @primitive geometry to the specified destination
+ * @framebuffer using the graphics processing pipeline described by @pipeline.
+ *
+ * <note>This api doesn't support any of the legacy global state options such
+ * as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
+ * cogl_program_use()</note>
+ *
+ * Stability: unstable
+ * Since: 1.10
+ */
+void
+cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglPrimitive *primitive);
+
+/**
+ * cogl_framebuffer_vdraw_attributes:
+ * @framebuffer: A destination #CoglFramebuffer
+ * @pipeline: A #CoglPipeline state object
+ * @mode: The #CoglVerticesMode defining the topology of vertices
+ * @first_vertex: The vertex offset within the given attributes to draw from
+ * @n_vertices: The number of vertices to draw from the given attributes
+ * @...: A set of vertex #CoglAttribute<!-- -->s defining vertex geometry
+ *
+ * First defines a geometry primitive by grouping a set of vertex attributes;
+ * specifying a @first_vertex; a number of vertices (@n_vertices) and
+ * specifying what kind of topology the vertices have via @mode.
+ *
+ * Then the function draws the given @primitive geometry to the specified
+ * destination @framebuffer using the graphics processing pipeline described by
+ * @pipeline.
+ *
+ * The list of #CoglAttribute<!-- -->s define the attributes of the vertices to
+ * be drawn, such as positions, colors and normals and should be %NULL
+ * terminated.
+ *
+ * Stability: unstable
+ * Since: 1.10
+ */
+void
+cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ ...) G_GNUC_NULL_TERMINATED;
+
+/**
+ * cogl_framebuffer_draw_attributes:
+ * @framebuffer: A destination #CoglFramebuffer
+ * @pipeline: A #CoglPipeline state object
+ * @mode: The #CoglVerticesMode defining the topology of vertices
+ * @first_vertex: The vertex offset within the given attributes to draw from
+ * @n_vertices: The number of vertices to draw from the given attributes
+ * @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex
+ * geometry
+ * @n_attributes: The number of attributes in the @attributes array.
+ *
+ * First defines a geometry primitive by grouping a set of vertex @attributes;
+ * specifying a @first_vertex; a number of vertices (@n_vertices) and
+ * specifying what kind of topology the vertices have via @mode.
+ *
+ * Then the function draws the given @primitive geometry to the specified
+ * destination @framebuffer using the graphics processing pipeline described by
+ * @pipeline.
+ *
+ * The list of #CoglAttribute<!-- -->s define the attributes of the vertices to
+ * be drawn, such as positions, colors and normals and the number of attributes
+ * is given as @n_attributes.
+ *
+ * <note>This api doesn't support any of the legacy global state options such
+ * as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
+ * cogl_program_use()</note>
+ *
+ * Stability: unstable
+ * Since: 1.10
+ */
+void
+cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes);
+
+/**
+ * cogl_framebuffer_vdraw_indexed_attributes:
+ * @framebuffer: A destination #CoglFramebuffer
+ * @pipeline: A #CoglPipeline state object
+ * @mode: The #CoglVerticesMode defining the topology of vertices
+ * @first_vertex: The vertex offset within the given attributes to draw from
+ * @n_vertices: The number of vertices to draw from the given attributes
+ * @indices: The array of indices used by the GPU to lookup attribute
+ * data for each vertex.
+ * @...: A set of vertex #CoglAttribute<!-- -->s defining vertex geometry
+ *
+ * Behaves the same as cogl_framebuffer_vdraw_attributes() except that
+ * instead of reading vertex data sequentially from the specified
+ * attributes the @indices provide an indirection for how the data
+ * should be indexed allowing a random access order to be
+ * specified.
+ *
+ * For example an indices array of [0, 1, 2, 0, 2, 3] could be used
+ * used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES +
+ * @n_vertices = 6) but only provide attribute data for the 4 corners
+ * of a rectangle. When the GPU needs to read in each of the 6
+ * vertices it will read the @indices array for each vertex in
+ * sequence and use the index to look up the vertex attribute data. So
+ * here you can see that first and fourth vertex will point to the
+ * same data and third and fifth vertex will also point to shared
+ * data.
+ *
+ * Drawing with indices can be a good way of minimizing the size of a
+ * mesh by allowing you to avoid data for duplicate vertices because
+ * multiple entries in the index array can refer back to a single
+ * shared vertex.
+ *
+ * <note>The @indices array must at least be as long @first_vertex +
+ * @n_vertices otherwise the GPU will overrun the indices array when
+ * looking up vertex data.</note>
+ *
+ * Since it's very common to want to draw a run of rectangles using
+ * indices to avoid duplicating vertex data you can use
+ * cogl_get_rectangle_indices() to get a set of indices that can be
+ * shared.
+ *
+ * <note>This api doesn't support any of the legacy global state
+ * options such as cogl_set_depth_test_enabled(),
+ * cogl_set_backface_culling_enabled() or cogl_program_use()</note>
+ *
+ * Stability: unstable
+ * Since: 1.10
+ */
+void
+cogl_framebuffer_vdraw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ ...) G_GNUC_NULL_TERMINATED;
+
+/**
+ * cogl_framebuffer_draw_indexed_attributes:
+ * @framebuffer: A destination #CoglFramebuffer
+ * @pipeline: A #CoglPipeline state object
+ * @mode: The #CoglVerticesMode defining the topology of vertices
+ * @first_vertex: The vertex offset within the given attributes to draw from
+ * @n_vertices: The number of vertices to draw from the given attributes
+ * @indices: The array of indices used by the GPU to lookup attribute
+ * data for each vertex.
+ * @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex
+ * geometry
+ * @n_attributes: The number of attributes in the @attributes array.
+ *
+ * Behaves the same as cogl_framebuffer_draw_attributes() except that
+ * instead of reading vertex data sequentially from the specified
+ * @attributes the @indices provide an indirection for how the data
+ * should be indexed allowing a random access order to be
+ * specified.
+ *
+ * For example an indices array of [0, 1, 2, 0, 2, 3] could be used
+ * used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES +
+ * @n_vertices = 6) but only provide attribute data for the 4 corners
+ * of a rectangle. When the GPU needs to read in each of the 6
+ * vertices it will read the @indices array for each vertex in
+ * sequence and use the index to look up the vertex attribute data. So
+ * here you can see that first and fourth vertex will point to the
+ * same data and third and fifth vertex will also point to shared
+ * data.
+ *
+ * Drawing with indices can be a good way of minimizing the size of a
+ * mesh by allowing you to avoid data for duplicate vertices because
+ * multiple entries in the index array can refer back to a single
+ * shared vertex.
+ *
+ * <note>The @indices array must at least be as long @first_vertex +
+ * @n_vertices otherwise the GPU will overrun the indices array when
+ * looking up vertex data.</note>
+ *
+ * Since it's very common to want to draw a run of rectangles using
+ * indices to avoid duplicating vertex data you can use
+ * cogl_get_rectangle_indices() to get a set of indices that can be
+ * shared.
+ *
+ * <note>This api doesn't support any of the legacy global state
+ * options such as cogl_set_depth_test_enabled(),
+ * cogl_set_backface_culling_enabled() or cogl_program_use()</note>
+ *
+ * Stability: unstable
+ * Since: 1.10
+ */
+void
+cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ CoglAttribute **attributes,
+ int n_attributes);
+
+
/* XXX: Should we take an n_buffers + buffer id array instead of using
* the CoglBufferBits type which doesn't seem future proof? */
/**
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index 5a67aa1d..27a93512 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -273,7 +273,8 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
CoglAttribute **attributes;
CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
- COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
+ COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
+ COGL_DRAW_SKIP_LEGACY_STATE);
COGL_STATIC_TIMER (time_flush_modelview_and_entries,
"flush: pipeline+entries", /* parent */
@@ -296,7 +297,6 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
}
attributes = (CoglAttribute **)state->attributes->data;
- _cogl_push_source (state->source, FALSE);
if (!_cogl_pipeline_get_real_blend_enabled (state->source))
draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE;
@@ -305,33 +305,40 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
if (ctx->driver == COGL_DRIVER_GL)
{
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
- _cogl_draw_attributes (GL_QUADS,
- state->current_vertex, batch_len * 4,
- attributes,
- state->attributes->len,
- draw_flags);
+ _cogl_framebuffer_draw_attributes (state->framebuffer,
+ state->source,
+ GL_QUADS,
+ state->current_vertex, batch_len * 4,
+ attributes,
+ state->attributes->len,
+ draw_flags);
}
else
#endif /* HAVE_COGL_GL */
{
if (batch_len > 1)
{
- _cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES,
- state->current_vertex * 6 / 4,
- batch_len * 6,
- state->indices,
- attributes,
- state->attributes->len,
- draw_flags);
-
+ CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES;
+ int first_vertex = state->current_vertex * 6 / 4;
+ _cogl_framebuffer_draw_indexed_attributes (state->framebuffer,
+ state->source,
+ mode,
+ first_vertex,
+ batch_len * 6,
+ state->indices,
+ attributes,
+ state->attributes->len,
+ draw_flags);
}
else
{
- _cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
- state->current_vertex, 4,
- attributes,
- state->attributes->len,
- draw_flags);
+ _cogl_framebuffer_draw_attributes (state->framebuffer,
+ state->source,
+ COGL_VERTICES_MODE_TRIANGLE_FAN,
+ state->current_vertex, 4,
+ attributes,
+ state->attributes->len,
+ draw_flags);
}
}
@@ -369,15 +376,16 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
(ctxt->journal_rectangles_color & 4) ?
color_intensity : 0,
0xff);
- cogl_set_source (outline);
loop_attributes[0] = attributes[0]; /* we just want the position */
for (i = 0; i < batch_len; i++)
- _cogl_draw_attributes (COGL_VERTICES_MODE_LINE_LOOP,
- 4 * i + state->current_vertex, 4,
- loop_attributes,
- 1,
- draw_flags);
+ _cogl_framebuffer_draw_attributes (state->framebuffer,
+ outline,
+ COGL_VERTICES_MODE_LINE_LOOP,
+ 4 * i + state->current_vertex, 4,
+ loop_attributes,
+ 1,
+ draw_flags);
/* Go to the next color */
do
@@ -390,8 +398,6 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
state->current_vertex += (4 * batch_len);
- cogl_pop_source ();
-
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries);
}
diff --git a/cogl/cogl-primitive.c b/cogl/cogl-primitive.c
index bef50a72..b6a3abdf 100644
--- a/cogl/cogl-primitive.c
+++ b/cogl/cogl-primitive.c
@@ -576,34 +576,6 @@ _cogl_primitive_immutable_unref (CoglPrimitive *primitive)
}
void
-_cogl_primitive_draw (CoglPrimitive *primitive,
- CoglDrawFlags flags)
-{
- if (primitive->indices)
- _cogl_draw_indexed_attributes (primitive->mode,
- primitive->first_vertex,
- primitive->n_vertices,
- primitive->indices,
- primitive->attributes,
- primitive->n_attributes,
- flags);
- else
- _cogl_draw_attributes (primitive->mode,
- primitive->first_vertex,
- primitive->n_vertices,
- primitive->attributes,
- primitive->n_attributes,
- flags);
-}
-
-/* XXX: cogl_draw_primitive() ? */
-void
-cogl_primitive_draw (CoglPrimitive *primitive)
-{
- _cogl_primitive_draw (primitive, 0 /* no flags */);
-}
-
-void
cogl_primitive_foreach_attribute (CoglPrimitive *primitive,
CoglPrimitiveAttributeCallback callback,
void *user_data)
diff --git a/cogl/cogl-primitive.h b/cogl/cogl-primitive.h
index fa54fc6b..fea8fd60 100644
--- a/cogl/cogl-primitive.h
+++ b/cogl/cogl-primitive.h
@@ -803,18 +803,6 @@ CoglPrimitive *
cogl_primitive_copy (CoglPrimitive *primitive);
/**
- * cogl_primitive_draw:
- * @primitive: A #CoglPrimitive object
- *
- * Draw the given @primitive with the current source material.
- *
- * Since: 1.6
- * Stability: Unstable
- */
-void
-cogl_primitive_draw (CoglPrimitive *primitive);
-
-/**
* cogl_is_primitive:
* @object: A #CoglObject
*
diff --git a/cogl/cogl-primitives-private.h b/cogl/cogl-primitives-private.h
index debd90c5..49333967 100644
--- a/cogl/cogl-primitives-private.h
+++ b/cogl/cogl-primitives-private.h
@@ -33,7 +33,9 @@ G_BEGIN_DECLS
where the code may be called while the journal is already being
flushed. In that case using the journal would go wrong */
void
-_cogl_rectangle_immediate (float x_1,
+_cogl_rectangle_immediate (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ float x_1,
float y_1,
float x_2,
float y_2);
diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c
index 4a409163..d8328b0c 100644
--- a/cogl/cogl-primitives.c
+++ b/cogl/cogl-primitives.c
@@ -38,6 +38,7 @@
#include "cogl-attribute-private.h"
#include "cogl-private.h"
#include "cogl-meta-texture.h"
+#include "cogl-framebuffer-private.h"
#include <string.h>
#include <math.h>
@@ -839,7 +840,9 @@ cogl_rectangle (float x_1,
}
void
-_cogl_rectangle_immediate (float x_1,
+_cogl_rectangle_immediate (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ float x_1,
float y_1,
float x_2,
float y_2)
@@ -866,14 +869,17 @@ _cogl_rectangle_immediate (float x_1,
2, /* n_components */
COGL_ATTRIBUTE_TYPE_FLOAT);
- _cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
- 0, /* first_index */
- 4, /* n_vertices */
- attributes,
- 1,
- COGL_DRAW_SKIP_JOURNAL_FLUSH |
- COGL_DRAW_SKIP_PIPELINE_VALIDATION |
- COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
+ _cogl_framebuffer_draw_attributes (framebuffer,
+ pipeline,
+ COGL_VERTICES_MODE_TRIANGLE_STRIP,
+ 0, /* first_index */
+ 4, /* n_vertices */
+ attributes,
+ 1,
+ COGL_DRAW_SKIP_JOURNAL_FLUSH |
+ COGL_DRAW_SKIP_PIPELINE_VALIDATION |
+ COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
+ COGL_DRAW_SKIP_LEGACY_STATE);
cogl_object_unref (attributes[0]);
@@ -1093,12 +1099,21 @@ cogl_polygon (const CoglTextureVertex *vertices,
v,
ctx->polygon_vertices->len * sizeof (float));
+ /* XXX: although this may seem redundant, we need to do this since
+ * cogl_polygon() can be used with legacy state and its the source stack
+ * which track whether legacy state is enabled.
+ *
+ * (We only have a CoglDrawFlag to disable legacy state not one
+ * to enable it) */
cogl_push_source (pipeline);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
- 0, n_vertices,
- attributes,
- n_attributes);
+ _cogl_framebuffer_draw_attributes (cogl_get_draw_framebuffer (),
+ pipeline,
+ COGL_VERTICES_MODE_TRIANGLE_FAN,
+ 0, n_vertices,
+ attributes,
+ n_attributes,
+ 0 /* no draw flags */);
cogl_pop_source ();
diff --git a/cogl/cogl-vertex-buffer.c b/cogl/cogl-vertex-buffer.c
index be8c8190..ff795a1a 100644
--- a/cogl/cogl-vertex-buffer.c
+++ b/cogl/cogl-vertex-buffer.c
@@ -1618,9 +1618,18 @@ update_primitive_and_draw (CoglVertexBuffer *buffer,
pipeline_priv);
}
+ /* XXX: although this may seem redundant, we need to do this since
+ * CoglVertexBuffers can be used with legacy state and its the source stack
+ * which track whether legacy state is enabled.
+ *
+ * (We only have a CoglDrawFlag to disable legacy state not one
+ * to enable it) */
cogl_push_source (pipeline_priv->real_source);
- cogl_primitive_draw (buffer->primitive);
+ _cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
+ pipeline_priv->real_source,
+ buffer->primitive,
+ 0 /* no draw flags */);
cogl_pop_source ();
}
diff --git a/cogl/cogl2-path.c b/cogl/cogl2-path.c
index 781b8847..cd7e4534 100644
--- a/cogl/cogl2-path.c
+++ b/cogl/cogl2-path.c
@@ -230,10 +230,12 @@ _cogl_path_stroke_nodes (CoglPath *path)
{
node = &g_array_index (data->path_nodes, CoglPathNode, path_start);
- cogl_vdraw_attributes (COGL_VERTICES_MODE_LINE_STRIP,
- 0, node->path_size,
- data->stroke_attributes[path_num],
- NULL);
+ cogl_framebuffer_vdraw_attributes (cogl_get_draw_framebuffer (),
+ source,
+ COGL_VERTICES_MODE_LINE_STRIP,
+ 0, node->path_size,
+ data->stroke_attributes[path_num],
+ NULL);
path_num++;
}
@@ -322,8 +324,9 @@ void
_cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
{
gboolean needs_fallback = FALSE;
+ CoglPipeline *pipeline = cogl_get_source ();
- _cogl_pipeline_foreach_layer_internal (cogl_get_source (),
+ _cogl_pipeline_foreach_layer_internal (pipeline,
validate_layer_cb, &needs_fallback);
if (needs_fallback)
{
@@ -333,13 +336,15 @@ _cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
_cogl_path_build_fill_attribute_buffer (path);
- _cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- path->data->fill_vbo_n_indices,
- path->data->fill_vbo_indices,
- path->data->fill_attributes,
- COGL_PATH_N_ATTRIBUTES,
- flags);
+ _cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (),
+ pipeline,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ path->data->fill_vbo_n_indices,
+ path->data->fill_vbo_indices,
+ path->data->fill_attributes,
+ COGL_PATH_N_ATTRIBUTES,
+ flags);
}
void
diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-docs.xml.in b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-docs.xml.in
index be5b76c5..3f49e62e 100644
--- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-docs.xml.in
+++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-docs.xml.in
@@ -88,11 +88,6 @@
<title>Geometry</title>
<xi:include href="xml/cogl-primitive.xml"/>
<xi:include href="xml/cogl-paths.xml"/>
- </section>
-
- <section id="cogl-drawing-apis">
- <title>Drawing</title>
- <xi:include href="xml/cogl-drawing.xml"/>
<xi:include href="xml/cogl-rectangle.xml"/>
</section>
diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
index 50abc6f9..36f49193 100644
--- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
+++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
@@ -237,7 +237,6 @@ cogl_primitive_set_mode
cogl_primitive_set_attributes
cogl_primitive_get_indices
cogl_primitive_set_indices
-cogl_primitive_draw
cogl_primitive_copy
CoglPrimitiveAttributeCallback
cogl_primitive_foreach_attribute
@@ -307,15 +306,6 @@ cogl_path_stroke
</SECTION>
<SECTION>
-<FILE>cogl-drawing</FILE>
-<TITLE>Draw Vertex Attributes</TITLE>
-cogl_draw_vertex_attributes
-cogl_draw_vertex_attributes_array
-cogl_draw_indexed_vertex_attributes
-cogl_draw_indexed_vertex_attributes_array
-</SECTION>
-
-<SECTION>
<FILE>cogl-texture</FILE>
<TITLE>The Texture Interface</TITLE>
CoglTexture
@@ -419,6 +409,13 @@ cogl_framebuffer_set_point_samples_per_pixel
cogl_framebuffer_get_context
cogl_framebuffer_clear
cogl_framebuffer_clear4f
+
+<SUBSECTION>
+cogl_framebuffer_draw_primitive
+cogl_framebuffer_draw_attributes
+cogl_framebuffer_draw_indexed_attributes
+
+<SUBSECTION>
cogl_framebuffer_swap_buffers
cogl_framebuffer_swap_region
cogl_framebuffer_add_swap_buffers_callback
diff --git a/examples/cogl-crate.c b/examples/cogl-crate.c
index d157a18b..6b76a671 100644
--- a/examples/cogl-crate.c
+++ b/examples/cogl-crate.c
@@ -115,17 +115,7 @@ paint (Data *data)
cogl_framebuffer_rotate (fb, rotation, 0, 1, 0);
cogl_framebuffer_rotate (fb, rotation, 1, 0, 0);
- /* Whenever you draw something with Cogl using geometry defined by
- * one of cogl_rectangle, cogl_polygon, cogl_path or
- * cogl_vertex_buffer then you have a current pipeline that defines
- * how that geometry should be processed.
- *
- * Here we are making our crate pipeline current which will sample
- * the crate texture when fragment processing. */
- cogl_set_source (data->crate_pipeline);
-
- /* Give Cogl some geometry to draw. */
- cogl_primitive_draw (data->prim);
+ cogl_framebuffer_draw_primitive (fb, data->crate_pipeline, data->prim);
cogl_set_depth_test_enabled (FALSE);
diff --git a/examples/cogl-hello.c b/examples/cogl-hello.c
index 49055e72..5b8b2068 100644
--- a/examples/cogl-hello.c
+++ b/examples/cogl-hello.c
@@ -10,6 +10,7 @@ main (int argc, char **argv)
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
+ CoglPipeline *pipeline;
GError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0x80},
@@ -26,19 +27,20 @@ main (int argc, char **argv)
onscreen = cogl_onscreen_new (ctx, 640, 480);
cogl_onscreen_show (onscreen);
-
fb = COGL_FRAMEBUFFER (onscreen);
- cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
+
+ pipeline = cogl_pipeline_new ();
+
for (;;) {
CoglPollFD *poll_fds;
int n_poll_fds;
gint64 timeout;
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
- cogl_primitive_draw (triangle);
+ cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_swap_buffers (fb);
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
diff --git a/examples/cogl-msaa.c b/examples/cogl-msaa.c
index d89ecfe7..7316e538 100644
--- a/examples/cogl-msaa.c
+++ b/examples/cogl-msaa.c
@@ -77,8 +77,6 @@ main (int argc, char **argv)
cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
}
- cogl_push_framebuffer (fb);
-
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new ();
@@ -93,12 +91,11 @@ main (int argc, char **argv)
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_scale (fb, 0.5, 1, 1);
cogl_framebuffer_translate (fb, -1, 0, 0);
- cogl_set_source (pipeline);
- cogl_primitive_draw (triangle);
+ cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_pop_matrix (fb);
cogl_push_framebuffer (offscreen_fb);
- cogl_primitive_draw (triangle);
+ cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_resolve_samples (offscreen_fb);
cogl_pop_framebuffer ();
diff --git a/examples/cogl-sdl-hello.c b/examples/cogl-sdl-hello.c
index e0ca7aa5..db899abb 100644
--- a/examples/cogl-sdl-hello.c
+++ b/examples/cogl-sdl-hello.c
@@ -9,6 +9,7 @@
typedef struct Data
{
CoglPrimitive *triangle;
+ CoglPipeline *pipeline;
float center_x, center_y;
CoglFramebuffer *fb;
gboolean quit;
@@ -24,7 +25,7 @@ redraw (Data *data)
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);
- cogl_primitive_draw (data->triangle);
+ cogl_framebuffer_draw_primitive (fb, data->pipeline, data->triangle);
cogl_framebuffer_pop_matrix (fb);
cogl_framebuffer_swap_buffers (fb);
@@ -147,10 +148,9 @@ main (int argc, char **argv)
cogl_onscreen_show (onscreen);
- cogl_push_framebuffer (data.fb);
-
data.triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
+ data.pipeline = cogl_pipeline_new ();
while (!data.quit)
{
CoglPollFD *poll_fds;
@@ -173,8 +173,6 @@ main (int argc, char **argv)
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
}
- cogl_pop_framebuffer ();
-
cogl_object_unref (ctx);
cogl_object_unref (display);
cogl_object_unref (renderer);
diff --git a/examples/cogl-x11-foreign.c b/examples/cogl-x11-foreign.c
index 00dbb1f5..0113130e 100644
--- a/examples/cogl-x11-foreign.c
+++ b/examples/cogl-x11-foreign.c
@@ -42,6 +42,7 @@ main (int argc, char **argv)
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
+ CoglPipeline *pipeline;
GError *error = NULL;
guint32 visual;
XVisualInfo template, *xvisinfo;
@@ -147,10 +148,10 @@ main (int argc, char **argv)
XMapWindow (xdpy, xwin);
fb = COGL_FRAMEBUFFER (onscreen);
- cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
+ pipeline = cogl_pipeline_new ();
for (;;)
{
CoglPollFD *poll_fds;
@@ -170,7 +171,7 @@ main (int argc, char **argv)
cogl_xlib_renderer_handle_event (renderer, &event);
}
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
- cogl_primitive_draw (triangle);
+ cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_swap_buffers (fb);
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
diff --git a/examples/cogland.c b/examples/cogland.c
index a91e3f09..4f37d837 100644
--- a/examples/cogland.c
+++ b/examples/cogland.c
@@ -80,6 +80,7 @@ struct _CoglandCompositor
GQueue frame_callbacks;
CoglPrimitive *triangle;
+ CoglPipeline *triangle_pipeline;
GSource *wayland_event_source;
@@ -512,7 +513,8 @@ paint_cb (void *user_data)
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
- cogl_primitive_draw (compositor->triangle);
+ cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline,
+ compositor->triangle);
for (l2 = compositor->surfaces; l2; l2 = l2->next)
{
@@ -751,6 +753,7 @@ main (int argc, char **argv)
compositor.triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
+ compositor.triangle_pipeline = cogl_pipeline_new ();
g_timeout_add (16, paint_cb, &compositor);
diff --git a/tests/conform/test-custom-attributes.c b/tests/conform/test-custom-attributes.c
index bc3d09fa..adbb4f05 100644
--- a/tests/conform/test-custom-attributes.c
+++ b/tests/conform/test-custom-attributes.c
@@ -6,6 +6,7 @@
typedef struct _TestState
{
+ CoglFramebuffer *fb;
CoglPipeline *pipeline;
} TestState;
@@ -57,21 +58,19 @@ test_float_verts (TestState *state, int offset_x, int offset_y)
4, /* n_components */
COGL_ATTRIBUTE_TYPE_FLOAT);
- cogl_push_source (state->pipeline);
-
cogl_push_matrix ();
cogl_translate (offset_x, offset_y, 0.0f);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- 6, /* n_vertices */
- attributes,
- 2 /* n_attributes */);
+ cogl_framebuffer_draw_attributes (state->fb,
+ state->pipeline,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ 6, /* n_vertices */
+ attributes,
+ 2 /* n_attributes */);
cogl_pop_matrix ();
- cogl_pop_source ();
-
cogl_object_unref (attributes[1]);
cogl_object_unref (attributes[0]);
cogl_object_unref (buffer);
@@ -119,16 +118,16 @@ test_byte_verts (TestState *state, int offset_x, int offset_y)
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
cogl_attribute_set_normalized (attributes[1], TRUE);
- cogl_push_source (state->pipeline);
-
cogl_push_matrix ();
cogl_translate (offset_x, offset_y, 0.0f);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- 6, /* n_vertices */
- attributes,
- 2 /* n_attributes */);
+ cogl_framebuffer_draw_attributes (state->fb,
+ state->pipeline,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ 6, /* n_vertices */
+ attributes,
+ 2 /* n_attributes */);
cogl_object_unref (attributes[1]);
@@ -144,16 +143,16 @@ test_byte_verts (TestState *state, int offset_x, int offset_y)
cogl_translate (20, 0, 0);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- 3, /* n_vertices */
- attributes,
- 2 /* n_attributes */);
+ cogl_framebuffer_draw_attributes (state->fb,
+ state->pipeline,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ 3, /* n_vertices */
+ attributes,
+ 2 /* n_attributes */);
cogl_pop_matrix ();
- cogl_pop_source ();
-
cogl_object_unref (attributes[0]);
cogl_object_unref (attributes[1]);
cogl_object_unref (buffer);
@@ -200,21 +199,19 @@ test_short_verts (TestState *state, int offset_x, int offset_y)
2, /* n_components */
COGL_ATTRIBUTE_TYPE_SHORT);
- cogl_push_source (pipeline);
-
cogl_push_matrix ();
cogl_translate (offset_x + 10.0f, offset_y + 10.0f, 0.0f);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- 3, /* n_vertices */
- attributes,
- 1 /* n_attributes */);
+ cogl_framebuffer_draw_attributes (state->fb,
+ pipeline,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ 3, /* n_vertices */
+ attributes,
+ 1 /* n_attributes */);
cogl_pop_matrix ();
- cogl_pop_source ();
-
cogl_object_unref (attributes[0]);
/* Test again treating the attribute as unsigned */
@@ -228,21 +225,19 @@ test_short_verts (TestState *state, int offset_x, int offset_y)
pipeline2 = cogl_pipeline_copy (pipeline);
cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255);
- cogl_push_source (pipeline2);
-
cogl_push_matrix ();
cogl_translate (offset_x + 10.0f - 65525.0f, offset_y - 65525, 0.0f);
- cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
- 0, /* first_vertex */
- 3, /* n_vertices */
- attributes,
- 1 /* n_attributes */);
+ cogl_framebuffer_draw_attributes (state->fb,
+ pipeline2,
+ COGL_VERTICES_MODE_TRIANGLES,
+ 0, /* first_vertex */
+ 3, /* n_vertices */
+ attributes,
+ 1 /* n_attributes */);
cogl_pop_matrix ();
- cogl_pop_source ();
-
cogl_object_unref (attributes[0]);
cogl_object_unref (pipeline2);
@@ -277,6 +272,7 @@ test_cogl_custom_attributes (TestUtilsGTestFixture *fixture,
{
CoglSnippet *snippet;
TestState state;
+ state.fb = shared_state->fb;
cogl_ortho (/* left, right */
0, cogl_framebuffer_get_width (shared_state->fb),
diff --git a/tests/conform/test-primitive.c b/tests/conform/test-primitive.c
index e24e7e38..bed5c1d1 100644
--- a/tests/conform/test-primitive.c
+++ b/tests/conform/test-primitive.c
@@ -177,9 +177,7 @@ test_paint (TestState *state)
(PRIM_COLOR >> 8) & 0xff,
(PRIM_COLOR >> 0) & 0xff);
cogl_pipeline_set_layer_texture (pipeline, 0, tex);
- cogl_handle_unref (tex);
- cogl_set_source (pipeline);
- cogl_object_unref (pipeline);
+ cogl_object_unref (tex);
for (i = 0; i < G_N_ELEMENTS (test_prim_funcs); i++)
{
@@ -190,13 +188,15 @@ test_paint (TestState *state)
cogl_push_matrix ();
cogl_translate (i * 10, 0, 0);
- cogl_primitive_draw (prim);
+ cogl_framebuffer_draw_primitive (state->fb, pipeline, prim);
cogl_pop_matrix ();
test_utils_check_pixel (i * 10 + 2, 2, expected_color);
cogl_object_unref (prim);
}
+
+ cogl_object_unref (pipeline);
}
static gboolean