mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-03 14:48:06 +02:00
[gl] Allocate small number of rectangles on the stack
FillRectangle is most frequently used to fill an entire imagee with the background colour, i.e. with just a single, or few, rectangle. Avoid heap allocation for this common case by allocating enough space for 4 rectangles (vertices+colors) on the stack.
This commit is contained in:
parent
6ce200da9d
commit
769f4a4f47
1 changed files with 29 additions and 14 deletions
|
|
@ -1522,7 +1522,10 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface,
|
|||
cairo_rectangle_int_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
#define N_STACK_RECTS 4
|
||||
cairo_gl_surface_t *surface = abstract_surface;
|
||||
GLfloat vertices_stack[N_STACK_RECTS*4*2];
|
||||
GLfloat colors_stack[N_STACK_RECTS*4*4]
|
||||
cairo_gl_context_t *ctx;
|
||||
int i;
|
||||
GLfloat *vertices;
|
||||
|
|
@ -1536,23 +1539,32 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface,
|
|||
_cairo_gl_set_destination (surface);
|
||||
_cairo_gl_set_operator (surface, op);
|
||||
|
||||
vertices = _cairo_malloc_ab (num_rects, sizeof (GLfloat) * 4 * 2);
|
||||
colors = _cairo_malloc_ab (num_rects, sizeof (GLfloat) * 4 * 4);
|
||||
if (!vertices || !colors) {
|
||||
_cairo_gl_context_release (ctx);
|
||||
free (vertices);
|
||||
free (colors);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
if (num_rects > N_STACK_RECTS) {
|
||||
vertices = _cairo_malloc_ab (num_rects, sizeof (GLfloat) * 4 * 2);
|
||||
colors = _cairo_malloc_ab (num_rects, sizeof (GLfloat) * 4 * 4);
|
||||
if (!vertices || !colors) {
|
||||
_cairo_gl_context_release (ctx);
|
||||
free (vertices);
|
||||
free (colors);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
} else {
|
||||
vertices = vertices_stack;
|
||||
colors = colors_stack;
|
||||
}
|
||||
|
||||
/* This should be loaded in as either a blend constant and an operator
|
||||
* setup specific to this, or better, a fragment shader constant.
|
||||
*/
|
||||
for (i = 0; i < num_rects * 4; i++) {
|
||||
colors[i * 4 + 0] = color->red * color->alpha;
|
||||
colors[i * 4 + 1] = color->green * color->alpha;
|
||||
colors[i * 4 + 2] = color->blue * color->alpha;
|
||||
colors[i * 4 + 3] = color->alpha;
|
||||
colors[0] = color->red * color->alpha;
|
||||
colors[1] = color->green * color->alpha;
|
||||
colors[2] = color->blue * color->alpha;
|
||||
colors[3] = color->alpha;
|
||||
for (i = 1; i < num_rects * 4; i++) {
|
||||
colors[i*4 + 0] = colors[0];
|
||||
colors[i*4 + 1] = colors[1];
|
||||
colors[i*4 + 2] = colors[2];
|
||||
colors[i*4 + 3] = colors[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
|
|
@ -1570,6 +1582,7 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface,
|
|||
glEnableClientState (GL_VERTEX_ARRAY);
|
||||
glColorPointer (4, GL_FLOAT, sizeof (GLfloat)*4, colors);
|
||||
glEnableClientState (GL_COLOR_ARRAY);
|
||||
|
||||
glDrawArrays (GL_QUADS, 0, 4 * num_rects);
|
||||
|
||||
glDisableClientState (GL_COLOR_ARRAY);
|
||||
|
|
@ -1577,8 +1590,10 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface,
|
|||
glDisable (GL_BLEND);
|
||||
|
||||
_cairo_gl_context_release (ctx);
|
||||
free (vertices);
|
||||
free (colors);
|
||||
if (vertices != vertices_stack)
|
||||
free (vertices);
|
||||
if (colors != colors_stack)
|
||||
free (colors);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue