primitive: adds immutable ref/unref mechanism

This adds a way to mark that a primitive is in use so that modifications
will generate a warning. The plan is to use this mechanism when batching
primitives in the journal to warn users that mid-scene modifications of
primitives is not allowed.
This commit is contained in:
Robert Bragg 2010-10-26 18:57:33 +01:00
parent a03a5814e7
commit b03f905094
2 changed files with 85 additions and 0 deletions

View File

@ -40,7 +40,15 @@ struct _CoglPrimitive
int n_vertices; int n_vertices;
CoglIndices *indices; CoglIndices *indices;
GArray *attributes; GArray *attributes;
int immutable_ref;
}; };
CoglPrimitive *
_cogl_primitive_immutable_ref (CoglPrimitive *primitive);
void
_cogl_primitive_immutable_unref (CoglPrimitive *primitive);
#endif /* __COGL_PRIMITIVE_PRIVATE_H */ #endif /* __COGL_PRIMITIVE_PRIVATE_H */

View File

@ -32,6 +32,7 @@
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-primitive.h" #include "cogl-primitive.h"
#include "cogl-primitive-private.h" #include "cogl-primitive-private.h"
#include "cogl-vertex-attribute-private.h"
#include <stdarg.h> #include <stdarg.h>
@ -54,6 +55,7 @@ cogl_primitive_new_with_attributes_array (CoglVerticesMode mode,
primitive->indices = NULL; primitive->indices = NULL;
primitive->attributes = primitive->attributes =
g_array_new (TRUE, FALSE, sizeof (CoglVertexAttribute *)); g_array_new (TRUE, FALSE, sizeof (CoglVertexAttribute *));
primitive->immutable_ref = 0;
for (i = 0; attributes[i]; i++) for (i = 0; attributes[i]; i++)
{ {
@ -366,12 +368,32 @@ _cogl_primitive_free (CoglPrimitive *primitive)
g_slice_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 void
cogl_primitive_set_attributes (CoglPrimitive *primitive, cogl_primitive_set_attributes (CoglPrimitive *primitive,
CoglVertexAttribute **attributes) CoglVertexAttribute **attributes)
{ {
int i; 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); free_attributes_list (primitive);
g_array_set_size (primitive->attributes, 0); 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)); g_return_if_fail (cogl_is_primitive (primitive));
if (G_UNLIKELY (primitive->immutable_ref))
{
warn_about_midscene_changes ();
return;
}
primitive->first_vertex = first_vertex; primitive->first_vertex = first_vertex;
} }
@ -431,6 +459,12 @@ cogl_primitive_set_mode (CoglPrimitive *primitive,
{ {
g_return_if_fail (cogl_is_primitive (primitive)); g_return_if_fail (cogl_is_primitive (primitive));
if (G_UNLIKELY (primitive->immutable_ref))
{
warn_about_midscene_changes ();
return;
}
primitive->mode = mode; primitive->mode = mode;
} }
@ -440,6 +474,12 @@ cogl_primitive_set_indices (CoglPrimitive *primitive,
{ {
g_return_if_fail (cogl_is_primitive (primitive)); g_return_if_fail (cogl_is_primitive (primitive));
if (G_UNLIKELY (primitive->immutable_ref))
{
warn_about_midscene_changes ();
return;
}
if (indices) if (indices)
cogl_object_ref (indices); cogl_object_ref (indices);
if (primitive->indices) if (primitive->indices)
@ -447,6 +487,43 @@ cogl_primitive_set_indices (CoglPrimitive *primitive,
primitive->indices = indices; 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() ? */ /* XXX: cogl_draw_primitive() ? */
void void
cogl_primitive_draw (CoglPrimitive *primitive) cogl_primitive_draw (CoglPrimitive *primitive)