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 * points to allocated memory in the
* fallback paths */ * fallback paths */
int immutable_ref;
guint store_created:1; guint store_created:1;
}; };
@ -137,6 +139,12 @@ GLenum
_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint, _cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
CoglBufferUpdateHint update_hint); CoglBufferUpdateHint update_hint);
CoglBuffer *
_cogl_buffer_immutable_ref (CoglBuffer *buffer);
void
_cogl_buffer_immutable_unref (CoglBuffer *buffer);
G_END_DECLS G_END_DECLS
#endif /* __COGL_BUFFER_PRIVATE_H__ */ #endif /* __COGL_BUFFER_PRIVATE_H__ */

View File

@ -275,6 +275,7 @@ _cogl_buffer_initialize (CoglBuffer *buffer,
buffer->usage_hint = usage_hint; buffer->usage_hint = usage_hint;
buffer->update_hint = update_hint; buffer->update_hint = update_hint;
buffer->data = NULL; buffer->data = NULL;
buffer->immutable_ref = 0;
if (use_malloc) if (use_malloc)
{ {
@ -299,6 +300,7 @@ void
_cogl_buffer_fini (CoglBuffer *buffer) _cogl_buffer_fini (CoglBuffer *buffer)
{ {
g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); 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 /* 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; 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 * guint8 *
cogl_buffer_map (CoglBuffer *buffer, cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access, CoglBufferAccess access,
CoglBufferMapHint hints) CoglBufferMapHint hints)
{ {
if (!cogl_is_buffer (buffer)) g_return_val_if_fail (cogl_is_buffer (buffer), NULL);
return NULL;
if (G_UNLIKELY (buffer->immutable_ref))
warn_about_midscene_changes ();
if (buffer->flags & COGL_BUFFER_FLAG_MAPPED) if (buffer->flags & COGL_BUFFER_FLAG_MAPPED)
return buffer->data; 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 (cogl_is_buffer (buffer), FALSE);
g_return_val_if_fail ((offset + size) <= buffer->size, 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); 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--;
}