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