Commit 94f9330609ec305d998e58abfddfbbdf8ae51c9d

  • avatar
  • Chia-I Wu <olvaffe @gm…l.com>
  • Fri Sep 18 09:32:26 CEST 2009
egl_android: New EGL driver for Android.
  
1LOCAL_PATH := $(call my-dir)
2
3include $(CLEAR_VARS)
4
5LOCAL_SRC_FILES := \
6 main/eglapi.c \
7 main/eglclient.c \
8 main/eglconfig.c \
9 main/eglconfigutil.c \
10 main/eglcontext.c \
11 main/eglcurrent.c \
12 main/egldisplay.c \
13 main/egldriver.c \
14 main/eglglobals.c \
15 main/eglimage.c \
16 main/egllog.c \
17 main/eglmisc.c \
18 main/eglmode.c \
19 main/eglscreen.c \
20 main/eglstring.c \
21 main/eglsurface.c
22
23LOCAL_SRC_FILES += \
24 drivers/android/egl_android.c \
25 drivers/android/droid_loader.c \
26 drivers/android/droid_ui.cpp \
27 drivers/android/droid_intel.c
28
29LOCAL_C_INCLUDES += \
30 $(LOCAL_PATH)/main \
31 external/mesa/include \
32 external/mesa/src/mesa \
33 external/drm/shared-core
34
35LOCAL_CFLAGS += -DPTHREADS -D_EGL_PLATFORM_X=1
36LOCAL_SHARED_LIBRARIES := libdl libui libutils
37LOCAL_STATIC_LIBRARIES := libes1api
38
39LOCAL_MODULE := libhgl
40
41include $(BUILD_SHARED_LIBRARY)
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * This is based on the work of eagle, by
5 * Copyright © 2008, 2009 Kristian Høgsberg
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#ifndef _DROID_H_
28#define _DROID_H_
29
30#include "GL/gl.h"
31#include "GL/internal/dri_interface.h"
32
33#include "eglcurrent.h"
34#include "egldisplay.h"
35#include "eglcontext.h"
36#include "eglsurface.h"
37#include "eglconfig.h"
38
39/* opaque types */
40struct droid_loader;
41struct droid_context;
42struct droid_drawable;
43struct droid_surface;
44
45struct droid_backend {
46 /* these are usually used by a loader */
47 const char *driver_name;
48 int (*initialize)(struct droid_backend *backend, int *fd, int *screen_number);
49 void (*destroy)(struct droid_backend *backend);
50
51 __DRIbuffer *(*get_native_buffer)(struct droid_backend *backend,
52 struct droid_surface *surf,
53 int *width, int *height);
54 __DRIbuffer *(*get_surface_buffers)(struct droid_backend *backend,
55 struct droid_surface *surf,
56 int *width, int *height,
57 unsigned int *attachments, int count,
58 int *out_count, int has_format);
59
60 /* public methods */
61 struct droid_surface *(*create_window_surface)(struct droid_backend *backend,
62 _EGLSurface *surf,
63 NativeWindowType win);
64 void (*destroy_surface)(struct droid_backend *backend, struct droid_surface *surf);
65 void (*swap_native_buffers)(struct droid_backend *backend,
66 struct droid_surface *surf);
67};
68
69struct droid_screen {
70 struct droid_loader *loader;
71
72 __DRIscreen *dri_screen;
73 __DRItexBufferExtension *tex_buffer;
74 __DRIcopyBufferExtension *copy_buffer;
75
76 const __DRIconfig **dri_configs;
77 int num_dri_configs;
78};
79
80struct droid_backend *
81droid_backend_create_intel(const char *dev);
82
83void
84droid_backend_destroy(struct droid_backend *backend);
85
86struct droid_screen *
87droid_screen_create(struct droid_backend *backend);
88
89void
90droid_screen_destroy(struct droid_screen *screen);
91
92void
93droid_screen_convert_config(struct droid_screen *screen,
94 const __DRIconfig *conf, _EGLConfig *egl_conf);
95
96struct droid_context *
97droid_screen_create_context(struct droid_screen *screen,
98 const __DRIconfig *conf,
99 struct droid_context *shared);
100
101void
102droid_screen_destroy_context(struct droid_screen *screen,
103 struct droid_context *ctx);
104
105struct droid_drawable *
106droid_screen_create_drawable(struct droid_screen *screen,
107 const __DRIconfig *conf,
108 struct droid_surface *surf);
109
110void
111droid_screen_destroy_drawable(struct droid_screen *screen,
112 struct droid_drawable *drawable);
113
114int
115droid_screen_bind_context(struct droid_screen *screen,
116 struct droid_drawable *draw,
117 struct droid_drawable *read,
118 struct droid_context *ctx);
119
120int
121droid_screen_swap_buffers(struct droid_screen *screen,
122 struct droid_context *ctx,
123 struct droid_drawable *drawable);
124
125#endif /* _DROID_H_ */
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * This is based on the work of eagle, by
5 * Copyright © 2008, 2009 Kristian Høgsberg
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that copyright
10 * notice and this permission notice appear in supporting documentation, and
11 * that the name of the copyright holders not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. The copyright holders make no representations
14 * about the suitability of this software for any purpose. It is provided "as
15 * is" without express or implied warranty.
16 *
17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 * OF THIS SOFTWARE.
24 */
25
26#define LOG_TAG "DROID-INTEL"
27#include <utils/Log.h>
28
29#include <stdio.h>
30#include <string.h>
31#include <stdlib.h>
32#include <stdint.h>
33#include <sys/ioctl.h>
34#include <sys/mman.h>
35#include <fcntl.h>
36#include <unistd.h>
37#include <i915_drm.h>
38#include <GL/gl.h> /* dri_interface.h uses some GL integer types... */
39#include <GL/internal/dri_interface.h>
40#include <EGL/egl.h>
41
42#include "droid.h"
43#include "droid_ui.h"
44
45#define INTEL_STRIDE_ALIGNMENT 64
46
47enum {
48 INTEL_SURFACE_TYPE_WINDOW,
49};
50
51struct droid_backend_intel {
52 struct droid_backend base;
53 int fd;
54 int screen_number;
55};
56
57struct droid_surface_intel {
58 int type;
59 union {
60 NativeWindowType win;
61 } native;
62 __DRIbuffer native_buffer;
63 unsigned int native_width, native_height;
64 int native_changed;
65
66 unsigned int attachments[20];
67 __DRIbuffer buffers[10];
68 uint32_t handles[10];
69 int num_buffers;
70 int depth_idx;
71
72 _EGLSurface *surf;
73};
74
75static INLINE struct droid_backend_intel *
76lookup_backend(struct droid_backend *backend)
77{
78 return (struct droid_backend_intel *) backend;
79}
80
81static INLINE struct droid_surface_intel *
82lookup_surface(struct droid_surface *surface)
83{
84 return (struct droid_surface_intel *) surface;
85}
86
87static __DRIbuffer *
88intel_get_native_buffer(struct droid_backend *backend,
89 struct droid_surface *surf,
90 int *width, int *height)
91{
92 struct droid_surface_intel *isurf = lookup_surface(surf);
93
94 if (!isurf->native_buffer.name)
95 return NULL;
96
97 if (width)
98 *width = isurf->native_width;
99 if (height)
100 *height = isurf->native_height;
101
102 return &isurf->native_buffer;
103}
104
105static inline uint32_t
106align_to(uint32_t value, uint32_t align)
107{
108 return (value + align - 1) & ~(align - 1);
109}
110
111static int
112create_buffer(int fd, GLint width, GLint height, GLint cpp, __DRIbuffer *buffer)
113{
114 struct drm_i915_gem_create create;
115 struct drm_gem_flink flink;
116 uint32_t size;
117
118 buffer->pitch = align_to(width * cpp, INTEL_STRIDE_ALIGNMENT);
119 size = buffer->pitch * height;
120 create.size = size;
121 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) {
122 LOGE("failed to create buffer");
123 return 0;
124 }
125
126 flink.handle = create.handle;
127 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
128 LOGE("failed to flink buffer");
129 return 0;
130 }
131
132 buffer->name = flink.name;
133 buffer->cpp = cpp;
134
135 return create.handle;
136}
137
138static void
139delete_buffers(struct droid_backend *backend, struct droid_surface *surf)
140{
141 struct droid_backend_intel *intel = lookup_backend(backend);
142 struct droid_surface_intel *isurf = lookup_surface(surf);
143 int i;
144
145 for (i = 0; i < isurf->num_buffers; i++) {
146 if (isurf->handles[i]) {
147 struct drm_gem_close close;
148
149 close.handle = isurf->handles[i];
150 if (ioctl(intel->fd, DRM_IOCTL_GEM_CLOSE, &close) < 0)
151 LOGE("failed to close bo %d", close.handle);
152 isurf->handles[i] = 0;
153 }
154 }
155
156 isurf->num_buffers = 0;
157}
158
159static __DRIbuffer *
160intel_get_surface_buffers(struct droid_backend *backend,
161 struct droid_surface *surf,
162 int *width, int *height,
163 unsigned int *attachments, int count,
164 int *out_count, int has_format)
165{
166 struct droid_backend_intel *intel = lookup_backend(backend);
167 struct droid_surface_intel *isurf = lookup_surface(surf);
168 unsigned int att_size;
169 __DRIbuffer buffers[10];
170 uint32_t handles[10];
171 int num = 0;
172
173 if (count > 10) {
174 LOGW("too many buffers requested");
175 count = 10;
176 }
177
178 att_size = sizeof(attachments[0]) * count * ((has_format) ? 2 : 1);
179
180 if (isurf->native_changed) {
181 delete_buffers(backend, surf);
182 isurf->native_changed = 0;
183 }
184
185 /* same buffers requested */
186 if (isurf->num_buffers == count &&
187 memcmp(isurf->attachments, attachments, att_size) == 0) {
188 num = isurf->num_buffers;
189 goto end;
190 }
191 memcpy(isurf->attachments, attachments, att_size);
192
193 while (count-- > 0) {
194 unsigned int att = *attachments++;
195 unsigned int format = (has_format) ? *attachments++ : 0;
196 unsigned int cpp = (format) ? format / 8 : isurf->native_buffer.cpp;
197 __DRIbuffer *buf = NULL;
198 int reuse;
199
200 /* re-use buffer */
201 for (reuse = 0; reuse < isurf->num_buffers; reuse++) {
202 if (isurf->buffers[reuse].attachment == att) {
203 if (isurf->buffers[reuse].cpp == cpp &&
204 isurf->handles[reuse])
205 buf = &isurf->buffers[reuse];
206 break;
207 }
208 }
209
210 if (0)
211 LOGD("%s buffer %d: att %d cpp %d",
212 (buf) ? "reuse" : "create", num, att, cpp);
213
214 if (buf) {
215 buffers[num] = isurf->buffers[reuse];
216 handles[num] = isurf->handles[reuse];
217 isurf->handles[reuse] = 0;
218 }
219 else {
220 buffers[num].attachment = att;
221 handles[num] = create_buffer(intel->fd,
222 isurf->native_width,
223 isurf->native_height,
224 cpp,
225 &buffers[num]);
226 }
227 num++;
228 }
229
230 /* delete buffers that are not re-used */
231 delete_buffers(backend, surf);
232
233 memcpy(isurf->buffers, buffers, sizeof(buffers[0]) * num);
234 memcpy(isurf->handles, handles, sizeof(handles[0]) * num);
235 isurf->num_buffers = num;
236
237end:
238 *out_count = num;
239 *width = isurf->native_width;
240 *height = isurf->native_height;
241
242 return isurf->buffers;
243}
244
245static void
246update_native_buffer(struct droid_surface *surf)
247{
248 struct droid_surface_intel *isurf = lookup_surface(surf);
249 unsigned int name, cpp, pitch, width, height;
250
251 switch (isurf->type) {
252 case INTEL_SURFACE_TYPE_WINDOW:
253 /* oem[0] always point to the buffer that a client is drawing to */
254 name = isurf->native.win->oem[0];
255 cpp = ui_bytes_per_pixel(isurf->native.win->format);
256 pitch = isurf->native.win->stride * cpp;
257 width = isurf->native.win->width;
258 height = isurf->native.win->height;
259 break;
260 default:
261 name = cpp = pitch = width = height = 0;
262 break;
263 }
264
265 isurf->native_buffer.attachment = __DRI_BUFFER_FRONT_LEFT;
266 isurf->native_buffer.name = name;
267 isurf->native_buffer.cpp = cpp;
268 isurf->native_buffer.pitch = pitch;
269 isurf->native_buffer.flags = 0;
270
271 isurf->native_width = width;
272 isurf->native_height = height;
273
274 isurf->native_changed = 1;
275}
276
277static struct droid_surface *
278intel_create_window_surface(struct droid_backend *backend,
279 _EGLSurface *surf,
280 NativeWindowType win)
281{
282 struct droid_surface_intel *isurf;
283 uint32_t pitch, cpp;
284
285 if (!win) {
286 LOGE("invalid native window");
287 _eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface");
288 return NULL;
289 }
290
291 /* TODO lift this limitation */
292 if (!win->oem[0]) {
293 LOGE("TODO support for non-gem based window");
294 _eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface");
295 return NULL;
296 }
297
298 cpp = ui_bytes_per_pixel(win->format);
299 pitch = win->stride * cpp;
300
301 isurf = calloc(1, sizeof(*isurf));
302 if (!isurf) {
303 _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
304 return NULL;
305 }
306
307 isurf->type = INTEL_SURFACE_TYPE_WINDOW;
308 isurf->native.win = win;
309
310 surf->Width = win->width;
311 surf->Height = win->height;
312 /* always back buffer */
313 surf->RenderBuffer = EGL_BACK_BUFFER;
314
315 isurf->surf = surf;
316
317 update_native_buffer((struct droid_surface *) isurf);
318
319 return (struct droid_surface *) isurf;
320}
321
322static void
323intel_destroy_surface(struct droid_backend *backend, struct droid_surface *surf)
324{
325 struct droid_surface_intel *isurf = lookup_surface(surf);
326 delete_buffers(backend, surf);
327 free(isurf);
328}
329
330static void
331intel_swap_native_buffers(struct droid_backend *backend,
332 struct droid_surface *surf)
333{
334 struct droid_surface_intel *isurf = lookup_surface(surf);
335
336 if (isurf->type == INTEL_SURFACE_TYPE_WINDOW) {
337 uint32_t flags;
338
339 flags = isurf->native.win->swapBuffers(isurf->native.win);
340 if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
341 update_native_buffer(surf);
342 } else {
343 /* oem[0] is changed after buffer swap */
344 isurf->native_buffer.name = isurf->native.win->oem[0];
345 }
346 }
347}
348
349static int
350intel_initialize(struct droid_backend *backend, int *fd, int *screen_number)
351{
352 struct droid_backend_intel *intel = lookup_backend(backend);
353 drm_auth_t auth;
354 int err;
355
356 err = ioctl(intel->fd, DRM_IOCTL_GET_MAGIC, &auth);
357 if (!err)
358 err = ui_auth_gpu(auth.magic);
359
360 if (err) {
361 LOGE("failed to authenticate");
362 return 0;
363 }
364
365 if (fd)
366 *fd = intel->fd;
367 if (screen_number)
368 *screen_number = intel->screen_number;
369
370 return 1;
371}
372
373static void
374intel_destroy(struct droid_backend *backend)
375{
376 struct droid_backend_intel *intel = lookup_backend(backend);
377 close(intel->fd);
378 free(intel);
379}
380
381struct droid_backend *
382droid_backend_create_intel(const char *dev)
383{
384 struct droid_backend_intel *intel;
385
386 intel = calloc(1, sizeof(*intel));
387 if (!intel)
388 return NULL;
389
390 intel->fd = open(dev, O_RDWR);
391 if (intel->fd < 0) {
392 LOGE("failed to open %s", dev);
393 free(intel);
394 return NULL;
395 }
396
397 intel->screen_number = 0;
398 intel->base.driver_name = "i915";
399 intel->base.initialize = intel_initialize;
400 intel->base.destroy = intel_destroy;
401
402 intel->base.get_native_buffer = intel_get_native_buffer;
403 intel->base.get_surface_buffers = intel_get_surface_buffers;
404
405 intel->base.create_window_surface = intel_create_window_surface;
406 intel->base.destroy_surface = intel_destroy_surface;
407 intel->base.swap_native_buffers = intel_swap_native_buffers;
408
409 return &intel->base;
410}
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * This is based on the work of eagle, by
5 * Copyright © 2008, 2009 Kristian Høgsberg
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#define LOG_TAG "DROID-LOADER"
28#include <utils/Log.h>
29
30#include <string.h>
31#include <errno.h>
32#include <dlfcn.h>
33#include <assert.h>
34
35#include "droid.h"
36
37#ifndef DROID_DRIVER_PATH
38#define DROID_DRIVER_PATH "/system/lib"
39#endif
40
41struct droid_loader {
42 struct droid_backend *backend;
43
44 char *filename;
45 void *handle;
46
47 __DRIcoreExtension *core;
48 __DRIdri2Extension *dri2;
49};
50
51struct droid_context {
52 __DRIcontext *dri_context;
53};
54
55struct droid_drawable {
56 struct droid_loader *loader;
57 struct droid_surface *surface;
58
59 __DRIdrawable *dri_drawable;
60};
61
62static __DRIbuffer *
63loader_ext_get_buffers_with_format(__DRIdrawable *driDrawable,
64 int *width, int *height,
65 unsigned int *attachments, int count,
66 int *out_count, void *loaderPrivate)
67{
68 struct droid_drawable *drawable = (struct droid_drawable *) loaderPrivate;
69 struct droid_loader *loader = drawable->loader;
70 __DRIbuffer *buffers;
71
72 buffers = loader->backend->get_surface_buffers(loader->backend,
73 drawable->surface,
74 width, height,
75 attachments, count,
76 out_count, 1);
77
78 return buffers;
79}
80
81static const __DRIdri2LoaderExtension loader_ext_dri2_loader = {
82 { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
83 NULL,
84 NULL,
85 loader_ext_get_buffers_with_format,
86};
87
88static int
89loader_ext_get_ust(int64_t *ust)
90{
91 struct timeval tv;
92
93 if (ust == NULL)
94 return -EFAULT;
95
96 if (gettimeofday(&tv, NULL) == 0) {
97 ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
98 return 0;
99 } else {
100 return -errno;
101 }
102}
103
104static const __DRIsystemTimeExtension loader_ext_system_time = {
105 { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
106 loader_ext_get_ust,
107 NULL,
108};
109
110static const __DRIextension *loader_extensions[] = {
111 &loader_ext_dri2_loader.base,
112 &loader_ext_system_time.base,
113 NULL
114};
115
116static struct droid_loader *
117loader_create(struct droid_backend *backend)
118{
119 struct droid_loader *loader;
120
121 loader = calloc(1, sizeof(*loader));
122 if (!loader)
123 return NULL;
124
125 loader->backend = backend;
126
127 return loader;
128}
129
130static void
131loader_destroy(struct droid_loader *loader)
132{
133 if (loader->filename)
134 free(loader->filename);
135 if (loader->handle)
136 dlclose(loader->handle);
137 free(loader);
138}
139
140static int
141loader_load(struct droid_loader *loader, const char *filename)
142{
143 const __DRIextension **extensions;
144 const char *path = NULL;
145 int i;
146
147 LOGD("Loading DRI driver %s", filename);
148
149 loader->handle = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
150 if (loader->handle == NULL) {
151 LOGE("dlopen: %s", dlerror());
152 return 0;
153 }
154
155 extensions = dlsym(loader->handle, __DRI_DRIVER_EXTENSIONS);
156 if (extensions == NULL) {
157 LOGE("dlsym: %s", dlerror());
158 dlclose(loader->handle);
159 loader->handle = NULL;
160 return 0;
161 }
162
163 for (i = 0; extensions[i]; i++) {
164 if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
165 extensions[i]->version >= __DRI_CORE_VERSION) {
166 loader->core = (__DRIcoreExtension *) extensions[i];
167 }
168
169 if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
170 extensions[i]->version >= __DRI_DRI2_VERSION) {
171 loader->dri2 = (__DRIdri2Extension *) extensions[i];
172 }
173 }
174
175 if (loader->core == NULL || loader->dri2 == NULL) {
176 LOGE("missing required DRI extensions");
177 dlclose(loader->handle);
178 loader->handle = NULL;
179 return 0;
180 }
181
182 return 1;
183}
184
185static int
186loader_init(struct droid_loader *loader)
187{
188 char filename[1024];
189 const char *path;
190
191 path = DROID_DRIVER_PATH;
192 snprintf(filename, sizeof(filename), "%s/%s_dri.so",
193 path, loader->backend->driver_name);
194
195 if (!loader_load(loader, filename))
196 return 0;
197
198 loader->filename = strdup(filename);
199
200 return 1;
201}
202
203void
204droid_backend_destroy(struct droid_backend *backend)
205{
206 backend->destroy(backend);
207}
208
209struct droid_screen *
210droid_screen_create(struct droid_backend *backend)
211{
212 struct droid_screen *screen = NULL;
213 struct droid_loader *loader;
214 const __DRIextension **extensions;
215 int fd, screen_number;
216 int i;
217
218 loader = loader_create(backend);
219 if (!loader || !loader_init(loader)) {
220 LOGE("failed to initialize loader");
221 goto fail;
222 }
223
224 screen = calloc(1, sizeof(*screen));
225 if (!screen) {
226 LOGE("failed to allocate new screen");
227 goto fail;
228 }
229
230 if (!loader->backend->initialize(loader->backend, &fd, &screen_number)) {
231 LOGE("failed to initialize backend");
232 goto fail;
233 }
234
235 screen->loader = loader;
236 screen->dri_screen =
237 loader->dri2->createNewScreen(screen_number, fd,
238 loader_extensions,
239 &screen->dri_configs, NULL);
240 if (!screen->dri_screen) {
241 LOGE("failed to create DRI screen");
242 goto fail;
243 }
244
245 extensions = loader->core->getExtensions(screen->dri_screen);
246
247 for (i = 0; extensions && extensions[i]; i++) {
248 if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0 &&
249 extensions[i]->version >= __DRI_TEX_BUFFER_VERSION)
250 screen->tex_buffer = (__DRItexBufferExtension *) extensions[i];
251
252 if (strcmp(extensions[i]->name, __DRI_COPY_BUFFER) == 0 &&
253 extensions[i]->version >= __DRI_COPY_BUFFER_VERSION)
254 screen->copy_buffer = (__DRIcopyBufferExtension *) extensions[i];
255 }
256
257 if (!screen->tex_buffer) {
258 LOGE("DRI driver has no TexBuffer extension");
259 goto fail;
260 }
261
262 if (!screen->tex_buffer) {
263 LOGE("DRI driver has no CopyBuffer extension");
264 goto fail;
265 }
266
267 for (i = 0; screen->dri_configs[i]; i++)
268 ;
269 screen->num_dri_configs = i;
270
271 return screen;
272
273fail:
274 if (screen)
275 droid_screen_destroy(screen);
276 if (loader)
277 loader_destroy(loader);
278
279 return NULL;
280}
281
282void
283droid_screen_destroy(struct droid_screen *screen)
284{
285 struct droid_loader *loader = screen->loader;
286 if (screen->dri_screen)
287 loader->core->destroyScreen(screen->dri_screen);
288 free(screen);
289}
290
291static const struct {
292 EGLenum egl_attrib;
293 unsigned int dri_attrib;
294} droid_attrib_map[] = {
295 { EGL_BUFFER_SIZE, __DRI_ATTRIB_BUFFER_SIZE },
296 { EGL_RED_SIZE, __DRI_ATTRIB_RED_SIZE },
297 { EGL_GREEN_SIZE, __DRI_ATTRIB_GREEN_SIZE },
298 { EGL_BLUE_SIZE, __DRI_ATTRIB_BLUE_SIZE },
299 { EGL_ALPHA_SIZE, __DRI_ATTRIB_ALPHA_SIZE },
300 { EGL_BIND_TO_TEXTURE_RGB, __DRI_ATTRIB_BIND_TO_TEXTURE_RGB },
301 { EGL_BIND_TO_TEXTURE_RGBA, __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA },
302 { EGL_CONFIG_CAVEAT, __DRI_ATTRIB_CONFIG_CAVEAT },
303 { EGL_DEPTH_SIZE, __DRI_ATTRIB_DEPTH_SIZE },
304 { EGL_LEVEL, __DRI_ATTRIB_LEVEL },
305 { EGL_MAX_PBUFFER_WIDTH, __DRI_ATTRIB_MAX_PBUFFER_WIDTH },
306 { EGL_MAX_PBUFFER_HEIGHT, __DRI_ATTRIB_MAX_PBUFFER_HEIGHT },
307 { EGL_MAX_PBUFFER_PIXELS, __DRI_ATTRIB_MAX_PBUFFER_PIXELS },
308 { EGL_SAMPLE_BUFFERS, __DRI_ATTRIB_SAMPLE_BUFFERS },
309 { EGL_SAMPLES, __DRI_ATTRIB_SAMPLES },
310 { EGL_STENCIL_SIZE, __DRI_ATTRIB_STENCIL_SIZE },
311};
312
313void
314droid_screen_convert_config(struct droid_screen *screen,
315 const __DRIconfig *conf, _EGLConfig *egl_conf)
316{
317 struct droid_loader *loader = screen->loader;
318 const int num_attrs =
319 sizeof(droid_attrib_map) / sizeof(droid_attrib_map[0]);
320 int i;
321
322 for (i = 0; i < num_attrs; i++) {
323 unsigned int dri_attrib = droid_attrib_map[i].dri_attrib;
324 unsigned int dri_value;
325 EGLenum egl_attrib = droid_attrib_map[i].egl_attrib;
326 EGLint egl_value;
327
328 if (!loader->core->getConfigAttrib(conf, dri_attrib, &dri_value)) {
329 LOGE("failed to get attribute %02d for %p", dri_attrib, conf);
330 continue;
331 }
332
333 switch (egl_attrib) {
334 case EGL_CONFIG_CAVEAT:
335 if (dri_value & __DRI_ATTRIB_SLOW_BIT)
336 egl_value = EGL_SLOW_CONFIG;
337 else if (dri_value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
338 egl_value = EGL_NON_CONFORMANT_CONFIG;
339 else
340 egl_value = EGL_NONE;
341 break;
342 default:
343 egl_value = (EGLint) dri_value;
344 break;
345 }
346 SET_CONFIG_ATTRIB(egl_conf, egl_attrib, egl_value);
347 }
348}
349
350struct droid_context *
351droid_screen_create_context(struct droid_screen *screen,
352 const __DRIconfig *conf,
353 struct droid_context *shared)
354{
355 struct droid_loader *loader = screen->loader;
356 struct droid_context *ctx;
357
358 ctx = calloc(1, sizeof(*ctx));
359 if (!ctx) {
360 LOGE("failed to allocate context");
361 return NULL;
362 }
363
364 ctx->dri_context =
365 loader->dri2->createNewContext(screen->dri_screen, conf,
366 (shared) ? shared->dri_context : NULL,
367 NULL);
368 if (!ctx->dri_context) {
369 LOGE("failed to create DRI context");
370 free(ctx);
371 return NULL;
372 }
373
374 return ctx;
375}
376
377void
378droid_screen_destroy_context(struct droid_screen *screen,
379 struct droid_context *ctx)
380{
381 struct droid_loader *loader = screen->loader;
382 loader->core->destroyContext(ctx->dri_context);
383 free(ctx);
384}
385
386struct droid_drawable *
387droid_screen_create_drawable(struct droid_screen *screen,
388 const __DRIconfig *conf,
389 struct droid_surface *surf)
390{
391 struct droid_loader *loader = screen->loader;
392 struct droid_drawable *drawable;
393
394 drawable = calloc(1, sizeof(*drawable));
395 if (!drawable) {
396 LOGE("failed to allocate drawable");
397 return NULL;
398 }
399
400 /* needed in GetBuffers */
401 drawable->loader = loader;
402 drawable->surface = surf;
403
404 drawable->dri_drawable =
405 loader->dri2->createNewDrawable(screen->dri_screen,
406 conf, (void *) drawable);
407 if (!drawable->dri_drawable) {
408 LOGE("failed to create DRI drawable");
409 free(drawable);
410 return NULL;
411 }
412
413 return drawable;
414}
415
416void
417droid_screen_destroy_drawable(struct droid_screen *screen,
418 struct droid_drawable *drawable)
419{
420 struct droid_loader *loader = screen->loader;
421 loader->core->destroyDrawable(drawable->dri_drawable);
422 free(drawable);
423}
424
425int
426droid_screen_bind_context(struct droid_screen *screen,
427 struct droid_drawable *draw,
428 struct droid_drawable *read,
429 struct droid_context *ctx)
430{
431 struct droid_loader *loader = screen->loader;
432 int ret = 0;
433
434 if (ctx) {
435 if (draw && read)
436 ret = loader->core->bindContext(ctx->dri_context,
437 draw->dri_drawable,
438 read->dri_drawable);
439 else if (!draw && !read)
440 ret = loader->core->unbindContext(ctx->dri_context);
441 }
442
443 if (!ret)
444 LOGE("failed to bind context %p", ctx);
445
446 return ret;
447}
448
449int
450droid_screen_swap_buffers(struct droid_screen *screen,
451 struct droid_context *ctx,
452 struct droid_drawable *drawable)
453{
454 struct droid_loader *loader = screen->loader;
455 __DRIbuffer *native;
456 int width, height;
457 int err = 0;
458
459 native = loader->backend->get_native_buffer(loader->backend,
460 drawable->surface,
461 &width, &height);
462
463 /* copy from front buffer to native buffer */
464 if (native)
465 err = screen->copy_buffer->copyBuffer(ctx->dri_context, native, 0, 0,
466 drawable->dri_drawable,
467 __DRI_BUFFER_FRONT_LEFT, 0, 0,
468 width, height);
469
470 if (!err)
471 loader->backend->swap_native_buffers(loader->backend, drawable->surface);
472
473 return (!err);
474}
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <ui/PixelFormat.h>
25#include <ui/ISurfaceComposer.h>
26
27#include "droid_ui.h"
28
29using namespace android;
30
31namespace android {
32 const sp<ISurfaceComposer>& _get_surface_manager();
33};
34
35int
36ui_auth_gpu(drm_magic_t magic)
37{
38 /*
39 * surface flinger itself or root; we might want something like
40 * getSurfaceFlinger() from libEGL
41 */
42 if (getuid() == 1000 || getuid() == 0)
43 return 0;
44
45 sp<ISurfaceComposer> sm(_get_surface_manager());
46 if (sm == NULL)
47 return -ENODEV;
48 return sm->authGPU(magic);
49}
50
51int ui_bytes_per_pixel(int format)
52{
53 return bytesPerPixel(format);
54}
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef _DROID_UI_H
25#define _DROID_UI_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif /*__cplusplus */
30
31#include <drm.h>
32
33int ui_auth_gpu(drm_magic_t magic);
34int ui_bytes_per_pixel(int format);
35
36#ifdef __cplusplus
37}
38#endif /*__cplusplus */
39
40#endif /* _DROID_UI_H */
  
