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 /* 54 * Maximum number of fds in a private_handle_t. 55 */ 56 #define MAX_FDS 4 57 58 /* 59 * One fd is reserved for metadata dmabuf. 60 */ 61 #define MAX_BUFFER_FDS MAX_FDS - 1 62 63 /* 64 * In the worst case, there will be one plane per fd. 65 */ 66 static_assert(MAX_BUFFER_FDS == MAX_PLANES, "MAX_PLANES and MAX_BUFFER_FDS defines do not match"); 67 68 #ifdef __cplusplus 69 #define DEFAULT_INITIALIZER(x) = x 70 #else 71 #define DEFAULT_INITIALIZER(x) 72 #endif 73 74 typedef struct plane_info { 75 76 /* 77 * Offset to plane (in bytes), 78 * from the start of the allocation. 79 */ 80 int64_t offset; 81 82 uint32_t fd_idx; 83 uint64_t size; 84 85 /* 86 * Byte Stride: number of bytes between two vertically adjacent 87 * pixels in given plane. This can be mathematically described by: 88 * 89 * byte_stride = ALIGN((alloc_width * bpp)/8, alignment) 90 * 91 * where, 92 * 93 * alloc_width: width of plane in pixels (c.f. pixel_stride) 94 * bpp: average bits per pixel 95 * alignment (in bytes): dependent upon pixel format and usage 96 * 97 * For uncompressed allocations, byte_stride might contain additional 98 * padding beyond the alloc_width. For AFBC, alignment is zero. 99 */ 100 uint64_t byte_stride; 101 102 /* 103 * Dimensions of plane (in pixels). 104 * 105 * For single plane formats, pixels equates to luma samples. 106 * For multi-plane formats, pixels equates to the number of sample sites 107 * for the corresponding plane, even if subsampled. 108 * 109 * AFBC compressed formats: requested width/height are rounded-up 110 * to a whole AFBC superblock/tile (next superblock at minimum). 111 * Uncompressed formats: dimensions typically match width and height 112 * but might require pixel stride alignment. 113 * 114 * See 'byte_stride' for relationship between byte_stride and alloc_width. 115 * 116 * Any crop rectangle defined by GRALLOC_ARM_BUFFER_ATTR_CROP_RECT must 117 * be wholly within the allocation dimensions. The crop region top-left 118 * will be relative to the start of allocation. 119 */ 120 uint64_t alloc_width; 121 uint64_t alloc_height; 122 } plane_info_t; 123 124 struct private_handle_t; 125 126 #ifndef __cplusplus 127 /* C99 with pedantic don't allow anonymous unions which is used in below struct 128 * Disable pedantic for C for this struct only. 129 */ 130 #pragma GCC diagnostic push 131 #pragma GCC diagnostic ignored "-Wpedantic" 132 #endif 133 134 #ifdef __cplusplus 135 struct private_handle_t : public native_handle 136 { 137 private: 138 /* Having a default constructor makes sure that we zero out the padding 139 * which prevents data leak. */ 140 private_handle_t() = default; 141 142 public: 143 144 #else 145 struct private_handle_t 146 { 147 struct native_handle nativeHandle; 148 #endif 149 150 #ifdef __cplusplus 151 /* Never intended to be used from C code */ 152 enum 153 { 154 PRIV_FLAGS_USES_2PRIVATE_DATA = 1U << 4, 155 PRIV_FLAGS_USES_3PRIVATE_DATA = 1U << 5, 156 }; 157 158 enum 159 { 160 LOCK_STATE_WRITE = 1 << 31, 161 LOCK_STATE_MAPPED = 1 << 30, 162 LOCK_STATE_READ_MASK = 0x3FFFFFFF 163 }; 164 #endif 165 166 /* 167 * Shared file descriptor for dma_buf sharing. This must be the first element in the 168 * structure so that binder knows where it is and can properly share it between 169 * processes. 170 * DO NOT MOVE THIS ELEMENT! 171 */ 172 union { 173 int fds[MAX_FDS]; 174 }; 175 176 // ints 177 int magic DEFAULT_INITIALIZER(sMagic); 178 int flags DEFAULT_INITIALIZER(0); 179 180 /* 181 * Number of dmabuf fds, NOT including the metadata fd 182 */ 183 int fd_count DEFAULT_INITIALIZER(1); 184 185 /* 186 * Input properties. 187 * 188 * req_format: Pixel format, base + private modifiers. 189 * width/height: Buffer dimensions. 190 * producer/consumer_usage: Buffer usage (indicates IP) 191 */ 192 int width DEFAULT_INITIALIZER(0); 193 int height DEFAULT_INITIALIZER(0); 194 int req_format DEFAULT_INITIALIZER(0); 195 uint64_t producer_usage DEFAULT_INITIALIZER(0); 196 uint64_t consumer_usage DEFAULT_INITIALIZER(0); 197 198 /* 199 * DEPRECATED members. 200 * Equivalent information can be obtained from other fields: 201 * 202 * - 'internal_format' --> alloc_format 203 * - 'stride' (pixel stride) ~= plane_info[0].alloc_width 204 * - 'byte_stride' ~= plane_info[0].byte_stride 205 * - 'internalWidth' ~= plane_info[0].alloc_width 206 * - 'internalHeight' ~= plane_info[0].alloc_height 207 * 208 * '~=' (approximately equal) is used because the fields were either previously 209 * incorrectly populated by gralloc or the meaning has slightly changed. 210 * 211 * NOTE: 'stride' values sometimes vary significantly from plane_info[0].alloc_width. 212 */ 213 uint64_t stride DEFAULT_INITIALIZER(0); 214 215 /* 216 * Allocation properties. 217 * 218 * alloc_format: Pixel format (base + modifiers). NOTE: base might differ from requested 219 * format (req_format) where fallback to single-plane format was required. 220 * plane_info: Per plane allocation information. 221 * size: Total bytes allocated for buffer (inc. all planes, layers. etc.). 222 * layer_count: Number of layers allocated to buffer. 223 * All layers are the same size (in bytes). 224 * Multi-layers supported in v1.0, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled. 225 * Layer size: 'size' / 'layer_count'. 226 * Layer (n) offset: n * ('size' / 'layer_count'), n=0 for the first layer. 227 * 228 */ 229 uint64_t alloc_format DEFAULT_INITIALIZER(0); 230 plane_info_t plane_info[MAX_PLANES] DEFAULT_INITIALIZER({}); 231 uint32_t layer_count DEFAULT_INITIALIZER(0); 232 233 uint64_t backing_store_id DEFAULT_INITIALIZER(0x0); 234 int cpu_read DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU read when non-zero. */ 235 int cpu_write DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU write when non-zero. */ 236 // locally mapped shared attribute area 237 238 int ion_handles[MAX_BUFFER_FDS]; 239 uint64_t alloc_sizes[MAX_BUFFER_FDS]; 240 241 off_t offset __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); 242 243 /* Size of the attribute shared region in bytes. */ 244 uint64_t attr_size __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); 245 246 uint64_t reserved_region_size DEFAULT_INITIALIZER(0); 247 248 uint64_t imapper_version DEFAULT_INITIALIZER(0); 249 250 #ifdef __cplusplus 251 /* 252 * We track the number of integers in the structure. There are 16 unconditional 253 * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is 254 * considered an int not an fd because it is not intended to be used outside the 255 * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the 256 * number of integers that are conditionally included. Similar considerations apply 257 * to the number of fds. 258 */ 259 static const int sMagic = 0x3141592; 260 private_handle_tprivate_handle_t261 private_handle_t( 262 int _flags, 263 uint64_t _alloc_sizes[MAX_BUFFER_FDS], 264 uint64_t _consumer_usage, uint64_t _producer_usage, 265 int _fds[MAX_FDS], int _fd_count, 266 int _req_format, uint64_t _alloc_format, 267 int _width, int _height, uint64_t _stride, 268 uint64_t _layer_count, plane_info_t _plane_info[MAX_PLANES]) 269 : private_handle_t() 270 { 271 flags = _flags; 272 fd_count = _fd_count; 273 width = _width; 274 height = _height; 275 req_format = _req_format; 276 producer_usage = _producer_usage; 277 consumer_usage = _consumer_usage; 278 stride = _stride; 279 alloc_format = _alloc_format; 280 layer_count = _layer_count; 281 version = sizeof(native_handle); 282 set_numfds(fd_count); 283 memcpy(plane_info, _plane_info, sizeof(plane_info_t) * MAX_PLANES); 284 285 if (_fds) 286 memcpy(fds, _fds, sizeof(fds)); 287 else 288 memset(fds, -1, sizeof(fds)); 289 290 if (_alloc_sizes) 291 memcpy(alloc_sizes, _alloc_sizes, sizeof(alloc_sizes)); 292 293 memset(ion_handles, 0, sizeof(ion_handles)); 294 } 295 ~private_handle_tprivate_handle_t296 ~private_handle_t() 297 { 298 magic = 0; 299 } 300 301 /* Set the number of allocated fds in the handle to n*/ set_numfdsprivate_handle_t302 void set_numfds(int n) 303 { 304 int total_ints = 305 (sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int); 306 307 numFds = n; 308 numInts = total_ints - n; 309 } 310 311 /* Increments number of allocated fds in the handle by n */ incr_numfdsprivate_handle_t312 int incr_numfds(int n) 313 { 314 numFds += n; 315 numInts -= n; 316 317 return numFds; 318 } 319 validateprivate_handle_t320 static int validate(const native_handle *h) 321 { 322 const private_handle_t *hnd = (const private_handle_t *)h; 323 324 // Always validate for native_handle members before validating 325 // private_handle_t members 326 if (!h || h->version != sizeof(native_handle) || 327 h->numFds + h->numInts != NUM_INTS_IN_PRIVATE_HANDLE) 328 { 329 return -EINVAL; 330 } 331 332 if (hnd->magic != sMagic) 333 { 334 return -EINVAL; 335 } 336 337 return 0; 338 } 339 is_multi_planeprivate_handle_t340 bool is_multi_plane() const 341 { 342 /* For multi-plane, the byte stride for the second plane will always be non-zero. */ 343 return (plane_info[1].byte_stride != 0); 344 } 345 get_usageprivate_handle_t346 uint64_t get_usage() const 347 { 348 return producer_usage | consumer_usage; 349 } 350 get_share_attr_fd_indexprivate_handle_t351 int get_share_attr_fd_index() const 352 { 353 /* share_attr can be at idx 1 to MAX_FDS */ 354 if (fd_count <= 0 || fd_count > MAX_FDS) 355 return -1; 356 357 return fd_count; 358 } 359 get_share_attr_fdprivate_handle_t360 int get_share_attr_fd() const 361 { 362 int idx = get_share_attr_fd_index(); 363 364 if (idx <= 0) 365 return -1; 366 367 return fds[idx]; 368 } 369 set_share_attr_fdprivate_handle_t370 void set_share_attr_fd(int fd) 371 { 372 int idx = get_share_attr_fd_index(); 373 374 if (idx <= 0) 375 return; 376 377 fds[idx] = fd; 378 } 379 close_share_attr_fdprivate_handle_t380 void close_share_attr_fd() 381 { 382 int fd = get_share_attr_fd(); 383 384 if (fd < 0) 385 return; 386 387 close(fd); 388 } 389 dumpprivate_handle_t390 void dump(const char *str) const 391 { 392 ALOGE("[%s] " 393 "numInts(%d) numFds(%d) fd_count(%d) " 394 "fd(%d %d %d %d) " 395 "flags(%d) " 396 "wh(%d %d) " 397 "req_format(%#x) alloc_format(%#" PRIx64 ") " 398 "usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") " 399 "stride(%" PRIu64 ") " 400 "psize(%" PRIu64 ") byte_stride(%" PRIu64 ") internal_wh(%" PRIu64 " %" PRIu64 ") " 401 "psize1(%" PRIu64 ") byte_stride1(%" PRIu64 ") internal_wh1(%" PRIu64 " %" PRIu64 ") " 402 "psize2(%" PRIu64 ") byte_stride2(%" PRIu64 ") internal_wh2(%" PRIu64 " %" PRIu64 ") " 403 "alloc_format(0x%" PRIx64 ") " 404 "alloc_sizes(%" PRIu64 " %" PRIu64 " %" PRIu64 ") " 405 "layer_count(%d) " 406 "\n", 407 str, 408 numInts, numFds, fd_count, 409 fds[0], fds[1], fds[2], fds[3], 410 flags, 411 width, height, 412 req_format, alloc_format, 413 producer_usage, consumer_usage, 414 stride, 415 plane_info[0].size, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, 416 plane_info[1].size, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height, 417 plane_info[2].size, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height, 418 alloc_format, 419 alloc_sizes[0], alloc_sizes[1], alloc_sizes[2], 420 layer_count 421 ); 422 } 423 get_alloc_formatprivate_handle_t424 int get_alloc_format() const 425 { 426 return (int)(alloc_format & 0x00000000ffffffffULL); 427 } 428 dynamicCastprivate_handle_t429 static private_handle_t *dynamicCast(const native_handle *in) 430 { 431 if (validate(in) == 0) 432 { 433 return (private_handle_t *)in; 434 } 435 436 return NULL; 437 } 438 #endif 439 }; 440 #ifndef __cplusplus 441 /* Restore previous diagnostic for pedantic */ 442 #pragma GCC diagnostic pop 443 #endif 444 445 // The size of private_handle_t is calculated manually. This check ensures that private_handle_t has 446 // the same layout for 32-bit and 64-bit processes. 447 static_assert(sizeof(private_handle_t) == 328); 448 449 #endif /* MALI_GRALLOC_BUFFER_H_ */ 450