swrast* (gallium, classic): add MESA_copy_sub_buffer support (v3)
[mesa.git] / src / gallium / winsys / sw / android / android_sw_winsys.cpp
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2010-2011 LunarG Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "pipe/p_compiler.h"
29 #include "pipe/p_state.h"
30 #include "util/u_memory.h"
31 #include "util/u_format.h"
32 #include "state_tracker/sw_winsys.h"
33
34 #include <hardware/gralloc.h>
35 #include <utils/Errors.h>
36
37 #if ANDROID_VERSION < 0x0300
38 #include <private/ui/sw_gralloc_handle.h>
39 #endif
40
41 #include "android_sw_winsys.h"
42
43 struct android_sw_winsys
44 {
45 struct sw_winsys base;
46
47 const gralloc_module_t *grmod;
48 };
49
50 struct android_sw_displaytarget
51 {
52 buffer_handle_t handle;
53 int stride;
54 int width, height;
55 int usage; /* gralloc usage */
56
57 void *mapped;
58 };
59
60 static INLINE struct android_sw_winsys *
61 android_sw_winsys(struct sw_winsys *ws)
62 {
63 return (struct android_sw_winsys *) ws;
64 }
65
66 static INLINE struct android_sw_displaytarget *
67 android_sw_displaytarget(struct sw_displaytarget *dt)
68 {
69 return (struct android_sw_displaytarget *) dt;
70 }
71
72 namespace android {
73
74 static void
75 android_displaytarget_display(struct sw_winsys *ws,
76 struct sw_displaytarget *dt,
77 void *context_private,
78 struct pipe_box *box)
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 }