diff --git a/cogl/cogl-primitive-private.h b/cogl/cogl-primitive-private.h index e3de65f69..15694891a 100644 --- a/cogl/cogl-primitive-private.h +++ b/cogl/cogl-primitive-private.h @@ -40,7 +40,15 @@ struct _CoglPrimitive int n_vertices; CoglIndices *indices; GArray *attributes; + + int immutable_ref; }; +CoglPrimitive * +_cogl_primitive_immutable_ref (CoglPrimitive *primitive); + +void +_cogl_primitive_immutable_unref (CoglPrimitive *primitive); + #endif /* __COGL_PRIMITIVE_PRIVATE_H */ diff --git a/cogl/cogl-primitive.c b/cogl/cogl-primitive.c index 85b0a53f1..709ec86b6 100644 --- a/cogl/cogl-primitive.c +++ b/cogl/cogl-primitive.c @@ -32,6 +32,7 @@ #include "cogl-object-private.h" #include "cogl-primitive.h" #include "cogl-primitive-private.h" +#include "cogl-vertex-attribute-private.h" #include @@ -54,6 +55,7 @@ cogl_primitive_new_with_attributes_array (CoglVerticesMode mode, primitive->indices = NULL; primitive->attributes = g_array_new (TRUE, FALSE, sizeof (CoglVertexAttribute *)); + primitive->immutable_ref = 0; for (i = 0; attributes[i]; i++) { @@ -366,12 +368,32 @@ _cogl_primitive_free (CoglPrimitive *primitive) g_slice_free (CoglPrimitive, primitive); } +static void +warn_about_midscene_changes (void) +{ + static gboolean seen = FALSE; + if (!seen) + { + g_warning ("Mid-scene modification of buffers has " + "undefined results\n"); + seen = TRUE; + } +} + void cogl_primitive_set_attributes (CoglPrimitive *primitive, CoglVertexAttribute **attributes) { int i; + g_return_if_fail (cogl_is_primitive (primitive)); + + if (G_UNLIKELY (primitive->immutable_ref)) + { + warn_about_midscene_changes (); + return; + } + free_attributes_list (primitive); g_array_set_size (primitive->attributes, 0); @@ -397,6 +419,12 @@ cogl_primitive_set_first_vertex (CoglPrimitive *primitive, { g_return_if_fail (cogl_is_primitive (primitive)); + if (G_UNLIKELY (primitive->immutable_ref)) + { + warn_about_midscene_changes (); + return; + } + primitive->first_vertex = first_vertex; } @@ -431,6 +459,12 @@ cogl_primitive_set_mode (CoglPrimitive *primitive, { g_return_if_fail (cogl_is_primitive (primitive)); + if (G_UNLIKELY (primitive->immutable_ref)) + { + warn_about_midscene_changes (); + return; + } + primitive->mode = mode; } @@ -440,6 +474,12 @@ cogl_primitive_set_indices (CoglPrimitive *primitive, { g_return_if_fail (cogl_is_primitive (primitive)); + if (G_UNLIKELY (primitive->immutable_ref)) + { + warn_about_midscene_changes (); + return; + } + if (indices) cogl_object_ref (indices); if (primitive->indices) @@ -447,6 +487,43 @@ cogl_primitive_set_indices (CoglPrimitive *primitive, primitive->indices = indices; } +CoglPrimitive * +_cogl_primitive_immutable_ref (CoglPrimitive *primitive) +{ + int i; + + g_return_val_if_fail (cogl_is_primitive (primitive), NULL); + + primitive->immutable_ref++; + + for (i = 0; i < primitive->attributes->len; i++) + { + CoglVertexAttribute *attribute = + g_array_index (primitive->attributes, CoglVertexAttribute *, i); + _cogl_vertex_attribute_immutable_ref (attribute); + } + + return primitive; +} + +void +_cogl_primitive_immutable_unref (CoglPrimitive *primitive) +{ + int i; + + g_return_if_fail (cogl_is_primitive (primitive)); + g_return_if_fail (primitive->immutable_ref > 0); + + primitive->immutable_ref--; + + for (i = 0; i < primitive->attributes->len; i++) + { + CoglVertexAttribute *attribute = + g_array_index (primitive->attributes, CoglVertexAttribute *, i); + _cogl_vertex_attribute_immutable_unref (attribute); + } +} + /* XXX: cogl_draw_primitive() ? */ void cogl_primitive_draw (CoglPrimitive *primitive)