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