[21/21] gl: Add fallback path for GLES2 implementations not supporting GL_OES_mapbuffer

Message ID 1311602208-5973-21-git-send-email-alexandros.frantzis@linaro.org
State Accepted
Headers show

Commit Message

alexandros.frantzis@linaro.org July 25, 2011, 1:56 p.m.
From: Alexandros Frantzis <alexandros.frantzis@linaro.org>

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 src/cairo-gl-composite.c |   18 ++++++++++++++----
 src/cairo-gl-device.c    |   14 ++++++++++++++
 src/cairo-gl-dispatch.c  |    3 +--
 src/cairo-gl-private.h   |    2 ++
 4 files changed, 31 insertions(+), 6 deletions(-)

Patch

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 575719b..bb88f59 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1014,7 +1014,12 @@  _cairo_gl_composite_flush (cairo_gl_context_t *ctx)
 
     count = ctx->vb_offset / ctx->vertex_size;
 
-    ctx->dispatch.UnmapBuffer (GL_ARRAY_BUFFER);
+    if (ctx->has_map_buffer)
+	ctx->dispatch.UnmapBuffer (GL_ARRAY_BUFFER);
+    else
+	ctx->dispatch.BufferData (GL_ARRAY_BUFFER, ctx->vb_offset,
+				  ctx->vb, GL_STREAM_DRAW);
+
     ctx->vb = NULL;
     ctx->vb_offset = 0;
 
@@ -1044,9 +1049,14 @@  _cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
 	_cairo_gl_composite_flush (ctx);
 
     if (ctx->vb == NULL) {
-	dispatch->BufferData (GL_ARRAY_BUFFER, CAIRO_GL_VBO_SIZE,
-			      NULL, GL_STREAM_DRAW);
-	ctx->vb = dispatch->MapBuffer (GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	if (ctx->has_map_buffer) {
+	    dispatch->BufferData (GL_ARRAY_BUFFER, CAIRO_GL_VBO_SIZE,
+				  NULL, GL_STREAM_DRAW);
+	    ctx->vb = dispatch->MapBuffer (GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	}
+	else {
+	    ctx->vb = ctx->vb_mem;
+	}
     }
 }
 
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index c94e36f..170cf96 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -132,6 +132,8 @@  _gl_destroy (void *device)
 
     cairo_region_destroy (ctx->clip_region);
 
+    free (ctx->vb_mem);
+
     ctx->destroy (ctx);
 
     free (ctx);
@@ -191,6 +193,10 @@  _cairo_gl_context_init (cairo_gl_context_t *ctx)
 	! _cairo_gl_has_extension ("GL_EXT_texture_format_BGRA8888"))
 	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
 
+    ctx->has_map_buffer = (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+			   (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+			    _cairo_gl_has_extension ("GL_OES_mapbuffer")));
+
     ctx->has_mesa_pack_invert =
 	_cairo_gl_has_extension ("GL_MESA_pack_invert");
 
@@ -209,6 +215,14 @@  _cairo_gl_context_init (cairo_gl_context_t *ctx)
     if (unlikely (status))
         return status;
 
+    if (! ctx->has_map_buffer) {
+	ctx->vb_mem = _cairo_malloc_ab (CAIRO_GL_VBO_SIZE, 1);
+	if (unlikely (ctx->vb_mem == NULL)) {
+	    _cairo_cache_fini (&ctx->gradients);
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	}
+    }
+
     /* PBO for any sort of texture upload */
     dispatch->GenBuffers (1, &ctx->texture_load_pbo);
     dispatch->GenBuffers (1, &ctx->vbo);
diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c
index 344b0eb..5bffddd 100644
--- a/src/cairo-gl-dispatch.c
+++ b/src/cairo-gl-dispatch.c
@@ -125,8 +125,7 @@  _cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
 	    return CAIRO_STATUS_DEVICE_ERROR;
     }
     else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
-	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0) &&
-	     _cairo_gl_has_extension ("GL_OES_mapbuffer"))
+	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
     {
 	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
     }
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 3f3153e..edd1355 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -285,6 +285,7 @@  struct _cairo_gl_context {
     cairo_gl_operand_t operands[2];
 
     char *vb;
+    char *vb_mem;
     unsigned int vb_offset;
     unsigned int vertex_size;
     cairo_region_t *clip_region;
@@ -293,6 +294,7 @@  struct _cairo_gl_context {
     cairo_gl_dispatch_t dispatch;
     GLfloat modelviewprojection_matrix[16];
     cairo_gl_flavor_t gl_flavor;
+    cairo_bool_t has_map_buffer;
 
     void (*acquire) (void *ctx);
     void (*release) (void *ctx);