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