buffer: adds immutable ref/unref mechanism

This adds an internal mechanism to mark that a buffer is in-use so that
a warning can be generated if the user attempts to modify the buffer.

The plans is for the journal to use this mechanism so that we can warn
users about mid-scene modifications of buffers.
This commit is contained in:
Robert Bragg 2010-10-26 19:08:51 +01:00
parent 7cc6dedea4
commit 7901e30aac
2 changed files with 48 additions and 2 deletions

View File

@ -95,6 +95,8 @@ struct _CoglBuffer
* points to allocated memory in the
* fallback paths */
int immutable_ref;
guint store_created:1;
};
@ -137,6 +139,12 @@ GLenum
_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
CoglBufferUpdateHint update_hint);
CoglBuffer *
_cogl_buffer_immutable_ref (CoglBuffer *buffer);
void
_cogl_buffer_immutable_unref (CoglBuffer *buffer);
G_END_DECLS
#endif /* __COGL_BUFFER_PRIVATE_H__ */

View File

@ -275,6 +275,7 @@ _cogl_buffer_initialize (CoglBuffer *buffer,
buffer->usage_hint = usage_hint;
buffer->update_hint = update_hint;
buffer->data = NULL;
buffer->immutable_ref = 0;
if (use_malloc)
{
@ -299,6 +300,7 @@ void
_cogl_buffer_fini (CoglBuffer *buffer)
{
g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED));
g_return_if_fail (buffer->immutable_ref == 0);
}
/* OpenGL ES 1.1 and 2 have a GL_OES_mapbuffer extension that is able to map
@ -428,13 +430,27 @@ cogl_buffer_get_update_hint (CoglBuffer *buffer)
return buffer->update_hint;
}
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;
}
}
guint8 *
cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access,
CoglBufferMapHint hints)
{
if (!cogl_is_buffer (buffer))
return NULL;
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
if (G_UNLIKELY (buffer->immutable_ref))
warn_about_midscene_changes ();
if (buffer->flags & COGL_BUFFER_FLAG_MAPPED)
return buffer->data;
@ -464,5 +480,27 @@ cogl_buffer_set_data (CoglBuffer *buffer,
g_return_val_if_fail (cogl_is_buffer (buffer), FALSE);
g_return_val_if_fail ((offset + size) <= buffer->size, FALSE);
if (G_UNLIKELY (buffer->immutable_ref))
warn_about_midscene_changes ();
return buffer->vtable.set_data (buffer, offset, data, size);
}
CoglBuffer *
_cogl_buffer_immutable_ref (CoglBuffer *buffer)
{
g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
buffer->immutable_ref++;
return buffer;
}
void
_cogl_buffer_immutable_unref (CoglBuffer *buffer)
{
g_return_if_fail (cogl_is_buffer (buffer));
g_return_if_fail (buffer->immutable_ref > 0);
buffer->immutable_ref--;
}