mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +00: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-handle.h"
|
||||||
#include "cogl-clip-stack.h"
|
#include "cogl-clip-stack.h"
|
||||||
|
|
||||||
|
#define COGL_JOURNAL_VBO_POOL_SIZE 8
|
||||||
|
|
||||||
typedef struct _CoglJournal
|
typedef struct _CoglJournal
|
||||||
{
|
{
|
||||||
CoglObject _parent;
|
CoglObject _parent;
|
||||||
@ -36,6 +38,16 @@ typedef struct _CoglJournal
|
|||||||
GArray *vertices;
|
GArray *vertices;
|
||||||
size_t needed_vbo_len;
|
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;
|
int fast_read_pixel_count;
|
||||||
|
|
||||||
} CoglJournal;
|
} CoglJournal;
|
||||||
|
@ -125,10 +125,17 @@ COGL_OBJECT_DEFINE (Journal, journal);
|
|||||||
static void
|
static void
|
||||||
_cogl_journal_free (CoglJournal *journal)
|
_cogl_journal_free (CoglJournal *journal)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (journal->entries)
|
if (journal->entries)
|
||||||
g_array_free (journal->entries, TRUE);
|
g_array_free (journal->entries, TRUE);
|
||||||
if (journal->vertices)
|
if (journal->vertices)
|
||||||
g_array_free (journal->vertices, TRUE);
|
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);
|
g_slice_free (CoglJournal, journal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1095,8 +1102,44 @@ compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
|
|||||||
return entry0->clip_stack == entry1->clip_stack;
|
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 *
|
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,
|
int n_entries,
|
||||||
size_t needed_vbo_len,
|
size_t needed_vbo_len,
|
||||||
GArray *vertices)
|
GArray *vertices)
|
||||||
@ -1110,7 +1153,7 @@ upload_vertices (const CoglJournalEntry *entries,
|
|||||||
|
|
||||||
g_assert (needed_vbo_len);
|
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);
|
buffer = COGL_BUFFER (attribute_buffer);
|
||||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC);
|
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
|
/* We upload the vertices after the clip stack pass in case it
|
||||||
modifies the entries */
|
modifies the entries */
|
||||||
state.attribute_buffer = upload_vertices (&g_array_index (journal->entries,
|
state.attribute_buffer =
|
||||||
CoglJournalEntry, 0),
|
upload_vertices (journal,
|
||||||
journal->entries->len,
|
&g_array_index (journal->entries, CoglJournalEntry, 0),
|
||||||
journal->needed_vbo_len,
|
journal->entries->len,
|
||||||
journal->vertices);
|
journal->needed_vbo_len,
|
||||||
|
journal->vertices);
|
||||||
state.array_offset = 0;
|
state.array_offset = 0;
|
||||||
|
|
||||||
/* batch_and_call() batches a list of journal entries according to some
|
/* batch_and_call() batches a list of journal entries according to some
|
||||||
|
Loading…
x
Reference in New Issue
Block a user