1 /*
2 * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
3 *
4 * Copyright (C) 2008 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 #include <errno.h>
19 #include <inttypes.h>
20
21 #if GRALLOC_USE_GRALLOC1_API == 1
22 #include <hardware/gralloc1.h>
23 #else
24 #include <hardware/gralloc.h>
25 #endif
26
27 #include "mali_gralloc_module.h"
28 #include "mali_gralloc_private_interface_types.h"
29 #include "mali_gralloc_buffer.h"
30 #include "mali_gralloc_formats.h"
31 #include "mali_gralloc_usages.h"
32 #include "mali_gralloc_ion.h"
33 #include "gralloc_helper.h"
34 #include <sync/sync.h>
35
mali_gralloc_lock(const mali_gralloc_module * m,buffer_handle_t buffer,uint64_t usage,int l,int t,int w,int h,void ** vaddr)36 int mali_gralloc_lock(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h,
37 void **vaddr)
38 {
39 GRALLOC_UNUSED(m);
40 GRALLOC_UNUSED(l);
41 GRALLOC_UNUSED(t);
42 GRALLOC_UNUSED(w);
43 GRALLOC_UNUSED(h);
44
45 if (private_handle_t::validate(buffer) < 0)
46 {
47 AERR("Locking invalid buffer %p, returning error", buffer);
48 return -EINVAL;
49 }
50
51 private_handle_t *hnd = (private_handle_t *)buffer;
52
53 if (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
54 {
55 AERR("Buffers with format YCbCr_420_888 must be locked using (*lock_ycbcr)");
56 return -EINVAL;
57 }
58
59 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
60 {
61 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
62 }
63
64 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
65 {
66 *vaddr = (void *)hnd->base;
67 }
68
69 return 0;
70 }
71
mali_gralloc_lock_ycbcr(const mali_gralloc_module * m,buffer_handle_t buffer,uint64_t usage,int l,int t,int w,int h,android_ycbcr * ycbcr)72 int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
73 int h, android_ycbcr *ycbcr)
74 {
75 GRALLOC_UNUSED(m);
76 GRALLOC_UNUSED(l);
77 GRALLOC_UNUSED(t);
78 GRALLOC_UNUSED(w);
79 GRALLOC_UNUSED(h);
80
81 if (private_handle_t::validate(buffer) < 0)
82 {
83 AERR("Locking invalid buffer %p, returning error", buffer);
84 return -EINVAL;
85 }
86
87 if (NULL == ycbcr)
88 {
89 return -EINVAL;
90 }
91
92 private_handle_t *hnd = (private_handle_t *)buffer;
93
94 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
95 {
96 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
97 }
98
99 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
100 !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
101 {
102 char *base = (char *)hnd->base;
103 int y_stride = hnd->byte_stride;
104 /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
105 int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
106 int y_size = y_stride * adjusted_height;
107
108 int u_offset = 0;
109 int v_offset = 0;
110 int c_stride = 0;
111 int step = 0;
112
113 uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
114
115 switch (base_format)
116 {
117 case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
118 c_stride = y_stride;
119 /* Y plane, UV plane */
120 u_offset = y_size;
121 v_offset = y_size + 1;
122 step = 2;
123 break;
124
125 case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
126 c_stride = y_stride;
127 /* Y plane, UV plane */
128 v_offset = y_size;
129 u_offset = y_size + 1;
130 step = 2;
131 break;
132
133 case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
134 {
135 int c_size;
136
137 /* Stride alignment set to 16 as the SW access flags were set */
138 c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
139 c_size = c_stride * (adjusted_height / 2);
140 /* Y plane, V plane, U plane */
141 v_offset = y_size;
142 u_offset = y_size + c_size;
143 step = 1;
144 break;
145 }
146
147 default:
148 AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
149 return -EINVAL;
150 }
151
152 ycbcr->y = base;
153 ycbcr->cb = base + u_offset;
154 ycbcr->cr = base + v_offset;
155 ycbcr->ystride = y_stride;
156 ycbcr->cstride = c_stride;
157 ycbcr->chroma_step = step;
158 }
159 else
160 {
161 AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
162 return -EINVAL;
163 }
164
165 return 0;
166 }
167
mali_gralloc_unlock(const mali_gralloc_module * m,buffer_handle_t buffer)168 int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer)
169 {
170 if (private_handle_t::validate(buffer) < 0)
171 {
172 AERR("Unlocking invalid buffer %p, returning error", buffer);
173 return -EINVAL;
174 }
175
176 private_handle_t *hnd = (private_handle_t *)buffer;
177
178 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
179 {
180 mali_gralloc_ion_sync(m, hnd);
181 }
182
183 return 0;
184 }
185
186 #if GRALLOC_USE_GRALLOC1_API == 1
mali_gralloc_get_num_flex_planes(const mali_gralloc_module * m,buffer_handle_t buffer,uint32_t * num_planes)187 int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes)
188 {
189 GRALLOC_UNUSED(m);
190
191 if (private_handle_t::validate(buffer) < 0)
192 {
193 AERR("Invalid buffer %p, returning error", buffer);
194 return -EINVAL;
195 }
196
197 if (NULL == num_planes)
198 {
199 return -EINVAL;
200 }
201
202 private_handle_t *hnd = (private_handle_t *)buffer;
203 uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
204
205 switch (base_format)
206 {
207 case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
208 case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
209 case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
210 *num_planes = 3;
211 break;
212
213 default:
214 AERR("Can't get planes number of buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
215 return -EINVAL;
216 }
217
218 return 0;
219 }
220 #endif
221
mali_gralloc_lock_async(const mali_gralloc_module * m,buffer_handle_t buffer,uint64_t usage,int l,int t,int w,int h,void ** vaddr,int32_t fence_fd)222 int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
223 int h, void **vaddr, int32_t fence_fd)
224 {
225 if (fence_fd >= 0)
226 {
227 sync_wait(fence_fd, -1);
228 close(fence_fd);
229 }
230
231 return mali_gralloc_lock(m, buffer, usage, l, t, w, h, vaddr);
232 }
233
mali_gralloc_lock_ycbcr_async(const mali_gralloc_module * m,buffer_handle_t buffer,uint64_t usage,int l,int t,int w,int h,android_ycbcr * ycbcr,int32_t fence_fd)234 int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
235 int w, int h, android_ycbcr *ycbcr, int32_t fence_fd)
236 {
237 if (fence_fd >= 0)
238 {
239 sync_wait(fence_fd, -1);
240 close(fence_fd);
241 }
242
243 return mali_gralloc_lock_ycbcr(m, buffer, usage, l, t, w, h, ycbcr);
244 }
245
246 #if GRALLOC_USE_GRALLOC1_API == 1
247
mali_gralloc_lock_flex_async(const mali_gralloc_module * m,buffer_handle_t buffer,uint64_t usage,int l,int t,int w,int h,struct android_flex_layout * flex_layout,int32_t fence_fd)248 int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
249 int w, int h, struct android_flex_layout *flex_layout, int32_t fence_fd)
250 {
251 GRALLOC_UNUSED(m);
252 GRALLOC_UNUSED(l);
253 GRALLOC_UNUSED(t);
254 GRALLOC_UNUSED(w);
255 GRALLOC_UNUSED(h);
256
257 if (private_handle_t::validate(buffer) < 0)
258 {
259 AERR("Locking invalid buffer %p, returning error", buffer);
260 return -EINVAL;
261 }
262
263 if (NULL == flex_layout)
264 {
265 return -EINVAL;
266 }
267
268 if (fence_fd >= 0)
269 {
270 sync_wait(fence_fd, -1);
271 close(fence_fd);
272 }
273
274 private_handle_t *hnd = (private_handle_t *)buffer;
275
276 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
277 {
278 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
279 }
280
281 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
282 !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
283 {
284 uint8_t *base = (uint8_t *)hnd->base;
285 int y_stride = hnd->byte_stride;
286 /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
287 int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
288 int y_size = y_stride * adjusted_height;
289
290 uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
291
292 switch (base_format)
293 {
294 case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
295 flex_layout->format = FLEX_FORMAT_YCbCr;
296 flex_layout->num_planes = 3;
297 flex_layout->planes[0].top_left = base;
298 flex_layout->planes[0].component = FLEX_COMPONENT_Y;
299 flex_layout->planes[0].bits_per_component = 8;
300 flex_layout->planes[0].bits_used = 8;
301 flex_layout->planes[0].h_increment = 1;
302 flex_layout->planes[0].v_increment = y_stride;
303 flex_layout->planes[0].h_subsampling = 1;
304 flex_layout->planes[0].v_subsampling = 1;
305 flex_layout->planes[1].top_left = base + y_size;
306 flex_layout->planes[1].component = FLEX_COMPONENT_Cb;
307 flex_layout->planes[1].bits_per_component = 8;
308 flex_layout->planes[1].bits_used = 8;
309 flex_layout->planes[1].h_increment = 2;
310 flex_layout->planes[1].v_increment = y_stride;
311 flex_layout->planes[1].h_subsampling = 2;
312 flex_layout->planes[1].v_subsampling = 2;
313 flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
314 flex_layout->planes[2].component = FLEX_COMPONENT_Cr;
315 flex_layout->planes[2].bits_per_component = 8;
316 flex_layout->planes[2].bits_used = 8;
317 flex_layout->planes[2].h_increment = 2;
318 flex_layout->planes[2].v_increment = y_stride;
319 flex_layout->planes[2].h_subsampling = 2;
320 flex_layout->planes[2].v_subsampling = 2;
321 break;
322
323 case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
324 flex_layout->format = FLEX_FORMAT_YCbCr;
325 flex_layout->num_planes = 3;
326 flex_layout->planes[0].top_left = base;
327 flex_layout->planes[0].component = FLEX_COMPONENT_Y;
328 flex_layout->planes[0].bits_per_component = 8;
329 flex_layout->planes[0].bits_used = 8;
330 flex_layout->planes[0].h_increment = 1;
331 flex_layout->planes[0].v_increment = y_stride;
332 flex_layout->planes[0].h_subsampling = 1;
333 flex_layout->planes[0].v_subsampling = 1;
334 flex_layout->planes[1].top_left = base + y_size;
335 flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
336 flex_layout->planes[1].bits_per_component = 8;
337 flex_layout->planes[1].bits_used = 8;
338 flex_layout->planes[1].h_increment = 2;
339 flex_layout->planes[1].v_increment = y_stride;
340 flex_layout->planes[1].h_subsampling = 2;
341 flex_layout->planes[1].v_subsampling = 2;
342 flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
343 flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
344 flex_layout->planes[2].bits_per_component = 8;
345 flex_layout->planes[2].bits_used = 8;
346 flex_layout->planes[2].h_increment = 2;
347 flex_layout->planes[2].v_increment = y_stride;
348 flex_layout->planes[2].h_subsampling = 2;
349 flex_layout->planes[2].v_subsampling = 2;
350 break;
351
352 case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
353 {
354 int c_size;
355 int c_stride;
356 /* Stride alignment set to 16 as the SW access flags were set */
357 c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
358 c_size = c_stride * (adjusted_height / 2);
359 /* Y plane, V plane, U plane */
360 flex_layout->format = FLEX_FORMAT_YCbCr;
361 flex_layout->num_planes = 3;
362 flex_layout->planes[0].top_left = base;
363 flex_layout->planes[0].component = FLEX_COMPONENT_Y;
364 flex_layout->planes[0].bits_per_component = 8;
365 flex_layout->planes[0].bits_used = 8;
366 flex_layout->planes[0].h_increment = 1;
367 flex_layout->planes[0].v_increment = y_stride;
368 flex_layout->planes[0].h_subsampling = 1;
369 flex_layout->planes[0].v_subsampling = 1;
370 flex_layout->planes[1].top_left = base + y_size;
371 flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
372 flex_layout->planes[1].bits_per_component = 8;
373 flex_layout->planes[1].bits_used = 8;
374 flex_layout->planes[1].h_increment = 1;
375 flex_layout->planes[1].v_increment = c_stride;
376 flex_layout->planes[1].h_subsampling = 2;
377 flex_layout->planes[1].v_subsampling = 2;
378 flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + c_size;
379 flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
380 flex_layout->planes[2].bits_per_component = 8;
381 flex_layout->planes[2].bits_used = 8;
382 flex_layout->planes[2].h_increment = 1;
383 flex_layout->planes[2].v_increment = c_stride;
384 flex_layout->planes[2].h_subsampling = 2;
385 flex_layout->planes[2].v_subsampling = 2;
386 break;
387 }
388
389 default:
390 AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
391 return -EINVAL;
392 }
393 }
394 else
395 {
396 AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
397 return -EINVAL;
398 }
399
400 return 0;
401 }
402 #endif
403
mali_gralloc_unlock_async(const mali_gralloc_module * m,buffer_handle_t buffer,int32_t * fence_fd)404 int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd)
405 {
406 *fence_fd = -1;
407
408 if (mali_gralloc_unlock(m, buffer) < 0)
409 {
410 return -EINVAL;
411 }
412
413 return 0;
414 }
415