diff options
author | Benjamin Otte <otte@redhat.com> | 2010-05-18 21:56:55 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-05-20 11:02:48 +0200 |
commit | 0d2d4c59026c31da084e6797d109a230341b396d (patch) | |
tree | fa48cf82f45e2a16d22a6f12e2886f9a52902eef | |
parent | b70eb275c4aa54f7c90a985b5de67da12ac08a30 (diff) |
gl: Detect color-pattern clears of surfaces
... and use glClear() there.
The common case here is a solid color and OPERATOR_OVER.
-rw-r--r-- | src/cairo-gl-private.h | 3 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 38 |
2 files changed, 29 insertions, 12 deletions
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 66c9165b..7a435678 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -264,9 +264,6 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t * cairo_private cairo_bool_t _cairo_gl_operator_is_supported (cairo_operator_t op); -cairo_private cairo_status_t -_cairo_gl_surface_clear (cairo_gl_surface_t *surface); - cairo_private void _cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op, cairo_bool_t component_alpha); diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index b8235949..dd4b35d4 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -350,21 +350,33 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx, return &surface->base; } -cairo_status_t -_cairo_gl_surface_clear (cairo_gl_surface_t *surface) +static cairo_status_t +_cairo_gl_surface_clear (cairo_gl_surface_t *surface, + const cairo_color_t *color) { cairo_gl_context_t *ctx; cairo_status_t status; + double r, g, b, a; status = _cairo_gl_context_acquire (surface->base.device, &ctx); if (unlikely (status)) return status; _cairo_gl_context_set_destination (ctx, surface); - if (surface->base.content == CAIRO_CONTENT_COLOR) - glClearColor (0.0, 0.0, 0.0, 1.0); - else - glClearColor (0.0, 0.0, 0.0, 0.0); + if (surface->base.content & CAIRO_CONTENT_COLOR) { + r = color->red * color->alpha; + g = color->green * color->alpha; + b = color->blue * color->alpha; + } else { + r = g = b = 0; + } + if (surface->base.content & CAIRO_CONTENT_ALPHA) { + a = color->alpha; + } else { + a = 1.0; + } + + glClearColor (r, g, b, a); glClear (GL_COLOR_BUFFER_BIT); _cairo_gl_context_release (ctx); @@ -406,7 +418,7 @@ cairo_gl_surface_create (cairo_device_t *abstract_device, } /* Cairo surfaces start out initialized to transparent (black) */ - status = _cairo_gl_surface_clear (surface); + status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT); if (unlikely (status)) { cairo_surface_destroy (&surface->base); _cairo_gl_context_release (ctx); @@ -1385,8 +1397,16 @@ _cairo_gl_surface_paint (void *abstract_surface, cairo_clip_t *clip) { /* simplify the common case of clearing the surface */ - if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) - return _cairo_gl_surface_clear (abstract_surface); + if (clip == NULL) { + if (op == CAIRO_OPERATOR_CLEAR) + return _cairo_gl_surface_clear (abstract_surface, CAIRO_COLOR_TRANSPARENT); + else if (source->type == CAIRO_PATTERN_TYPE_SOLID && + (op == CAIRO_OPERATOR_SOURCE || + (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) { + return _cairo_gl_surface_clear (abstract_surface, + &((cairo_solid_pattern_t *) source)->color); + } + } return CAIRO_INT_STATUS_UNSUPPORTED; } |