[cairo] [patch] gl - binding to NSOpenGL instead of GLX

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Mon Dec 31 13:12:17 PST 2012


>From 1f85ff3b349a7fbc1217e30f4278c174c93b549b Mon Sep 17 00:00:00 2001
From: Henry Song <hsong at sisa.samsung.com>
Date: Mon, 31 Dec 2012 12:48:09 -0800
Subject: [PATCH] gl: bind cairo-gl backend to apple's NSOpenGL and apple's
 OpenGL instead of mesa's GLX and GL.  It is not possible to create
 cairo_gl_surface to use apple's OpenGL directly.

Few notes:
1. disabled gl-surface-source test because it uses GLX, need to revise the
test
2. offscreen and NSView-based surface work fine, I have not implemented for
virtual screen yet.
3. After install macport's mesa package, it is possible to use GLX on mac,
but GLX and NSOpenGL are mutually execlusive.
4. To use NSOpenGL "./configure --enable-gl=yes --enable-glx=no
--enable-nsgl=yes
5. To use GLX "./configure --enable-gl-yes --enable-nsgl=no
--enable-glx=yes"
6. make test on NSOpenGL "make test TARGETS=nsgl"
---
 boilerplate/Makefile.sources         |   1 +
 boilerplate/Makefile.win32.features  |  12 +++
 boilerplate/cairo-boilerplate-nsgl.m | 150 +++++++++++++++++++++++++++
 build/Makefile.win32.features        |   1 +
 build/Makefile.win32.features-h      |   3 +
 build/configure.ac.features          |   1 +
 configure.ac                         |  24 ++++-
 perf/Makefile.am                     |  12 +++
 src/Makefile.sources                 |   2 +
 src/Makefile.win32.features          |  16 +++
 src/cairo-gl.h                       |  16 +++
 src/cairo-nsgl-context.m             | 193 +++++++++++++++++++++++++++++++++++
 test/Makefile.am                     |  10 ++
 test/Makefile.sources                |   2 +-
 14 files changed, 439 insertions(+), 4 deletions(-)
 create mode 100644 boilerplate/cairo-boilerplate-nsgl.m
 create mode 100644 src/cairo-nsgl-context.m

diff --git a/boilerplate/Makefile.sources b/boilerplate/Makefile.sources
index 101e997..77b77b5 100644
--- a/boilerplate/Makefile.sources
+++ b/boilerplate/Makefile.sources
@@ -25,6 +25,7 @@ cairo_boilerplate_drm_sources = cairo-boilerplate-drm.c
 cairo_boilerplate_glx_sources = cairo-boilerplate-glx.c
 cairo_boilerplate_wgl_sources = cairo-boilerplate-wgl.c
 cairo_boilerplate_egl_sources = cairo-boilerplate-egl.c
+cairo_boilerplate_nsgl_sources = cairo-boilerplate-nsgl.m
 cairo_boilerplate_pdf_sources = cairo-boilerplate-pdf.c
 cairo_boilerplate_ps_sources = cairo-boilerplate-ps.c
 cairo_boilerplate_qt_cxx_sources = cairo-boilerplate-qt.cpp
diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features
index e60a95b..11e3be7 100644
--- a/boilerplate/Makefile.win32.features
+++ b/boilerplate/Makefile.win32.features
@@ -319,6 +319,18 @@ enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_wgl_cxx_sources)
 enabled_cairo_boilerplate_sources += $(cairo_boilerplate_wgl_sources)
 endif

