blob: 578b2f649a9d511ba86abc0d471cd099cf962b21 [file] [log] [blame]
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05301/*
2 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <cutils/log.h>
31#include <algorithm>
32
33#include "gr_utils.h"
34#include "gr_allocator.h"
35#include "gr_adreno_info.h"
36#include "gralloc_priv.h"
37
38#include "qd_utils.h"
39#include "qdMetaData.h"
40
41#define ASTC_BLOCK_SIZE 16
42
43#ifndef ION_FLAG_CP_PIXEL
44#define ION_FLAG_CP_PIXEL 0
45#endif
46
47#ifndef ION_FLAG_ALLOW_NON_CONTIG
48#define ION_FLAG_ALLOW_NON_CONTIG 0
49#endif
50
Sushil Chauhandfe55a22016-09-12 15:48:29 -070051#ifndef ION_FLAG_CP_CAMERA_PREVIEW
52#define ION_FLAG_CP_CAMERA_PREVIEW 0
53#endif
54
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053055#ifdef MASTER_SIDE_CP
56#define CP_HEAP_ID ION_SECURE_HEAP_ID
57#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
58#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
59#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
Sushil Chauhandfe55a22016-09-12 15:48:29 -070060#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
61#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053062#else // SLAVE_SIDE_CP
63#define CP_HEAP_ID ION_CP_MM_HEAP_ID
64#define SD_HEAP_ID CP_HEAP_ID
65#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
66#define ION_SD_FLAGS ION_SECURE
Sushil Chauhandfe55a22016-09-12 15:48:29 -070067#define ION_SC_FLAGS ION_SECURE
68#define ION_SC_PREVIEW_FLAGS ION_SECURE
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053069#endif
70
71namespace gralloc1 {
72
73Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
74}
75
76bool Allocator::Init() {
77 ion_allocator_ = new IonAlloc();
78 if (!ion_allocator_->Init()) {
79 return false;
80 }
81
82 adreno_helper_ = new AdrenoMemInfo();
83 if (!adreno_helper_->Init()) {
84 return false;
85 }
86
87 gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU();
88 int supports_macrotile = 0;
89 qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile);
90 display_support_macrotile = !!supports_macrotile;
91
92 return true;
93}
94
95Allocator::~Allocator() {
96 if (ion_allocator_) {
97 delete ion_allocator_;
98 }
99
100 if (adreno_helper_) {
101 delete adreno_helper_;
102 }
103}
104
105int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
106 gralloc1_consumer_usage_t cons_usage) {
107 int ret;
108 alloc_data->uncached = UseUncached(prod_usage);
109
110 // After this point we should have the right heap set, there is no fallback
111 GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
112 &alloc_data->flags);
113
114 ret = ion_allocator_->AllocBuffer(alloc_data);
115 if (ret >= 0) {
116 alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
117 } else {
118 ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
119 alloc_data->heap_id, alloc_data->flags);
120 }
121
122 return ret;
123}
124
125// Allocates buffer from width, height and format into a
126// private_handle_t. It is the responsibility of the caller
127// to free the buffer using the FreeBuffer function
128int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) {
129 AllocData data;
130 unsigned int aligned_w, aligned_h;
131 data.base = 0;
132 data.fd = -1;
133 data.offset = 0;
134 data.align = (unsigned int)getpagesize();
135 int format = descriptor.GetFormat();
136 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
137 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
138 GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h);
139
140 int err = AllocateMem(&data, prod_usage, cons_usage);
141 if (0 != err) {
142 ALOGE("%s: allocate failed", __FUNCTION__);
143 return -ENOMEM;
144 }
145
146 if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
147 data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
148 }
149
150 // Metadata is not allocated. would be empty
151 private_handle_t *hnd = new private_handle_t(
152 data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1,
153 0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage);
154 hnd->base = (uint64_t)data.base;
155 hnd->offset = data.offset;
156 hnd->gpuaddr = 0;
157 *pHnd = hnd;
158
159 return 0;
160}
161
162int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
163 if (ion_allocator_) {
164 return ion_allocator_->MapBuffer(base, size, offset, fd);
165 }
166
167 return -EINVAL;
168}
169
170int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
171 if (ion_allocator_) {
172 return ion_allocator_->FreeBuffer(base, size, offset, fd);
173 }
174
175 return -EINVAL;
176}
177
178int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
179 if (ion_allocator_) {
180 return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
181 }
182
183 return -EINVAL;
184}
185
186bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
187 int *max_index) {
188 unsigned int cur_heap_id = 0, prev_heap_id = 0;
189 unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
190 unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
191 bool cur_uncached = false, prev_uncached = false;
192 unsigned int alignedw, alignedh;
193 unsigned int max_size = 0;
194
195 *max_index = -1;
196 for (uint32_t i = 0; i < num_descriptors; i++) {
197 // Check Cached vs non-cached and all the ION flags
198 cur_uncached = UseUncached(descriptors[i].GetProducerUsage());
199 GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(),
200 &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
201
202 if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
203 cur_ion_flags != prev_ion_flags)) {
204 return false;
205 }
206
207 // For same format type, find the descriptor with bigger size
208 GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh);
209 unsigned int size = GetSize(descriptors[i], alignedw, alignedh);
210 if (max_size < size) {
211 *max_index = INT(i);
212 max_size = size;
213 }
214
215 prev_heap_id = cur_heap_id;
216 prev_uncached = cur_uncached;
217 prev_ion_flags = cur_ion_flags;
218 prev_alloc_type = cur_alloc_type;
219 }
220
221 return true;
222}
223
224bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
225 gralloc1_consumer_usage_t cons_usage) {
226 bool tile_enabled = false;
227
228 // Check whether GPU & MDSS supports MacroTiling feature
229 if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) {
230 return tile_enabled;
231 }
232
233 // check the format
234 switch (format) {
235 case HAL_PIXEL_FORMAT_RGBA_8888:
236 case HAL_PIXEL_FORMAT_RGBX_8888:
237 case HAL_PIXEL_FORMAT_BGRA_8888:
238 case HAL_PIXEL_FORMAT_RGB_565:
239 case HAL_PIXEL_FORMAT_BGR_565:
240 if (!CpuCanAccess(prod_usage, cons_usage)) {
241 // not touched by CPU
242 tile_enabled = true;
243 }
244 break;
245 default:
246 break;
247 }
248
249 return tile_enabled;
250}
251
252// helper function
253unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
254 unsigned int alignedh) {
255 unsigned int size = 0;
256 int format = descriptor.GetFormat();
257 int width = descriptor.GetWidth();
258 int height = descriptor.GetHeight();
259 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
260 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
261
262 if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
263 return GetUBwcSize(width, height, format, alignedw, alignedh);
264 }
265
266 if (IsUncompressedRGBFormat(format)) {
267 uint32_t bpp = GetBppForUncompressedRGB(format);
268 size = alignedw * alignedh * bpp;
269 return size;
270 }
271
272 if (IsCompressedRGBFormat(format)) {
273 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
274 return size;
275 }
276
277 // Below switch should be for only YUV/custom formats
278 switch (format) {
279 case HAL_PIXEL_FORMAT_RAW16:
280 size = alignedw * alignedh * 2;
281 break;
282 case HAL_PIXEL_FORMAT_RAW10:
283 size = ALIGN(alignedw * alignedh, SIZE_4K);
284 break;
285
286 // adreno formats
287 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
288 size = ALIGN(alignedw * alignedh, SIZE_4K);
289 size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
290 break;
291 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
292 // The chroma plane is subsampled,
293 // but the pitch in bytes is unchanged
294 // The GPU needs 4K alignment, but the video decoder needs 8K
295 size = ALIGN(alignedw * alignedh, SIZE_8K);
296 size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
297 break;
298 case HAL_PIXEL_FORMAT_YV12:
299 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
300 ALOGE("w or h is odd for the YV12 format");
301 return 0;
302 }
303 size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
304 size = ALIGN(size, (unsigned int)SIZE_4K);
305 break;
306 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
307 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
308 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
309 break;
Ramkumar Radhakrishnan3083fe92016-12-15 18:05:40 -0800310 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
311 size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
312 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530313 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
314 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
315 case HAL_PIXEL_FORMAT_YCbCr_422_I:
316 case HAL_PIXEL_FORMAT_YCrCb_422_I:
317 if (width & 1) {
318 ALOGE("width is odd for the YUV422_SP format");
319 return 0;
320 }
321 size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
322 break;
323 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
324 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
325 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
326 break;
327 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
328 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
329 break;
330 case HAL_PIXEL_FORMAT_BLOB:
331 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
332 if (height != 1) {
333 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
334 return 0;
335 }
336 size = (unsigned int)width;
337 break;
338 case HAL_PIXEL_FORMAT_NV21_ZSL:
339 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
340 break;
341 default:
342 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
343 return 0;
344 }
345
346 return size;
347}
348
349void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
350 unsigned int *alignedw, unsigned int *alignedh) {
351 BufferDescriptor descriptor = BufferDescriptor(width, height, format);
352 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
353
354 *size = GetSize(descriptor, *alignedw, *alignedh);
355}
356
357void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
358 unsigned int *alignedw, unsigned int *alignedh) {
359 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
360
361 *size = GetSize(descriptor, *alignedw, *alignedh);
362}
363
364void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw,
365 unsigned int *alignedh, int *tiled, unsigned int *size) {
366 int format = descriptor.GetFormat();
367 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
368 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
369
370 *tiled = false;
371 if (IsUBwcEnabled(format, prod_usage, cons_usage) ||
372 IsMacroTileEnabled(format, prod_usage, cons_usage)) {
373 *tiled = true;
374 }
375
376 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
377 *size = GetSize(descriptor, *alignedw, *alignedh);
378}
379
380void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
381 int color_format, struct android_ycbcr *ycbcr) {
382 // UBWC buffer has these 4 planes in the following sequence:
383 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
384 unsigned int y_meta_stride, y_meta_height, y_meta_size;
385 unsigned int y_stride, y_height, y_size;
386 unsigned int c_meta_stride, c_meta_height, c_meta_size;
387 unsigned int alignment = 4096;
388
389 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
390 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
391 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
392
393 y_stride = VENUS_Y_STRIDE(color_format, INT(width));
394 y_height = VENUS_Y_SCANLINES(color_format, INT(height));
395 y_size = ALIGN((y_stride * y_height), alignment);
396
397 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
398 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
399 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
400
401 ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
402 ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
403 ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
404 ycbcr->ystride = y_stride;
405 ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
406}
407
408void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
409 struct android_ycbcr *ycbcr) {
410 unsigned int ystride, cstride;
411
412 ystride = cstride = UINT(width) * bpp;
413 ycbcr->y = reinterpret_cast<void *>(base);
414 ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
415 ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
416 ycbcr->ystride = ystride;
417 ycbcr->cstride = cstride;
418 ycbcr->chroma_step = 2 * bpp;
419}
420
421int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
422 int err = 0;
423 uint32_t width = UINT(hnd->width);
424 uint32_t height = UINT(hnd->height);
425 int format = hnd->format;
426 gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
427 gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
428 unsigned int ystride, cstride;
429
430 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
431 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
432
433 // Check if UBWC buffer has been rendered in linear format.
434 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
435 format = INT(metadata->linearFormat);
436 }
437
438 // Check metadata if the geometry has been updated.
439 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
440 int usage = 0;
441
442 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
443 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
444 }
445
446 BufferDescriptor descriptor =
447 BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
448 prod_usage, cons_usage);
449 GetAlignedWidthAndHeight(descriptor, &width, &height);
450 }
451
452 // Get the chroma offsets from the handle width/height. We take advantage
453 // of the fact the width _is_ the stride
454 switch (format) {
455 // Semiplanar
456 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
457 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
458 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
459 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
460 // Same as YCbCr_420_SP_VENUS
461 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
462 break;
463
464 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
465 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
466 break;
467
468 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
469 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
470 ycbcr->chroma_step = 2;
471 break;
472
473 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
474 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
475 ycbcr->chroma_step = 3;
476 break;
477
478 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
479 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
480 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
481 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
482 case HAL_PIXEL_FORMAT_NV21_ZSL:
483 case HAL_PIXEL_FORMAT_RAW16:
484 case HAL_PIXEL_FORMAT_RAW10:
485 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
486 std::swap(ycbcr->cb, ycbcr->cr);
487 break;
488
489 // Planar
490 case HAL_PIXEL_FORMAT_YV12:
491 ystride = width;
492 cstride = ALIGN(width / 2, 16);
493 ycbcr->y = reinterpret_cast<void *>(hnd->base);
494 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
495 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
496 ycbcr->ystride = ystride;
497 ycbcr->cstride = cstride;
498 ycbcr->chroma_step = 1;
499 break;
500
501 // Unsupported formats
502 case HAL_PIXEL_FORMAT_YCbCr_422_I:
503 case HAL_PIXEL_FORMAT_YCrCb_422_I:
504 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
505 default:
506 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
507 err = -EINVAL;
508 }
509
510 return err;
511}
512
513int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
514 gralloc1_consumer_usage_t cons_usage, int format) {
515 int gr_format = format;
516
517 // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
518 // the usage bits, gralloc assigns a format.
519 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
520 format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
521 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
522 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
523 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
524 gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
525 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) {
526 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21 ZSL
527 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
528 gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
529 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
530 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
531 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
532 } else {
533 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
534 }
535 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
536 // XXX: If we still haven't set a format, default to RGBA8888
537 gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
538 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
539 // If no other usage flags are detected, default the
540 // flexible YUV format to NV21_ZSL
541 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
542 }
543 }
544
545 return gr_format;
546}
547
548// Explicitly defined UBWC formats
549bool Allocator::IsUBwcFormat(int format) {
550 switch (format) {
551 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
552 return true;
553 default:
554 return false;
555 }
556}
557
558bool Allocator::IsUBwcSupported(int format) {
559 // Existing HAL formats with UBWC support
560 switch (format) {
561 case HAL_PIXEL_FORMAT_BGR_565:
562 case HAL_PIXEL_FORMAT_RGBA_8888:
563 case HAL_PIXEL_FORMAT_RGBX_8888:
564 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
565 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
566 return true;
567 default:
568 break;
569 }
570
571 return false;
572}
573
574/* The default policy is to return cached buffers unless the client explicity
575 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
576 * read or written in software. */
577// TODO(user) : As of now relying only on producer usage
578bool Allocator::UseUncached(gralloc1_producer_usage_t usage) {
579 if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
580 (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
581 return true;
582 }
583
584 // CPU read rarely
585 if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
586 !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
587 return true;
588 }
589
590 // CPU write rarely
591 if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
592 !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
593 return true;
594 }
595
596 return false;
597}
598
599void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
600 gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
601 unsigned int *alloc_type, unsigned int *ion_flags) {
602 unsigned int heap_id = 0;
603 unsigned int type = 0;
604 int flags = 0;
605 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
606 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
607 heap_id = ION_HEAP(SD_HEAP_ID);
608 /*
609 * There is currently no flag in ION for Secure Display
610 * VM. Please add it to the define once available.
611 */
612 flags |= ION_SD_FLAGS;
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700613 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
614 heap_id = ION_HEAP(SD_HEAP_ID);
615 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
616 flags |= ION_SC_PREVIEW_FLAGS;
617 } else {
618 flags |= ION_SC_FLAGS;
619 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530620 } else {
621 heap_id = ION_HEAP(CP_HEAP_ID);
622 flags |= ION_CP_FLAGS;
623 }
624 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
625 // MM Heap is exclusively a secure heap.
626 // If it is used for non secure cases, fallback to IOMMU heap
627 ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
628 heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
629 }
630
631 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
632 heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
633 }
634
635 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) {
636 heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
637 }
638
639 if (flags & ION_SECURE) {
640 type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
641 }
642
643 // if no ion heap flags are set, default to system heap
644 if (!heap_id) {
645 heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
646 }
647
648 *alloc_type = type;
649 *ion_flags = (unsigned int)flags;
650 *ion_heap_id = heap_id;
651
652 return;
653}
654
655bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
656 gralloc1_consumer_usage_t cons_usage) {
657 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
658 if (IsUBwcFormat(format)) {
659 return true;
660 }
661
662 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
663 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
664 // usage flag and MDP supports the format.
665 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
666 bool enable = true;
667 // Query GPU for UBWC only if buffer is intended to be used by GPU.
668 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
669 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
670 enable = adreno_helper_->IsUBWCSupportedByGPU(format);
671 }
672
673 // Allow UBWC, only if CPU usage flags are not set
674 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
675 return true;
676 }
677 }
678
679 return false;
680}
681
682void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
683 unsigned int *aligned_h) {
684 switch (format) {
685 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
686 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
687 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
688 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
689 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
690 break;
Arun Kumar K.Rfc2a27f2016-09-07 18:59:46 -0700691 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
692 // The macro returns the stride which is 4/3 times the width, hence * 3/4
693 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
694 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
695 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530696 default:
697 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
698 *aligned_w = 0;
699 *aligned_h = 0;
700 break;
701 }
702}
703
704void Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
705 *block_width = 0;
706 *block_height = 0;
707
708 switch (bpp) {
709 case 2:
710 case 4:
711 *block_width = 16;
712 *block_height = 4;
713 break;
714 case 8:
715 *block_width = 8;
716 *block_height = 4;
717 break;
718 case 16:
719 *block_width = 4;
720 *block_height = 4;
721 break;
722 default:
723 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
724 break;
725 }
726}
727
728unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
729 unsigned int size = 0;
730 int meta_width, meta_height;
731 int block_width, block_height;
732
733 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
734 if (!block_width || !block_height) {
735 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
736 return size;
737 }
738
739 // Align meta buffer height to 16 blocks
740 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
741
742 // Align meta buffer width to 64 blocks
743 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
744
745 // Align meta buffer size to 4K
746 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
747
748 return size;
749}
750
751unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
752 unsigned int alignedh) {
753 unsigned int size = 0;
754 uint32_t bpp = 0;
755 switch (format) {
756 case HAL_PIXEL_FORMAT_BGR_565:
757 case HAL_PIXEL_FORMAT_RGBA_8888:
758 case HAL_PIXEL_FORMAT_RGBX_8888:
759 case HAL_PIXEL_FORMAT_RGBA_1010102:
760 case HAL_PIXEL_FORMAT_RGBX_1010102:
761 bpp = GetBppForUncompressedRGB(format);
762 size = alignedw * alignedh * bpp;
763 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
764 break;
765 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
766 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
767 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
768 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
769 break;
770 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
771 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
772 break;
773 default:
774 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
775 break;
776 }
777
778 return size;
779}
780
781int Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
782 int err = 0;
783
784 // This api is for RGB* formats
785 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
786 return -EINVAL;
787 }
788
789 // linear buffer, nothing to do further
790 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
791 *rgb_data = reinterpret_cast<void *>(hnd->base);
792 return err;
793 }
794
795 unsigned int meta_size = 0;
796 uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
797 switch (hnd->format) {
798 case HAL_PIXEL_FORMAT_BGR_565:
799 case HAL_PIXEL_FORMAT_RGBA_8888:
800 case HAL_PIXEL_FORMAT_RGBX_8888:
801 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
802 break;
803 default:
804 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
805 err = -EINVAL;
806 break;
807 }
808 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
809
810 return err;
811}
812
813void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
814 unsigned int *alignedh) {
815 int width = descriptor.GetWidth();
816 int height = descriptor.GetHeight();
817 int format = descriptor.GetFormat();
818 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
819 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
820
821 // Currently surface padding is only computed for RGB* surfaces.
822 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
823 int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage);
824
825 if (IsUncompressedRGBFormat(format)) {
826 adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
827 return;
828 }
829
830 if (ubwc_enabled) {
831 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
832 return;
833 }
834
835 if (IsCompressedRGBFormat(format)) {
836 adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
837 return;
838 }
839
840 int aligned_w = width;
841 int aligned_h = height;
842 unsigned int alignment = 32;
843
844 // Below should be only YUV family
845 switch (format) {
846 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
847 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
848 alignment = adreno_helper_->GetGpuPixelAlignment();
849 aligned_w = ALIGN(width, alignment);
850 break;
851 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
852 aligned_w = ALIGN(width, alignment);
853 break;
854 case HAL_PIXEL_FORMAT_RAW16:
855 aligned_w = ALIGN(width, 16);
856 break;
857 case HAL_PIXEL_FORMAT_RAW10:
858 aligned_w = ALIGN(width * 10 / 8, 16);
859 break;
860 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
861 aligned_w = ALIGN(width, 128);
862 break;
863 case HAL_PIXEL_FORMAT_YV12:
864 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
865 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
866 case HAL_PIXEL_FORMAT_YCbCr_422_I:
867 case HAL_PIXEL_FORMAT_YCrCb_422_I:
Ramkumar Radhakrishnan3083fe92016-12-15 18:05:40 -0800868 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530869 aligned_w = ALIGN(width, 16);
870 break;
871 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
872 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
873 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
874 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
875 break;
876 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
877 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
878 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
879 break;
880 case HAL_PIXEL_FORMAT_BLOB:
881 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
882 break;
883 case HAL_PIXEL_FORMAT_NV21_ZSL:
884 aligned_w = ALIGN(width, 64);
885 aligned_h = ALIGN(height, 64);
886 break;
887 default:
888 break;
889 }
890
891 *alignedw = (unsigned int)aligned_w;
892 *alignedh = (unsigned int)aligned_h;
893}
894
895} // namespace gralloc1