blob: e2cfdd4059d318d388b66fb4a4d9784f5ffa4886 [file] [log] [blame]
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05301/*
Saurabh Shahc5b2b702016-10-24 17:16:01 -07002 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05303 * Not a Contribution
4 *
5 * Copyright (C) 2010 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Naseer Ahmed699b4572017-03-09 12:28:45 -050020#define DEBUG 0
Naseer Ahmeddc918132017-03-07 15:25:14 -050021#include <iomanip>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053022#include <utility>
Naseer Ahmede69031e2016-11-22 20:05:16 -050023#include <vector>
Naseer Ahmeddc918132017-03-07 15:25:14 -050024#include <sstream>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053025
26#include "qd_utils.h"
27#include "gr_priv_handle.h"
28#include "gr_buf_descriptor.h"
29#include "gr_utils.h"
30#include "gr_buf_mgr.h"
31#include "qdMetaData.h"
32
33namespace gralloc1 {
Naseer Ahmede69031e2016-11-22 20:05:16 -050034std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053035
Naseer Ahmede69031e2016-11-22 20:05:16 -050036BufferManager::BufferManager() : next_id_(0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053037 char property[PROPERTY_VALUE_MAX];
38
39 // Map framebuffer memory
40 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
41 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
42 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
43 map_fb_mem_ = true;
44 }
45
46 // Enable UBWC for framebuffer
47 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
48 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
49 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
50 ubwc_for_fb_ = true;
51 }
52
53 handles_map_.clear();
Naseer Ahmede69031e2016-11-22 20:05:16 -050054 allocator_ = new Allocator();
55 allocator_->Init();
56}
57
58
59gralloc1_error_t BufferManager::CreateBufferDescriptor(
60 gralloc1_buffer_descriptor_t *descriptor_id) {
61 std::lock_guard<std::mutex> lock(locker_);
62 auto descriptor = std::make_shared<BufferDescriptor>();
63 descriptors_map_.emplace(descriptor->GetId(), descriptor);
64 *descriptor_id = descriptor->GetId();
65 return GRALLOC1_ERROR_NONE;
66}
67
68gralloc1_error_t BufferManager::DestroyBufferDescriptor(
69 gralloc1_buffer_descriptor_t descriptor_id) {
70 std::lock_guard<std::mutex> lock(locker_);
71 const auto descriptor = descriptors_map_.find(descriptor_id);
72 if (descriptor == descriptors_map_.end()) {
73 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
74 }
75 descriptors_map_.erase(descriptor);
76 return GRALLOC1_ERROR_NONE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053077}
78
79BufferManager::~BufferManager() {
80 if (allocator_) {
81 delete allocator_;
82 }
83}
84
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053085gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
Naseer Ahmede69031e2016-11-22 20:05:16 -050086 const gralloc1_buffer_descriptor_t *descriptor_ids,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053087 buffer_handle_t *out_buffers) {
88 bool shared = true;
89 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
90
91 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
92 // client can ask to test the allocation by passing NULL out_buffers
93 bool test_allocate = !out_buffers;
94
Naseer Ahmede69031e2016-11-22 20:05:16 -050095 // Validate descriptors
96 std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
97 for (uint32_t i = 0; i < num_descriptors; i++) {
98 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
99 if (map_descriptor == descriptors_map_.end()) {
100 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
101 } else {
102 descriptors.push_back(map_descriptor->second);
103 }
104 }
105
106 // Resolve implementation defined formats
107 for (auto &descriptor : descriptors) {
108 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
109 descriptor->GetConsumerUsage(),
110 descriptor->GetFormat()));
111 }
112
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530113 // Check if input descriptors can be supported AND
114 // Find out if a single buffer can be shared for all the given input descriptors
115 uint32_t i = 0;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500116 ssize_t max_buf_index = -1;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530117 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
118
119 if (test_allocate) {
120 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
121 return status;
122 }
123
124 if (shared && (max_buf_index >= 0)) {
125 // Allocate one and duplicate/copy the handles for each descriptor
Naseer Ahmede69031e2016-11-22 20:05:16 -0500126 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530127 return GRALLOC1_ERROR_NO_RESOURCES;
128 }
129
130 for (i = 0; i < num_descriptors; i++) {
131 // Create new handle for a given descriptor.
132 // Current assumption is even MetaData memory would be same
133 // Need to revisit if there is a need for own metadata memory
134 if (i != UINT(max_buf_index)) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500135 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530136 }
137 }
138 } else {
139 // Buffer sharing is not feasible.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500140 // Allocate separate buffer for each descriptor
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530141 for (i = 0; i < num_descriptors; i++) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500142 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530143 return GRALLOC1_ERROR_NO_RESOURCES;
144 }
145 }
146 }
147
148 // Allocation is successful. If backstore is not shared inform the client.
149 if (!shared) {
150 return GRALLOC1_ERROR_NOT_SHARED;
151 }
152
153 return status;
154}
155
156void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
157 buffer_handle_t *outbuffer) {
158 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
159
160 // Get Buffer attributes or dimension
161 unsigned int alignedw = 0, alignedh = 0;
162 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
163
164 // create new handle from input reference handle and given descriptor
165 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
166 descriptor.GetConsumerUsage());
167 int buffer_type = GetBufferType(descriptor.GetFormat());
168
169 // Duplicate the fds
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700170 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
Naseer Ahmede69031e2016-11-22 20:05:16 -0500171 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
172 dup(input->fd_metadata),
173 flags,
174 INT(alignedw),
175 INT(alignedh),
176 descriptor.GetWidth(),
177 descriptor.GetHeight(),
178 descriptor.GetFormat(),
179 buffer_type,
180 input->size,
181 descriptor.GetProducerUsage(),
182 descriptor.GetConsumerUsage());
183 out_hnd->id = ++next_id_;
184 // TODO(user): Base address of shared handle and ion handles
185 auto buffer = std::make_shared<Buffer>(out_hnd);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500186 handles_map_.emplace(std::make_pair(out_hnd, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530187 *outbuffer = out_hnd;
188}
189
Naseer Ahmede69031e2016-11-22 20:05:16 -0500190gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
191 auto hnd = buf->handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530192 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500193 hnd->fd, buf->ion_handle_main) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530194 return GRALLOC1_ERROR_BAD_HANDLE;
195 }
196
197 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
198 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500199 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530200 return GRALLOC1_ERROR_BAD_HANDLE;
201 }
202
Naseer Ahmede69031e2016-11-22 20:05:16 -0500203 // TODO(user): delete handle once framework bug around this is confirmed
204 // to be resolved
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530205 return GRALLOC1_ERROR_NONE;
206}
207
208gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
209 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
210
211 hnd->base = 0;
212 hnd->base_metadata = 0;
213 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
214 hnd->fd) != 0) {
215 return GRALLOC1_ERROR_BAD_HANDLE;
216 }
217
218 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
219 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
220 hnd->offset_metadata, hnd->fd_metadata) != 0) {
221 return GRALLOC1_ERROR_BAD_HANDLE;
222 }
223
224 return GRALLOC1_ERROR_NONE;
225}
226
227gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500228 std::lock_guard<std::mutex> lock(locker_);
Naseer Ahmed699b4572017-03-09 12:28:45 -0500229 ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530230
231 // find if this handle is already in map
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500232 auto it = handles_map_.find(hnd);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530233 if (it != handles_map_.end()) {
234 // It's already in map, Just increment refcnt
235 // No need to mmap the memory.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500236 auto buf = it->second;
237 buf->ref_count++;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530238 } else {
239 // not present in the map. mmap and then add entry to map
240 if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500241 auto buffer = std::make_shared<Buffer>(hnd);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500242 handles_map_.emplace(std::make_pair(hnd, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530243 }
244 }
245
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530246 return GRALLOC1_ERROR_NONE;
247}
248
249gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500250 std::lock_guard<std::mutex> lock(locker_);
Naseer Ahmed699b4572017-03-09 12:28:45 -0500251 ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530252 // find if this handle is already in map
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500253 auto it = handles_map_.find(hnd);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530254 if (it == handles_map_.end()) {
255 // Corrupt handle or map.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500256 ALOGE("Could not find handle");
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530257 return GRALLOC1_ERROR_BAD_HANDLE;
258 } else {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500259 auto buf = it->second;
260 buf->ref_count--;
261 if (buf->ref_count == 0) {
262 handles_map_.erase(it);
263 FreeBuffer(buf);
264 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530265 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530266 return GRALLOC1_ERROR_NONE;
267}
268
269gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
270 gralloc1_producer_usage_t prod_usage,
271 gralloc1_consumer_usage_t cons_usage) {
272 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
273
274 // If buffer is not meant for CPU return err
275 if (!CpuCanAccess(prod_usage, cons_usage)) {
276 return GRALLOC1_ERROR_BAD_VALUE;
277 }
278
279 if (hnd->base == 0) {
280 // we need to map for real
281 locker_.lock();
282 err = MapBuffer(hnd);
283 locker_.unlock();
284 }
285
286 // Invalidate if CPU reads in software and there are non-CPU
287 // writers. No need to do this for the metadata buffer as it is
288 // only read/written in software.
289 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
290 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
291 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
292 hnd->fd, CACHE_INVALIDATE)) {
293 return GRALLOC1_ERROR_BAD_HANDLE;
294 }
295 }
296
297 // Mark the buffer to be flushed after CPU write.
298 if (!err && CpuCanWrite(prod_usage)) {
299 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
300 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
301 }
302
303 return err;
304}
305
306gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
307 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
308
309 locker_.lock();
310 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
311
312 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
313 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
314 hnd->fd, CACHE_CLEAN) != 0) {
315 status = GRALLOC1_ERROR_BAD_HANDLE;
316 }
317 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
318 }
319
320 locker_.unlock();
321 return status;
322}
323
Naseer Ahmede69031e2016-11-22 20:05:16 -0500324uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530325 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500326 uint32_t align = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530327 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
328 align = 8192;
329 }
330
331 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700332 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
333 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530334 // The alignment here reflects qsee mmu V7L/V8L requirement
335 align = SZ_2M;
336 } else {
337 align = SECURE_ALIGN;
338 }
339 }
340
341 return align;
342}
343
344int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
345 gralloc1_consumer_usage_t cons_usage) {
346 int flags = 0;
347 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
348 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
349 }
350
351 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
352 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
353 }
354
355 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
356 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
357 }
358
359 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
360 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
361 }
362
363 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
364 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
365 }
366
367 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
368 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
369 }
370
371 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
372 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
373 }
374
375 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
376 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
377 }
378
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530379 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
380 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
381 }
382
383 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
384 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
385 }
386
387 // TODO(user): is this correct???
388 if ((cons_usage &
389 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
390 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
391 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
392 }
393
394 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
395 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
396 }
397
398 if (!allocator_->UseUncached(prod_usage)) {
399 flags |= private_handle_t::PRIV_FLAGS_CACHED;
400 }
401
402 return flags;
403}
404
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700405int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
406 int unaligned_h, int format, int bufferType,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530407 gralloc1_producer_usage_t prod_usage,
408 gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500409 auto page_size = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530410 int err = 0;
411 int flags = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530412 AllocData data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500413 data.align = GetDataAlignment(format, prod_usage, cons_usage);
414 data.size = ALIGN(size, data.align);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530415 data.handle = (uintptr_t)handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530416 data.uncached = allocator_->UseUncached(prod_usage);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500417
418 // Allocate buffer memory
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530419 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
420 if (err) {
421 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530422 return err;
423 }
424
Naseer Ahmede69031e2016-11-22 20:05:16 -0500425 // Allocate memory for MetaData
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530426 AllocData e_data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500427 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530428 e_data.handle = data.handle;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500429 e_data.align = page_size;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530430
431 err =
432 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500433 if (err) {
434 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
435 return err;
436 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530437
438 flags = GetHandleFlags(format, prod_usage, cons_usage);
439 flags |= data.alloc_type;
440
441 // Create handle
Naseer Ahmede69031e2016-11-22 20:05:16 -0500442 private_handle_t *hnd = new private_handle_t(data.fd,
443 e_data.fd,
444 flags,
445 aligned_w,
446 aligned_h,
447 unaligned_w,
448 unaligned_h,
449 format,
450 bufferType,
451 size,
452 prod_usage,
453 cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530454
Naseer Ahmede69031e2016-11-22 20:05:16 -0500455 hnd->id = ++next_id_;
456 hnd->base = reinterpret_cast<uint64_t >(data.base);
457 hnd->base_metadata = reinterpret_cast<uint64_t >(e_data.base);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530458
Naseer Ahmede69031e2016-11-22 20:05:16 -0500459 ColorSpace_t colorSpace = ITU_R_601;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530460 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530461 *handle = hnd;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500462 auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500463 handles_map_.emplace(std::make_pair(hnd, buffer));
Naseer Ahmed699b4572017-03-09 12:28:45 -0500464 ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
465 if (DEBUG) {
466 private_handle_t::Dump(hnd);
467 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530468 return err;
469}
470
471int BufferManager::GetBufferType(int inputFormat) {
472 int buffer_type = BUFFER_TYPE_VIDEO;
473 if (IsUncompressedRGBFormat(inputFormat)) {
474 // RGB formats
475 buffer_type = BUFFER_TYPE_UI;
476 }
477
478 return buffer_type;
479}
480
481int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
482 unsigned int bufferSize) {
483 if (!handle)
484 return -EINVAL;
485
486 int format = descriptor.GetFormat();
487 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
488 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
489
490 // Get implementation defined format
491 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
492
493 bool use_fb_mem = false;
494 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
495 use_fb_mem = true;
496 }
497
498 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
499 prod_usage =
500 (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
501 }
502
503 unsigned int size;
504 unsigned int alignedw, alignedh;
505 int buffer_type = GetBufferType(gralloc_format);
506 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
507
508 size = (bufferSize >= size) ? bufferSize : size;
509
510 int err = 0;
511 if (use_fb_mem) {
512 // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
513 } else {
514 err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
515 descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
516 descriptor.GetConsumerUsage(), handle);
517 }
518
519 if (err < 0) {
520 return err;
521 }
522
523 return 0;
524}
525
526gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
527 switch (operation) {
528 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
529 int fd = va_arg(args, int);
530 unsigned int size = va_arg(args, unsigned int);
531 unsigned int offset = va_arg(args, unsigned int);
532 void *base = va_arg(args, void *);
533 int width = va_arg(args, int);
534 int height = va_arg(args, int);
535 int format = va_arg(args, int);
536
537 native_handle_t **handle = va_arg(args, native_handle_t **);
538 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
539 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
540 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700541 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530542 hnd->magic = private_handle_t::kMagic;
543 hnd->fd = fd;
544 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
545 hnd->size = size;
546 hnd->offset = offset;
547 hnd->base = uint64_t(base) + offset;
548 hnd->gpuaddr = 0;
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700549 BufferDescriptor descriptor(width, height, format);
550 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
551 hnd->unaligned_width = width;
552 hnd->unaligned_height = height;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500553 hnd->width = INT(alignedw);
554 hnd->height = INT(alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530555 hnd->format = format;
556 *handle = reinterpret_cast<native_handle_t *>(hnd);
557 }
558 } break;
559
560 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
561 int width = va_arg(args, int);
562 int format = va_arg(args, int);
563 int *stride = va_arg(args, int *);
564 unsigned int alignedw = 0, alignedh = 0;
565 BufferDescriptor descriptor(width, width, format);
566 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
567 *stride = INT(alignedw);
568 } break;
569
570 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
571 private_handle_t *hnd = va_arg(args, private_handle_t *);
572 int *stride = va_arg(args, int *);
573 if (private_handle_t::validate(hnd) != 0) {
574 return GRALLOC1_ERROR_BAD_HANDLE;
575 }
576
577 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
578 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
579 *stride = metadata->bufferDim.sliceWidth;
580 } else {
581 *stride = hnd->width;
582 }
583 } break;
584
585 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
586 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
587 private_handle_t *hnd = va_arg(args, private_handle_t *);
588 int *stride = va_arg(args, int *);
589 int *height = va_arg(args, int *);
590 if (private_handle_t::validate(hnd) != 0) {
591 return GRALLOC1_ERROR_BAD_HANDLE;
592 }
593
594 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
595 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
596 *stride = metadata->bufferDim.sliceWidth;
597 *height = metadata->bufferDim.sliceHeight;
598 } else {
599 *stride = hnd->width;
600 *height = hnd->height;
601 }
602 } break;
603
604 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
605 // TODO(user): Usage is split now. take care of it from Gfx client.
606 // see if we can directly expect descriptor from gfx client.
607 int width = va_arg(args, int);
608 int height = va_arg(args, int);
609 int format = va_arg(args, int);
610 uint64_t producer_usage = va_arg(args, uint64_t);
611 uint64_t consumer_usage = va_arg(args, uint64_t);
612 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
613 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
614
615 int *aligned_width = va_arg(args, int *);
616 int *aligned_height = va_arg(args, int *);
617 int *tile_enabled = va_arg(args, int *);
618 unsigned int alignedw, alignedh;
619 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
Saurabh Shahc5b2b702016-10-24 17:16:01 -0700620 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530621
622 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
623 *aligned_width = INT(alignedw);
624 *aligned_height = INT(alignedh);
625 } break;
626
627 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
628 private_handle_t *hnd = va_arg(args, private_handle_t *);
629 int *color_space = va_arg(args, int *);
630 if (private_handle_t::validate(hnd) != 0) {
631 return GRALLOC1_ERROR_BAD_HANDLE;
632 }
633 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700634 if (!metadata) {
635 return GRALLOC1_ERROR_BAD_HANDLE;
636#ifdef USE_COLOR_METADATA
637 } else if (metadata->operation & COLOR_METADATA) {
638 ColorMetaData *colorMetadata = &metadata->color;
639 switch (colorMetadata->colorPrimaries) {
640 case ColorPrimaries_BT709_5:
641 *color_space = HAL_CSC_ITU_R_709;
642 break;
643 case ColorPrimaries_BT601_6_525:
644 *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
645 break;
646 case ColorPrimaries_BT2020:
647 *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
648 break;
649 default:
650 ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
651 break;
652 }
653#endif
654 } else if (metadata->operation & UPDATE_COLOR_SPACE) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530655 *color_space = metadata->colorSpace;
656 }
657 } break;
658 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
659 private_handle_t *hnd = va_arg(args, private_handle_t *);
660 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
661 if (private_handle_t::validate(hnd) != 0) {
662 return GRALLOC1_ERROR_BAD_HANDLE;
663 }
664 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
665 return GRALLOC1_ERROR_UNDEFINED;
666 }
667 } break;
668
669 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
670 private_handle_t *hnd = va_arg(args, private_handle_t *);
671 int *map_secure_buffer = va_arg(args, int *);
672 if (private_handle_t::validate(hnd) != 0) {
673 return GRALLOC1_ERROR_BAD_HANDLE;
674 }
675 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
676 if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
677 *map_secure_buffer = metadata->mapSecureBuffer;
678 } else {
679 *map_secure_buffer = 0;
680 }
681 } break;
682
683 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
684 private_handle_t *hnd = va_arg(args, private_handle_t *);
685 int *flag = va_arg(args, int *);
686 if (private_handle_t::validate(hnd) != 0) {
687 return GRALLOC1_ERROR_BAD_HANDLE;
688 }
689 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
690 } break;
691
692 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
693 private_handle_t *hnd = va_arg(args, private_handle_t *);
694 void **rgb_data = va_arg(args, void **);
695 if (private_handle_t::validate(hnd) != 0) {
696 return GRALLOC1_ERROR_BAD_HANDLE;
697 }
698 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
699 return GRALLOC1_ERROR_UNDEFINED;
700 }
701 } break;
702
Naseer Ahmede69031e2016-11-22 20:05:16 -0500703 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
704 int width = va_arg(args, int);
705 int height = va_arg(args, int);
706 int format = va_arg(args, int);
707 uint64_t p_usage = va_arg(args, uint64_t);
708 uint64_t c_usage = va_arg(args, uint64_t);
709 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
710 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
711 uint32_t *aligned_width = va_arg(args, uint32_t *);
712 uint32_t *aligned_height = va_arg(args, uint32_t *);
713 uint32_t *size = va_arg(args, uint32_t *);
714 auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
715 allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
716 // Align size
717 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
718 *size = ALIGN(*size, align);
719 } break;
720
721 // TODO(user): Break out similar functionality, preferably moving to a common lib.
722
723 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
724 int width = va_arg(args, int);
725 int height = va_arg(args, int);
726 int format = va_arg(args, int);
727 uint64_t p_usage = va_arg(args, uint64_t);
728 uint64_t c_usage = va_arg(args, uint64_t);
729 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
730 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
731 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
732 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
733 unsigned int size;
734 unsigned int alignedw, alignedh;
735 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
736 AllocateBuffer(descriptor, hnd, size);
737 } break;
738
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530739 default:
740 break;
741 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530742 return GRALLOC1_ERROR_NONE;
743}
744
Naseer Ahmede69031e2016-11-22 20:05:16 -0500745static bool IsYuvFormat(const private_handle_t *hnd) {
746 switch (hnd->format) {
747 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
748 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
749 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
750 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
751 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
752 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
753 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
754 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
755 case HAL_PIXEL_FORMAT_NV21_ZSL:
756 case HAL_PIXEL_FORMAT_RAW16:
757 case HAL_PIXEL_FORMAT_RAW10:
758 case HAL_PIXEL_FORMAT_YV12:
759 return true;
760 default:
761 return false;
762 }
763}
764
765gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
766 uint32_t *out_num_planes) {
767 if (!IsYuvFormat(hnd)) {
768 return GRALLOC1_ERROR_UNSUPPORTED;
769 } else {
770 *out_num_planes = 3;
771 }
772 return GRALLOC1_ERROR_NONE;
773}
774
775gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
776 struct android_flex_layout *layout) {
777 if (!IsYuvFormat(hnd)) {
778 return GRALLOC1_ERROR_UNSUPPORTED;
779 }
780
781 android_ycbcr ycbcr;
782 int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
783
784 if (err != 0) {
785 return GRALLOC1_ERROR_BAD_HANDLE;
786 }
787
788 layout->format = FLEX_FORMAT_YCbCr;
789 layout->num_planes = 3;
790
791 for (uint32_t i = 0; i < layout->num_planes; i++) {
792 layout->planes[i].bits_per_component = 8;
793 layout->planes[i].bits_used = 8;
794 layout->planes[i].h_increment = 1;
795 layout->planes[i].v_increment = 1;
796 layout->planes[i].h_subsampling = 2;
797 layout->planes[i].v_subsampling = 2;
798 }
799
800 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
801 layout->planes[0].component = FLEX_COMPONENT_Y;
802 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
803
804 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
805 layout->planes[1].component = FLEX_COMPONENT_Cb;
806 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
807 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
808
809 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
810 layout->planes[2].component = FLEX_COMPONENT_Cr;
811 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
812 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
813 return GRALLOC1_ERROR_NONE;
814}
Naseer Ahmeddc918132017-03-07 15:25:14 -0500815
816gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
817 for (auto it : handles_map_) {
818 auto buf = it.second;
819 auto hnd = buf->handle;
820 *os << "handle id: " << std::setw(4) << hnd->id;
821 *os << " fd: " << std::setw(3) << hnd->fd;
822 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
823 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
824 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
825 *os << std::setw(4) << hnd->unaligned_height;
826 *os << " size: " << std::setw(9) << hnd->size;
827 *os << std::hex << std::setfill('0');
828 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
829 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
830 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
831 // TODO(user): get format string from qdutils
832 *os << " format: " << "0x" << std::setw(8) << hnd->format;
833 *os << std::dec << std::setfill(' ') << std::endl;
834 }
835 return GRALLOC1_ERROR_NONE;
836}
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530837} // namespace gralloc1