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