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 <log/log.h>
31#include <algorithm>
32#include <vector>
33
34#include "gr_utils.h"
35#include "gr_allocator.h"
36#include "gralloc_priv.h"
37
38#include "qd_utils.h"
39
40#ifndef ION_FLAG_CP_PIXEL
41#define ION_FLAG_CP_PIXEL 0
42#endif
43
44#ifndef ION_FLAG_ALLOW_NON_CONTIG
45#define ION_FLAG_ALLOW_NON_CONTIG 0
46#endif
47
48#ifndef ION_FLAG_CP_CAMERA_PREVIEW
49#define ION_FLAG_CP_CAMERA_PREVIEW 0
50#endif
51
52#ifdef MASTER_SIDE_CP
53#define CP_HEAP_ID ION_SECURE_HEAP_ID
54#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
55#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
56#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
57#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
58#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
59#else  // SLAVE_SIDE_CP
60#define CP_HEAP_ID ION_CP_MM_HEAP_ID
61#define SD_HEAP_ID CP_HEAP_ID
62#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
63#define ION_SD_FLAGS ION_SECURE
64#define ION_SC_FLAGS ION_SECURE
65#define ION_SC_PREVIEW_FLAGS ION_SECURE
66#endif
67
68using std::vector;
69using std::shared_ptr;
70
71namespace gralloc1 {
72
73static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
74  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
75                    descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
76}
77
78Allocator::Allocator() : ion_allocator_(NULL) {
79}
80
81bool Allocator::Init() {
82  ion_allocator_ = new IonAlloc();
83  if (!ion_allocator_->Init()) {
84    return false;
85  }
86
87  return true;
88}
89
90Allocator::~Allocator() {
91  if (ion_allocator_) {
92    delete ion_allocator_;
93  }
94}
95
96int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
97                           gralloc1_consumer_usage_t cons_usage) {
98  int ret;
99  alloc_data->uncached = UseUncached(prod_usage, cons_usage);
100
101  // After this point we should have the right heap set, there is no fallback
102  GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
103                 &alloc_data->flags);
104
105  ret = ion_allocator_->AllocBuffer(alloc_data);
106  if (ret >= 0) {
107    alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
108  } else {
109    ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
110          alloc_data->heap_id, alloc_data->flags);
111  }
112
113  return ret;
114}
115
116int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
117  if (ion_allocator_) {
118    return ion_allocator_->MapBuffer(base, size, offset, fd);
119  }
120
121  return -EINVAL;
122}
123
124int Allocator::ImportBuffer(int fd) {
125  if (ion_allocator_) {
126    return ion_allocator_->ImportBuffer(fd);
127  }
128  return -EINVAL;
129}
130
131int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
132                          int handle) {
133  if (ion_allocator_) {
134    return ion_allocator_->FreeBuffer(base, size, offset, fd, handle);
135  }
136
137  return -EINVAL;
138}
139
140int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
141  if (ion_allocator_) {
142    return ion_allocator_->CleanBuffer(base, size, offset, handle, op);
143  }
144
145  return -EINVAL;
146}
147
148bool Allocator::CheckForBufferSharing(uint32_t num_descriptors,
149                                      const vector<shared_ptr<BufferDescriptor>>& descriptors,
150                                      ssize_t *max_index) {
151  unsigned int cur_heap_id = 0, prev_heap_id = 0;
152  unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
153  unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
154  bool cur_uncached = false, prev_uncached = false;
155  unsigned int alignedw, alignedh;
156  unsigned int max_size = 0;
157
158  *max_index = -1;
159  for (uint32_t i = 0; i < num_descriptors; i++) {
160    // Check Cached vs non-cached and all the ION flags
161    cur_uncached = UseUncached(descriptors[i]->GetProducerUsage(),
162                               descriptors[i]->GetConsumerUsage());
163    GetIonHeapInfo(descriptors[i]->GetProducerUsage(), descriptors[i]->GetConsumerUsage(),
164                   &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
165
166    if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
167                  cur_ion_flags != prev_ion_flags)) {
168      return false;
169    }
170
171    // For same format type, find the descriptor with bigger size
172    GetAlignedWidthAndHeight(GetBufferInfo(*descriptors[i]), &alignedw, &alignedh);
173    unsigned int size = GetSize(GetBufferInfo(*descriptors[i]), alignedw, alignedh);
174    if (max_size < size) {
175      *max_index = INT(i);
176      max_size = size;
177    }
178
179    prev_heap_id = cur_heap_id;
180    prev_uncached = cur_uncached;
181    prev_ion_flags = cur_ion_flags;
182    prev_alloc_type = cur_alloc_type;
183  }
184
185  return true;
186}
187
188int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
189                                    gralloc1_consumer_usage_t cons_usage, int format) {
190  int gr_format = format;
191
192  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
193  // the usage bits, gralloc assigns a format.
194  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
195      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
196    if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
197      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
198    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
199      gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
200    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
201      if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
202        // Assumed ZSL if both producer and consumer camera flags set
203        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
204      } else {
205        gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
206      }
207    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
208      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
209        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
210      } else {
211        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
212      }
213    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
214      // XXX: If we still haven't set a format, default to RGBA8888
215      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
216    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
217      // If no other usage flags are detected, default the
218      // flexible YUV format to NV21_ZSL
219      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
220    }
221  }
222
223  return gr_format;
224}
225
226/* The default policy is to return cached buffers unless the client explicity
227 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
228 * read or written in software. */
229bool Allocator::UseUncached(gralloc1_producer_usage_t prod_usage,
230                            gralloc1_consumer_usage_t cons_usage) {
231  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
232      (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
233    return true;
234  }
235
236  // CPU read rarely
237  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
238      !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
239    return true;
240  }
241
242  // CPU  write rarely
243  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
244      !(prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
245    return true;
246  }
247
248  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA) ||
249      (cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER)) {
250    return true;
251  }
252
253  return false;
254}
255
256void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
257                               gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
258                               unsigned int *alloc_type, unsigned int *ion_flags) {
259  unsigned int heap_id = 0;
260  unsigned int type = 0;
261  uint32_t flags = 0;
262  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
263    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
264      heap_id = ION_HEAP(SD_HEAP_ID);
265      /*
266       * There is currently no flag in ION for Secure Display
267       * VM. Please add it to the define once available.
268       */
269      flags |= UINT(ION_SD_FLAGS);
270    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
271      heap_id = ION_HEAP(SD_HEAP_ID);
272      if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
273        flags |= UINT(ION_SC_PREVIEW_FLAGS);
274      } else {
275        flags |= UINT(ION_SC_FLAGS);
276      }
277    } else {
278      heap_id = ION_HEAP(CP_HEAP_ID);
279      flags |= UINT(ION_CP_FLAGS);
280    }
281  } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
282    // MM Heap is exclusively a secure heap.
283    // If it is used for non secure cases, fallback to IOMMU heap
284    ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
285    heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
286  }
287
288  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
289    heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
290  }
291
292  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP ||
293      prod_usage & GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA) {
294    heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
295  }
296
297  if (flags & UINT(ION_SECURE)) {
298    type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
299  }
300
301  // if no ion heap flags are set, default to system heap
302  if (!heap_id) {
303    heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
304  }
305
306  *alloc_type = type;
307  *ion_flags = flags;
308  *ion_heap_id = heap_id;
309
310  return;
311}
312}  // namespace gralloc1
313