1 /*
2  * Copyright (C) 2017-2020 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 #ifndef MALI_GRALLOC_BUFFER_H_
19 #define MALI_GRALLOC_BUFFER_H_
20 
21 #include <stdint.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <sys/mman.h>
26 #include <cutils/native_handle.h>
27 #include <string.h>
28 #include <log/log.h>
29 #include <inttypes.h>
30 
31 /* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0
32  * 8 is big enough for "gpu0" & "fb0" currently
33  */
34 #define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8
35 
36 /* Define number of shared file descriptors. Not guaranteed to be constant for a private_handle_t object
37  * as fds that do not get initialized may instead be treated as integers.
38  */
39 
40 #define NUM_INTS_IN_PRIVATE_HANDLE ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int))
41 
42 #define SZ_4K 0x00001000
43 #define SZ_2M 0x00200000
44 
45 /*
46  * Maximum number of pixel format planes.
47  * Plane [0]: Single plane formats (inc. RGB, YUV) and Y
48  * Plane [1]: U/V, UV
49  * Plane [2]: V/U
50  */
51 #define MAX_PLANES 3
52 
53 #ifdef __cplusplus
54 #define DEFAULT_INITIALIZER(x) = x
55 #else
56 #define DEFAULT_INITIALIZER(x)
57 #endif
58 
59 typedef struct plane_info {
60 
61 	/*
62 	 * Offset to plane (in bytes),
63 	 * from the start of the allocation.
64 	 */
65 	int64_t offset;
66 
67 	uint32_t fd_idx;
68 	uint64_t size;
69 
70 	/*
71 	 * Byte Stride: number of bytes between two vertically adjacent
72 	 * pixels in given plane. This can be mathematically described by:
73 	 *
74 	 * byte_stride = ALIGN((alloc_width * bpp)/8, alignment)
75 	 *
76 	 * where,
77 	 *
78 	 * alloc_width: width of plane in pixels (c.f. pixel_stride)
79 	 * bpp: average bits per pixel
80 	 * alignment (in bytes): dependent upon pixel format and usage
81 	 *
82 	 * For uncompressed allocations, byte_stride might contain additional
83 	 * padding beyond the alloc_width. For AFBC, alignment is zero.
84 	 */
85 	uint32_t byte_stride;
86 
87 	/*
88 	 * Dimensions of plane (in pixels).
89 	 *
90 	 * For single plane formats, pixels equates to luma samples.
91 	 * For multi-plane formats, pixels equates to the number of sample sites
92 	 * for the corresponding plane, even if subsampled.
93 	 *
94 	 * AFBC compressed formats: requested width/height are rounded-up
95 	 * to a whole AFBC superblock/tile (next superblock at minimum).
96 	 * Uncompressed formats: dimensions typically match width and height
97 	 * but might require pixel stride alignment.
98 	 *
99 	 * See 'byte_stride' for relationship between byte_stride and alloc_width.
100 	 *
101 	 * Any crop rectangle defined by GRALLOC_ARM_BUFFER_ATTR_CROP_RECT must
102 	 * be wholly within the allocation dimensions. The crop region top-left
103 	 * will be relative to the start of allocation.
104 	 */
105 	uint32_t alloc_width;
106 	uint32_t alloc_height;
107 } plane_info_t;
108 
109 struct private_handle_t;
110 
111 #ifndef __cplusplus
112 /* C99 with pedantic don't allow anonymous unions which is used in below struct
113  * Disable pedantic for C for this struct only.
114  */
115 #pragma GCC diagnostic push
116 #pragma GCC diagnostic ignored "-Wpedantic"
117 #endif
118 
119 #ifdef __cplusplus
120 struct private_handle_t : public native_handle
121 {
122 #else
123 struct private_handle_t
124 {
125 	struct native_handle nativeHandle;
126 #endif
127 
128 #ifdef __cplusplus
129 	/* Never intended to be used from C code */
130 	enum
131 	{
132 		PRIV_FLAGS_USES_2PRIVATE_DATA = 1U << 4,
133 		PRIV_FLAGS_USES_3PRIVATE_DATA = 1U << 5,
134 	};
135 
136 	enum
137 	{
138 		LOCK_STATE_WRITE = 1 << 31,
139 		LOCK_STATE_MAPPED = 1 << 30,
140 		LOCK_STATE_READ_MASK = 0x3FFFFFFF
141 	};
142 #endif
143 
144 	/*
145 	 * Shared file descriptor for dma_buf sharing. This must be the first element in the
146 	 * structure so that binder knows where it is and can properly share it between
147 	 * processes.
148 	 * DO NOT MOVE THIS ELEMENT!
149 	 */
150 	union {
151 		int fds[5];
152 	};
153 
154 	// ints
155 	int magic DEFAULT_INITIALIZER(sMagic);
156 	int flags DEFAULT_INITIALIZER(0);
157 
158 	int fd_count DEFAULT_INITIALIZER(1);
159 
160 	/*
161 	 * Input properties.
162 	 *
163 	 * req_format: Pixel format, base + private modifiers.
164 	 * width/height: Buffer dimensions.
165 	 * producer/consumer_usage: Buffer usage (indicates IP)
166 	 */
167 	int width DEFAULT_INITIALIZER(0);
168 	int height DEFAULT_INITIALIZER(0);
169 	int req_format DEFAULT_INITIALIZER(0);
170 	uint64_t producer_usage DEFAULT_INITIALIZER(0);
171 	uint64_t consumer_usage DEFAULT_INITIALIZER(0);
172 
173 	/*
174 	 * DEPRECATED members.
175 	 * Equivalent information can be obtained from other fields:
176 	 *
177 	 * - 'internal_format' --> alloc_format
178 	 * - 'stride' (pixel stride) ~= plane_info[0].alloc_width
179 	 * - 'byte_stride' ~= plane_info[0].byte_stride
180 	 * - 'internalWidth' ~= plane_info[0].alloc_width
181 	 * - 'internalHeight' ~= plane_info[0].alloc_height
182 	 *
183 	 * '~=' (approximately equal) is used because the fields were either previously
184 	 * incorrectly populated by gralloc or the meaning has slightly changed.
185 	 *
186 	 * NOTE: 'stride' values sometimes vary significantly from plane_info[0].alloc_width.
187 	 */
188 	int stride DEFAULT_INITIALIZER(0);
189 
190 	/*
191 	 * Allocation properties.
192 	 *
193 	 * alloc_format: Pixel format (base + modifiers). NOTE: base might differ from requested
194 	 *               format (req_format) where fallback to single-plane format was required.
195 	 * plane_info:   Per plane allocation information.
196 	 * size:         Total bytes allocated for buffer (inc. all planes, layers. etc.).
197 	 * layer_count:  Number of layers allocated to buffer.
198 	 *               All layers are the same size (in bytes).
199 	 *               Multi-layers supported in v1.0, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled.
200 	 *               Layer size: 'size' / 'layer_count'.
201 	 *               Layer (n) offset: n * ('size' / 'layer_count'), n=0 for the first layer.
202 	 *
203 	 */
204 	uint64_t alloc_format DEFAULT_INITIALIZER(0);
205 	plane_info_t plane_info[MAX_PLANES] DEFAULT_INITIALIZER({});
206 	uint32_t layer_count DEFAULT_INITIALIZER(0);
207 
208 	uint64_t backing_store_id DEFAULT_INITIALIZER(0x0);
209 	int cpu_read DEFAULT_INITIALIZER(0);               /**< Buffer is locked for CPU read when non-zero. */
210 	int cpu_write DEFAULT_INITIALIZER(0);              /**< Buffer is locked for CPU write when non-zero. */
211 	int allocating_pid DEFAULT_INITIALIZER(0);
212 	int remote_pid DEFAULT_INITIALIZER(-1);
213 	int ref_count DEFAULT_INITIALIZER(0);
214 	// locally mapped shared attribute area
215 
216 	int ion_handles[3];
217 	uint64_t bases[3];
218 	uint64_t alloc_sizes[3];
219 
220 	void *attr_base __attribute__((aligned (8))) DEFAULT_INITIALIZER(nullptr);
221 	off_t offset    __attribute__((aligned (8))) DEFAULT_INITIALIZER(0);
222 
223 	/* Size of the attribute shared region in bytes. */
224 	uint64_t attr_size __attribute__((aligned (8))) DEFAULT_INITIALIZER(0);
225 
226 	uint64_t reserved_region_size DEFAULT_INITIALIZER(0);
227 
228 	uint64_t imapper_version DEFAULT_INITIALIZER(0);
229 
230 #ifdef __cplusplus
231 	/*
232 	 * We track the number of integers in the structure. There are 16 unconditional
233 	 * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is
234 	 * considered an int not an fd because it is not intended to be used outside the
235 	 * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the
236 	 * number of integers that are conditionally included. Similar considerations apply
237 	 * to the number of fds.
238 	 */
239 	static const int sMagic = 0x3141592;
240 
private_handle_tprivate_handle_t241 	private_handle_t(
242 		int _flags,
243 		uint64_t _alloc_sizes[3],
244 		uint64_t _consumer_usage, uint64_t _producer_usage,
245 		int _fds[5], int _fd_count,
246 		int _req_format, uint64_t _alloc_format,
247 		int _width, int _height, int _stride,
248 		uint64_t _layer_count, plane_info_t _plane_info[MAX_PLANES])
249 	    : flags(_flags)
250 	    , fd_count(_fd_count)
251 	    , width(_width)
252 	    , height(_height)
253 	    , req_format(_req_format)
254 	    , producer_usage(_producer_usage)
255 	    , consumer_usage(_consumer_usage)
256 	    , stride(_stride)
257 	    , alloc_format(_alloc_format)
258 	    , layer_count(_layer_count)
259 	    , allocating_pid(getpid())
260 	    , ref_count(1)
261 	{
262 		version = sizeof(native_handle);
263 		set_numfds(fd_count);
264 		memcpy(plane_info, _plane_info, sizeof(plane_info_t) * MAX_PLANES);
265 
266 		if (_fds)
267 			memcpy(fds, _fds, sizeof(fds));
268 
269 		if (_alloc_sizes)
270 			memcpy(alloc_sizes, _alloc_sizes, sizeof(alloc_sizes));
271 
272 		memset(bases, 0, sizeof(bases));
273 		memset(ion_handles, 0, sizeof(ion_handles));
274 	}
275 
~private_handle_tprivate_handle_t276 	~private_handle_t()
277 	{
278 		magic = 0;
279 	}
280 
281 	/* Set the number of allocated fds in the handle to n*/
set_numfdsprivate_handle_t282 	void set_numfds(int n)
283 	{
284 		int total_ints =
285 			(sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int);
286 
287 		numFds = n;
288 		numInts = total_ints - n;
289 	}
290 
291 	/* Increments number of allocated fds in the handle by n */
incr_numfdsprivate_handle_t292 	int incr_numfds(int n)
293 	{
294 		numFds += n;
295 		numInts -= n;
296 
297 		return numFds;
298 	}
299 
validateprivate_handle_t300 	static int validate(const native_handle *h)
301 	{
302 		const private_handle_t *hnd = (const private_handle_t *)h;
303 		if (!h || h->version != sizeof(native_handle) || hnd->magic != sMagic ||
304 		    h->numFds + h->numInts != NUM_INTS_IN_PRIVATE_HANDLE)
305 		{
306 			return -EINVAL;
307 		}
308 		return 0;
309 	}
310 
is_multi_planeprivate_handle_t311 	bool is_multi_plane() const
312 	{
313 		/* For multi-plane, the byte stride for the second plane will always be non-zero. */
314 		return (plane_info[1].byte_stride != 0);
315 	}
316 
get_usageprivate_handle_t317 	uint64_t get_usage() const
318 	{
319 		return producer_usage | consumer_usage;
320 	}
321 
get_share_attr_fd_indexprivate_handle_t322 	int get_share_attr_fd_index() const
323 	{
324 		/* share_attr can be at idx 1 to 4 */
325 		if (fd_count <= 0 || fd_count > 4)
326 			return -1;
327 
328 		return fd_count;
329 	}
330 
get_share_attr_fdprivate_handle_t331 	int get_share_attr_fd() const
332 	{
333 		int idx = get_share_attr_fd_index();
334 
335 		if (idx <= 0)
336 			return -1;
337 
338 		return fds[idx];
339 	}
340 
set_share_attr_fdprivate_handle_t341 	void set_share_attr_fd(int fd)
342 	{
343 		int idx = get_share_attr_fd_index();
344 
345 		if (idx <= 0)
346 			return;
347 
348 		fds[idx] = fd;
349 	}
350 
close_share_attr_fdprivate_handle_t351 	void close_share_attr_fd()
352 	{
353 		int fd = get_share_attr_fd();
354 
355 		if (fd < 0)
356 			return;
357 
358 		close(fd);
359 	}
360 
dumpprivate_handle_t361 	void dump(const char *str) const
362 	{
363 		ALOGE("[%s] "
364 			"numInts(%d) numFds(%d) fd_count(%d) "
365 			"fd(%d %d %d %d %d) "
366 			"flags(%d) "
367 			"wh(%d %d) "
368 			"req_format(%#x) alloc_format(%#" PRIx64 ") "
369 			"usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") "
370 			"stride(%d) "
371 			"psize(%" PRIu64 ") byte_stride(%d) internal_wh(%d %d) "
372 			"psize1(%" PRIu64 ") byte_stride1(%d) internal_wh1(%d %d) "
373 			"psize2(%" PRIu64 ") byte_stride2(%d) internal_wh2(%d %d) "
374 			"alloc_format(0x%" PRIx64 ") "
375 			"alloc_sizes(%" PRIu64 " %" PRIu64 " %" PRIu64 ") "
376 			"layer_count(%d) "
377 			"bases(%p %p %p %p) "
378 			"\n",
379 			str,
380 			numInts, numFds, fd_count,
381 			fds[0], fds[1], fds[2], fds[3], fds[4],
382 			flags,
383 			width, height,
384 			req_format, alloc_format,
385 			producer_usage, consumer_usage,
386 			stride,
387 			plane_info[0].size, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height,
388 			plane_info[1].size, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height,
389 			plane_info[2].size, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height,
390 			alloc_format,
391 			alloc_sizes[0], alloc_sizes[1], alloc_sizes[2],
392 			layer_count,
393 			(void*)bases[0], (void*)bases[1], (void*)bases[2], attr_base
394 		);
395 	}
396 
get_alloc_formatprivate_handle_t397 	int get_alloc_format() const
398 	{
399 		return (int)(alloc_format & 0x00000000ffffffffULL);
400 	}
401 
dynamicCastprivate_handle_t402 	static private_handle_t *dynamicCast(const native_handle *in)
403 	{
404 		if (validate(in) == 0)
405 		{
406 			return (private_handle_t *)in;
407 		}
408 
409 		return NULL;
410 	}
411 #endif
412 };
413 #ifndef __cplusplus
414 /* Restore previous diagnostic for pedantic */
415 #pragma GCC diagnostic pop
416 #endif
417 
418 #endif /* MALI_GRALLOC_BUFFER_H_ */
419