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