blob: 32bcc07d98bc17c2667dc9513cd308b35a5a936d [file] [log] [blame]
Jorge E. Moreira7a8dadd2017-08-22 17:01:39 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "gralloc_vsoc_priv.h"
18#include <hardware/gralloc.h>
19#include <hardware/hardware.h>
20#include <log/log.h>
21#include <stdlib.h>
22
23namespace {
24
25static const int kSwiftShaderPadding = 4;
26
27inline void formatToYcbcr(
28 int format, int width, int height, void* base_v, android_ycbcr* ycbcr) {
29 uintptr_t it = reinterpret_cast<uintptr_t>(base_v);
30 // Clear reserved fields;
31 memset(ycbcr, 0, sizeof(*ycbcr));
32 switch (format) {
33 case HAL_PIXEL_FORMAT_YV12:
34 case HAL_PIXEL_FORMAT_YCbCr_420_888:
35 ycbcr->ystride = align(width, 16);
36 ycbcr->cstride = align(ycbcr->ystride / 2, 16);
37 ycbcr->chroma_step = 1;
38 ycbcr->y = reinterpret_cast<void*>(it);
39 it += ycbcr->ystride * height;
40 ycbcr->cr = reinterpret_cast<void*>(it);
41 it += ycbcr->cstride * height / 2;
42 ycbcr->cb = reinterpret_cast<void*>(it);
43 break;
44 default:
45 ALOGE("%s: can't deal with format=0x%x", __FUNCTION__, format);
46 }
47}
48
49inline int formatToBytesPerPixel(int format) {
50 switch (format) {
51 case HAL_PIXEL_FORMAT_RGBA_8888:
52 case HAL_PIXEL_FORMAT_RGBX_8888:
53 case HAL_PIXEL_FORMAT_BGRA_8888:
54 // The camera 3.0 implementation assumes that IMPLEMENTATION_DEFINED
55 // means HAL_PIXEL_FORMAT_RGBA_8888
56 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
57 return 4;
58 case HAL_PIXEL_FORMAT_RGB_888:
59 return 3;
60 case HAL_PIXEL_FORMAT_RGB_565:
61 case HAL_PIXEL_FORMAT_YV12:
62 case HAL_PIXEL_FORMAT_YCbCr_420_888:
63 return 2;
64 case HAL_PIXEL_FORMAT_BLOB:
65 return 1;
66 default:
67 ALOGE("%s: unknown format=%d", __FUNCTION__, format);
68 return 4;
69 }
70}
71
72inline int formatToBytesPerFrame(int format, int w, int h) {
73 int bytes_per_pixel = formatToBytesPerPixel(format);
74 int w16, h16;
75 int y_size, c_size;
76
77 switch (format) {
78 // BLOB is used to allocate buffers for JPEG formatted data. Bytes per pixel
79 // is 1, the desired buffer size is in w, and h should be 1. We refrain from
80 // adding additional padding, although the caller is likely to round
81 // up to a page size.
82 case HAL_PIXEL_FORMAT_BLOB:
83 return bytes_per_pixel * w * h;
84 case HAL_PIXEL_FORMAT_YV12:
85 case HAL_PIXEL_FORMAT_YCbCr_420_888:
86 android_ycbcr strides;
87 formatToYcbcr(format, w, h, NULL, &strides);
88 y_size = strides.ystride * h;
89 c_size = strides.cstride * h / 2;
90 return (y_size + 2 * c_size + kSwiftShaderPadding);
91 /*case HAL_PIXEL_FORMAT_RGBA_8888:
92 case HAL_PIXEL_FORMAT_RGBX_8888:
93 case HAL_PIXEL_FORMAT_BGRA_8888:
94 case HAL_PIXEL_FORMAT_RGB_888:
95 case HAL_PIXEL_FORMAT_RGB_565:*/
96 default:
97 w16 = align(w, 16);
98 h16 = align(h, 16);
99 return bytes_per_pixel * w16 * h16 + kSwiftShaderPadding;
100 }
101}
102
103}
104
105/******************************************************************************/
106
107void dump(struct alloc_device_t */*dev*/, char */*buff*/, int /*buff_len*/) {}
108
109/******************************************************************************/
110
111int lock(struct gralloc_module_t const* /*module*/,
112 buffer_handle_t handle,
113 int /*usage*/,
114 int /*l*/,
115 int /*t*/,
116 int /*w*/,
117 int /*h*/,
118 void** vaddr) {
119 if (!vaddr || vsoc_buffer_handle_t::validate(handle)) {
120 return -EINVAL;
121 }
122 // TODO(jemoreira): Check allocation usage flags against requested usage.
123 const vsoc_buffer_handle_t* hnd =
124 reinterpret_cast<const vsoc_buffer_handle_t*>(handle);
125 void* mapped = reference_buffer(hnd);
126 if (mapped == NULL) {
127 ALOGE("Unable to reference buffer, %s", __FUNCTION__);
128 return -1;
129 }
130 *vaddr = mapped;
131 return 0;
132}
133
134int unlock(struct gralloc_module_t const* /*module*/, buffer_handle_t handle) {
135 if (vsoc_buffer_handle_t::validate(handle)) {
136 return -EINVAL;
137 }
138 return unreference_buffer(
139 reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
140}
141
142int lock_ycbcr(struct gralloc_module_t const* module,
143 buffer_handle_t handle,
144 int usage,
145 int l,
146 int t,
147 int w,
148 int h,
149 struct android_ycbcr* ycbcr) {
150 void* mapped;
151 int retval = lock(module, handle, usage, l, t, w, h, &mapped);
152 if (retval) {
153 return retval;
154 }
155 const vsoc_buffer_handle_t* hnd =
156 reinterpret_cast<const vsoc_buffer_handle_t*>(handle);
157 formatToYcbcr(hnd->format, w, h, mapped, ycbcr);
158 return 0;
159}
160
161/******************************************************************************/
162
163static int gralloc_alloc(
164 alloc_device_t* dev, int w, int h, int format, int /*usage*/,
165 buffer_handle_t* pHandle, int* pStrideInPixels) {
166 int fd = -1;
167
168 int bytes_per_pixel = formatToBytesPerPixel(format);
169 int bytes_per_line;
170 int stride_in_pixels;
171 int size = 0;
172 uint32_t offset = 0;
173 // SwiftShader can't handle RGB_888, so fail fast and hard if we try to create
174 // a gralloc buffer in this format.
175 ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888);
176 if (format == HAL_PIXEL_FORMAT_YV12) {
177 bytes_per_line = align(bytes_per_pixel * w, 16);
178 } else {
179 bytes_per_line = align(bytes_per_pixel * w, 8);
180 }
181 size = align(size + formatToBytesPerFrame(format, w, h), PAGE_SIZE);
182 size += PAGE_SIZE;
183 fd = reinterpret_cast<vsoc_alloc_device_t*>(dev)
184 ->gralloc_region->AllocateBuffer(size, &offset);
185 if (fd < 0) {
186 ALOGE("Unable to allocate buffer (%s)", strerror(-fd));
187 return fd;
188 }
189
190 stride_in_pixels = bytes_per_line / bytes_per_pixel;
191 vsoc_buffer_handle_t* hnd = new vsoc_buffer_handle_t(fd,
192 offset,
193 size,
194 format,
195 w, h,
196 stride_in_pixels);
197 void* addr =
198 reference_buffer(reinterpret_cast<const vsoc_buffer_handle_t*>(hnd));
199 if (!addr) {
200 ALOGE("Unable to reference buffer, %s", __FUNCTION__);
201 return -EIO;
202 }
203
204 *pHandle = hnd;
205 *pStrideInPixels = stride_in_pixels;
206
207 return 0;
208}
209
210static int gralloc_free(alloc_device_t* /*dev*/, buffer_handle_t handle) {
211 // No need to do anything else, the buffer will be atomatically deallocated
212 // when the handle is closed.
213 return unreference_buffer(
214 reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
215}
216
217static int register_buffer(struct gralloc_module_t const* /*module*/,
218 buffer_handle_t handle) {
219 if (vsoc_buffer_handle_t::validate(handle)) {
220 return -EINVAL;
221 }
222 void* addr =
223 reference_buffer(reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
224 if (!addr) {
225 ALOGE("Unable to reference buffer, %s", __FUNCTION__);
226 return -EIO;
227 }
228 return 0;
229}
230
231int unregister_buffer(struct gralloc_module_t const* /*module*/,
232 buffer_handle_t handle) {
233 if (vsoc_buffer_handle_t::validate(handle)) {
234 return -EINVAL;
235 }
236 return unreference_buffer(
237 reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
238}
239
240/******************************************************************************/
241
242static int gralloc_device_close(struct hw_device_t *dev) {
243 vsoc_alloc_device_t* pdev = reinterpret_cast<vsoc_alloc_device_t*>(dev);
244 if (pdev) {
245 free(pdev);
246 }
247 return 0;
248}
249
250static int gralloc_device_open(
251 const hw_module_t* module, const char* name, hw_device_t** device) {
252 int status = -EINVAL;
253 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
254 vsoc_alloc_device_t *dev;
255 dev = (vsoc_alloc_device_t*) malloc(sizeof(*dev));
256 LOG_FATAL_IF(!dev, "%s: malloc returned NULL.", __FUNCTION__);
257
258 /* initialize our state here */
259 memset(dev, 0, sizeof(*dev));
260
261 /* initialize the procs */
262 dev->device.common.tag = HARDWARE_DEVICE_TAG;
263 dev->device.common.version = 0; // TODO(jemoreira): Bump to 0_2 when stable
264 dev->device.common.module = const_cast<hw_module_t*>(module);
265 dev->device.common.close = gralloc_device_close;
266
267 dev->device.alloc = gralloc_alloc;
268 dev->device.free = gralloc_free;
269
Greg Hartmand072a342017-12-05 20:27:40 -0800270 dev->gralloc_region = vsoc::gralloc::GrallocRegionView::GetInstance();
Jorge E. Moreira7a8dadd2017-08-22 17:01:39 -0700271 if (!dev->gralloc_region) {
272 LOG_FATAL("Unable to instantiate the gralloc region");
273 free(dev);
274 return -EIO;
275 }
276
277 *device = &dev->device.common;
278 status = 0;
279 }
280 // TODO(jemoreira): Consider opening other type of devices (framebuffer)
281 return status;
282}
283
284/******************************************************************************/
285
286static struct hw_module_methods_t gralloc_module_methods = {
287 .open = gralloc_device_open
288};
289
290struct vsoc_gralloc_module_t HAL_MODULE_INFO_SYM = {
291 .base = {
292 .common = {
293 .tag = HARDWARE_MODULE_TAG,
294 .version_major = GRALLOC_MODULE_API_VERSION_0_2,
295 .version_minor = 0,
296 .id = GRALLOC_HARDWARE_MODULE_ID,
297 .name = "VSoC X86 Graphics Memory Allocator Module",
298 .author = "The Android Open Source Project",
299 .methods = &gralloc_module_methods,
300 .dso = NULL,
301 .reserved = {0},
302 },
303 .registerBuffer = register_buffer,
304 .unregisterBuffer = unregister_buffer,
305 .lock = lock,
306 .unlock = unlock,
307 .lock_ycbcr = lock_ycbcr,
308 .perform = NULL,
309 },
310};