native_android.cpp revision d3d3c12a95bddb7b624818af559ab6b18d890d2f
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.12 4 * 5 * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com> 6 * Copyright (C) 2010-2011 LunarG Inc. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the 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 "EGL-GALLIUM" 28#include <cutils/log.h> 29#include <cutils/properties.h> 30#include <hardware/gralloc.h> 31#include <utils/Errors.h> 32#include <ui/android_native_buffer.h> 33 34extern "C" { 35#include "egllog.h" 36} 37 38#include "util/u_memory.h" 39#include "util/u_inlines.h" 40#include "util/u_format.h" 41#include "util/u_box.h" 42#include "common/native.h" 43#include "common/native_helper.h" 44#include "android/android_sw_winsys.h" 45#include "state_tracker/drm_driver.h" 46 47struct android_config; 48 49struct android_display { 50 struct native_display base; 51 52 boolean use_drm; 53 const struct native_event_handler *event_handler; 54 struct android_config *configs; 55 int num_configs; 56}; 57 58struct android_surface { 59 struct native_surface base; 60 61 struct android_display *adpy; 62 android_native_window_t *win; 63 64 /* staging color buffer for when buffer preserving is enabled */ 65 struct pipe_resource *color_res; 66 67 uint stamp; 68 android_native_buffer_t *buf; 69 struct pipe_resource *buf_res; 70 71 /* cache the current back buffers */ 72 struct { 73 int width; 74 int height; 75 int format; 76 } cache_key; 77 void *cache_handles[2]; 78 struct pipe_resource *cache_resources[2]; 79}; 80 81struct android_config { 82 struct native_config base; 83}; 84 85static INLINE struct android_display * 86android_display(const struct native_display *ndpy) 87{ 88 return (struct android_display *) ndpy; 89} 90 91static INLINE struct android_surface * 92android_surface(const struct native_surface *nsurf) 93{ 94 return (struct android_surface *) nsurf; 95} 96 97static INLINE struct android_config * 98android_config(const struct native_config *nconf) 99{ 100 return (struct android_config *) nconf; 101} 102 103namespace android { 104 105static enum pipe_format 106get_pipe_format(int native) 107{ 108 enum pipe_format fmt; 109 110 switch (native) { 111 case HAL_PIXEL_FORMAT_RGBA_8888: 112 fmt = PIPE_FORMAT_R8G8B8A8_UNORM; 113 break; 114 case HAL_PIXEL_FORMAT_RGBX_8888: 115 fmt = PIPE_FORMAT_R8G8B8X8_UNORM; 116 break; 117 case HAL_PIXEL_FORMAT_RGB_888: 118 fmt = PIPE_FORMAT_R8G8B8_UNORM; 119 break; 120 case HAL_PIXEL_FORMAT_RGB_565: 121 fmt = PIPE_FORMAT_B5G6R5_UNORM; 122 break; 123 case HAL_PIXEL_FORMAT_BGRA_8888: 124 fmt = PIPE_FORMAT_B8G8R8A8_UNORM; 125 break; 126 case HAL_PIXEL_FORMAT_RGBA_5551: 127 /* fmt = PIPE_FORMAT_A1B5G5R5_UNORM; */ 128 case HAL_PIXEL_FORMAT_RGBA_4444: 129 /* fmt = PIPE_FORMAT_A4B4G4R4_UNORM; */ 130 default: 131 LOGE("unsupported native format 0x%x", native); 132 fmt = PIPE_FORMAT_NONE; 133 break; 134 } 135 136 return fmt; 137} 138 139#ifndef ANDROID_BACKEND_NO_DRM 140 141#include <gralloc_drm_handle.h> 142static int 143get_handle_name(buffer_handle_t handle) 144{ 145 struct gralloc_drm_handle_t *dh; 146 147 /* check that the buffer is allocated by drm_gralloc and cast */ 148 dh = gralloc_drm_handle(handle); 149 150 return (dh) ? dh->name : 0; 151} 152 153#else 154 155static int 156get_handle_name(buffer_handle_t handle) 157{ 158 return 0; 159} 160 161#endif /* ANDROID_BACKEND_NO_DRM */ 162 163/** 164 * Import an android_native_buffer_t allocated by the server. 165 */ 166static struct pipe_resource * 167import_buffer(struct android_display *adpy, const struct pipe_resource *templ, 168 struct android_native_buffer_t *abuf) 169{ 170 struct pipe_screen *screen = adpy->base.screen; 171 struct pipe_resource *res; 172 173 if (templ->bind & PIPE_BIND_RENDER_TARGET) { 174 if (!screen->is_format_supported(screen, templ->format, 175 templ->target, 0, PIPE_BIND_RENDER_TARGET)) 176 LOGW("importing unsupported buffer as render target"); 177 } 178 if (templ->bind & PIPE_BIND_SAMPLER_VIEW) { 179 if (!screen->is_format_supported(screen, templ->format, 180 templ->target, 0, PIPE_BIND_SAMPLER_VIEW)) 181 LOGW("importing unsupported buffer as sampler view"); 182 } 183 184 if (adpy->use_drm) { 185 struct winsys_handle handle; 186 187 memset(&handle, 0, sizeof(handle)); 188 handle.type = DRM_API_HANDLE_TYPE_SHARED; 189 /* for DRM, we need the GEM name */ 190 handle.handle = get_handle_name(abuf->handle); 191 if (!handle.handle) { 192 LOGE("unable to import invalid buffer %p", abuf); 193 return NULL; 194 } 195 196 handle.stride = 197 abuf->stride * util_format_get_blocksize(templ->format); 198 199 res = screen->resource_from_handle(screen, templ, &handle); 200 } 201 else { 202 struct android_winsys_handle handle; 203 204 memset(&handle, 0, sizeof(handle)); 205 handle.handle = abuf->handle; 206 handle.stride = 207 abuf->stride * util_format_get_blocksize(templ->format); 208 209 res = screen->resource_from_handle(screen, 210 templ, (struct winsys_handle *) &handle); 211 } 212 213 if (!res) 214 LOGE("failed to import buffer %p", abuf); 215 216 return res; 217} 218 219static void 220android_surface_clear_cache(struct native_surface *nsurf) 221{ 222 struct android_surface *asurf = android_surface(nsurf); 223 int i; 224 225 for (i = 0; i < Elements(asurf->cache_handles); i++) { 226 asurf->cache_handles[i] = NULL; 227 pipe_resource_reference(&asurf->cache_resources[i], NULL); 228 } 229 230 memset(&asurf->cache_key, 0, sizeof(asurf->cache_key)); 231} 232 233static struct pipe_resource * 234android_surface_add_cache(struct native_surface *nsurf, 235 struct android_native_buffer_t *abuf) 236{ 237 struct android_surface *asurf = android_surface(nsurf); 238 void *handle; 239 int idx; 240 241 /* how about abuf->usage? */ 242 if (asurf->cache_key.width != abuf->width || 243 asurf->cache_key.height != abuf->height || 244 asurf->cache_key.format != abuf->format) 245 android_surface_clear_cache(&asurf->base); 246 247 if (asurf->adpy->use_drm) 248 handle = (void *) get_handle_name(abuf->handle); 249 else 250 handle = (void *) abuf->handle; 251 /* NULL is invalid */ 252 if (!handle) { 253 LOGE("invalid buffer native buffer %p", abuf); 254 return NULL; 255 } 256 257 /* find the slot to use */ 258 for (idx = 0; idx < Elements(asurf->cache_handles); idx++) { 259 if (asurf->cache_handles[idx] == handle || !asurf->cache_handles[idx]) 260 break; 261 } 262 if (idx == Elements(asurf->cache_handles)) { 263 LOGW("cache full: buf %p, width %d, height %d, format %d, usage 0x%x", 264 abuf, abuf->width, abuf->height, abuf->format, abuf->usage); 265 android_surface_clear_cache(&asurf->base); 266 idx = 0; 267 } 268 269 if (idx == 0) { 270 asurf->cache_key.width = abuf->width; 271 asurf->cache_key.height = abuf->height; 272 asurf->cache_key.format = abuf->format; 273 } 274 275 if (!asurf->cache_handles[idx]) { 276 struct pipe_resource templ; 277 278 assert(!asurf->cache_resources[idx]); 279 280 memset(&templ, 0, sizeof(templ)); 281 templ.target = PIPE_TEXTURE_2D; 282 templ.format = get_pipe_format(asurf->buf->format); 283 templ.bind = PIPE_BIND_RENDER_TARGET; 284 if (!asurf->adpy->use_drm) { 285 templ.bind |= PIPE_BIND_TRANSFER_WRITE | 286 PIPE_BIND_TRANSFER_READ; 287 } 288 289 templ.width0 = asurf->buf->width; 290 templ.height0 = asurf->buf->height; 291 templ.depth0 = 1; 292 templ.array_size = 1; 293 294 if (templ.format != PIPE_FORMAT_NONE) { 295 asurf->cache_resources[idx] = 296 import_buffer(asurf->adpy, &templ, asurf->buf); 297 } 298 else { 299 asurf->cache_resources[idx] = NULL; 300 } 301 302 asurf->cache_handles[idx] = handle; 303 } 304 305 return asurf->cache_resources[idx]; 306} 307 308/** 309 * Dequeue the next back buffer for rendering. 310 */ 311static boolean 312android_surface_dequeue_buffer(struct native_surface *nsurf) 313{ 314 struct android_surface *asurf = android_surface(nsurf); 315 struct pipe_resource *res; 316 317 if (asurf->win->dequeueBuffer(asurf->win, &asurf->buf) != NO_ERROR) { 318 LOGE("failed to dequeue window %p", asurf->win); 319 return FALSE; 320 } 321 322 asurf->buf->common.incRef(&asurf->buf->common); 323 asurf->win->lockBuffer(asurf->win, asurf->buf); 324 325 res = android_surface_add_cache(&asurf->base, asurf->buf); 326 if (!res) 327 return FALSE; 328 329 pipe_resource_reference(&asurf->buf_res, res); 330 331 return TRUE; 332} 333 334/** 335 * Enqueue the back buffer. This will make it the next front buffer. 336 */ 337static boolean 338android_surface_enqueue_buffer(struct native_surface *nsurf) 339{ 340 struct android_surface *asurf = android_surface(nsurf); 341 342 pipe_resource_reference(&asurf->buf_res, NULL); 343 344 asurf->win->queueBuffer(asurf->win, asurf->buf); 345 346 asurf->buf->common.decRef(&asurf->buf->common); 347 asurf->buf = NULL; 348 349 return TRUE; 350} 351 352static boolean 353android_surface_swap_buffers(struct native_surface *nsurf) 354{ 355 struct android_surface *asurf = android_surface(nsurf); 356 struct android_display *adpy = asurf->adpy; 357 358 android_surface_enqueue_buffer(&asurf->base); 359 360 asurf->stamp++; 361 adpy->event_handler->invalid_surface(&adpy->base, 362 &asurf->base, asurf->stamp); 363 364 return TRUE; 365} 366 367static void 368copy_resources(struct native_display *ndpy, 369 struct pipe_resource *src, 370 struct pipe_resource *dst) 371{ 372 struct pipe_context *pipe; 373 struct pipe_box box; 374 375 pipe = ndpy_get_copy_context(ndpy); 376 if (!pipe) 377 return; 378 379 u_box_origin_2d(src->width0, src->height0, &box); 380 pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &box); 381 pipe->flush(pipe, NULL); 382} 383 384static boolean 385android_surface_present(struct native_surface *nsurf, 386 const native_present_control *ctrl) 387{ 388 struct android_surface *asurf = android_surface(nsurf); 389 struct android_display *adpy = asurf->adpy; 390 boolean ret; 391 392 if (ctrl->swap_interval || ctrl->natt != NATIVE_ATTACHMENT_BACK_LEFT) 393 return FALSE; 394 395 /* this happens when eglSwapBuffers is called more than once in a row */ 396 if (!asurf->buf) 397 return TRUE; 398 399 /* we always render to color_res first when it exists */ 400 if (asurf->color_res) { 401 copy_resources(&adpy->base, asurf->color_res, asurf->buf_res); 402 if (!ctrl->preserve) 403 pipe_resource_reference(&asurf->color_res, NULL); 404 } 405 else if (ctrl->preserve) { 406 struct pipe_resource templ; 407 408 memset(&templ, 0, sizeof(templ)); 409 templ.target = asurf->buf_res->target; 410 templ.format = asurf->buf_res->format; 411 templ.bind = PIPE_BIND_RENDER_TARGET; 412 templ.width0 = asurf->buf_res->width0; 413 templ.height0 = asurf->buf_res->height0; 414 templ.depth0 = asurf->buf_res->depth0; 415 templ.array_size = asurf->buf_res->array_size; 416 417 asurf->color_res = 418 adpy->base.screen->resource_create(adpy->base.screen, &templ); 419 if (!asurf->color_res) 420 return FALSE; 421 422 /* preserve the contents */ 423 copy_resources(&adpy->base, asurf->buf_res, asurf->color_res); 424 } 425 426 return android_surface_swap_buffers(nsurf); 427} 428 429static boolean 430android_surface_validate(struct native_surface *nsurf, uint attachment_mask, 431 unsigned int *seq_num, struct pipe_resource **textures, 432 int *width, int *height) 433{ 434 struct android_surface *asurf = android_surface(nsurf); 435 struct winsys_handle handle; 436 437 if (!asurf->buf) { 438 if (!android_surface_dequeue_buffer(&asurf->base)) 439 return FALSE; 440 441 /* color_res must be compatible with buf_res */ 442 if (asurf->color_res && 443 (asurf->color_res->format != asurf->buf_res->format || 444 asurf->color_res->width0 != asurf->buf_res->width0 || 445 asurf->color_res->height0 != asurf->buf_res->height0)) 446 pipe_resource_reference(&asurf->color_res, NULL); 447 } 448 449 if (textures) { 450 /* we have access to only the back buffer */ 451 const enum native_attachment att = NATIVE_ATTACHMENT_BACK_LEFT; 452 453 if (native_attachment_mask_test(attachment_mask, att)) { 454 textures[att] = NULL; 455 pipe_resource_reference(&textures[att], 456 (asurf->color_res) ? asurf->color_res : asurf->buf_res); 457 } 458 } 459 460 if (seq_num) 461 *seq_num = asurf->stamp; 462 if (width) 463 *width = asurf->buf->width; 464 if (height) 465 *height = asurf->buf->height; 466 467 return TRUE; 468} 469 470static void 471android_surface_wait(struct native_surface *nsurf) 472{ 473} 474 475static void 476android_surface_destroy(struct native_surface *nsurf) 477{ 478 struct android_surface *asurf = android_surface(nsurf); 479 int i; 480 481 pipe_resource_reference(&asurf->color_res, NULL); 482 483 if (asurf->buf) 484 android_surface_enqueue_buffer(&asurf->base); 485 486 android_surface_clear_cache(&asurf->base); 487 488 asurf->win->common.decRef(&asurf->win->common); 489 490 FREE(asurf); 491} 492 493static struct native_surface * 494android_display_create_window_surface(struct native_display *ndpy, 495 EGLNativeWindowType win, 496 const struct native_config *nconf) 497{ 498 struct android_display *adpy = android_display(ndpy); 499 struct android_config *aconf = android_config(nconf); 500 struct android_surface *asurf; 501 enum pipe_format format; 502 int val; 503 504 if (win->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { 505 LOGE("invalid native window with magic 0x%x", win->common.magic); 506 return NULL; 507 } 508 if (win->query(win, NATIVE_WINDOW_FORMAT, &val)) { 509 LOGE("failed to query native window format"); 510 return NULL; 511 } 512 format = get_pipe_format(val); 513 if (format != nconf->color_format) { 514 LOGW("native window format 0x%x != config format 0x%x", 515 format, nconf->color_format); 516 if (!adpy->base.screen->is_format_supported(adpy->base.screen, 517 format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) { 518 LOGE("and the native window cannot be used as a render target"); 519 return NULL; 520 } 521 } 522 523 asurf = CALLOC_STRUCT(android_surface); 524 if (!asurf) 525 return NULL; 526 527 asurf->adpy = adpy; 528 asurf->win = win; 529 asurf->win->common.incRef(&asurf->win->common); 530 531 /* request buffers that are for CPU access */ 532 if (!adpy->use_drm) { 533 native_window_set_usage(asurf->win, 534 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 535 } 536 537 asurf->base.destroy = android_surface_destroy; 538 asurf->base.present = android_surface_present; 539 asurf->base.validate = android_surface_validate; 540 asurf->base.wait = android_surface_wait; 541 542 return &asurf->base; 543} 544 545static boolean 546android_display_init_configs(struct native_display *ndpy) 547{ 548 struct android_display *adpy = android_display(ndpy); 549 const int native_formats[] = { 550 HAL_PIXEL_FORMAT_RGBA_8888, 551 HAL_PIXEL_FORMAT_RGBX_8888, 552 HAL_PIXEL_FORMAT_RGB_888, 553 HAL_PIXEL_FORMAT_RGB_565, 554 HAL_PIXEL_FORMAT_BGRA_8888, 555 }; 556 int i; 557 558 adpy->configs = (struct android_config *) 559 CALLOC(Elements(native_formats), sizeof(*adpy->configs)); 560 if (!adpy->configs) 561 return FALSE; 562 563 for (i = 0; i < Elements(native_formats); i++) { 564 enum pipe_format color_format; 565 struct android_config *aconf; 566 567 color_format = get_pipe_format(native_formats[i]); 568 if (color_format == PIPE_FORMAT_NONE || 569 !adpy->base.screen->is_format_supported(adpy->base.screen, 570 color_format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) { 571 LOGI("skip unsupported native format 0x%x", native_formats[i]); 572 continue; 573 } 574 575 aconf = &adpy->configs[adpy->num_configs++]; 576 /* only the back buffer */ 577 aconf->base.buffer_mask = 1 << NATIVE_ATTACHMENT_BACK_LEFT; 578 aconf->base.color_format = color_format; 579 aconf->base.window_bit = TRUE; 580 581 aconf->base.native_visual_id = native_formats[i]; 582 aconf->base.native_visual_type = native_formats[i]; 583 } 584 585 return TRUE; 586} 587 588static boolean 589android_display_init_drm(struct native_display *ndpy) 590{ 591 struct android_display *adpy = android_display(ndpy); 592 const hw_module_t *mod; 593 int fd, err; 594 595#ifndef ANDROID_BACKEND_NO_DRM 596 /* get the authorized fd from gralloc */ 597 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod); 598 if (!err) { 599 const gralloc_module_t *gr = (gralloc_module_t *) mod; 600 601 err = -EINVAL; 602 if (gr->perform) 603 err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd); 604 } 605 if (!err && fd >= 0) { 606 adpy->base.screen = 607 adpy->event_handler->new_drm_screen(&adpy->base, NULL, fd); 608 } 609#endif 610 611 if (adpy->base.screen) { 612 LOGI("using DRM screen"); 613 return TRUE; 614 } 615 else { 616 LOGW("failed to create DRM screen"); 617 LOGW("will fall back to other EGL drivers if any"); 618 return FALSE; 619 } 620} 621 622static boolean 623android_display_init_sw(struct native_display *ndpy) 624{ 625 struct android_display *adpy = android_display(ndpy); 626 struct sw_winsys *ws; 627 628 ws = android_create_sw_winsys(); 629 if (ws) { 630 adpy->base.screen = 631 adpy->event_handler->new_sw_screen(&adpy->base, ws); 632 } 633 634 if (adpy->base.screen) { 635 LOGI("using SW screen"); 636 return TRUE; 637 } 638 else { 639 LOGE("failed to create SW screen"); 640 return FALSE; 641 } 642} 643 644static boolean 645android_display_init_screen(struct native_display *ndpy) 646{ 647 struct android_display *adpy = android_display(ndpy); 648 649 if (adpy->use_drm) 650 android_display_init_drm(&adpy->base); 651 else 652 android_display_init_sw(&adpy->base); 653 654 if (!adpy->base.screen) 655 return FALSE; 656 657 if (!android_display_init_configs(&adpy->base)) { 658 adpy->base.screen->destroy(adpy->base.screen); 659 adpy->base.screen = NULL; 660 return FALSE; 661 } 662 663 return TRUE; 664} 665 666static void 667android_display_destroy(struct native_display *ndpy) 668{ 669 struct android_display *adpy = android_display(ndpy); 670 671 FREE(adpy->configs); 672 if (adpy->base.screen) 673 adpy->base.screen->destroy(adpy->base.screen); 674 FREE(adpy); 675} 676 677static const struct native_config ** 678android_display_get_configs(struct native_display *ndpy, int *num_configs) 679{ 680 struct android_display *adpy = android_display(ndpy); 681 const struct native_config **configs; 682 int i; 683 684 configs = (const struct native_config **) 685 MALLOC(adpy->num_configs * sizeof(*configs)); 686 if (configs) { 687 for (i = 0; i < adpy->num_configs; i++) 688 configs[i] = (const struct native_config *) &adpy->configs[i]; 689 if (num_configs) 690 *num_configs = adpy->num_configs; 691 } 692 693 return configs; 694} 695 696static int 697android_display_get_param(struct native_display *ndpy, 698 enum native_param_type param) 699{ 700 int val; 701 702 switch (param) { 703 case NATIVE_PARAM_PRESERVE_BUFFER: 704 val = 1; 705 break; 706 default: 707 val = 0; 708 break; 709 } 710 711 return val; 712} 713 714static struct pipe_resource * 715android_display_import_buffer(struct native_display *ndpy, 716 struct native_buffer *nbuf) 717{ 718 struct android_display *adpy = android_display(ndpy); 719 struct android_native_buffer_t *abuf; 720 enum pipe_format format; 721 struct pipe_resource templ; 722 723 if (nbuf->type != NATIVE_BUFFER_ANDROID) 724 return NULL; 725 726 abuf = nbuf->u.android; 727 728 if (!abuf || abuf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC || 729 abuf->common.version != sizeof(*abuf)) { 730 LOGE("invalid android native buffer"); 731 return NULL; 732 } 733 734 format = get_pipe_format(abuf->format); 735 if (format == PIPE_FORMAT_NONE) 736 return NULL; 737 738 memset(&templ, 0, sizeof(templ)); 739 templ.target = PIPE_TEXTURE_2D; 740 templ.format = format; 741 /* assume for texturing only */ 742 templ.bind = PIPE_BIND_SAMPLER_VIEW; 743 templ.width0 = abuf->width; 744 templ.height0 = abuf->height; 745 templ.depth0 = 1; 746 templ.array_size = 1; 747 748 return import_buffer(adpy, &templ, abuf); 749} 750 751static boolean 752android_display_export_buffer(struct native_display *ndpy, 753 struct pipe_resource *res, 754 struct native_buffer *nbuf) 755{ 756 return FALSE; 757} 758 759static struct native_display_buffer android_display_buffer = { 760 android_display_import_buffer, 761 android_display_export_buffer 762}; 763 764static struct android_display * 765android_display_create(const struct native_event_handler *event_handler, 766 boolean use_sw) 767{ 768 struct android_display *adpy; 769 char value[PROPERTY_VALUE_MAX]; 770 boolean force_sw; 771 772 /* check if SW renderer is forced */ 773 if (property_get("debug.mesa.software", value, NULL)) 774 force_sw = (atoi(value) != 0); 775 else 776 force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); 777 if (force_sw) 778 use_sw = TRUE; 779 780 adpy = CALLOC_STRUCT(android_display); 781 if (!adpy) 782 return NULL; 783 784 adpy->event_handler = event_handler; 785 adpy->use_drm = !use_sw; 786 787 adpy->base.init_screen = android_display_init_screen; 788 adpy->base.destroy = android_display_destroy; 789 adpy->base.get_param = android_display_get_param; 790 adpy->base.get_configs = android_display_get_configs; 791 adpy->base.create_window_surface = android_display_create_window_surface; 792 793 adpy->base.buffer = &android_display_buffer; 794 795 return adpy; 796} 797 798static const struct native_event_handler *android_event_handler; 799 800static struct native_display * 801native_create_display(void *dpy, boolean use_sw) 802{ 803 struct android_display *adpy; 804 805 adpy = android_display_create(android_event_handler, use_sw); 806 807 return (adpy) ? &adpy->base : NULL; 808} 809 810static const struct native_platform android_platform = { 811 "Android", /* name */ 812 native_create_display 813}; 814 815}; /* namespace android */ 816 817using namespace android; 818 819static void 820android_log(EGLint level, const char *msg) 821{ 822 switch (level) { 823 case _EGL_DEBUG: 824 LOGD("%s", msg); 825 break; 826 case _EGL_INFO: 827 LOGI("%s", msg); 828 break; 829 case _EGL_WARNING: 830 LOGW("%s", msg); 831 break; 832 case _EGL_FATAL: 833 LOG_FATAL("%s", msg); 834 break; 835 default: 836 break; 837 } 838} 839 840const struct native_platform * 841native_get_android_platform(const struct native_event_handler *event_handler) 842{ 843 android_event_handler = event_handler; 844 /* use Android logger */ 845 _eglSetLogProc(android_log); 846 847 return &android_platform; 848} 849