+supported_cairo_boilerplate_headers += $(cairo_boilerplate_nsgl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_nsgl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_nsgl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_nsgl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_nsgl_sources)
+ifeq ($(CAIRO_HAS_NSGL_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_nsgl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_nsgl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_nsgl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_nsgl_sources)
+endif
+
 supported_cairo_boilerplate_headers += $(cairo_boilerplate_script_headers)
 all_cairo_boilerplate_headers += $(cairo_boilerplate_script_headers)
 all_cairo_boilerplate_private += $(cairo_boilerplate_script_private)
diff --git a/boilerplate/cairo-boilerplate-nsgl.m b/boilerplate/cairo-boilerplate-nsgl.m
new file mode 100644
index 0000000..0d6d458
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-nsgl.m
@@ -0,0 +1,150 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2012 Henry Song
+ *
+ * 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.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ *
+ * Contributors
+ * Henry Song <henry.song at samsung.com>
+ */
+
+#import "cairo-boilerplate-private.h"
+
+#import <cairo-gl.h>
+
+#import <AppKit/NSOpenGL.h>
+#import <Foundation/NSAutoreleasePool.h>
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _nsgl_target_closure {
+    NSOpenGLContext *ctx;
+    NSAutoreleasePool *pool;
+
+    cairo_device_t *device;
+    cairo_surface_t *surface;
+} nsgl_target_closure_t;
+
+static void
+_cairo_boilerplate_nsgl_cleanup (void *closure)
+{
+    nsgl_target_closure_t *gltc = closure;
+
+    cairo_device_finish (gltc->device);
+    cairo_device_destroy (gltc->device);
+
+    [NSOpenGLContext clearCurrentContext];
+    [gltc->pool release];
+
+    free (gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_nsgl_create_surface (const char *name,
+       cairo_content_t  content,
+       double  width,
+       double  height,
+       double  max_width,
+       double  max_height,
+       cairo_boilerplate_mode_t   mode,
+       void **closure)
+{
+    nsgl_target_closure_t *gltc;
+    cairo_surface_t *surface;
+    NSOpenGLPixelFormat *pixelFormat;
+
+    NSOpenGLPixelFormatAttribute attrs[] = {
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAStencilSize, 8,
+ NSOpenGLPFAAlphaSize, 8,
+ 0
+    };
+
+    gltc = xcalloc (1, sizeof (nsgl_target_closure_t));
+    *closure = gltc;
+    gltc->pool = [[NSAutoreleasePool alloc] init];
+
+    pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes: attrs];
+    if (!pixelFormat)
+ return NULL;
+
+    gltc->ctx = [[NSOpenGLContext alloc] initWithFormat: pixelFormat
+  shareContext: nil];
+
+    if (!gltc->ctx)
+ return NULL;
+
+    [gltc->ctx makeCurrentContext];
+    gltc->device = cairo_nsgl_device_create (gltc->ctx);
+
+    if (width < 1)
+ width = 1;
+    if (height < 1)
+ height = 1;
+
+    gltc->surface = surface = cairo_gl_surface_create (gltc->device,
+       content,
+       ceil (width),
+       ceil (height));
+    if (cairo_surface_status (surface))
+ _cairo_boilerplate_nsgl_cleanup (gltc);
+
+    return surface;
+}
+
+static void
+_cairo_boilerplate_nsgl_synchronize (void *closure)
+{
+    nsgl_target_closure_t *gltc = closure;
+
+    if (cairo_device_acquire (gltc->device))
+ return;
+
+    glFinish ();
+
+    cairo_device_release (gltc->device);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+    {
+ "nsgl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_nsgl_device_create",
+ _cairo_boilerplate_nsgl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_nsgl_cleanup,
+ _cairo_boilerplate_nsgl_synchronize,
+        NULL,
+ TRUE, FALSE, FALSE
+    }
+};
+CAIRO_BOILERPLATE (nsgl, targets)
diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features
index 8cb155d..b45d65f 100644
--- a/build/Makefile.win32.features
+++ b/build/Makefile.win32.features
@@ -25,6 +25,7 @@ CAIRO_HAS_VG_SURFACE=0
 CAIRO_HAS_EGL_FUNCTIONS=0
 CAIRO_HAS_GLX_FUNCTIONS=0
 CAIRO_HAS_WGL_FUNCTIONS=0
+CAIRO_HAS_NSGL_FUNCTIONS=0
 CAIRO_HAS_SCRIPT_SURFACE=1
 CAIRO_HAS_FT_FONT=0
 CAIRO_HAS_FC_FONT=0
diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h
index 13904cf..ef4ae47 100644
--- a/build/Makefile.win32.features-h
+++ b/build/Makefile.win32.features-h
@@ -80,6 +80,9 @@ endif
 ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1)
  @echo "#define CAIRO_HAS_WGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h
 endif
+ifeq ($(CAIRO_HAS_NSGL_FUNCTIONS),1)
+ @echo "#define CAIRO_HAS_NSGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h
+endif
 ifeq ($(CAIRO_HAS_SCRIPT_SURFACE),1)
  @echo "#define CAIRO_HAS_SCRIPT_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
 endif
diff --git a/build/configure.ac.features b/build/configure.ac.features
index e4a2aaf..91737b0 100644
--- a/build/configure.ac.features
+++ b/build/configure.ac.features
@@ -402,6 +402,7 @@ AC_DEFUN([CAIRO_REPORT],
  echo "  GLX functions:   $use_glx"
  echo "  WGL functions:   $use_wgl"
  echo "  EGL functions:   $use_egl"
+ echo "  NSOpenGL functions: $use_nsgl"
  echo "  X11-xcb functions: $use_xlib_xcb"
  echo "  XCB-shm functions: $use_xcb_shm"
  echo ""
diff --git a/configure.ac b/configure.ac
index fc8d3b1..e456249 100644
--- a/configure.ac
+++ b/configure.ac
@@ -331,19 +331,20 @@ CAIRO_ENABLE_SURFACE_BACKEND(gl, OpenGL, no, [
   gl_REQUIRES="gl"
   PKG_CHECK_MODULES(gl, $gl_REQUIRES,, [
   dnl Fallback to searching for headers
-  AC_CHECK_HEADER(GL/gl.h,, [use_gl="no (gl.pc nor OpenGL headers not found)"])
+  AC_CHECK_HEADER([GL/gl.h, OpenGL/gl.h],, [use_gl="no (gl.pc nor OpenGL headers not found)"])
   if test "x$use_gl" = "xyes"; then
       gl_NONPKGCONFIG_CFLAGS=
-      gl_NONPKGCONFIG_LIBS="-lGL"
+      gl_NONPKGCONFIG_LIBS=
   fi])

   if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then
-    gl_LIBS="$gl_LIBS -ldl"
+    gl_LIBS="-ldl"
   fi

   need_glx_functions=yes
   need_wgl_functions=yes
   need_egl_functions=yes
+  need_nsgl_functions=yes
 ])

 dnl ===========================================================================
@@ -431,6 +432,7 @@ CAIRO_ENABLE_FUNCTIONS(glx, GLX, auto, [
     glx_NONPKGCONFIG_CFLAGS=
     glx_NONPKGCONFIG_LIBS="-lGL"
     CFLAGS="$save_CFLAGS"
+    need_nsgl_functions="no"
   else
       use_glx="no (not required by any backend)"
   fi
@@ -446,6 +448,22 @@ CAIRO_ENABLE_FUNCTIONS(wgl, WGL, auto, [

 dnl ===========================================================================

+CAIRO_ENABLE_FUNCTIONS(nsgl, NSOpenGL, auto, [
+  if test "x$need_nsgl_functions" = "xyes"; then
+    AC_LANG_PUSH([Objective C])
+    dnl There is no pkgconfig for NSOpenGL; lets do a header check
+    AC_CHECK_HEADERS([OpenGL/gl.h], [], [use_nsgl="no (requires AppKit and OpenGL framework)"], [])
+    nsgl_LIBS="-Xlinker -framework -Xlinker OpenGL -Xlinker -framework -Xlinker AppKit"
+      gl_NONPKGCONFIG_CFLAGS=
+      gl_NONPKGCONFIG_LIBS=
+    AC_LANG_POP([Objective C])
+  else
+      use_nsgl="no (use enable-nsgl=yes to enable)"
+  fi
+])
+
+dnl ===========================================================================
+
 any2ppm_cs=no
 CAIRO_ENABLE_SURFACE_BACKEND(script, script, yes, [
   any2ppm_cs=yes
diff --git a/perf/Makefile.am b/perf/Makefile.am
index 92f0dfc..7929387 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -34,11 +34,21 @@ EXTRA_PROGRAMS += \
 EXTRA_DIST += cairo-perf-diff COPYING
 EXTRA_LTLIBRARIES += libcairoperf.la

+if CAIRO_HAS_NSGL_FUNCTIONS
+cairo_nsgl_LIBS = \
+ -Xlinker -framework -Xlinker OpenGL \
+ -Xlinker -framework -Xlinker AppKit \
+ -Xlinker -framework -Xlinker Foundation
+else
+cairo_nsgl_LIBS =
+endif
+
 LDADD = libcairoperf.la \
  $(top_builddir)/boilerplate/libcairoboilerplate.la \
  $(top_builddir)/src/libcairo.la

 cairo_perf_micro_SOURCES = $(cairo_perf_micro_sources)
+cairo_perf_micro_LDFLAGS = $(cairo_nsgl_LIBS)
 cairo_perf_micro_LDADD = \
  $(top_builddir)/perf/micro/libcairo-perf-micro.la \
  $(LDADD)
@@ -55,6 +65,7 @@ libcairoperf_la_SOURCES = \
 cairo_analyse_trace_SOURCES = \
  $(cairo_analyse_trace_sources) \
  $(cairo_analyse_trace_external_sources)
+cairo_analyse_trace_LDFLAGS = $(cairo_nsgl_LIBS)
 cairo_analyse_trace_LDADD = \
  $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
  $(top_builddir)/util/cairo-missing/libcairo-missing.la \
@@ -67,6 +78,7 @@ cairo_analyse_trace_DEPENDENCIES = \
 cairo_perf_trace_SOURCES = \
  $(cairo_perf_trace_sources) \
  $(cairo_perf_trace_external_sources)
+cairo_perf_trace_LDFLAGS = $(cairo_nsgl_LIBS)
 cairo_perf_trace_LDADD = \
  $(top_builddir)/util/cairo-script/libcairo-script-interpreter.la \
  $(top_builddir)/util/cairo-missing/libcairo-missing.la \
diff --git a/src/Makefile.sources b/src/Makefile.sources
index d6793b0..85b43da 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -258,6 +258,7 @@ cairo_sources += $(_cairo_font_subset_sources)
 cairo_egl_sources =
 cairo_glx_sources =
 cairo_wgl_sources =
+cairo_nsgl_sources =

 _cairo_pdf_operators_private = cairo-pdf-operators-private.h cairo-pdf-shading-private.h
 _cairo_pdf_operators_sources = cairo-pdf-operators.c cairo-pdf-shading.c
@@ -404,6 +405,7 @@ cairo_glesv2_sources = $(cairo_gl_sources)
 cairo_egl_sources += cairo-egl-context.c
 cairo_glx_sources += cairo-glx-context.c
 cairo_wgl_sources += cairo-wgl-context.c
+cairo_nsgl_sources += cairo-nsgl-context.m

 cairo_directfb_headers = cairo-directfb.h
 cairo_directfb_sources = cairo-directfb-surface.c
diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features
index 2274f4a..c885908 100644
--- a/src/Makefile.win32.features
+++ b/src/Makefile.win32.features
@@ -421,6 +421,22 @@ ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1)
 enabled_cairo_pkgconf += cairo-wgl.pc
 endif

+supported_cairo_headers += $(cairo_nsgl_headers)
+all_cairo_headers += $(cairo_nsgl_headers)
+all_cairo_private += $(cairo_nsgl_private)
+all_cairo_cxx_sources += $(cairo_nsgl_cxx_sources)
+all_cairo_sources += $(cairo_nsgl_sources)
+ifeq ($(CAIRO_HAS_NSGL_FUNCTIONS),1)
+enabled_cairo_headers += $(cairo_nsgl_headers)
+enabled_cairo_private += $(cairo_nsgl_private)
+enabled_cairo_cxx_sources += $(cairo_nsgl_cxx_sources)
+enabled_cairo_sources += $(cairo_nsgl_sources)
+endif
+all_cairo_pkgconf += cairo-nsgl.pc
+ifeq ($(CAIRO_HAS_NSGL_FUNCTIONS),1)
+enabled_cairo_pkgconf += cairo-nsgl.pc
+endif
+
 supported_cairo_headers += $(cairo_script_headers)
 all_cairo_headers += $(cairo_script_headers)
 all_cairo_private += $(cairo_script_private)
diff --git a/src/cairo-gl.h b/src/cairo-gl.h
index cec3173..dec2216 100644
--- a/src/cairo-gl.h
+++ b/src/cairo-gl.h
@@ -126,6 +126,22 @@ cairo_gl_surface_create_for_dc (cairo_device_t *device,
  int height);
 #endif

+#if CAIRO_HAS_NSGL_FUNCTIONS
+#include <OpenGL/gl.h>
+
+cairo_public cairo_device_t *
+cairo_nsgl_device_create (void *abstract_ctx);
+
+cairo_public void *
+cairo_nsgl_device_get_context (cairo_device_t *device);
+
+cairo_public cairo_surface_t *
+cairo_gl_surface_create_for_view (cairo_device_t *device,
+  void *abstract_view,
+  int width,
+  int height);
+#endif
+
 #if CAIRO_HAS_EGL_FUNCTIONS
 #include <EGL/egl.h>

diff --git a/src/cairo-nsgl-context.m b/src/cairo-nsgl-context.m
new file mode 100644
index 0000000..b3e893c
--- /dev/null
+++ b/src/cairo-nsgl-context.m
@@ -0,0 +1,193 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2012 Henry Song
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * 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.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ * Carl Worth <cworth at cworth.org>
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ * Henry Song <henry.song at samsung.com>
+ */
+
+#import "cairoint.h"
+
+#import "cairo-gl-private.h"
+
+#import "cairo-error-private.h"
+
+#import <dlfcn.h>
+#import <stdlib.h>
+#import <string.h>
+#import <AppKit/NSOpenGL.h>
+#import <AppKit/NSOpenGLView.h>
+
+/* XXX needs hooking into XCloseDisplay() */
+
+typedef struct _cairo_nsgl_context {
+    cairo_gl_context_t base;
+
+    NSOpenGLContext *context;
+
+} cairo_nsgl_context_t;
+
+typedef struct _cairo_nsgl_surface {
+    cairo_gl_surface_t base;
+    NSView *view;
+} cairo_nsgl_surface_t;
+
+static void *
+nsglGetProcAddress (const char *name)
+{
+    return dlsym (RTLD_DEFAULT, name);
+}
+
+static void
+_nsgl_acquire (void *abstract_ctx)
+{
+    cairo_nsgl_context_t *ctx = abstract_ctx;
+
+    [ctx->context makeCurrentContext];
+}
+
+static void
+_nsgl_release (void *abstract_ctx)
+{
+    /* no-op */
+}
+
+static void
+_nsgl_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface)
+{
+    cairo_nsgl_context_t *ctx = abstract_ctx;
+    cairo_nsgl_surface_t *surface = (cairo_nsgl_surface_t *) abstract_surface;
+
+    /* Set the window as the target of our context. */
+    [ctx->context setView: surface->view];
+}
+
+static void
+_nsgl_swap_buffers (void *abstract_ctx,
+    cairo_gl_surface_t *abstract_surface)
+{
+    cairo_nsgl_context_t *ctx = abstract_ctx;
+    [ctx->context flushBuffer];
+}
+
+static void
+_nsgl_destroy (void *abstract_ctx)
+{
+    cairo_nsgl_context_t *ctx = abstract_ctx;
+
+    [ctx->context release];
+}
+
+cairo_device_t *
+cairo_nsgl_device_create (void *abstract_ctx)
+{
+    cairo_nsgl_context_t *ctx;
+    cairo_status_t status;
+    NSOpenGLContext *nsgl_ctx = (NSOpenGLContext *)abstract_ctx;
+
+    ctx = calloc (1, sizeof (cairo_nsgl_context_t));
+    if (unlikely (ctx == NULL))
+ return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
+
+    [ctx->context makeCurrentContext];
+
+    ctx->context = [nsgl_ctx retain];
+
+    ctx->base.acquire = _nsgl_acquire;
+    ctx->base.release = _nsgl_release;
+    ctx->base.make_current = _nsgl_make_current;
+    ctx->base.swap_buffers = _nsgl_swap_buffers;
+    ctx->base.destroy = _nsgl_destroy;
+
+    status = _cairo_gl_dispatch_init (&ctx->base.dispatch,
+      (cairo_gl_get_proc_addr_func_t) nsglGetProcAddress);
+    if (unlikely (status)) {
+ free (ctx);
+ return _cairo_gl_context_create_in_error (status);
+    }
+
+    status = _cairo_gl_context_init (&ctx->base);
+    if (unlikely (status)) {
+ free (ctx);
+ return _cairo_gl_context_create_in_error (status);
+    }
+
+    ctx->base.release (ctx);
+
+    return &ctx->base.base;
+}
+
+void *
+cairo_nsgl_device_get_context (cairo_device_t *device)
+{
+    cairo_nsgl_context_t *ctx;
+
+    if (device->backend->type != CAIRO_DEVICE_TYPE_GL) {
+ _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
+ return NULL;
+    }
+
+    ctx = (cairo_nsgl_context_t *) device;
+
+    return ctx->context;
+}
+
+cairo_surface_t *
+cairo_gl_surface_create_for_view (cairo_device_t *device,
+  void *abstract_view,
+  int width,
+  int height)
+{
+    cairo_nsgl_surface_t *surface;
+
+    if (unlikely (device->status))
+ return _cairo_surface_create_in_error (device->status);
+
+    if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
+
+    if (width <= 0 || height <= 0)
+        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+
+    surface = calloc (1, sizeof (cairo_nsgl_surface_t));
+    if (unlikely (surface == NULL))
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+    _cairo_gl_surface_init (device, &surface->base,
+    CAIRO_CONTENT_COLOR_ALPHA, width, height);
+    surface->view = (NSView *)abstract_view;
+
+    return &surface->base.base;
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index 07826ff..1e148d7 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -71,6 +71,15 @@ endif
 endif
 test_sources += $(test)

+if CAIRO_HAS_NSGL_FUNCTIONS
+cairo_nsgl_LIBS = \
+ -Xlinker -framework -Xlinker OpenGL \
+ -Xlinker -framework -Xlinker Appkit \
+ -Xlinker -framework -Xlinker Foundation
+else
+cairo_nsgl_LIBS =
+endif
+
 noinst_PROGRAMS = cairo-test-suite$(EXEEXT) # always build

 TESTS += cairo-test-suite$(EXEEXT)
@@ -84,6 +93,7 @@ cairo_test_suite_SOURCES = \
  $(test_sources) \
  cairo-test-constructors.c
 cairo_test_suite_CFLAGS = $(AM_CFLAGS) $(real_pthread_CFLAGS)
+cairo_test_suite_LDFLAGS = $(cairo_nsgl_LIBS)
 cairo_test_suite_LDADD = \
  $(real_pthread_LIBS) \
  $(top_builddir)/test/pdiff/libpdiff.la \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 1bf93e5..74a3623 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -390,7 +390,7 @@ ft_font_test_sources = \
  ft-text-vertical-layout-type3.c \
  ft-text-antialias-none.c

-gl_surface_test_sources = \
+#gl_surface_test_sources = \
  gl-surface-source.c

 quartz_surface_test_sources = quartz-surface-source.c
--
1.8.0.1

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20121231/463dd22d/attachment-0001.html>


More information about the cairo mailing list