1/*
2 * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include "glapi/glapi.h"
25
26#include "eglconfig.h"
27#include "eglcontext.h"
28#include "egldisplay.h"
29#include "egldriver.h"
30#include "eglglobals.h"
31#include "egllog.h"
32#include "eglsurface.h"
33#include "eglimage.h"
34
35#include "EGL/internal/eglimage_dri.h"
36
37#include "droid.h"
38
39#ifndef DROID_DEVICE_PATH
40#define DROID_DEVICE_PATH "/dev/dri/card0"
41#endif
42
43struct droid_egl_driver
44{
45 _EGLDriver base;
46
47 /* EGL_DEFAULT_DISPLAY */
48 struct droid_egl_display *default_display;
49 void (*flush_current)(void);
50 void (*finish_current)(void);
51};
52
53struct droid_egl_display
54{
55 EGLint refcnt;
56
57 EGLint apis;
58 EGLint major;
59 EGLint minor;
60
61 struct droid_backend *backend;
62 struct droid_screen *screen;
63};
64
65struct droid_egl_context {
66 _EGLContext base;
67 struct droid_context *context;
68};
69
70struct droid_egl_surface {
71 _EGLSurface base;
72 struct droid_drawable *drawable;
73 struct droid_surface *surface;
74};
75
76struct droid_egl_config {
77 _EGLConfig base;
78 const __DRIconfig *config;
79};
80
81static INLINE struct droid_egl_driver *
82lookup_driver(_EGLDriver *drv)
83{
84 return (struct droid_egl_driver *) drv;
85}
86
87static INLINE struct droid_egl_display *
88lookup_display(_EGLDisplay *dpy)
89{
90 return (struct droid_egl_display *) dpy->DriverData;
91}
92
93static INLINE struct droid_egl_context *
94lookup_context(_EGLContext *context)
95{
96 return (struct droid_egl_context *) context;
97}
98
99static INLINE struct droid_egl_surface *
100lookup_surface(_EGLSurface *surface)
101{
102 return (struct droid_egl_surface *) surface;
103}
104
105static INLINE struct droid_egl_config *
106lookup_config(_EGLConfig *conf)
107{
108 return (struct droid_egl_config *) conf;
109}
110
111static void
112droid_create_configs(_EGLDisplay *dpy, struct droid_egl_display *droid_dpy,
113 const __DRIconfig **configs, EGLint num_configs)
114{
115 EGLint i;
116 EGLint id = 1;
117
118 for (i = 0; i < num_configs; i++) {
119 struct droid_egl_config *droid_conf = calloc(1, sizeof(*droid_conf));
120 EGLint val;
121
122 if (!droid_conf)
123 break;
124
125 _eglInitConfig(&droid_conf->base, id);
126 droid_conf->config = configs[i];
127 droid_screen_convert_config(droid_dpy->screen, droid_conf->config,
128 &droid_conf->base);
129
130 val = GET_CONFIG_ATTRIB(&droid_conf->base, EGL_CONFIG_CAVEAT);
131 /* we do not want slow configs */
132 if (val == EGL_SLOW_CONFIG) {
133 free(droid_conf);
134 } else {
135 _eglAddConfig(dpy, &droid_conf->base);
136 id++;
137 }
138 }
139}
140
141
142static EGLBoolean
143droid_initialize_display(struct droid_egl_display *droid_dpy)
144{
145 const char *path = DROID_DEVICE_PATH;
146
147 droid_dpy->backend = droid_backend_create_intel(path);
148 if (!droid_dpy->backend)
149 return EGL_FALSE;
150
151 droid_dpy->screen = droid_screen_create(droid_dpy->backend);
152 if (!droid_dpy->screen) {
153 free(droid_dpy->backend);
154 droid_dpy->backend = NULL;
155 return EGL_FALSE;
156 }
157
158 droid_dpy->apis = EGL_OPENGL_ES_BIT;
159 droid_dpy->major = 1;
160 droid_dpy->major = 4;
161
162 return EGL_TRUE;
163}
164
165static EGLBoolean
166droid_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
167 EGLint *major, EGLint *minor)
168{
169 struct droid_egl_driver *droid_drv = lookup_driver(drv);
170 struct droid_egl_display *droid_dpy;
171
172 if (dpy->NativeDisplay != EGL_DEFAULT_DISPLAY)
173 return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
174
175 /* the default display */
176 droid_dpy = droid_drv->default_display;
177 if (!droid_dpy) {
178 droid_dpy = calloc(1, sizeof(*droid_dpy));
179 if (!droid_dpy)
180 return _eglError(EGL_BAD_ALLOC, "eglInitialize");
181 if (!droid_initialize_display(droid_dpy))
182 return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
183
184 droid_create_configs(dpy, droid_dpy, droid_dpy->screen->dri_configs,
185 droid_dpy->screen->num_dri_configs);
186
187 droid_drv->default_display = droid_dpy;
188 }
189
190 dpy->DriverData = (void *) droid_dpy;
191 droid_dpy->refcnt++;
192
193 *major = droid_dpy->major;
194 *minor = droid_dpy->minor;
195
196 return EGL_TRUE;
197}
198
199static EGLBoolean
200droid_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
201{
202 struct droid_egl_driver *droid_drv = lookup_driver(drv);
203 struct droid_egl_display *droid_dpy = lookup_display(dpy);
204
205 dpy->DriverData = NULL;
206 droid_dpy->refcnt--;
207 if (!droid_dpy->refcnt) {
208 _eglReleaseDisplayResources(drv, dpy);
209 _eglCleanupDisplay(dpy);
210
211 free(droid_dpy);
212 droid_drv->default_display = NULL;
213 }
214
215 return EGL_TRUE;
216}
217
218static _EGLProc
219droid_eglGetProcAddress(const char *procname)
220{
221 return (_EGLProc) _glapi_get_proc_address(procname);
222}
223
224static _EGLContext *
225droid_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
226 _EGLContext *share_list, const EGLint *attrib_list)
227{
228 struct droid_egl_display *droid_dpy = lookup_display(dpy);
229 struct droid_egl_config *droid_conf = lookup_config(conf);
230 struct droid_egl_context *shared = lookup_context(share_list);
231 struct droid_egl_context *ctx;
232
233 ctx = calloc(1, sizeof(*ctx));
234 if (!ctx) {
235 _eglError(EGL_BAD_ALLOC, "eglCreateContext");
236 return NULL;
237 }
238
239 if (!_eglInitContext(drv, &ctx->base, &droid_conf->base, attrib_list)) {
240 free(ctx);
241 return NULL;
242 }
243
244 ctx->context =
245 droid_screen_create_context(droid_dpy->screen, droid_conf->config,
246 (shared) ? shared->context : NULL);
247 if (!ctx->context) {
248 free(ctx);
249 return NULL;
250 }
251
252 return &ctx->base;
253}
254
255static EGLBoolean
256droid_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
257{
258 struct droid_egl_display *droid_dpy = lookup_display(dpy);
259 struct droid_egl_context *droid_ctx = lookup_context(ctx);
260
261 if (!_eglIsContextBound(ctx))
262 droid_screen_destroy_context(droid_dpy->screen, droid_ctx->context);
263
264 return EGL_TRUE;
265}
266
267static EGLBoolean
268droid_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
269 _EGLSurface *r, _EGLContext *ctx)
270{
271 struct droid_egl_driver *droid_drv = lookup_driver(drv);
272 struct droid_egl_display *droid_dpy = lookup_display(dpy);
273 struct droid_egl_surface *draw = lookup_surface(d);
274 struct droid_egl_surface *read = lookup_surface(r);
275 struct droid_egl_context *droid_ctx = lookup_context(ctx);
276 _EGLContext *old;
277 struct droid_egl_context *droid_old;
278
279 old = _eglGetCurrentContext();
280 /* an unlinked context will be invalid after context switch */
281 if (!_eglIsContextLinked(old))
282 old = NULL;
283
284 droid_old = lookup_context(old);
285
286 if (!_eglMakeCurrent(drv, dpy, d, r, ctx))
287 return EGL_FALSE;
288
289 if (droid_old && droid_old != droid_ctx && droid_drv->flush_current)
290 droid_drv->flush_current();
291
292 _glapi_check_multithread();
293
294 /* bind new context or unbind old one */
295 if (droid_ctx)
296 droid_screen_bind_context(droid_dpy->screen,
297 draw->drawable, read->drawable,
298 droid_ctx->context);
299 else if (droid_old)
300 droid_screen_bind_context(droid_dpy->screen,
301 NULL, NULL,
302 droid_old->context);
303
304 return EGL_TRUE;
305}
306
307static _EGLSurface *
308droid_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
309 NativeWindowType window, const EGLint *attrib_list)
310{
311 struct droid_egl_display *droid_dpy = lookup_display(dpy);
312 struct droid_egl_config *droid_conf = lookup_config(conf);
313 struct droid_egl_surface *surf;
314
315 surf = calloc(1, sizeof(*surf));
316 if (!surf) {
317 _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
318 return NULL;
319 }
320
321 if (!_eglInitSurface(drv, &surf->base, EGL_WINDOW_BIT, &droid_conf->base, attrib_list)) {
322 free(surf);
323 return NULL;
324 }
325
326 surf->surface =
327 droid_dpy->backend->create_window_surface(droid_dpy->backend,
328 &surf->base, window);
329 if (!surf->surface) {
330 free(surf);
331 return NULL;
332 }
333
334 surf->drawable = droid_screen_create_drawable(droid_dpy->screen,
335 droid_conf->config,
336 surf->surface);
337 if (!surf->drawable) {
338 droid_dpy->backend->destroy_surface(droid_dpy->backend, surf->surface);
339 free(surf);
340 return NULL;
341 }
342
343 return &surf->base;
344}
345
346static EGLBoolean
347droid_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
348{
349 struct droid_egl_display *droid_dpy = lookup_display(dpy);
350 struct droid_egl_surface *droid_surf = lookup_surface(surf);
351
352 if (_eglIsSurfaceBound(&droid_surf->base))
353 return EGL_TRUE;
354
355 droid_screen_destroy_drawable(droid_dpy->screen, droid_surf->drawable);
356 droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_surf->surface);
357 free(droid_surf);
358
359 return EGL_TRUE;
360}
361
362static EGLBoolean
363droid_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
364{
365 struct droid_egl_driver *droid_drv = lookup_driver(drv);
366 struct droid_egl_display *droid_dpy = lookup_display(dpy);
367 struct droid_egl_surface *droid_surf = lookup_surface(surf);
368 _EGLContext *ctx = _eglGetCurrentContext();
369 struct droid_egl_context *droid_ctx = lookup_context(ctx);
370
371 if (droid_ctx) {
372 if (droid_drv->flush_current)
373 droid_drv->flush_current();
374
375 droid_screen_swap_buffers(droid_dpy->screen,
376 droid_ctx->context,
377 droid_surf->drawable);
378 }
379
380 return EGL_TRUE;
381}
382
383static EGLBoolean
384droid_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy)
385{
386 struct droid_egl_driver *droid_drv = lookup_driver(drv);
387 _EGLContext *ctx = _eglGetCurrentContext();
388
389 if (!ctx || !droid_drv->finish_current)
390 return EGL_TRUE;
391
392 if (!_eglIsSurfaceLinked(ctx->DrawSurface))
393 return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitClient");
394
395 droid_drv->finish_current();
396
397 return EGL_TRUE;
398}
399
400static EGLBoolean
401droid_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
402{
403 struct droid_egl_display *droid_dpy = lookup_display(dpy);
404 _EGLContext *ctx = _eglGetCurrentContext();
405 struct droid_egl_surface *droid_surf;
406
407 if (engine != EGL_CORE_NATIVE_ENGINE)
408 return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
409
410 if (!ctx)
411 return EGL_TRUE;
412
413 if (!_eglIsSurfaceLinked(ctx->DrawSurface))
414 return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitNative");
415
416 droid_surf = lookup_surface(ctx->DrawSurface);
417 droid_dpy->backend->swap_native_buffers(droid_dpy->backend,
418 droid_surf->surface);
419
420 return EGL_TRUE;
421}
422
423static void
424droid_Unload(_EGLDriver *drv)
425{
426 struct droid_egl_driver *droid_drv = lookup_driver(drv);
427 free(droid_drv);
428}
429
430_EGLDriver *
431_eglMain(const char *args)
432{
433 struct droid_egl_driver *droid_drv = calloc(1, sizeof(*droid_drv));
434 if (!droid_drv)
435 return NULL;
436
437 _eglInitDriverFallbacks(&droid_drv->base);
438 droid_drv->base.API.Initialize = droid_eglInitialize;
439 droid_drv->base.API.Terminate = droid_eglTerminate;
440
441 droid_drv->base.API.GetProcAddress = droid_eglGetProcAddress;
442
443 droid_drv->base.API.CreateContext = droid_eglCreateContext;
444 droid_drv->base.API.DestroyContext = droid_eglDestroyContext;
445 droid_drv->base.API.MakeCurrent = droid_eglMakeCurrent;
446 droid_drv->base.API.CreateWindowSurface = droid_eglCreateWindowSurface;
447 droid_drv->base.API.DestroySurface = droid_eglDestroySurface;
448 droid_drv->base.API.SwapBuffers = droid_eglSwapBuffers;
449 droid_drv->base.API.WaitClient = droid_eglWaitClient;
450 droid_drv->base.API.WaitNative = droid_eglWaitNative;
451
452 droid_drv->base.Name = "Android/i915";
453 droid_drv->base.Unload = droid_Unload;
454
455 /* we need a way to flush commands */
456 droid_drv->flush_current =
457 (void (*)(void)) droid_eglGetProcAddress("glFlush");
458 droid_drv->finish_current =
459 (void (*)(void)) droid_eglGetProcAddress("glFinish");
460
461 return &droid_drv->base;
462}
  
