[cairo] [PATCH 2/3] gl: Add new cairo-gl surface constructor to create surface for texture

Kristian Høgsberg krh at bitplanet.net
Thu Jun 17 15:30:34 PDT 2010


---
 src/cairo-gl-private.h |    1 +
 src/cairo-gl-surface.c |   80 +++++++++++++++++++++++++++++++++++++++++------
 src/cairo-gl.h         |    4 ++
 3 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 132fcb8..0019429 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -477,5 +477,6 @@ cairo_private void
 _cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader);
 
 slim_hidden_proto (cairo_gl_surface_create);
+slim_hidden_proto (cairo_gl_surface_create_for_texture);
 
 #endif /* CAIRO_GL_PRIVATE_H */
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index e6aa655..fe2612e 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -237,13 +237,13 @@ _cairo_gl_surface_init (cairo_device_t *device,
 }
 
 static cairo_surface_t *
-_cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
-				  cairo_content_t	content,
-				  int			width,
-				  int			height)
+_cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
+					      cairo_content_t	    content,
+					      GLuint		    tex,
+					      int		    width,
+					      int		    height)
 {
     cairo_gl_surface_t *surface;
-    GLenum format;
 
     assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
 
@@ -253,6 +253,32 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
 
     _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
 
+    /* Create the texture used to store the surface's data. */
+    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
+    glBindTexture (ctx->tex_target, surface->tex);
+    glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    return &surface->base;
+}
+
+static cairo_surface_t *
+_cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
+				  cairo_content_t	content,
+				  int			width,
+				  int			height)
+{
+    cairo_gl_surface_t *surface;
+    GLenum format;
+    GLuint tex;
+
+    glGenTextures (1, &tex);
+    surface = (cairo_gl_surface_t *)
+	_cairo_gl_surface_create_scratch_for_texture (ctx, content,
+						      tex, width, height);
+    if (unlikely (surface->base.status))
+	return &surface->base;
+
     /* adjust the texture size after setting our real extents */
     if (width < 1)
 	width = 1;
@@ -282,12 +308,6 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
 	break;
     }
 
-    /* Create the texture used to store the surface's data. */
-    _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
-    glGenTextures (1, &surface->tex);
-    glBindTexture (ctx->tex_target, surface->tex);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexImage2D (ctx->tex_target, 0, format, width, height, 0,
 		  format, GL_UNSIGNED_BYTE, NULL);
 
@@ -380,6 +400,44 @@ cairo_gl_surface_create (cairo_device_t		*abstract_device,
 }
 slim_hidden_def (cairo_gl_surface_create);
 
+
+cairo_surface_t *
+cairo_gl_surface_create_for_texture (cairo_device_t	*abstract_device,
+				     cairo_content_t	 content,
+				     GLuint		 tex,
+				     int		 width,
+				     int		 height)
+{
+    cairo_gl_context_t *ctx;
+    cairo_gl_surface_t *surface;
+    cairo_status_t status;
+
+    if (! CAIRO_CONTENT_VALID (content))
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
+
+    if (abstract_device == NULL)
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
+
+    if (abstract_device->status)
+	return _cairo_surface_create_in_error (abstract_device->status);
+
+    if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
+
+    status = _cairo_gl_context_acquire (abstract_device, &ctx);
+    if (unlikely (status))
+	return _cairo_surface_create_in_error (status);
+
+    surface = (cairo_gl_surface_t *)
+	_cairo_gl_surface_create_scratch_for_texture (ctx, content,
+						      tex, width, height);
+    _cairo_gl_context_release (ctx);
+
+    return &surface->base;
+}
+slim_hidden_def (cairo_gl_surface_create_for_texture);
+
+
 void
 cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
 			   int              width,
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
index 7657a93..e61c1f8 100644
--- a/src/cairo-gl.h
+++ b/src/cairo-gl.h
@@ -45,6 +45,10 @@ cairo_gl_surface_create (cairo_device_t *device,
 			 cairo_content_t content,
 			 int width, int height);
 
+cairo_public cairo_surface_t *
+cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device,
+				     cairo_content_t content,
+				     GLuint tex, int width, int height);
 cairo_public void
 cairo_gl_surface_set_size (cairo_surface_t *surface, int width, int height);
 
-- 
1.7.1



More information about the cairo mailing list