[cogl] cogl-journal: Use a pool of vertex arrays
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl] cogl-journal: Use a pool of vertex arrays
- Date: Wed, 1 Jun 2011 13:39:47 +0000 (UTC)
commit efadc439a46206252c279a1cef72cdaab673107c
Author: Neil Roberts <neil linux intel com>
Date: Wed Jun 1 14:30:45 2011 +0100
cogl-journal: Use a pool of vertex arrays
Previously whenever the journal is flushed a new vertex array would be
created to contain the vertices. To avoid the overhead of reallocating
a buffer every time, this patch makes it use a pool of 8 buffers which
are cycled in turn. The buffers are never destroyed but instead the
data is replaced. The journal should only ever be using one buffer at
a time but we cache more than one buffer anyway in case the GL driver
is internally using the buffer in which case mapping the buffer may
cause it to create a new buffer anyway.
cogl/cogl-journal-private.h | 12 +++++++++
cogl/cogl-journal.c | 58 +++++++++++++++++++++++++++++++++++++-----
2 files changed, 63 insertions(+), 7 deletions(-)
---
diff --git a/cogl/cogl-journal-private.h b/cogl/cogl-journal-private.h
index 7212dca..6eb7a2d 100644
--- a/cogl/cogl-journal-private.h
+++ b/cogl/cogl-journal-private.h
@@ -28,6 +28,8 @@
#include "cogl-handle.h"
#include "cogl-clip-stack.h"
+#define COGL_JOURNAL_VBO_POOL_SIZE 8
+
typedef struct _CoglJournal
{
CoglObject _parent;
@@ -36,6 +38,16 @@ typedef struct _CoglJournal
GArray *vertices;
size_t needed_vbo_len;
+ /* A pool of attribute buffers is used so that we can avoid repeatedly
+ reallocating buffers. Only one of these buffers at a time will be
+ used by Cogl but we keep more than one alive anyway in case the
+ GL driver is internally using the buffer and it would have to
+ allocate a new one when we start writing to it */
+ CoglAttributeBuffer *vbo_pool[COGL_JOURNAL_VBO_POOL_SIZE];
+ /* The next vbo to use from the pool. We just cycle through them in
+ order */
+ unsigned int next_vbo_in_pool;
+
int fast_read_pixel_count;
} CoglJournal;
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index a2180be..cb378bb 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -125,10 +125,17 @@ COGL_OBJECT_DEFINE (Journal, journal);
static void
_cogl_journal_free (CoglJournal *journal)
{
+ int i;
+
if (journal->entries)
g_array_free (journal->entries, TRUE);
if (journal->vertices)
g_array_free (journal->vertices, TRUE);
+
+ for (i = 0; i < COGL_JOURNAL_VBO_POOL_SIZE; i++)
+ if (journal->vbo_pool[i])
+ cogl_object_unref (journal->vbo_pool[i]);
+
g_slice_free (CoglJournal, journal);
}
@@ -1095,8 +1102,44 @@ compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
return entry0->clip_stack == entry1->clip_stack;
}
+/* Gets a new vertex array from the pool. A reference is taken on the
+ array so it can be treated as if it was just newly allocated */
+static CoglAttributeBuffer *
+create_attribute_buffer (CoglJournal *journal,
+ gsize n_bytes)
+{
+ CoglAttributeBuffer *vbo;
+
+ /* If CoglBuffers are being emulated with malloc then there's not
+ really any point in using the pool so we'll just allocate the
+ buffer directly */
+ if (!cogl_features_available (COGL_FEATURE_VBOS))
+ return cogl_attribute_buffer_new (n_bytes, NULL);
+
+ vbo = journal->vbo_pool[journal->next_vbo_in_pool];
+
+ if (vbo == NULL)
+ {
+ vbo = cogl_attribute_buffer_new (n_bytes, NULL);
+ journal->vbo_pool[journal->next_vbo_in_pool] = vbo;
+ }
+ else if (cogl_buffer_get_size (COGL_BUFFER (vbo)) < n_bytes)
+ {
+ /* If the buffer is too small then we'll just recreate it */
+ cogl_object_unref (vbo);
+ vbo = cogl_attribute_buffer_new (n_bytes, NULL);
+ journal->vbo_pool[journal->next_vbo_in_pool] = vbo;
+ }
+
+ journal->next_vbo_in_pool = ((journal->next_vbo_in_pool + 1) %
+ COGL_JOURNAL_VBO_POOL_SIZE);
+
+ return cogl_object_ref (vbo);
+}
+
static CoglAttributeBuffer *
-upload_vertices (const CoglJournalEntry *entries,
+upload_vertices (CoglJournal *journal,
+ const CoglJournalEntry *entries,
int n_entries,
size_t needed_vbo_len,
GArray *vertices)
@@ -1110,7 +1153,7 @@ upload_vertices (const CoglJournalEntry *entries,
g_assert (needed_vbo_len);
- attribute_buffer = cogl_attribute_buffer_new (needed_vbo_len * 4, NULL);
+ attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4);
buffer = COGL_BUFFER (attribute_buffer);
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC);
@@ -1343,11 +1386,12 @@ _cogl_journal_flush (CoglJournal *journal,
/* We upload the vertices after the clip stack pass in case it
modifies the entries */
- state.attribute_buffer = upload_vertices (&g_array_index (journal->entries,
- CoglJournalEntry, 0),
- journal->entries->len,
- journal->needed_vbo_len,
- journal->vertices);
+ state.attribute_buffer =
+ upload_vertices (journal,
+ &g_array_index (journal->entries, CoglJournalEntry, 0),
+ journal->entries->len,
+ journal->needed_vbo_len,
+ journal->vertices);
state.array_offset = 0;
/* batch_and_call() batches a list of journal entries according to some
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]