Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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