1 /* Cairo - a vector graphics library with display and print output
3 * Copyright © 2009 Chris Wilson
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is Chris Wilson.
33 #include "cairo-boilerplate-private.h"
37 /* XXX Not sure how to handle library specific context initialization */
41 #if CAIRO_HAS_GLX_FUNCTIONS
46 typedef struct _vg_closure {
52 cairo_surface_t *surface;
56 _cairo_boilerplate_vg_cleanup_glx (void *closure)
58 vg_closure_glx_t *vgc = closure;
61 vgDestroyContextAM ();
64 vgDestroyContextSH ();
67 glXDestroyContext (vgc->dpy, vgc->ctx);
68 XDestroyWindow (vgc->dpy, vgc->win);
69 XCloseDisplay (vgc->dpy);
73 static cairo_surface_t *
74 _cairo_boilerplate_vg_create_surface_glx (const char *name,
75 cairo_content_t content,
80 cairo_boilerplate_mode_t mode,
83 int rgba_attribs[] = {
103 XSetWindowAttributes swa;
104 cairo_surface_t *surface;
105 cairo_vg_context_t *context;
106 vg_closure_glx_t *vgc;
108 vgc = malloc (sizeof (vg_closure_glx_t));
116 dpy = XOpenDisplay (NULL);
118 if (vgc->dpy == NULL) {
119 fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
124 if (content == CAIRO_CONTENT_COLOR)
125 vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgb_attribs);
127 vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
130 fprintf (stderr, "Failed to create RGB, double-buffered visual\n");
136 vgc->ctx = glXCreateContext (dpy, vi, NULL, True);
137 cmap = XCreateColormap (dpy,
138 RootWindow (dpy, vi->screen),
142 swa.border_pixel = 0;
143 vgc->win = XCreateWindow (dpy, RootWindow (dpy, vi->screen),
148 CWBorderPixel | CWColormap, &swa);
149 XFreeColormap (dpy, cmap);
152 XMapWindow (dpy, vgc->win);
154 /* we need an active context to initialise VG */
155 glXMakeContextCurrent (dpy, vgc->win, vgc->win, vgc->ctx);
158 vgInitContextAM (width, height, VG_FALSE, VG_TRUE);
161 vgCreateContextSH (width, height);
164 context = cairo_vg_context_create_for_glx (dpy, vgc->ctx);
165 vgc->surface = cairo_vg_surface_create (context, content, width, height);
166 cairo_vg_context_destroy (context);
168 surface = vgc->surface;
169 if (cairo_surface_status (surface))
170 _cairo_boilerplate_vg_cleanup_glx (vgc);
176 #if CAIRO_HAS_EGL_FUNCTIONS
177 typedef struct _vg_closure_egl {
184 _cairo_boilerplate_vg_cleanup_egl (void *closure)
186 vg_closure_egl_t *vgc = closure;
189 vgDestroyContextAM ();
192 vgDestroyContextSH ();
195 eglDestroyContext (vgc->dpy, vgc->ctx);
196 eglDestroySurface (vgc->dpy, vgc->dummy);
197 eglTerminate (vgc->dpy);
201 static cairo_surface_t *
202 _cairo_boilerplate_vg_create_surface_egl (const char *name,
203 cairo_content_t content,
208 cairo_boilerplate_mode_t mode,
211 int rgba_attribs[] = {
216 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
217 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
220 int rgb_attribs[] = {
225 EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE_BIT,
226 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
227 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
230 int dummy_attribs[] = {
231 EGL_WIDTH, 8, EGL_HEIGHT, 8,
238 EGLContext *egl_context;
240 cairo_vg_context_t *context;
241 cairo_surface_t *surface;
242 vg_closure_egl_t *vgc;
244 dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
246 if (! eglInitialize (dpy, &major, &minor))
249 eglBindAPI (EGL_OPENVG_API);
251 if (! eglChooseConfig (dpy,
252 content == CAIRO_CONTENT_COLOR_ALPHA ?
253 rgba_attribs : rgb_attribs,
254 &config, 1, &num_configs) ||
260 egl_context = eglCreateContext (dpy, config, NULL, NULL);
261 if (egl_context == NULL)
264 /* Create a dummy surface in order to enable a context to initialise VG */
265 dummy = eglCreatePbufferSurface (dpy, config, dummy_attribs);
268 if (! eglMakeCurrent (dpy, dummy, dummy, egl_context))
272 vgInitContextAM (width, height, VG_FALSE, VG_TRUE);
275 vgCreateContextSH (width, height);
278 vgc = xmalloc (sizeof (vg_closure_egl_t));
280 vgc->ctx = egl_context;
284 context = cairo_vg_context_create_for_egl (vgc->dpy, vgc->ctx);
285 surface = cairo_vg_surface_create (context, content, width, height);
286 cairo_vg_context_destroy (context);
288 if (cairo_surface_status (surface))
289 _cairo_boilerplate_vg_cleanup_egl (vgc);
296 _cairo_boilerplate_vg_synchronize (void *closure)
301 static const cairo_boilerplate_target_t targets[] = {
302 #if CAIRO_HAS_GLX_FUNCTIONS
304 "vg-glx", "vg", NULL, NULL,
305 CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR_ALPHA, 1,
306 "cairo_vg_context_create_for_glx",
307 _cairo_boilerplate_vg_create_surface_glx,
308 cairo_surface_create_similar,
310 _cairo_boilerplate_get_image_surface,
311 cairo_surface_write_to_png,
312 _cairo_boilerplate_vg_cleanup_glx,
313 _cairo_boilerplate_vg_synchronize,
318 "vg-glx", "vg", NULL, NULL,
319 CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR, 1,
320 "cairo_vg_context_create_for_glx",
321 _cairo_boilerplate_vg_create_surface_glx,
322 cairo_surface_create_similar,
324 _cairo_boilerplate_get_image_surface,
325 cairo_surface_write_to_png,
326 _cairo_boilerplate_vg_cleanup_glx,
327 _cairo_boilerplate_vg_synchronize,
332 #if CAIRO_HAS_EGL_FUNCTIONS
334 "vg-egl", "vg", NULL, NULL,
335 CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR_ALPHA, 1,
336 "cairo_vg_context_create_for_egl",
337 _cairo_boilerplate_vg_create_surface_egl,
338 cairo_surface_create_similar,
340 _cairo_boilerplate_get_image_surface,
341 cairo_surface_write_to_png,
342 _cairo_boilerplate_vg_cleanup_egl,
343 _cairo_boilerplate_vg_synchronize,
348 "vg-egl", "vg", NULL, NULL,
349 CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR, 1,
350 "cairo_vg_context_create_for_egl",
351 _cairo_boilerplate_vg_create_surface_egl,
352 cairo_surface_create_similar,
354 _cairo_boilerplate_get_image_surface,
355 cairo_surface_write_to_png,
356 _cairo_boilerplate_vg_cleanup_egl,
357 _cairo_boilerplate_vg_synchronize,
363 CAIRO_BOILERPLATE (vg, targets)