[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