[cairo] [patch] gl - use direct mode for uploading gradient texture

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Mon Mar 19 17:32:01 PDT 2012


Using pbo to upload gradient fails on ATI/fglrx driver (latest 12.2).  glGetError () after glTexSubImage2D() always returns GL_INVALID_OPERATION.  Not sure why, might be fglrx bug.  PBO works for other drivers.
To make it work in ATI/flgrlx, I have attached the following patch.  Figured that since gradient is small, non-pbo performance hit should be minimal.  If you think that cairo should keep pbo and let fglrx fails until they fix bugs.  I am fine with that.

Here is the patch

Author: Henry Song <henry.song at samsung.com>
Date:   Mon Mar 19 17:21:27 2012 -0700

    use direct mode to upload gradient texture instead of pbo.

diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index aad2773..0936b53 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -238,38 +238,14 @@ _cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
     _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
     glBindTexture (ctx->tex_target, gradient->tex);
 
-    /* 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);
+    data = _cairo_malloc_ab (tex_width, sizeof (uint32_t));
 
-	status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
+    status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width);
 
-	dispatch->UnmapBuffer (GL_PIXEL_UNPACK_BUFFER);
-
-	if (unlikely (status)) {
-	    dispatch->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
-	    free (gradient);
-	    return status;
-	}
-
-	glTexImage2D (ctx->tex_target, 0, GL_RGBA8, tex_width, 1, 0,
-		      GL_BGRA, GL_UNSIGNED_BYTE, 0);
-
-	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);
+    glTexImage2D (ctx->tex_target, 0, GL_RGBA, tex_width, 1, 0,
+   		  GL_BGRA, GL_UNSIGNED_BYTE, data);
 
 	free (data);
-    }
 
     /* we ignore errors here and just return an uncached gradient */
     if (unlikely (_cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))


More information about the cairo mailing list