Commit 94f9330609ec305d998e58abfddfbbdf8ae51c9d
- Diff rendering mode:
- inline
- side by side
src/egl/Android.mk
(41 / 0)
|   | |||
| 1 | LOCAL_PATH := $(call my-dir) | ||
| 2 | |||
| 3 | include $(CLEAR_VARS) | ||
| 4 | |||
| 5 | LOCAL_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 | |||
| 23 | LOCAL_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 | |||
| 29 | LOCAL_C_INCLUDES += \ | ||
| 30 | $(LOCAL_PATH)/main \ | ||
| 31 | external/mesa/include \ | ||
| 32 | external/mesa/src/mesa \ | ||
| 33 | external/drm/shared-core | ||
| 34 | |||
| 35 | LOCAL_CFLAGS += -DPTHREADS -D_EGL_PLATFORM_X=1 | ||
| 36 | LOCAL_SHARED_LIBRARIES := libdl libui libutils | ||
| 37 | LOCAL_STATIC_LIBRARIES := libes1api | ||
| 38 | |||
| 39 | LOCAL_MODULE := libhgl | ||
| 40 | |||
| 41 | include $(BUILD_SHARED_LIBRARY) |
src/egl/drivers/android/droid.h
(125 / 0)
|   | |||
| 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 */ | ||
| 40 | struct droid_loader; | ||
| 41 | struct droid_context; | ||
| 42 | struct droid_drawable; | ||
| 43 | struct droid_surface; | ||
| 44 | |||
| 45 | struct 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 | |||
| 69 | struct 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 | |||
| 80 | struct droid_backend * | ||
| 81 | droid_backend_create_intel(const char *dev); | ||
| 82 | |||
| 83 | void | ||
| 84 | droid_backend_destroy(struct droid_backend *backend); | ||
| 85 | |||
| 86 | struct droid_screen * | ||
| 87 | droid_screen_create(struct droid_backend *backend); | ||
| 88 | |||
| 89 | void | ||
| 90 | droid_screen_destroy(struct droid_screen *screen); | ||
| 91 | |||
| 92 | void | ||
| 93 | droid_screen_convert_config(struct droid_screen *screen, | ||
| 94 | const __DRIconfig *conf, _EGLConfig *egl_conf); | ||
| 95 | |||
| 96 | struct droid_context * | ||
| 97 | droid_screen_create_context(struct droid_screen *screen, | ||
| 98 | const __DRIconfig *conf, | ||
| 99 | struct droid_context *shared); | ||
| 100 | |||
| 101 | void | ||
| 102 | droid_screen_destroy_context(struct droid_screen *screen, | ||
| 103 | struct droid_context *ctx); | ||
| 104 | |||
| 105 | struct droid_drawable * | ||
| 106 | droid_screen_create_drawable(struct droid_screen *screen, | ||
| 107 | const __DRIconfig *conf, | ||
| 108 | struct droid_surface *surf); | ||
| 109 | |||
| 110 | void | ||
| 111 | droid_screen_destroy_drawable(struct droid_screen *screen, | ||
| 112 | struct droid_drawable *drawable); | ||
| 113 | |||
| 114 | int | ||
| 115 | droid_screen_bind_context(struct droid_screen *screen, | ||
| 116 | struct droid_drawable *draw, | ||
| 117 | struct droid_drawable *read, | ||
| 118 | struct droid_context *ctx); | ||
| 119 | |||
| 120 | int | ||
| 121 | droid_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 | |||
| 47 | enum { | ||
| 48 | INTEL_SURFACE_TYPE_WINDOW, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct droid_backend_intel { | ||
| 52 | struct droid_backend base; | ||
| 53 | int fd; | ||
| 54 | int screen_number; | ||
| 55 | }; | ||
| 56 | |||
| 57 | struct 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 | |||
| 75 | static INLINE struct droid_backend_intel * | ||
| 76 | lookup_backend(struct droid_backend *backend) | ||
| 77 | { | ||
| 78 | return (struct droid_backend_intel *) backend; | ||
| 79 | } | ||
| 80 | |||
| 81 | static INLINE struct droid_surface_intel * | ||
| 82 | lookup_surface(struct droid_surface *surface) | ||
| 83 | { | ||
| 84 | return (struct droid_surface_intel *) surface; | ||
| 85 | } | ||
| 86 | |||
| 87 | static __DRIbuffer * | ||
| 88 | intel_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 | |||
| 105 | static inline uint32_t | ||
| 106 | align_to(uint32_t value, uint32_t align) | ||
| 107 | { | ||
| 108 | return (value + align - 1) & ~(align - 1); | ||
| 109 | } | ||
| 110 | |||
| 111 | static int | ||
| 112 | create_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 | |||
| 138 | static void | ||
| 139 | delete_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 | |||
| 159 | static __DRIbuffer * | ||
| 160 | intel_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 | |||
| 237 | end: | ||
| 238 | *out_count = num; | ||
| 239 | *width = isurf->native_width; | ||
| 240 | *height = isurf->native_height; | ||
| 241 | |||
| 242 | return isurf->buffers; | ||
| 243 | } | ||
| 244 | |||
| 245 | static void | ||
| 246 | update_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 | |||
| 277 | static struct droid_surface * | ||
| 278 | intel_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 | |||
| 322 | static void | ||
| 323 | intel_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 | |||
| 330 | static void | ||
| 331 | intel_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 | |||
| 349 | static int | ||
| 350 | intel_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 | |||
| 373 | static void | ||
| 374 | intel_destroy(struct droid_backend *backend) | ||
| 375 | { | ||
| 376 | struct droid_backend_intel *intel = lookup_backend(backend); | ||
| 377 | close(intel->fd); | ||
| 378 | free(intel); | ||
| 379 | } | ||
| 380 | |||
| 381 | struct droid_backend * | ||
| 382 | droid_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 | |||
| 41 | struct droid_loader { | ||
| 42 | struct droid_backend *backend; | ||
| 43 | |||
| 44 | char *filename; | ||
| 45 | void *handle; | ||
| 46 | |||
| 47 | __DRIcoreExtension *core; | ||
| 48 | __DRIdri2Extension *dri2; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct droid_context { | ||
| 52 | __DRIcontext *dri_context; | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct droid_drawable { | ||
| 56 | struct droid_loader *loader; | ||
| 57 | struct droid_surface *surface; | ||
| 58 | |||
| 59 | __DRIdrawable *dri_drawable; | ||
| 60 | }; | ||
| 61 | |||
| 62 | static __DRIbuffer * | ||
| 63 | loader_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 | |||
| 81 | static 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 | |||
| 88 | static int | ||
| 89 | loader_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 | |||
| 104 | static const __DRIsystemTimeExtension loader_ext_system_time = { | ||
| 105 | { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, | ||
| 106 | loader_ext_get_ust, | ||
| 107 | NULL, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static const __DRIextension *loader_extensions[] = { | ||
| 111 | &loader_ext_dri2_loader.base, | ||
| 112 | &loader_ext_system_time.base, | ||
| 113 | NULL | ||
| 114 | }; | ||
| 115 | |||
| 116 | static struct droid_loader * | ||
| 117 | loader_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 | |||
| 130 | static void | ||
| 131 | loader_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 | |||
| 140 | static int | ||
| 141 | loader_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 | |||
| 185 | static int | ||
| 186 | loader_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 | |||
| 203 | void | ||
| 204 | droid_backend_destroy(struct droid_backend *backend) | ||
| 205 | { | ||
| 206 | backend->destroy(backend); | ||
| 207 | } | ||
| 208 | |||
| 209 | struct droid_screen * | ||
| 210 | droid_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 | |||
| 273 | fail: | ||
| 274 | if (screen) | ||
| 275 | droid_screen_destroy(screen); | ||
| 276 | if (loader) | ||
| 277 | loader_destroy(loader); | ||
| 278 | |||
| 279 | return NULL; | ||
| 280 | } | ||
| 281 | |||
| 282 | void | ||
| 283 | droid_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 | |||
| 291 | static 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 | |||
| 313 | void | ||
| 314 | droid_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 | |||
| 350 | struct droid_context * | ||
| 351 | droid_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 | |||
| 377 | void | ||
| 378 | droid_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 | |||
| 386 | struct droid_drawable * | ||
| 387 | droid_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 | |||
| 416 | void | ||
| 417 | droid_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 | |||
| 425 | int | ||
| 426 | droid_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 | |||
| 449 | int | ||
| 450 | droid_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 | |||
| 29 | using namespace android; | ||
| 30 | |||
| 31 | namespace android { | ||
| 32 | const sp<ISurfaceComposer>& _get_surface_manager(); | ||
| 33 | }; | ||
| 34 | |||
| 35 | int | ||
| 36 | ui_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 | |||
| 51 | int 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 | ||
| 28 | extern "C" { | ||
| 29 | #endif /*__cplusplus */ | ||
| 30 | |||
| 31 | #include <drm.h> | ||
| 32 | |||
| 33 | int ui_auth_gpu(drm_magic_t magic); | ||
| 34 | int 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 | |||
| 43 | struct 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 | |||
| 53 | struct 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 | |||
| 65 | struct droid_egl_context { | ||
| 66 | _EGLContext base; | ||
| 67 | struct droid_context *context; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct droid_egl_surface { | ||
| 71 | _EGLSurface base; | ||
| 72 | struct droid_drawable *drawable; | ||
| 73 | struct droid_surface *surface; | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct droid_egl_config { | ||
| 77 | _EGLConfig base; | ||
| 78 | const __DRIconfig *config; | ||
| 79 | }; | ||
| 80 | |||
| 81 | static INLINE struct droid_egl_driver * | ||
| 82 | lookup_driver(_EGLDriver *drv) | ||
| 83 | { | ||
| 84 | return (struct droid_egl_driver *) drv; | ||
| 85 | } | ||
| 86 | |||
| 87 | static INLINE struct droid_egl_display * | ||
| 88 | lookup_display(_EGLDisplay *dpy) | ||
| 89 | { | ||
| 90 | return (struct droid_egl_display *) dpy->DriverData; | ||
| 91 | } | ||
| 92 | |||
| 93 | static INLINE struct droid_egl_context * | ||
| 94 | lookup_context(_EGLContext *context) | ||
| 95 | { | ||
| 96 | return (struct droid_egl_context *) context; | ||
| 97 | } | ||
| 98 | |||
| 99 | static INLINE struct droid_egl_surface * | ||
| 100 | lookup_surface(_EGLSurface *surface) | ||
| 101 | { | ||
| 102 | return (struct droid_egl_surface *) surface; | ||
| 103 | } | ||
| 104 | |||
| 105 | static INLINE struct droid_egl_config * | ||
| 106 | lookup_config(_EGLConfig *conf) | ||
| 107 | { | ||
| 108 | return (struct droid_egl_config *) conf; | ||
| 109 | } | ||
| 110 | |||
| 111 | static void | ||
| 112 | droid_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 | |||
| 142 | static EGLBoolean | ||
| 143 | droid_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 | |||
| 165 | static EGLBoolean | ||
| 166 | droid_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 | |||
| 199 | static EGLBoolean | ||
| 200 | droid_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 | |||
| 218 | static _EGLProc | ||
| 219 | droid_eglGetProcAddress(const char *procname) | ||
| 220 | { | ||
| 221 | return (_EGLProc) _glapi_get_proc_address(procname); | ||
| 222 | } | ||
| 223 | |||
| 224 | static _EGLContext * | ||
| 225 | droid_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 | |||
| 255 | static EGLBoolean | ||
| 256 | droid_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 | |||
| 267 | static EGLBoolean | ||
| 268 | droid_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 | |||
| 307 | static _EGLSurface * | ||
| 308 | droid_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 | |||
| 346 | static EGLBoolean | ||
| 347 | droid_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 | |||
| 362 | static EGLBoolean | ||
| 363 | droid_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 | |||
| 383 | static EGLBoolean | ||
| 384 | droid_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 | |||
| 400 | static EGLBoolean | ||
| 401 | droid_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 | |||
| 423 | static void | ||
| 424 | droid_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 | } |
src/egl/main/egldriver.c
(5 / 1)
|   | |||
| 195 | 195 | lib_handle lib; | |
| 196 | 196 | _EGLDriver *drv = NULL; | |
| 197 | 197 | ||
| 198 | mainFunc = _eglOpenLibrary(path, &lib); | ||
| 198 | /* temporary hack */ | ||
| 199 | (void) _eglOpenLibrary; | ||
| 200 | mainFunc = _eglMain; | ||
| 201 | lib = (lib_handle) 0; | ||
| 202 | |||
| 199 | 203 | if (!mainFunc) | |
| 200 | 204 | return NULL; | |
| 201 | 205 |
src/egl/main/egltypedefs.h
(56 / 0)
|   | |||
| 6 | 6 | #include <EGL/egl.h> | |
| 7 | 7 | #include <EGL/eglext.h> | |
| 8 | 8 | ||
| 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 | |||
| 23 | typedef uint32_t EGLScreenMESA; | ||
| 24 | typedef uint32_t EGLModeMESA; | ||
| 25 | |||
| 26 | #ifdef EGL_EGLEXT_PROTOTYPES | ||
| 27 | EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); | ||
| 28 | EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); | ||
| 29 | EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value); | ||
| 30 | EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); | ||
| 31 | EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); | ||
| 32 | EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode); | ||
| 33 | EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); | ||
| 34 | EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); | ||
| 35 | EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface); | ||
| 36 | EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); | ||
| 37 | EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode); | ||
| 38 | #endif /* EGL_EGLEXT_PROTOTYPES */ | ||
| 39 | |||
| 40 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); | ||
| 41 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); | ||
| 42 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value); | ||
| 43 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); | ||
| 44 | typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); | ||
| 45 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode); | ||
| 46 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); | ||
| 47 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); | ||
| 48 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface); | ||
| 49 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); | ||
| 50 | typedef 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 | ||
| 58 | EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); | ||
| 59 | #endif /* EGL_EGLEXT_PROTOTYPES */ | ||
| 60 | |||
| 61 | typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); | ||
| 62 | |||
| 63 | #endif /* EGL_MESA_copy_context */ | ||
| 64 | |||
| 9 | 65 | #include "eglcompiler.h" | |
| 10 | 66 | ||
| 11 | 67 | typedef struct _egl_api _EGLAPI; |

