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