From patchwork Mon Jul 25 14:05:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 3098 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 6A57923E54 for ; Mon, 25 Jul 2011 14:05:21 +0000 (UTC) Received: from mail-qy0-f173.google.com (mail-qy0-f173.google.com [209.85.216.173]) by fiordland.canonical.com (Postfix) with ESMTP id F1095A184C7 for ; Mon, 25 Jul 2011 14:05:20 +0000 (UTC) Received: by qyk10 with SMTP id 10so1062982qyk.11 for ; Mon, 25 Jul 2011 07:05:20 -0700 (PDT) Received: by 10.229.1.217 with SMTP id 25mr1010396qcg.38.1311602720357; Mon, 25 Jul 2011 07:05:20 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs78168qcb; Mon, 25 Jul 2011 07:05:20 -0700 (PDT) Received: by 10.223.62.76 with SMTP id w12mr6759142fah.123.1311602719427; Mon, 25 Jul 2011 07:05:19 -0700 (PDT) Received: from mail-fx0-f44.google.com (mail-fx0-f44.google.com [209.85.161.44]) by mx.google.com with ESMTPS id o15si7048838fal.135.2011.07.25.07.05.19 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 25 Jul 2011 07:05:19 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.161.44 is neither permitted nor denied by best guess record for domain of alexandros.frantzis@linaro.org) client-ip=209.85.161.44; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.161.44 is neither permitted nor denied by best guess record for domain of alexandros.frantzis@linaro.org) smtp.mail=alexandros.frantzis@linaro.org Received: by mail-fx0-f44.google.com with SMTP id 6so6811099fxe.17 for ; Mon, 25 Jul 2011 07:05:19 -0700 (PDT) Received: by 10.223.24.17 with SMTP id t17mr6743528fab.143.1311602718979; Mon, 25 Jul 2011 07:05:18 -0700 (PDT) Received: from localhost (77.49.93.204.dsl.dyn.forthnet.gr [77.49.93.204]) by mx.google.com with ESMTPS id o17sm3812184fal.2.2011.07.25.07.05.17 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 25 Jul 2011 07:05:18 -0700 (PDT) From: alexandros.frantzis@linaro.org To: patches@linaro.org Subject: =?UTF-8?q?=5BPATCH=202/9=5D=20gl=3A=20Add=20infrastructure=20for=20calling=20GL=20functions=20using=20a=20dispatch=20table?= Date: Mon, 25 Jul 2011 17:05:06 +0300 Message-Id: <1311602713-6182-2-git-send-email-alexandros.frantzis@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1311602713-6182-1-git-send-email-alexandros.frantzis@linaro.org> References: <1311602713-6182-1-git-send-email-alexandros.frantzis@linaro.org> MIME-Version: 1.0 From: Alexandros Frantzis Some GL functions can be called using different names depending on the GL version and available extensions (ARB, EXT). The dispatch table abstracts these differences and provides a uniform API for dealing with these functions. --- src/Makefile.sources | 2 + src/cairo-gl-dispatch-private.h | 99 +++++++++++++++++++++++++++ src/cairo-gl-dispatch.c | 144 +++++++++++++++++++++++++++++++++++++++ src/cairo-gl-private.h | 58 ++++++++++++++++ 4 files changed, 303 insertions(+), 0 deletions(-) create mode 100644 src/cairo-gl-dispatch-private.h create mode 100644 src/cairo-gl-dispatch.c diff --git a/src/Makefile.sources b/src/Makefile.sources index ae19e7f..168429f 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -313,12 +313,14 @@ cairo_beos_cxx_sources = cairo-beos-surface.cpp cairo_gl_headers = cairo-gl.h cairo_gl_private = cairo-gl-private.h \ + cairo-gl-dispatch-private.h \ cairo-gl-gradient-private.h \ glew/GL/glew.h \ glew/GL/glxew.h cairo_gl_sources = cairo-gl-composite.c \ cairo-gl-device.c \ + cairo-gl-dispatch.c \ cairo-gl-glyphs.c \ cairo-gl-gradient.c \ cairo-gl-info.c \ diff --git a/src/cairo-gl-dispatch-private.h b/src/cairo-gl-dispatch-private.h new file mode 100644 index 0000000..cfe737c --- /dev/null +++ b/src/cairo-gl-dispatch-private.h @@ -0,0 +1,99 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2010 Linaro Limited + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * Contributor(s): + * Alexandros Frantzis + */ + +#ifndef CAIRO_GL_DISPATCH_PRIVATE_H +#define CAIRO_GL_DISPATCH_PRIVATE_H + +#include +#include "cairo-gl-private.h" + +typedef struct _cairo_gl_dispatch_entry { + const char *name_core; + const char *name_ext; + size_t offset; +} cairo_gl_dispatch_entry_t; + +#define DISPATCH_ENTRY_ARB(name) { "gl"#name, "gl"#name"ARB", \ + offsetof(cairo_gl_dispatch_t, name) } +#define DISPATCH_ENTRY_EXT(name) { "gl"#name, "gl"#name"EXT", \ + offsetof(cairo_gl_dispatch_t, name) } +#define DISPATCH_ENTRY_CUSTOM(name, name2) { "gl"#name, "gl"#name2, \ + offsetof(cairo_gl_dispatch_t, name)} +#define DISPATCH_ENTRY_LAST { NULL, NULL, 0 } + +cairo_gl_dispatch_entry_t dispatch_buffers_entries[] = { + DISPATCH_ENTRY_ARB (GenBuffers), + DISPATCH_ENTRY_ARB (BindBuffer), + DISPATCH_ENTRY_ARB (BufferData), + DISPATCH_ENTRY_ARB (MapBuffer), + DISPATCH_ENTRY_ARB (UnmapBuffer), + DISPATCH_ENTRY_LAST +}; + +cairo_gl_dispatch_entry_t dispatch_shaders_entries[] = { + /* Shaders */ + DISPATCH_ENTRY_CUSTOM (CreateShader, CreateShaderObjectARB), + DISPATCH_ENTRY_ARB (ShaderSource), + DISPATCH_ENTRY_ARB (CompileShader), + DISPATCH_ENTRY_CUSTOM (GetShaderiv, GetObjectParameterivARB), + DISPATCH_ENTRY_CUSTOM (GetShaderInfoLog, GetInfoLogARB), + DISPATCH_ENTRY_CUSTOM (DeleteShader, DeleteObjectARB), + + /* Programs */ + DISPATCH_ENTRY_CUSTOM (CreateProgram, CreateProgramObjectARB), + DISPATCH_ENTRY_CUSTOM (AttachShader, AttachObjectARB), + DISPATCH_ENTRY_CUSTOM (DeleteProgram, DeleteObjectARB), + DISPATCH_ENTRY_ARB (LinkProgram), + DISPATCH_ENTRY_CUSTOM (UseProgram, UseProgramObjectARB), + DISPATCH_ENTRY_CUSTOM (GetProgramiv, GetObjectParameterivARB), + DISPATCH_ENTRY_CUSTOM (GetProgramInfoLog, GetInfoLogARB), + + /* Uniforms */ + DISPATCH_ENTRY_ARB (GetUniformLocation), + DISPATCH_ENTRY_ARB (Uniform1f), + DISPATCH_ENTRY_ARB (Uniform2f), + DISPATCH_ENTRY_ARB (Uniform3f), + DISPATCH_ENTRY_ARB (Uniform4f), + DISPATCH_ENTRY_ARB (UniformMatrix3fv), + DISPATCH_ENTRY_ARB (Uniform1i), + DISPATCH_ENTRY_LAST +}; + +cairo_gl_dispatch_entry_t dispatch_fbo_entries[] = { + DISPATCH_ENTRY_EXT (GenFramebuffers), + DISPATCH_ENTRY_EXT (BindFramebuffer), + DISPATCH_ENTRY_EXT (FramebufferTexture2D), + DISPATCH_ENTRY_EXT (CheckFramebufferStatus), + DISPATCH_ENTRY_EXT (DeleteFramebuffers), + DISPATCH_ENTRY_LAST +}; + +#endif /* CAIRO_GL_DISPATCH_PRIVATE_H */ diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c new file mode 100644 index 0000000..f44d3b8 --- /dev/null +++ b/src/cairo-gl-dispatch.c @@ -0,0 +1,144 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2010 Linaro Limited + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * Contributor(s): + * Alexandros Frantzis + */ + +#include "cairo-gl-private.h" +#include "cairo-gl-dispatch-private.h" + +static void +_cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr, + cairo_gl_dispatch_entry_t *entries, + cairo_bool_t use_ext) +{ + cairo_gl_dispatch_entry_t *entry = entries; + + while (entry->name_core != NULL) { + void *dispatch_ptr = &((char *) dispatch)[entry->offset]; + const char *name = use_ext ? entry->name_ext : + entry->name_core; + + cairo_gl_generic_func_t func = get_proc_addr (name); + + *((cairo_gl_generic_func_t *) dispatch_ptr) = func; + + ++entry; + } + +} + +static cairo_status_t +_cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr, + int gl_version) +{ + cairo_bool_t use_ext; + + if (gl_version >= CAIRO_GL_VERSION_ENCODE (1, 5)) + use_ext = 0; + else if (_cairo_gl_has_extension ("GL_ARB_vertex_buffer_object")) + use_ext = 1; + else + return CAIRO_STATUS_DEVICE_ERROR; + + _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, + dispatch_buffers_entries, use_ext); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr, + int gl_version) +{ + cairo_bool_t use_ext; + + /* Note: shader support is not necessary at the moment */ + if (gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) + use_ext = 0; + else if (_cairo_gl_has_extension ("GL_ARB_shader_objects")) + use_ext = 1; + else + return CAIRO_STATUS_SUCCESS; + + _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, + dispatch_shaders_entries, use_ext); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr, + int gl_version) +{ + cairo_bool_t use_ext; + + if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) || + _cairo_gl_has_extension ("GL_ARB_framebuffer_object")) + use_ext = 0; + else if (_cairo_gl_has_extension ("GL_EXT_framebuffer_object")) + use_ext = 1; + else + return CAIRO_STATUS_DEVICE_ERROR; + + _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, + dispatch_fbo_entries, use_ext); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_gl_dispatch_init (cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr) +{ + cairo_status_t status; + int gl_version; + + gl_version = _cairo_gl_get_version (); + + status = _cairo_gl_dispatch_init_buffers (dispatch, get_proc_addr, + gl_version); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + status = _cairo_gl_dispatch_init_shaders (dispatch, get_proc_addr, + gl_version); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + status = _cairo_gl_dispatch_init_fbo (dispatch, get_proc_addr, + gl_version); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + return CAIRO_STATUS_SUCCESS; +} diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 2a818aa..a050e18 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -175,6 +175,59 @@ typedef struct cairo_gl_operand { unsigned int vertex_offset; } cairo_gl_operand_t; +typedef void (*cairo_gl_generic_func_t)(void); +typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(const char *procname); + +typedef struct _cairo_gl_dispatch { + /* Buffers */ + void (*GenBuffers) (GLsizei n, GLuint *buffers); + void (*BindBuffer) (GLenum target, GLuint buffer); + void (*BufferData) (GLenum target, GLsizeiptr size, + const GLvoid* data, GLenum usage); + GLvoid *(*MapBuffer) (GLenum target, GLenum access); + GLboolean (*UnmapBuffer) (GLenum target); + + /* Shaders */ + GLuint (*CreateShader) (GLenum type); + void (*ShaderSource) (GLuint shader, GLsizei count, + const GLchar** string, const GLint* length); + void (*CompileShader) (GLuint shader); + void (*GetShaderiv) (GLuint shader, GLenum pname, GLint *params); + void (*GetShaderInfoLog) (GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void (*DeleteShader) (GLuint shader); + + /* Programs */ + GLuint (*CreateProgram) (void); + void (*AttachShader) (GLuint program, GLuint shader); + void (*DeleteProgram) (GLuint program); + void (*LinkProgram) (GLuint program); + void (*UseProgram) (GLuint program); + void (*GetProgramiv) (GLuint program, GLenum pname, GLint *params); + void (*GetProgramInfoLog) (GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + + /* Uniforms */ + GLint (*GetUniformLocation) (GLuint program, const GLchar* name); + void (*Uniform1f) (GLint location, GLfloat x); + void (*Uniform2f) (GLint location, GLfloat x, GLfloat y); + void (*Uniform3f) (GLint location, GLfloat x, GLfloat y, GLfloat z); + void (*Uniform4f) (GLint location, GLfloat x, GLfloat y, GLfloat z, + GLfloat w); + void (*UniformMatrix3fv) (GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value); + void (*Uniform1i) (GLint location, GLint x); + + /* Framebuffer objects */ + void (*GenFramebuffers) (GLsizei n, GLuint* framebuffers); + void (*BindFramebuffer) (GLenum target, GLuint framebuffer); + void (*FramebufferTexture2D) (GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level); + GLenum (*CheckFramebufferStatus) (GLenum target); + void (*DeleteFramebuffers) (GLsizei n, const GLuint* framebuffers); +} cairo_gl_dispatch_t; + struct _cairo_gl_context { cairo_device_t base; @@ -489,6 +542,11 @@ _cairo_gl_get_version (void); cairo_private cairo_bool_t _cairo_gl_has_extension (const char *ext); +cairo_private cairo_status_t +_cairo_gl_dispatch_init(cairo_gl_dispatch_t *dispatch, + cairo_gl_get_proc_addr_func_t get_proc_addr); + + slim_hidden_proto (cairo_gl_surface_create); slim_hidden_proto (cairo_gl_surface_create_for_texture);