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