195195 lib_handle lib;
196196 _EGLDriver *drv = NULL;
197197
198 mainFunc = _eglOpenLibrary(path, &lib);
198 /* temporary hack */
199 (void) _eglOpenLibrary;
200 mainFunc = _eglMain;
201 lib = (lib_handle) 0;
202
199203 if (!mainFunc)
200204 return NULL;
201205
  
66#include <EGL/egl.h>
77#include <EGL/eglext.h>
88
9#ifndef EGL_MESA_screen_surface
10#define EGL_MESA_screen_surface 1
11
12#define EGL_BAD_SCREEN_MESA 0x4000
13#define EGL_BAD_MODE_MESA 0x4001
14#define EGL_SCREEN_COUNT_MESA 0x4002
15#define EGL_SCREEN_POSITION_MESA 0x4003
16#define EGL_SCREEN_POSITION_GRANULARITY_MESA 0x4004
17#define EGL_MODE_ID_MESA 0x4005
18#define EGL_REFRESH_RATE_MESA 0x4006
19#define EGL_OPTIMAL_MESA 0x4007
20#define EGL_INTERLACED_MESA 0x4008
21#define EGL_SCREEN_BIT_MESA 0x08
22
23typedef uint32_t EGLScreenMESA;
24typedef uint32_t EGLModeMESA;
25
26#ifdef EGL_EGLEXT_PROTOTYPES
27EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
28EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
29EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
30EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
31EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
32EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
33EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
34EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
35EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
36EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
37EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
38#endif /* EGL_EGLEXT_PROTOTYPES */
39
40typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
41typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
42typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
43typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
44typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
45typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
46typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
47typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
48typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
49typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
50typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
51
52#endif /* EGL_MESA_screen_surface */
53
54#ifndef EGL_MESA_copy_context
55#define EGL_MESA_copy_context 1
56
57#ifdef EGL_EGLEXT_PROTOTYPES
58EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
59#endif /* EGL_EGLEXT_PROTOTYPES */
60
61typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
62
63#endif /* EGL_MESA_copy_context */
64
965#include "eglcompiler.h"
1066
1167typedef struct _egl_api _EGLAPI;