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 private: 123 /* Having a default constructor makes sure that we zero out the padding 124 * which prevents data leak. */ 125 private_handle_t() = default; 126 127 public: 128 129 #else 130 struct private_handle_t 131 { 132 struct native_handle nativeHandle; 133 #endif 134 135 #ifdef __cplusplus 136 /* Never intended to be used from C code */ 137 enum 138 { 139 PRIV_FLAGS_USES_2PRIVATE_DATA = 1U << 4, 140 PRIV_FLAGS_USES_3PRIVATE_DATA = 1U << 5, 141 }; 142 143 enum 144 { 145 LOCK_STATE_WRITE = 1 << 31, 146 LOCK_STATE_MAPPED = 1 << 30, 147 LOCK_STATE_READ_MASK = 0x3FFFFFFF 148 }; 149 #endif 150 151 /* 152 * Shared file descriptor for dma_buf sharing. This must be the first element in the 153 * structure so that binder knows where it is and can properly share it between 154 * processes. 155 * DO NOT MOVE THIS ELEMENT! 156 */ 157 union { 158 int fds[5]; 159 }; 160 161 // ints 162 int magic DEFAULT_INITIALIZER(sMagic); 163 int flags DEFAULT_INITIALIZER(0); 164 165 int fd_count DEFAULT_INITIALIZER(1); 166 167 /* 168 * Input properties. 169 * 170 * req_format: Pixel format, base + private modifiers. 171 * width/height: Buffer dimensions. 172 * producer/consumer_usage: Buffer usage (indicates IP) 173 */ 174 int width DEFAULT_INITIALIZER(0); 175 int height DEFAULT_INITIALIZER(0); 176 int req_format DEFAULT_INITIALIZER(0); 177 uint64_t producer_usage DEFAULT_INITIALIZER(0); 178 uint64_t consumer_usage DEFAULT_INITIALIZER(0); 179 180 /* 181 * DEPRECATED members. 182 * Equivalent information can be obtained from other fields: 183 * 184 * - 'internal_format' --> alloc_format 185 * - 'stride' (pixel stride) ~= plane_info[0].alloc_width 186 * - 'byte_stride' ~= plane_info[0].byte_stride 187 * - 'internalWidth' ~= plane_info[0].alloc_width 188 * - 'internalHeight' ~= plane_info[0].alloc_height 189 * 190 * '~=' (approximately equal) is used because the fields were either previously 191 * incorrectly populated by gralloc or the meaning has slightly changed. 192 * 193 * NOTE: 'stride' values sometimes vary significantly from plane_info[0].alloc_width. 194 */ 195 int stride DEFAULT_INITIALIZER(0); 196 197 /* 198 * Allocation properties. 199 * 200 * alloc_format: Pixel format (base + modifiers). NOTE: base might differ from requested 201 * format (req_format) where fallback to single-plane format was required. 202 * plane_info: Per plane allocation information. 203 * size: Total bytes allocated for buffer (inc. all planes, layers. etc.). 204 * layer_count: Number of layers allocated to buffer. 205 * All layers are the same size (in bytes). 206 * Multi-layers supported in v1.0, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled. 207 * Layer size: 'size' / 'layer_count'. 208 * Layer (n) offset: n * ('size' / 'layer_count'), n=0 for the first layer. 209 * 210 */ 211 uint64_t alloc_format DEFAULT_INITIALIZER(0); 212 plane_info_t plane_info[MAX_PLANES] DEFAULT_INITIALIZER({}); 213 uint32_t layer_count DEFAULT_INITIALIZER(0); 214 215 uint64_t backing_store_id DEFAULT_INITIALIZER(0x0); 216 int cpu_read DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU read when non-zero. */ 217 int cpu_write DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU write when non-zero. */ 218 int allocating_pid DEFAULT_INITIALIZER(0); 219 int remote_pid DEFAULT_INITIALIZER(-1); 220 int ref_count DEFAULT_INITIALIZER(0); 221 // locally mapped shared attribute area 222 223 int ion_handles[3]; 224 uint64_t bases[3]; 225 uint64_t alloc_sizes[3]; 226 227 void *attr_base __attribute__((aligned (8))) DEFAULT_INITIALIZER(nullptr); 228 off_t offset __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); 229 230 /* Size of the attribute shared region in bytes. */ 231 uint64_t attr_size __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); 232 233 uint64_t reserved_region_size DEFAULT_INITIALIZER(0); 234 235 uint64_t imapper_version DEFAULT_INITIALIZER(0); 236 237 #ifdef __cplusplus 238 /* 239 * We track the number of integers in the structure. There are 16 unconditional 240 * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is 241 * considered an int not an fd because it is not intended to be used outside the 242 * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the 243 * number of integers that are conditionally included. Similar considerations apply 244 * to the number of fds. 245 */ 246 static const int sMagic = 0x3141592; 247 private_handle_tprivate_handle_t248 private_handle_t( 249 int _flags, 250 uint64_t _alloc_sizes[3], 251 uint64_t _consumer_usage, uint64_t _producer_usage, 252 int _fds[5], int _fd_count, 253 int _req_format, uint64_t _alloc_format, 254 int _width, int _height, int _stride, 255 uint64_t _layer_count, plane_info_t _plane_info[MAX_PLANES]) 256 : private_handle_t() 257 { 258 flags = _flags; 259 fd_count = _fd_count; 260 width = _width; 261 height = _height; 262 req_format = _req_format; 263 producer_usage = _producer_usage; 264 consumer_usage = _consumer_usage; 265 stride = _stride; 266 alloc_format = _alloc_format; 267 layer_count = _layer_count; 268 allocating_pid = getpid(); 269 ref_count = 1; 270 version = sizeof(native_handle); 271 set_numfds(fd_count); 272 memcpy(plane_info, _plane_info, sizeof(plane_info_t) * MAX_PLANES); 273 274 if (_fds) 275 memcpy(fds, _fds, sizeof(fds)); 276 277 if (_alloc_sizes) 278 memcpy(alloc_sizes, _alloc_sizes, sizeof(alloc_sizes)); 279 280 memset(bases, 0, sizeof(bases)); 281 memset(ion_handles, 0, sizeof(ion_handles)); 282 } 283 ~private_handle_tprivate_handle_t284 ~private_handle_t() 285 { 286 magic = 0; 287 } 288 289 /* Set the number of allocated fds in the handle to n*/ set_numfdsprivate_handle_t290 void set_numfds(int n) 291 { 292 int total_ints = 293 (sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int); 294 295 numFds = n; 296 numInts = total_ints - n; 297 } 298 299 /* Increments number of allocated fds in the handle by n */ incr_numfdsprivate_handle_t300 int incr_numfds(int n) 301 { 302 numFds += n; 303 numInts -= n; 304 305 return numFds; 306 } 307 validateprivate_handle_t308 static int validate(const native_handle *h) 309 { 310 const private_handle_t *hnd = (const private_handle_t *)h; 311 if (!h || h->version != sizeof(native_handle) || hnd->magic != sMagic || 312 h->numFds + h->numInts != NUM_INTS_IN_PRIVATE_HANDLE) 313 { 314 return -EINVAL; 315 } 316 return 0; 317 } 318 is_multi_planeprivate_handle_t319 bool is_multi_plane() const 320 { 321 /* For multi-plane, the byte stride for the second plane will always be non-zero. */ 322 return (plane_info[1].byte_stride != 0); 323 } 324 get_usageprivate_handle_t325 uint64_t get_usage() const 326 { 327 return producer_usage | consumer_usage; 328 } 329 get_share_attr_fd_indexprivate_handle_t330 int get_share_attr_fd_index() const 331 { 332 /* share_attr can be at idx 1 to 4 */ 333 if (fd_count <= 0 || fd_count > 4) 334 return -1; 335 336 return fd_count; 337 } 338 get_share_attr_fdprivate_handle_t339 int get_share_attr_fd() const 340 { 341 int idx = get_share_attr_fd_index(); 342 343 if (idx <= 0) 344 return -1; 345 346 return fds[idx]; 347 } 348 set_share_attr_fdprivate_handle_t349 void set_share_attr_fd(int fd) 350 { 351 int idx = get_share_attr_fd_index(); 352 353 if (idx <= 0) 354 return; 355 356 fds[idx] = fd; 357 } 358 close_share_attr_fdprivate_handle_t359 void close_share_attr_fd() 360 { 361 int fd = get_share_attr_fd(); 362 363 if (fd < 0) 364 return; 365 366 close(fd); 367 } 368 dumpprivate_handle_t369 void dump(const char *str) const 370 { 371 ALOGE("[%s] " 372 "numInts(%d) numFds(%d) fd_count(%d) " 373 "fd(%d %d %d %d %d) " 374 "flags(%d) " 375 "wh(%d %d) " 376 "req_format(%#x) alloc_format(%#" PRIx64 ") " 377 "usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") " 378 "stride(%d) " 379 "psize(%" PRIu64 ") byte_stride(%d) internal_wh(%d %d) " 380 "psize1(%" PRIu64 ") byte_stride1(%d) internal_wh1(%d %d) " 381 "psize2(%" PRIu64 ") byte_stride2(%d) internal_wh2(%d %d) " 382 "alloc_format(0x%" PRIx64 ") " 383 "alloc_sizes(%" PRIu64 " %" PRIu64 " %" PRIu64 ") " 384 "layer_count(%d) " 385 "bases(%p %p %p %p) " 386 "\n", 387 str, 388 numInts, numFds, fd_count, 389 fds[0], fds[1], fds[2], fds[3], fds[4], 390 flags, 391 width, height, 392 req_format, alloc_format, 393 producer_usage, consumer_usage, 394 stride, 395 plane_info[0].size, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, 396 plane_info[1].size, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height, 397 plane_info[2].size, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height, 398 alloc_format, 399 alloc_sizes[0], alloc_sizes[1], alloc_sizes[2], 400 layer_count, 401 (void*)bases[0], (void*)bases[1], (void*)bases[2], attr_base 402 ); 403 } 404 get_alloc_formatprivate_handle_t405 int get_alloc_format() const 406 { 407 return (int)(alloc_format & 0x00000000ffffffffULL); 408 } 409 dynamicCastprivate_handle_t410 static private_handle_t *dynamicCast(const native_handle *in) 411 { 412 if (validate(in) == 0) 413 { 414 return (private_handle_t *)in; 415 } 416 417 return NULL; 418 } 419 #endif 420 }; 421 #ifndef __cplusplus 422 /* Restore previous diagnostic for pedantic */ 423 #pragma GCC diagnostic pop 424 #endif 425 426 #endif /* MALI_GRALLOC_BUFFER_H_ */ 427