mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
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.
This commit is contained in:
parent
54f94a0ed0
commit
efadc439a4
@ -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;
|
||||
|
@ -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 *
|
||||
upload_vertices (const CoglJournalEntry *entries,
|
||||
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 (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
|
||||
|
Loading…
Reference in New Issue
Block a user