• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 *
android_sw_winsys(struct sw_winsys * ws)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 *
android_sw_displaytarget(struct sw_displaytarget * dt)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
android_displaytarget_display(struct sw_winsys * ws,struct sw_displaytarget * dt,void * context_private)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 *
android_displaytarget_create(struct sw_winsys * ws,unsigned tex_usage,enum pipe_format format,unsigned width,unsigned height,unsigned alignment,unsigned * stride)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
android_displaytarget_destroy(struct sw_winsys * ws,struct sw_displaytarget * dt)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
android_displaytarget_unmap(struct sw_winsys * ws,struct sw_displaytarget * dt)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 *
android_displaytarget_map(struct sw_winsys * ws,struct sw_displaytarget * dt,unsigned flags)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 *
android_displaytarget_from_handle(struct sw_winsys * ws,const struct pipe_resource * templ,struct winsys_handle * whandle,unsigned * stride)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
android_displaytarget_get_handle(struct sw_winsys * ws,struct sw_displaytarget * dt,struct winsys_handle * whandle)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
android_is_displaytarget_format_supported(struct sw_winsys * ws,unsigned tex_usage,enum pipe_format format)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
android_destroy(struct sw_winsys * ws)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 *
android_create_sw_winsys(void)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