Home | History | Annotate | Download | only in android
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.12
      4  *
      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  * Authors:
     26  *    Chia-I Wu <olv (at) lunarg.com>
     27  */
     28 
     29 #include "pipe/p_compiler.h"
     30 #include "pipe/p_state.h"
     31 #include "util/u_memory.h"
     32 #include "util/u_format.h"
     33 #include "state_tracker/sw_winsys.h"
     34 
     35 #include <hardware/gralloc.h>
     36 #include <utils/Errors.h>
     37 
     38 #if ANDROID_VERSION < 0x0300
     39 #include <private/ui/sw_gralloc_handle.h>
     40 #endif
     41 
     42 #include "android_sw_winsys.h"
     43 
     44 struct android_sw_winsys
     45 {
     46    struct sw_winsys base;
     47 
     48    const gralloc_module_t *grmod;
     49 };
     50 
     51 struct android_sw_displaytarget
     52 {
     53    buffer_handle_t handle;
     54    int stride;
     55    int width, height;
     56    int usage; /* gralloc usage */
     57 
     58    void *mapped;
     59 };
     60 
     61 static INLINE struct android_sw_winsys *
     62 android_sw_winsys(struct sw_winsys *ws)
     63 {
     64    return (struct android_sw_winsys *) ws;
     65 }
     66 
     67 static INLINE struct android_sw_displaytarget *
     68 android_sw_displaytarget(struct sw_displaytarget *dt)
     69 {
     70    return (struct android_sw_displaytarget *) dt;
     71 }
     72 
     73 namespace android {
     74 
     75 static void
     76 android_displaytarget_display(struct sw_winsys *ws,
     77                               struct sw_displaytarget *dt,
     78                               void *context_private)
     79 {
     80 }
     81 
     82 static struct sw_displaytarget *
     83 android_displaytarget_create(struct sw_winsys *ws,
     84                              unsigned tex_usage,
     85                              enum pipe_format format,
     86                              unsigned width, unsigned height,
     87                              unsigned alignment,
     88                              unsigned *stride)
     89 {
     90    return NULL;
     91 }
     92 
     93 static void
     94 android_displaytarget_destroy(struct sw_winsys *ws,
     95                               struct sw_displaytarget *dt)
     96 {
     97    struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
     98 
     99    assert(!adt->mapped);
    100    FREE(adt);
    101 }
    102 
    103 static void
    104 android_displaytarget_unmap(struct sw_winsys *ws,
    105                             struct sw_displaytarget *dt)
    106 {
    107    struct android_sw_winsys *droid = android_sw_winsys(ws);
    108    struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
    109 
    110 #if ANDROID_VERSION < 0x0300
    111    /* try sw_gralloc first */
    112    if (adt->mapped && sw_gralloc_handle_t::validate(adt->handle) >= 0) {
    113       adt->mapped = NULL;
    114       return;
    115    }
    116 #endif
    117 
    118    if (adt->mapped) {
    119       droid->grmod->unlock(droid->grmod, adt->handle);
    120       adt->mapped = NULL;
    121    }
    122 }
    123 
    124 static void *
    125 android_displaytarget_map(struct sw_winsys *ws,
    126                           struct sw_displaytarget *dt,
    127                           unsigned flags)
    128 {
    129    struct android_sw_winsys *droid = android_sw_winsys(ws);
    130    struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
    131 
    132 #if ANDROID_VERSION < 0x0300
    133    /* try sw_gralloc first */
    134    if (sw_gralloc_handle_t::validate(adt->handle) >= 0) {
    135       const sw_gralloc_handle_t *swhandle =
    136          reinterpret_cast<const sw_gralloc_handle_t *>(adt->handle);
    137       adt->mapped = reinterpret_cast<void *>(swhandle->base);
    138 
    139       return adt->mapped;
    140    }
    141 #endif
    142 
    143    if (!adt->mapped) {
    144       /* lock the buffer for CPU access */
    145       droid->grmod->lock(droid->grmod, adt->handle,
    146             adt->usage, 0, 0, adt->width, adt->height, &adt->mapped);
    147    }
    148 
    149    return adt->mapped;
    150 }
    151 
    152 static struct sw_displaytarget *
    153 android_displaytarget_from_handle(struct sw_winsys *ws,
    154                                   const struct pipe_resource *templ,
    155                                   struct winsys_handle *whandle,
    156                                   unsigned *stride)
    157 {
    158    struct android_winsys_handle *ahandle =
    159       (struct android_winsys_handle *) whandle;
    160    struct android_sw_displaytarget *adt;
    161 
    162    adt = CALLOC_STRUCT(android_sw_displaytarget);
    163    if (!adt)
    164       return NULL;
    165 
    166    adt->handle = ahandle->handle;
    167    adt->stride = ahandle->stride;
    168    adt->width = templ->width0;
    169    adt->height = templ->height0;
    170 
    171    if (templ->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_WRITE))
    172       adt->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
    173    if (templ->bind & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ))
    174       adt->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
    175 
    176    if (stride)
    177       *stride = adt->stride;
    178 
    179    return reinterpret_cast<struct sw_displaytarget *>(adt);
    180 }
    181 
    182 static boolean
    183 android_displaytarget_get_handle(struct sw_winsys *ws,
    184                                  struct sw_displaytarget *dt,
    185                                  struct winsys_handle *whandle)
    186 {
    187    return FALSE;
    188 }
    189 
    190 static boolean
    191 android_is_displaytarget_format_supported(struct sw_winsys *ws,
    192                                           unsigned tex_usage,
    193                                           enum pipe_format format)
    194 {
    195    struct android_sw_winsys *droid = android_sw_winsys(ws);
    196    int fmt = -1;
    197 
    198    switch (format) {
    199    case PIPE_FORMAT_R8G8B8A8_UNORM:
    200       fmt = HAL_PIXEL_FORMAT_RGBA_8888;
    201       break;
    202    case PIPE_FORMAT_R8G8B8X8_UNORM:
    203       fmt = HAL_PIXEL_FORMAT_RGBX_8888;
    204       break;
    205    case PIPE_FORMAT_R8G8B8_UNORM:
    206       fmt = HAL_PIXEL_FORMAT_RGB_888;
    207       break;
    208    case PIPE_FORMAT_B5G6R5_UNORM:
    209       fmt = HAL_PIXEL_FORMAT_RGB_565;
    210       break;
    211    case PIPE_FORMAT_B8G8R8A8_UNORM:
    212       fmt = HAL_PIXEL_FORMAT_BGRA_8888;
    213       break;
    214    default:
    215       break;
    216    }
    217 
    218    return (fmt != -1);
    219 }
    220 
    221 static void
    222 android_destroy(struct sw_winsys *ws)
    223 {
    224    struct android_sw_winsys *droid = android_sw_winsys(ws);
    225 
    226    FREE(droid);
    227 }
    228 
    229 }; /* namespace android */
    230 
    231 using namespace android;
    232 
    233 struct sw_winsys *
    234 android_create_sw_winsys(void)
    235 {
    236    struct android_sw_winsys *droid;
    237    const hw_module_t *mod;
    238 
    239    droid = CALLOC_STRUCT(android_sw_winsys);
    240    if (!droid)
    241       return NULL;
    242 
    243    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod)) {
    244       FREE(droid);
    245       return NULL;
    246    }
    247 
    248    droid->grmod = (const gralloc_module_t *) mod;
    249 
    250    droid->base.destroy = android_destroy;
    251    droid->base.is_displaytarget_format_supported =
    252       android_is_displaytarget_format_supported;
    253 
    254    droid->base.displaytarget_create = android_displaytarget_create;
    255    droid->base.displaytarget_destroy = android_displaytarget_destroy;
    256    droid->base.displaytarget_from_handle = android_displaytarget_from_handle;
    257    droid->base.displaytarget_get_handle = android_displaytarget_get_handle;
    258 
    259    droid->base.displaytarget_map = android_displaytarget_map;
    260    droid->base.displaytarget_unmap = android_displaytarget_unmap;
    261    droid->base.displaytarget_display = android_displaytarget_display;
    262 
    263    return &droid->base;
    264 }
    265