[10/21] gl: Use conventional texture upload for GLES2

Message ID 1311602208-5973-10-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>

GLES2 doesn't support Pixel Buffer Objects. Use conventional texture upload
for GLES2 (using client-side memory).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 src/cairo-gl-device.c   |    3 ++-
 src/cairo-gl-gradient.c |   43 ++++++++++++++++++++++++++-----------------
 2 files changed, 28 insertions(+), 18 deletions(-)

Patch

diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index ca7b6e8..92cd82a 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -176,7 +176,8 @@  _cairo_gl_context_init (cairo_gl_context_t *ctx)
     else
 	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
 
-    if (gl_version < CAIRO_GL_VERSION_ENCODE (2, 1) &&
+    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP &&
+	gl_version < CAIRO_GL_VERSION_ENCODE (2, 1) &&
 	! _cairo_gl_has_extension ("GL_ARB_pixel_buffer_object"))
 	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
 
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 0718c75..862430e 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -234,33 +234,42 @@  _cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
     gradient->stops = gradient->stops_embedded;
     memcpy (gradient->stops_embedded, stops, n_stops * sizeof (cairo_gradient_stop_t));
 
-    dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, ctx->texture_load_pbo);
-    dispatch->BufferData (GL_PIXEL_UNPACK_BUFFER,
-			  tex_width * sizeof (uint32_t), 0, GL_STREAM_DRAW);
-    data = dispatch->MapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
+    glGenTextures (1, &gradient->tex);
+    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
+    glBindTexture (ctx->tex_target, gradient->tex);
 
-    status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
+    /* GL_PIXEL_UNPACK_BUFFER is only available in Desktop GL */
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
+	dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, ctx->texture_load_pbo);
+	dispatch->BufferData (GL_PIXEL_UNPACK_BUFFER,
+			      tex_width * sizeof (uint32_t), 0, GL_STREAM_DRAW);
+	data = dispatch->MapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
 
-    dispatch->UnmapBuffer (GL_PIXEL_UNPACK_BUFFER);
+	status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
 
-    if (unlikely (status)) {
-        dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
-        free (gradient);
-        return status;
-    }
+	dispatch->UnmapBuffer (GL_PIXEL_UNPACK_BUFFER);
 
-    glGenTextures (1, &gradient->tex);
-    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
-    glBindTexture (ctx->tex_target, gradient->tex);
+	if (unlikely (status)) {
+	    dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
+	    free (gradient);
+	    return status;
+	}
 
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
 	glTexImage2D (ctx->tex_target, 0, GL_RGBA8, tex_width, 1, 0,
 		      GL_BGRA, GL_UNSIGNED_BYTE, 0);
-    else
+
+	dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
+    }
+    else {
+	data = _cairo_malloc_ab (tex_width, sizeof (uint32_t));
+
+	status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
+
 	glTexImage2D (ctx->tex_target, 0, GL_BGRA, tex_width, 1, 0,
 		      GL_BGRA, GL_UNSIGNED_BYTE, data);
 
-    dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
+	free (data);
+    }
 
     /* we ignore errors here and just return an uncached gradient */
     if (likely (! _cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))