[cairo-commit] 2 commits - boilerplate/cairo-boilerplate-glx.c src/cairo-gl-surface.c
Martin Robinson
mrobinson at kemper.freedesktop.org
Fri Jan 4 16:35:01 PST 2013
boilerplate/cairo-boilerplate-glx.c | 170 ++++++++++++++++++++----------------
src/cairo-gl-surface.c | 43 +++++++--
2 files changed, 133 insertions(+), 80 deletions(-)
New commits:
commit 9194904fa838a115b4dc58e5bff7a235cc2a9a7a
Author: Martin Robinson <mrobinson at igalia.com>
Date: Fri Jan 4 16:31:01 2013 -0800
gl: Better handling of clear surfaces
When clearing a GL surface, set is_clear to true, and when mapping to an
image, handle is_clear like surfaces without modification. Additionally,
explicitly clear surfaces created via cairo_surface_create_similar.
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 4b74cf0..4ca876c 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -508,9 +508,36 @@ _cairo_gl_surface_clear (cairo_gl_surface_t *surface,
glClearColor (r, g, b, a);
glClear (GL_COLOR_BUFFER_BIT);
+ if (a == 0)
+ surface->base.is_clear = TRUE;
+
return _cairo_gl_context_release (ctx, status);
}
+static cairo_surface_t *
+_cairo_gl_surface_create_and_clear_scratch (cairo_gl_context_t *ctx,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ cairo_gl_surface_t *surface;
+ cairo_int_status_t status;
+
+ surface = (cairo_gl_surface_t *)
+ _cairo_gl_surface_create_scratch (ctx, content, width, height);
+ if (unlikely (surface->base.status))
+ return &surface->base;
+
+ /* Cairo surfaces start out initialized to transparent (black) */
+ status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
+ if (unlikely (status)) {
+ cairo_surface_destroy (&surface->base);
+ return _cairo_surface_create_in_error (status);
+ }
+
+ return &surface->base;
+}
+
cairo_surface_t *
cairo_gl_surface_create (cairo_device_t *abstract_device,
cairo_content_t content,
@@ -538,16 +565,13 @@ cairo_gl_surface_create (cairo_device_t *abstract_device,
return _cairo_surface_create_in_error (status);
surface = (cairo_gl_surface_t *)
- _cairo_gl_surface_create_scratch (ctx, content, width, height);
+ _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
if (unlikely (surface->base.status)) {
status = _cairo_gl_context_release (ctx, surface->base.status);
cairo_surface_destroy (&surface->base);
return _cairo_surface_create_in_error (status);
}
- /* Cairo surfaces start out initialized to transparent (black) */
- status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
-
status = _cairo_gl_context_release (ctx, status);
if (unlikely (status)) {
cairo_surface_destroy (&surface->base);
@@ -740,7 +764,7 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
if (unlikely (status))
return _cairo_surface_create_in_error (status);
- surface = _cairo_gl_surface_create_scratch (ctx, content, width, height);
+ surface = _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
status = _cairo_gl_context_release (ctx, status);
if (unlikely (status)) {
@@ -1055,13 +1079,20 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
extents->width,
extents->height,
-1);
- if (unlikely (image->base.status) || surface->base.serial == 0) {
+ if (unlikely (image->base.status)) {
status = _cairo_gl_context_release (ctx, status);
return image;
}
cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y);
+ /* If the original surface has not been modified or
+ * is clear, we can avoid downloading data. */
+ if (surface->base.is_clear || surface->base.serial == 0) {
+ status = _cairo_gl_context_release (ctx, status);
+ return image;
+ }
+
/* This is inefficient, as we'd rather just read the thing without making
* it the destination. But then, this is the fallback path, so let's not
* fall back instead.
commit 9bff4508443abe002fcb0ffdb9b1897272f1c588
Author: Martin Robinson <mrobinson at igalia.com>
Date: Fri Jan 4 15:47:13 2013 -0800
boilerplate/glx: Add a target with multisampling and stencil support
Add a gl-window target that supports multisampling. This is useful for
testing the MSAA backend on the default framebuffer.
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
index 28026dc..52cd99f 100644
--- a/boilerplate/cairo-boilerplate-glx.c
+++ b/boilerplate/cairo-boilerplate-glx.c
@@ -144,32 +144,21 @@ _cairo_boilerplate_gl_create_surface (const char *name,
}
static cairo_surface_t *
-_cairo_boilerplate_gl_create_window (const char *name,
- cairo_content_t content,
- double width,
- double height,
- double max_width,
- double max_height,
- cairo_boilerplate_mode_t mode,
- void **closure)
+_cairo_boilerplate_gl_create_window_common (int rgba_attribs[],
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ gl_target_closure_t *gltc)
{
- int rgba_attribs[] = { GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_ALPHA_SIZE, 1,
- GLX_DOUBLEBUFFER,
- None };
XVisualInfo *vi;
GLXContext ctx;
- gl_target_closure_t *gltc;
cairo_surface_t *surface;
Display *dpy;
XSetWindowAttributes attr;
- gltc = calloc (1, sizeof (gl_target_closure_t));
- *closure = gltc;
-
width = ceil (width);
height = ceil (height);
@@ -219,13 +208,75 @@ _cairo_boilerplate_gl_create_window (const char *name,
gltc->surface = surface = cairo_gl_surface_create_for_window (gltc->device,
gltc->drawable,
width, height);
- if (cairo_surface_status (surface))
+ if (cairo_surface_status (surface)) {
_cairo_boilerplate_gl_cleanup (gltc);
-
+ return NULL;
+ }
return surface;
}
static cairo_surface_t *
+_cairo_boilerplate_gl_create_window (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ gl_target_closure_t *gltc;
+
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+
+ return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_window_msaa (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ gl_target_closure_t *gltc;
+
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
+ GLX_SAMPLES, 4,
+ GLX_SAMPLE_BUFFERS, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+ return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
+
+}
+
+static cairo_surface_t *
_cairo_boilerplate_gl_create_window_db (const char *name,
cairo_content_t content,
double width,
@@ -235,6 +286,10 @@ _cairo_boilerplate_gl_create_window_db (const char *name,
cairo_boilerplate_mode_t mode,
void **closure)
{
+ cairo_status_t status;
+ cairo_surface_t *surface;
+ gl_target_closure_t *gltc;
+
int rgba_attribs[] = { GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
@@ -242,66 +297,18 @@ _cairo_boilerplate_gl_create_window_db (const char *name,
GLX_ALPHA_SIZE, 1,
GLX_DOUBLEBUFFER,
None };
- XVisualInfo *vi;
- GLXContext ctx;
- gl_target_closure_t *gltc;
- cairo_surface_t *surface;
- Display *dpy;
- XSetWindowAttributes attr;
- cairo_status_t status;
gltc = calloc (1, sizeof (gl_target_closure_t));
*closure = gltc;
- width = ceil (width);
- height = ceil (height);
-
- if (width == 0)
- width = 1;
- if (height == 0)
- height = 1;
+ surface = _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
- dpy = XOpenDisplay (NULL);
- gltc->dpy = dpy;
- if (!gltc->dpy) {
- fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
- free (gltc);
- return NULL;
- }
-
- if (mode == CAIRO_BOILERPLATE_MODE_TEST)
- XSynchronize (gltc->dpy, 1);
-
- vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
- if (vi == NULL) {
- fprintf (stderr, "Failed to create RGBA, double-buffered visual\n");
- XCloseDisplay (dpy);
- free (gltc);
+ if (! surface)
return NULL;
- }
-
- attr.colormap = XCreateColormap (dpy,
- RootWindow (dpy, vi->screen),
- vi->visual,
- AllocNone);
- attr.border_pixel = 0;
- attr.override_redirect = True;
- gltc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
- width, height, 0, vi->depth,
- InputOutput, vi->visual,
- CWOverrideRedirect | CWBorderPixel | CWColormap,
- &attr);
- XMapWindow (dpy, gltc->drawable);
-
- ctx = glXCreateContext (dpy, vi, NULL, True);
- XFree (vi);
- gltc->ctx = ctx;
- gltc->device = cairo_glx_device_create (dpy, ctx);
-
- gltc->surface = cairo_gl_surface_create_for_window (gltc->device,
- gltc->drawable,
- width, height);
surface = cairo_surface_create_similar (gltc->surface, content, width, height);
status = cairo_surface_set_user_data (surface, &gl_closure_key, gltc, NULL);
if (status == CAIRO_STATUS_SUCCESS)
@@ -414,6 +421,21 @@ static const cairo_boilerplate_target_t targets[] = {
FALSE, FALSE, FALSE
},
{
+ "gl-window-msaa", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create_for_window",
+ _cairo_boilerplate_gl_create_window_msaa,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_gl_finish_window,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ FALSE, FALSE, FALSE
+ },
+ {
"gl-window&", "gl", NULL, NULL,
CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
"cairo_gl_surface_create_for_window",
More information about the cairo-commit
mailing list