summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-18 21:56:55 +0200
committerBenjamin Otte <otte@redhat.com>2010-05-20 11:02:48 +0200
commit0d2d4c59026c31da084e6797d109a230341b396d (patch)
treefa48cf82f45e2a16d22a6f12e2886f9a52902eef
parentb70eb275c4aa54f7c90a985b5de67da12ac08a30 (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.h3
-rw-r--r--src/cairo-gl-surface.c38
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;
}