1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.12 4 * 5 * Copyright (C) 2010-2011 Chia-I Wu <olvaffe (at) gmail.com> 6 * Copyright (C) 2010-2011 LunarG Inc. 7 * 8 * Based on platform_x11, which has 9 * 10 * Copyright 2011 Intel Corporation 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included 20 * in all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 * DEALINGS IN THE SOFTWARE. 29 */ 30 31 #include <errno.h> 32 #include <dlfcn.h> 33 34 /* for droid_get_pci_id */ 35 #include <xf86drm.h> 36 #include <i915_drm.h> 37 #include <radeon_drm.h> 38 39 #include "egl_dri2.h" 40 41 static int 42 get_format_bpp(int native) 43 { 44 int bpp; 45 46 switch (native) { 47 case HAL_PIXEL_FORMAT_RGBA_8888: 48 case HAL_PIXEL_FORMAT_RGBX_8888: 49 case HAL_PIXEL_FORMAT_BGRA_8888: 50 bpp = 4; 51 break; 52 case HAL_PIXEL_FORMAT_RGB_888: 53 bpp = 3; 54 break; 55 case HAL_PIXEL_FORMAT_RGB_565: 56 case HAL_PIXEL_FORMAT_RGBA_5551: 57 case HAL_PIXEL_FORMAT_RGBA_4444: 58 bpp = 2; 59 break; 60 default: 61 bpp = 0; 62 break; 63 } 64 65 return bpp; 66 } 67 68 static int 69 get_native_buffer_name(struct ANativeWindowBuffer *buf) 70 { 71 struct gralloc_drm_handle_t *handle; 72 73 /* check that the buffer is allocated by drm_gralloc and cast */ 74 handle = gralloc_drm_handle(buf->handle); 75 76 return (handle) ? handle->name : 0; 77 } 78 79 static EGLBoolean 80 droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) 81 { 82 if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer)) 83 return EGL_FALSE; 84 85 dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common); 86 dri2_surf->window->lockBuffer(dri2_surf->window, dri2_surf->buffer); 87 88 return EGL_TRUE; 89 } 90 91 static EGLBoolean 92 droid_window_enqueue_buffer(struct dri2_egl_surface *dri2_surf) 93 { 94 dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer); 95 96 dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common); 97 dri2_surf->buffer = NULL; 98 99 return EGL_TRUE; 100 } 101 102 static void 103 droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) 104 { 105 /* no cancel buffer? */ 106 droid_window_enqueue_buffer(dri2_surf); 107 } 108 109 static __DRIbuffer * 110 droid_alloc_local_buffer(struct dri2_egl_surface *dri2_surf, 111 unsigned int att, unsigned int format) 112 { 113 struct dri2_egl_display *dri2_dpy = 114 dri2_egl_display(dri2_surf->base.Resource.Display); 115 116 if (att >= ARRAY_SIZE(dri2_surf->local_buffers)) 117 return NULL; 118 119 if (!dri2_surf->local_buffers[att]) { 120 dri2_surf->local_buffers[att] = 121 dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, att, format, 122 dri2_surf->base.Width, dri2_surf->base.Height); 123 } 124 125 return dri2_surf->local_buffers[att]; 126 } 127 128 static void 129 droid_free_local_buffers(struct dri2_egl_surface *dri2_surf) 130 { 131 struct dri2_egl_display *dri2_dpy = 132 dri2_egl_display(dri2_surf->base.Resource.Display); 133 int i; 134 135 for (i = 0; i < ARRAY_SIZE(dri2_surf->local_buffers); i++) { 136 if (dri2_surf->local_buffers[i]) { 137 dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, 138 dri2_surf->local_buffers[i]); 139 dri2_surf->local_buffers[i] = NULL; 140 } 141 } 142 } 143 144 static _EGLSurface * 145 droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, 146 _EGLConfig *conf, EGLNativeWindowType window, 147 const EGLint *attrib_list) 148 { 149 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 150 struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); 151 struct dri2_egl_surface *dri2_surf; 152 dri2_surf = calloc(1, sizeof *dri2_surf); 153 if (!dri2_surf) { 154 _eglError(EGL_BAD_ALLOC, "droid_create_surface"); 155 return NULL; 156 } 157 158 if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) 159 goto cleanup_surface; 160 161 if (type == EGL_WINDOW_BIT) { 162 int format; 163 164 if (!window || window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { 165 _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); 166 goto cleanup_surface; 167 } 168 if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) { 169 _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); 170 goto cleanup_surface; 171 } 172 173 if (format != dri2_conf->base.NativeVisualID) { 174 _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x", 175 format, dri2_conf->base.NativeVisualID); 176 } 177 178 window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width); 179 window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height); 180 } 181 182 dri2_surf->dri_drawable = 183 (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, 184 dri2_conf->dri_double_config, 185 dri2_surf); 186 if (dri2_surf->dri_drawable == NULL) { 187 _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); 188 goto cleanup_surface; 189 } 190 191 if (window) { 192 window->common.incRef(&window->common); 193 dri2_surf->window = window; 194 } 195 196 return &dri2_surf->base; 197 198 cleanup_surface: 199 free(dri2_surf); 200 201 return NULL; 202 } 203 204 static _EGLSurface * 205 droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, 206 _EGLConfig *conf, EGLNativeWindowType window, 207 const EGLint *attrib_list) 208 { 209 return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf, 210 window, attrib_list); 211 } 212 213 static _EGLSurface * 214 droid_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp, 215 _EGLConfig *conf, EGLNativePixmapType pixmap, 216 const EGLint *attrib_list) 217 { 218 return NULL; 219 } 220 221 static _EGLSurface * 222 droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp, 223 _EGLConfig *conf, const EGLint *attrib_list) 224 { 225 return droid_create_surface(drv, disp, EGL_PBUFFER_BIT, conf, 226 NULL, attrib_list); 227 } 228 229 static EGLBoolean 230 droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) 231 { 232 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 233 struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 234 235 if (!_eglPutSurface(surf)) 236 return EGL_TRUE; 237 238 droid_free_local_buffers(dri2_surf); 239 240 if (dri2_surf->base.Type == EGL_WINDOW_BIT) { 241 if (dri2_surf->buffer) 242 droid_window_cancel_buffer(dri2_surf); 243 244 dri2_surf->window->common.decRef(&dri2_surf->window->common); 245 } 246 247 (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); 248 249 free(dri2_surf); 250 251 return EGL_TRUE; 252 } 253 254 static EGLBoolean 255 droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) 256 { 257 struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); 258 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 259 struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); 260 _EGLContext *ctx; 261 262 if (dri2_surf->base.Type != EGL_WINDOW_BIT) 263 return EGL_TRUE; 264 265 if (dri2_drv->glFlush) { 266 ctx = _eglGetCurrentContext(); 267 if (ctx && ctx->DrawSurface == &dri2_surf->base) 268 dri2_drv->glFlush(); 269 } 270 271 (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); 272 273 if (dri2_surf->buffer) 274 droid_window_enqueue_buffer(dri2_surf); 275 276 (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); 277 278 return EGL_TRUE; 279 } 280 281 static _EGLImage * 282 dri2_create_image_android_native_buffer(_EGLDisplay *disp, 283 struct ANativeWindowBuffer *buf) 284 { 285 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 286 struct dri2_egl_image *dri2_img; 287 int name; 288 EGLint format; 289 290 if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC || 291 buf->common.version != sizeof(*buf)) { 292 _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); 293 return NULL; 294 } 295 296 name = get_native_buffer_name(buf); 297 if (!name) { 298 _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); 299 return NULL; 300 } 301 302 /* see the table in droid_add_configs_for_visuals */ 303 switch (buf->format) { 304 case HAL_PIXEL_FORMAT_BGRA_8888: 305 format = __DRI_IMAGE_FORMAT_ARGB8888; 306 break; 307 case HAL_PIXEL_FORMAT_RGB_565: 308 format = __DRI_IMAGE_FORMAT_RGB565; 309 break; 310 case HAL_PIXEL_FORMAT_RGBA_8888: 311 format = __DRI_IMAGE_FORMAT_ABGR8888; 312 break; 313 case HAL_PIXEL_FORMAT_RGBX_8888: 314 format = __DRI_IMAGE_FORMAT_XBGR8888; 315 break; 316 case HAL_PIXEL_FORMAT_RGB_888: 317 case HAL_PIXEL_FORMAT_RGBA_5551: 318 case HAL_PIXEL_FORMAT_RGBA_4444: 319 /* unsupported */ 320 default: 321 _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", buf->format); 322 return NULL; 323 break; 324 } 325 326 dri2_img = calloc(1, sizeof(*dri2_img)); 327 if (!dri2_img) { 328 _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); 329 return NULL; 330 } 331 332 if (!_eglInitImage(&dri2_img->base, disp)) { 333 free(dri2_img); 334 return NULL; 335 } 336 337 dri2_img->dri_image = 338 dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, 339 buf->width, 340 buf->height, 341 format, 342 name, 343 buf->stride, 344 dri2_img); 345 if (!dri2_img->dri_image) { 346 free(dri2_img); 347 _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); 348 return NULL; 349 } 350 351 return &dri2_img->base; 352 } 353 354 static _EGLImage * 355 droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, 356 _EGLContext *ctx, EGLenum target, 357 EGLClientBuffer buffer, const EGLint *attr_list) 358 { 359 switch (target) { 360 case EGL_NATIVE_BUFFER_ANDROID: 361 return dri2_create_image_android_native_buffer(disp, 362 (struct ANativeWindowBuffer *) buffer); 363 default: 364 return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); 365 } 366 } 367 368 static void 369 droid_init_driver_functions(_EGLDriver *drv) 370 { 371 drv->API.CreateWindowSurface = droid_create_window_surface; 372 drv->API.CreatePixmapSurface = droid_create_pixmap_surface; 373 drv->API.CreatePbufferSurface = droid_create_pbuffer_surface; 374 drv->API.DestroySurface = droid_destroy_surface; 375 drv->API.SwapBuffers = droid_swap_buffers; 376 377 drv->API.CreateImageKHR = droid_create_image_khr; 378 } 379 380 static void 381 droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) 382 { 383 } 384 385 static int 386 droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, 387 unsigned int *attachments, int count) 388 { 389 int num_buffers = 0, i; 390 391 /* fill dri2_surf->buffers */ 392 for (i = 0; i < count * 2; i += 2) { 393 __DRIbuffer *buf, *local; 394 395 assert(num_buffers < ARRAY_SIZE(dri2_surf->buffers)); 396 buf = &dri2_surf->buffers[num_buffers]; 397 398 switch (attachments[i]) { 399 case __DRI_BUFFER_BACK_LEFT: 400 if (dri2_surf->base.Type == EGL_WINDOW_BIT) { 401 buf->attachment = attachments[i]; 402 buf->name = get_native_buffer_name(dri2_surf->buffer); 403 buf->cpp = get_format_bpp(dri2_surf->buffer->format); 404 buf->pitch = dri2_surf->buffer->stride * buf->cpp; 405 buf->flags = 0; 406 407 if (buf->name) 408 num_buffers++; 409 410 break; 411 } 412 /* fall through for pbuffers */ 413 case __DRI_BUFFER_DEPTH: 414 case __DRI_BUFFER_STENCIL: 415 case __DRI_BUFFER_ACCUM: 416 case __DRI_BUFFER_DEPTH_STENCIL: 417 case __DRI_BUFFER_HIZ: 418 local = droid_alloc_local_buffer(dri2_surf, 419 attachments[i], attachments[i + 1]); 420 421 if (local) { 422 *buf = *local; 423 num_buffers++; 424 } 425 break; 426 case __DRI_BUFFER_FRONT_LEFT: 427 case __DRI_BUFFER_FRONT_RIGHT: 428 case __DRI_BUFFER_FAKE_FRONT_LEFT: 429 case __DRI_BUFFER_FAKE_FRONT_RIGHT: 430 case __DRI_BUFFER_BACK_RIGHT: 431 default: 432 /* no front or right buffers */ 433 break; 434 } 435 } 436 437 return num_buffers; 438 } 439 440 static __DRIbuffer * 441 droid_get_buffers_with_format(__DRIdrawable * driDrawable, 442 int *width, int *height, 443 unsigned int *attachments, int count, 444 int *out_count, void *loaderPrivate) 445 { 446 struct dri2_egl_surface *dri2_surf = loaderPrivate; 447 struct dri2_egl_display *dri2_dpy = 448 dri2_egl_display(dri2_surf->base.Resource.Display); 449 int i; 450 451 if (dri2_surf->base.Type == EGL_WINDOW_BIT) { 452 /* try to dequeue the next back buffer */ 453 if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) 454 return NULL; 455 456 /* free outdated buffers and update the surface size */ 457 if (dri2_surf->base.Width != dri2_surf->buffer->width || 458 dri2_surf->base.Height != dri2_surf->buffer->height) { 459 droid_free_local_buffers(dri2_surf); 460 dri2_surf->base.Width = dri2_surf->buffer->width; 461 dri2_surf->base.Height = dri2_surf->buffer->height; 462 } 463 } 464 465 dri2_surf->buffer_count = 466 droid_get_buffers_parse_attachments(dri2_surf, attachments, count); 467 468 if (width) 469 *width = dri2_surf->base.Width; 470 if (height) 471 *height = dri2_surf->base.Height; 472 473 *out_count = dri2_surf->buffer_count;; 474 475 return dri2_surf->buffers; 476 } 477 478 static EGLBoolean 479 droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) 480 { 481 struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); 482 const struct { 483 int format; 484 int size; 485 unsigned int rgba_masks[4]; 486 } visuals[] = { 487 { HAL_PIXEL_FORMAT_RGBA_8888, 32, { 0xff, 0xff00, 0xff0000, 0xff000000 } }, 488 { HAL_PIXEL_FORMAT_RGBX_8888, 32, { 0xff, 0xff00, 0xff0000, 0x0 } }, 489 { HAL_PIXEL_FORMAT_RGB_888, 24, { 0xff, 0xff00, 0xff0000, 0x0 } }, 490 { HAL_PIXEL_FORMAT_RGB_565, 16, { 0xf800, 0x7e0, 0x1f, 0x0 } }, 491 { HAL_PIXEL_FORMAT_BGRA_8888, 32, { 0xff0000, 0xff00, 0xff, 0xff000000 } }, 492 { 0, 0, { 0, 0, 0, 0 } } 493 }; 494 int count, i, j; 495 496 count = 0; 497 for (i = 0; visuals[i].format; i++) { 498 int format_count = 0; 499 500 for (j = 0; dri2_dpy->driver_configs[j]; j++) { 501 const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; 502 struct dri2_egl_config *dri2_conf; 503 unsigned int double_buffered = 0; 504 505 dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[j], 506 __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered); 507 508 /* support only double buffered configs */ 509 if (!double_buffered) 510 continue; 511 512 dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j], 513 count + 1, visuals[i].size, surface_type, NULL, 514 visuals[i].rgba_masks); 515 if (dri2_conf) { 516 dri2_conf->base.NativeVisualID = visuals[i].format; 517 dri2_conf->base.NativeVisualType = visuals[i].format; 518 count++; 519 format_count++; 520 } 521 } 522 523 if (!format_count) { 524 _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x", 525 visuals[i].format); 526 } 527 } 528 529 /* post-process configs */ 530 for (i = 0; i < dpy->Configs->Size; i++) { 531 struct dri2_egl_config *dri2_conf = dri2_egl_config(dpy->Configs->Elements[i]); 532 533 /* there is no front buffer so no OpenGL */ 534 dri2_conf->base.RenderableType &= ~EGL_OPENGL_BIT; 535 dri2_conf->base.Conformant &= ~EGL_OPENGL_BIT; 536 } 537 538 return (count != 0); 539 } 540 541 static EGLBoolean 542 droid_get_pci_id(int fd, int *vendor_id, int *chip_id) 543 { 544 drmVersionPtr version; 545 546 *chip_id = -1; 547 548 version = drmGetVersion(fd); 549 if (!version) { 550 _eglLog(_EGL_WARNING, "invalid drm fd"); 551 return EGL_FALSE; 552 } 553 if (!version->name) { 554 _eglLog(_EGL_WARNING, "unable to determine the driver name"); 555 drmFreeVersion(version); 556 return EGL_FALSE; 557 } 558 559 if (strcmp(version->name, "i915") == 0) { 560 struct drm_i915_getparam gp; 561 int ret; 562 563 *vendor_id = 0x8086; 564 565 memset(&gp, 0, sizeof(gp)); 566 gp.param = I915_PARAM_CHIPSET_ID; 567 gp.value = chip_id; 568 ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 569 if (ret) { 570 _eglLog(_EGL_WARNING, "failed to get param for i915"); 571 *chip_id = -1; 572 } 573 } 574 else if (strcmp(version->name, "radeon") == 0) { 575 struct drm_radeon_info info; 576 int ret; 577 578 *vendor_id = 0x1002; 579 580 memset(&info, 0, sizeof(info)); 581 info.request = RADEON_INFO_DEVICE_ID; 582 info.value = (unsigned long) chip_id; 583 ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); 584 if (ret) { 585 _eglLog(_EGL_WARNING, "failed to get info for radeon"); 586 *chip_id = -1; 587 } 588 } 589 else if (strcmp(version->name, "nouveau") == 0) { 590 *vendor_id = 0x10de; 591 /* not used */ 592 *chip_id = 0; 593 } 594 else if (strcmp(version->name, "vmwgfx") == 0) { 595 *vendor_id = 0x15ad; 596 /* assume SVGA II */ 597 *chip_id = 0x0405; 598 } 599 600 drmFreeVersion(version); 601 602 return (*chip_id >= 0); 603 } 604 605 #define DRIVER_MAP_DRI2_ONLY 606 #include "pci_ids/pci_id_driver_map.h" 607 static const char * 608 droid_get_driver_name(int fd) 609 { 610 int vendor_id = -1, chip_id = -1; 611 int idx, i; 612 char *name; 613 614 if (!droid_get_pci_id(fd, &vendor_id, &chip_id)) 615 return NULL; 616 617 for (idx = 0; driver_map[idx].driver; idx++) { 618 if (vendor_id != driver_map[idx].vendor_id) 619 continue; 620 621 if (driver_map[idx].num_chips_ids == -1) 622 break; 623 624 for (i = 0; i < driver_map[idx].num_chips_ids; i++) { 625 if (driver_map[idx].chip_ids[i] == chip_id) 626 break; 627 } 628 if (i < driver_map[idx].num_chips_ids) 629 break; 630 } 631 632 _eglLog(_EGL_INFO, "pci id for fd %d: %04x:%04x, driver %s", 633 fd, vendor_id, chip_id, driver_map[idx].driver); 634 635 return driver_map[idx].driver; 636 } 637 638 static int 639 droid_open_device(void) 640 { 641 const hw_module_t *mod; 642 int fd = -1, err; 643 644 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod); 645 if (!err) { 646 const gralloc_module_t *gr = (gralloc_module_t *) mod; 647 648 err = -EINVAL; 649 if (gr->perform) 650 err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd); 651 } 652 if (err || fd < 0) { 653 _eglLog(_EGL_WARNING, "fail to get drm fd"); 654 fd = -1; 655 } 656 657 return (fd >= 0) ? dup(fd) : -1; 658 } 659 660 /* support versions < JellyBean */ 661 #ifndef ALOGW 662 #define ALOGW LOGW 663 #endif 664 #ifndef ALOGD 665 #define ALOGD LOGD 666 #endif 667 #ifndef ALOGI 668 #define ALOGI LOGI 669 #endif 670 671 static void 672 droid_log(EGLint level, const char *msg) 673 { 674 switch (level) { 675 case _EGL_DEBUG: 676 ALOGD("%s", msg); 677 break; 678 case _EGL_INFO: 679 ALOGI("%s", msg); 680 break; 681 case _EGL_WARNING: 682 ALOGW("%s", msg); 683 break; 684 case _EGL_FATAL: 685 LOG_FATAL("%s", msg); 686 break; 687 default: 688 break; 689 } 690 } 691 692 EGLBoolean 693 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) 694 { 695 struct dri2_egl_display *dri2_dpy; 696 const char *err; 697 698 _eglSetLogProc(droid_log); 699 700 dri2_dpy = calloc(1, sizeof(*dri2_dpy)); 701 if (!dri2_dpy) 702 return _eglError(EGL_BAD_ALLOC, "eglInitialize"); 703 704 dpy->DriverData = (void *) dri2_dpy; 705 706 dri2_dpy->fd = droid_open_device(); 707 if (dri2_dpy->fd < 0) { 708 err = "DRI2: failed to open device"; 709 goto cleanup_display; 710 } 711 712 dri2_dpy->driver_name = (char *) droid_get_driver_name(dri2_dpy->fd); 713 if (dri2_dpy->driver_name == NULL) { 714 err = "DRI2: failed to get driver name"; 715 goto cleanup_device; 716 } 717 718 if (!dri2_load_driver(dpy)) { 719 err = "DRI2: failed to load driver"; 720 goto cleanup_device; 721 } 722 723 dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; 724 dri2_dpy->dri2_loader_extension.base.version = 3; 725 dri2_dpy->dri2_loader_extension.getBuffers = NULL; 726 dri2_dpy->dri2_loader_extension.flushFrontBuffer = droid_flush_front_buffer; 727 dri2_dpy->dri2_loader_extension.getBuffersWithFormat = 728 droid_get_buffers_with_format; 729 730 dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; 731 dri2_dpy->extensions[1] = &image_lookup_extension.base; 732 dri2_dpy->extensions[2] = &use_invalidate.base; 733 dri2_dpy->extensions[3] = NULL; 734 735 if (!dri2_create_screen(dpy)) { 736 err = "DRI2: failed to create screen"; 737 goto cleanup_driver; 738 } 739 740 if (!droid_add_configs_for_visuals(drv, dpy)) { 741 err = "DRI2: failed to add configs"; 742 goto cleanup_screen; 743 } 744 745 dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE; 746 dpy->Extensions.KHR_image_base = EGL_TRUE; 747 748 /* we're supporting EGL 1.4 */ 749 dpy->VersionMajor = 1; 750 dpy->VersionMinor = 4; 751 752 droid_init_driver_functions(drv); 753 754 return EGL_TRUE; 755 756 cleanup_screen: 757 dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); 758 cleanup_driver: 759 dlclose(dri2_dpy->driver); 760 cleanup_device: 761 close(dri2_dpy->fd); 762 cleanup_display: 763 free(dri2_dpy); 764 765 return _eglError(EGL_NOT_INITIALIZED, err); 766 } 767