1 /* cairo - a vector graphics library with display and print output
2 *
3 * Copyright © 2009 Eric Anholt
4 * Copyright © 2009 Chris Wilson
5 * Copyright © 2005 Red Hat, Inc
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
14 *
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
20 *
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
25 *
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
29 *
30 * The Original Code is the cairo graphics library.
31 *
32 * The Initial Developer of the Original Code is Red Hat, Inc.
33 *
34 * Contributor(s):
35 * Carl Worth <cworth@cworth.org>
36 * Chris Wilson <chris@chris-wilson.co.uk>
37 */
38
39 #include "cairoint.h"
40
41 #include "cairo-gl-private.h"
42
43 #include <i915_drm.h> /* XXX dummy surface for glewInit() */
44 #include <sys/ioctl.h>
45
46 typedef struct _cairo_eagle_context {
47 cairo_gl_context_t base;
48
49 EGLDisplay display;
50 EGLContext context;
51 } cairo_eagle_context_t;
52
53 typedef struct _cairo_eagle_surface {
54 cairo_gl_surface_t base;
55
56 EGLSurface eagle;
57 } cairo_eagle_surface_t;
58
59 static void
_eagle_make_current(void * abstract_ctx,cairo_gl_surface_t * abstract_surface)60 _eagle_make_current (void *abstract_ctx,
61 cairo_gl_surface_t *abstract_surface)
62 {
63 cairo_eagle_context_t *ctx = abstract_ctx;
64 cairo_eagle_surface_t *surface = (cairo_eagle_surface_t *) abstract_surface;
65
66 eagleMakeCurrent (ctx->display, surface->eagle, surface->eagle, ctx->context);
67 }
68
69 static void
_eagle_swap_buffers(void * abstract_ctx,cairo_gl_surface_t * abstract_surface)70 _eagle_swap_buffers (void *abstract_ctx,
71 cairo_gl_surface_t *abstract_surface)
72 {
73 cairo_eagle_context_t *ctx = abstract_ctx;
74 cairo_eagle_surface_t *surface = (cairo_eagle_surface_t *) abstract_surface;
75
76 eagleSwapBuffers (ctx->display, surface->eagle);
77 }
78
79 static void
_eagle_destroy(void * abstract_ctx)80 _eagle_destroy (void *abstract_ctx)
81 {
82 }
83
84 static cairo_bool_t
_eagle_init(EGLDisplay display,EGLContext context)85 _eagle_init (EGLDisplay display, EGLContext context)
86 {
87 const EGLint config_attribs[] = {
88 EGL_CONFIG_CAVEAT, EGL_NONE,
89 EGL_NONE
90 };
91 const EGLint surface_attribs[] = {
92 EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
93 EGL_NONE
94 };
95 EGLConfig config;
96 EGLSurface dummy;
97 struct drm_i915_gem_create create;
98 struct drm_gem_flink flink;
99 int fd;
100 GLenum err;
101
102 if (! eagleChooseConfig (display, config_attribs, &config, 1, NULL)) {
103 fprintf (stderr, "Unable to choose config\n");
104 return FALSE;
105 }
106
107 /* XXX */
108 fd = eagleGetDisplayFD (display);
109
110 create.size = 4096;
111 if (ioctl (fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
112 fprintf (stderr, "gem create failed: %m\n");
113 return FALSE;
114 }
115 flink.handle = create.handle;
116 if (ioctl (fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
117 fprintf (stderr, "gem flink failed: %m\n");
118 return FALSE;
119 }
120
121 dummy = eagleCreateSurfaceForName (display, config, flink.name,
122 1, 1, 4, surface_attribs);
123 if (dummy == NULL) {
124 fprintf (stderr, "Failed to create dummy surface\n");
125 return FALSE;
126 }
127
128 eagleMakeCurrent (display, dummy, dummy, context);
129 }
130
131 cairo_gl_context_t *
cairo_eagle_context_create(EGLDisplay display,EGLContext context)132 cairo_eagle_context_create (EGLDisplay display, EGLContext context)
133 {
134 cairo_eagle_context_t *ctx;
135 cairo_status_t status;
136
137 if (! _eagle_init (display, context)) {
138 return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
139 }
140
141 ctx = calloc (1, sizeof (cairo_eagle_context_t));
142 if (ctx == NULL)
143 return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
144
145 ctx->display = display;
146 ctx->context = context;
147
148 ctx->base.make_current = _eagle_make_current;
149 ctx->base.swap_buffers = _eagle_swap_buffers;
150 ctx->base.destroy = _eagle_destroy;
151
152 status = _cairo_gl_context_init (&ctx->base);
153 if (status) {
154 free (ctx);
155 return _cairo_gl_context_create_in_error (status);
156 }
157
158 return &ctx->base;
159 }
160
161 cairo_surface_t *
cairo_gl_surface_create_for_eagle(cairo_gl_context_t * ctx,EGLSurface eagle,int width,int height)162 cairo_gl_surface_create_for_eagle (cairo_gl_context_t *ctx,
163 EGLSurface eagle,
164 int width,
165 int height)
166 {
167 cairo_eagle_surface_t *surface;
168
169 if (ctx->status)
170 return _cairo_surface_create_in_error (ctx->status);
171
172 surface = calloc (1, sizeof (cairo_eagle_surface_t));
173 if (unlikely (surface == NULL))
174 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
175
176 _cairo_gl_surface_init (ctx, &surface->base,
177 CAIRO_CONTENT_COLOR_ALPHA, width, height);
178 surface->eagle = eagle;
179
180 return &surface->base.base;
181 }
182