blob: 3431c424f2d471faf09208dc7c0b1cd9b7d85b3c [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 Ahmeddc918132017-03-07 15:25:14 -050020#include <iomanip>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053021#include <utility>
Naseer Ahmede69031e2016-11-22 20:05:16 -050022#include <vector>
Naseer Ahmeddc918132017-03-07 15:25:14 -050023#include <sstream>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053024
25#include "qd_utils.h"
26#include "gr_priv_handle.h"
27#include "gr_buf_descriptor.h"
28#include "gr_utils.h"
29#include "gr_buf_mgr.h"
30#include "qdMetaData.h"
31
32namespace gralloc1 {
Naseer Ahmede69031e2016-11-22 20:05:16 -050033std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053034
Naseer Ahmede69031e2016-11-22 20:05:16 -050035BufferManager::BufferManager() : next_id_(0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053036 char property[PROPERTY_VALUE_MAX];
37
38 // Map framebuffer memory
39 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
40 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
41 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
42 map_fb_mem_ = true;
43 }
44
45 // Enable UBWC for framebuffer
46 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
47 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
48 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
49 ubwc_for_fb_ = true;
50 }
51
52 handles_map_.clear();
Naseer Ahmede69031e2016-11-22 20:05:16 -050053 allocator_ = new Allocator();
54 allocator_->Init();
55}
56
57
58gralloc1_error_t BufferManager::CreateBufferDescriptor(
59 gralloc1_buffer_descriptor_t *descriptor_id) {
60 std::lock_guard<std::mutex> lock(locker_);
61 auto descriptor = std::make_shared<BufferDescriptor>();
62 descriptors_map_.emplace(descriptor->GetId(), descriptor);
63 *descriptor_id = descriptor->GetId();
64 return GRALLOC1_ERROR_NONE;
65}
66
67gralloc1_error_t BufferManager::DestroyBufferDescriptor(
68 gralloc1_buffer_descriptor_t descriptor_id) {
69 std::lock_guard<std::mutex> lock(locker_);
70 const auto descriptor = descriptors_map_.find(descriptor_id);
71 if (descriptor == descriptors_map_.end()) {
72 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
73 }
74 descriptors_map_.erase(descriptor);
75 return GRALLOC1_ERROR_NONE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053076}
77
78BufferManager::~BufferManager() {
79 if (allocator_) {
80 delete allocator_;
81 }
82}
83
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053084gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
Naseer Ahmede69031e2016-11-22 20:05:16 -050085 const gralloc1_buffer_descriptor_t *descriptor_ids,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053086 buffer_handle_t *out_buffers) {
87 bool shared = true;
88 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
89
90 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
91 // client can ask to test the allocation by passing NULL out_buffers
92 bool test_allocate = !out_buffers;
93
Naseer Ahmede69031e2016-11-22 20:05:16 -050094 // Validate descriptors
95 std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
96 for (uint32_t i = 0; i < num_descriptors; i++) {
97 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
98 if (map_descriptor == descriptors_map_.end()) {
99 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
100 } else {
101 descriptors.push_back(map_descriptor->second);
102 }
103 }
104
105 // Resolve implementation defined formats
106 for (auto &descriptor : descriptors) {
107 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
108 descriptor->GetConsumerUsage(),
109 descriptor->GetFormat()));
110 }
111
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530112 // Check if input descriptors can be supported AND
113 // Find out if a single buffer can be shared for all the given input descriptors
114 uint32_t i = 0;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500115 ssize_t max_buf_index = -1;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530116 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
117
118 if (test_allocate) {
119 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
120 return status;
121 }
122
123 if (shared && (max_buf_index >= 0)) {
124 // Allocate one and duplicate/copy the handles for each descriptor
Naseer Ahmede69031e2016-11-22 20:05:16 -0500125 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530126 return GRALLOC1_ERROR_NO_RESOURCES;
127 }
128
129 for (i = 0; i < num_descriptors; i++) {
130 // Create new handle for a given descriptor.
131 // Current assumption is even MetaData memory would be same
132 // Need to revisit if there is a need for own metadata memory
133 if (i != UINT(max_buf_index)) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500134 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530135 }
136 }
137 } else {
138 // Buffer sharing is not feasible.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500139 // Allocate separate buffer for each descriptor
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530140 for (i = 0; i < num_descriptors; i++) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500141 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530142 return GRALLOC1_ERROR_NO_RESOURCES;
143 }
144 }
145 }
146
147 // Allocation is successful. If backstore is not shared inform the client.
148 if (!shared) {
149 return GRALLOC1_ERROR_NOT_SHARED;
150 }
151
152 return status;
153}
154
155void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
156 buffer_handle_t *outbuffer) {
157 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
158
159 // Get Buffer attributes or dimension
160 unsigned int alignedw = 0, alignedh = 0;
161 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
162
163 // create new handle from input reference handle and given descriptor
164 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
165 descriptor.GetConsumerUsage());
166 int buffer_type = GetBufferType(descriptor.GetFormat());
167
168 // Duplicate the fds
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700169 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
Naseer Ahmede69031e2016-11-22 20:05:16 -0500170 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
171 dup(input->fd_metadata),
172 flags,
173 INT(alignedw),
174 INT(alignedh),
175 descriptor.GetWidth(),
176 descriptor.GetHeight(),
177 descriptor.GetFormat(),
178 buffer_type,
179 input->size,
180 descriptor.GetProducerUsage(),
181 descriptor.GetConsumerUsage());
182 out_hnd->id = ++next_id_;
183 // TODO(user): Base address of shared handle and ion handles
184 auto buffer = std::make_shared<Buffer>(out_hnd);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500185 handles_map_.emplace(std::make_pair(out_hnd, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530186 *outbuffer = out_hnd;
187}
188
Naseer Ahmede69031e2016-11-22 20:05:16 -0500189gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
190 auto hnd = buf->handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530191 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500192 hnd->fd, buf->ion_handle_main) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530193 return GRALLOC1_ERROR_BAD_HANDLE;
194 }
195
196 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
197 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500198 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530199 return GRALLOC1_ERROR_BAD_HANDLE;
200 }
201
Naseer Ahmede69031e2016-11-22 20:05:16 -0500202 // TODO(user): delete handle once framework bug around this is confirmed
203 // to be resolved
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530204 return GRALLOC1_ERROR_NONE;
205}
206
207gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
208 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
209
210 hnd->base = 0;
211 hnd->base_metadata = 0;
212 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
213 hnd->fd) != 0) {
214 return GRALLOC1_ERROR_BAD_HANDLE;
215 }
216
217 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
218 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
219 hnd->offset_metadata, hnd->fd_metadata) != 0) {
220 return GRALLOC1_ERROR_BAD_HANDLE;
221 }
222
223 return GRALLOC1_ERROR_NONE;
224}
225
226gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500227 std::lock_guard<std::mutex> lock(locker_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530228
229 // find if this handle is already in map
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500230 auto it = handles_map_.find(hnd);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530231 if (it != handles_map_.end()) {
232 // It's already in map, Just increment refcnt
233 // No need to mmap the memory.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500234 auto buf = it->second;
235 buf->ref_count++;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530236 } else {
237 // not present in the map. mmap and then add entry to map
238 if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500239 auto buffer = std::make_shared<Buffer>(hnd);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500240 handles_map_.emplace(std::make_pair(hnd, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530241 }
242 }
243
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530244 return GRALLOC1_ERROR_NONE;
245}
246
247gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500248 std::lock_guard<std::mutex> lock(locker_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530249 // find if this handle is already in map
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500250 auto it = handles_map_.find(hnd);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530251 if (it == handles_map_.end()) {
252 // Corrupt handle or map.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500253 ALOGE("Could not find handle");
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530254 return GRALLOC1_ERROR_BAD_HANDLE;
255 } else {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500256 auto buf = it->second;
257 buf->ref_count--;
258 if (buf->ref_count == 0) {
259 handles_map_.erase(it);
260 FreeBuffer(buf);
261 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530262 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530263 return GRALLOC1_ERROR_NONE;
264}
265
266gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
267 gralloc1_producer_usage_t prod_usage,
268 gralloc1_consumer_usage_t cons_usage) {
269 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
270
271 // If buffer is not meant for CPU return err
272 if (!CpuCanAccess(prod_usage, cons_usage)) {
273 return GRALLOC1_ERROR_BAD_VALUE;
274 }
275
276 if (hnd->base == 0) {
277 // we need to map for real
278 locker_.lock();
279 err = MapBuffer(hnd);
280 locker_.unlock();
281 }
282
283 // Invalidate if CPU reads in software and there are non-CPU
284 // writers. No need to do this for the metadata buffer as it is
285 // only read/written in software.
286 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
287 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
288 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
289 hnd->fd, CACHE_INVALIDATE)) {
290 return GRALLOC1_ERROR_BAD_HANDLE;
291 }
292 }
293
294 // Mark the buffer to be flushed after CPU write.
295 if (!err && CpuCanWrite(prod_usage)) {
296 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
297 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
298 }
299
300 return err;
301}
302
303gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
304 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
305
306 locker_.lock();
307 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
308
309 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
310 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
311 hnd->fd, CACHE_CLEAN) != 0) {
312 status = GRALLOC1_ERROR_BAD_HANDLE;
313 }
314 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
315 }
316
317 locker_.unlock();
318 return status;
319}
320
Naseer Ahmede69031e2016-11-22 20:05:16 -0500321uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530322 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500323 uint32_t align = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530324 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
325 align = 8192;
326 }
327
328 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700329 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
330 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530331 // The alignment here reflects qsee mmu V7L/V8L requirement
332 align = SZ_2M;
333 } else {
334 align = SECURE_ALIGN;
335 }
336 }
337
338 return align;
339}
340
341int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
342 gralloc1_consumer_usage_t cons_usage) {
343 int flags = 0;
344 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
345 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
346 }
347
348 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
349 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
350 }
351
352 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
353 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
354 }
355
356 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
357 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
358 }
359
360 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
361 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
362 }
363
364 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
365 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
366 }
367
368 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
369 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
370 }
371
372 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
373 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
374 }
375
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530376 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
377 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
378 }
379
380 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
381 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
382 }
383
384 // TODO(user): is this correct???
385 if ((cons_usage &
386 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
387 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
388 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
389 }
390
391 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
392 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
393 }
394
395 if (!allocator_->UseUncached(prod_usage)) {
396 flags |= private_handle_t::PRIV_FLAGS_CACHED;
397 }
398
399 return flags;
400}
401
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700402int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
403 int unaligned_h, int format, int bufferType,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530404 gralloc1_producer_usage_t prod_usage,
405 gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500406 auto page_size = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530407 int err = 0;
408 int flags = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530409 AllocData data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500410 data.align = GetDataAlignment(format, prod_usage, cons_usage);
411 data.size = ALIGN(size, data.align);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530412 data.handle = (uintptr_t)handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530413 data.uncached = allocator_->UseUncached(prod_usage);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500414
415 // Allocate buffer memory
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530416 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
417 if (err) {
418 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530419 return err;
420 }
421
Naseer Ahmede69031e2016-11-22 20:05:16 -0500422 // Allocate memory for MetaData
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530423 AllocData e_data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500424 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530425 e_data.handle = data.handle;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500426 e_data.align = page_size;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530427
428 err =
429 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500430 if (err) {
431 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
432 return err;
433 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530434
435 flags = GetHandleFlags(format, prod_usage, cons_usage);
436 flags |= data.alloc_type;
437
438 // Create handle
Naseer Ahmede69031e2016-11-22 20:05:16 -0500439 private_handle_t *hnd = new private_handle_t(data.fd,
440 e_data.fd,
441 flags,
442 aligned_w,
443 aligned_h,
444 unaligned_w,
445 unaligned_h,
446 format,
447 bufferType,
448 size,
449 prod_usage,
450 cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530451
Naseer Ahmede69031e2016-11-22 20:05:16 -0500452 hnd->id = ++next_id_;
453 hnd->base = reinterpret_cast<uint64_t >(data.base);
454 hnd->base_metadata = reinterpret_cast<uint64_t >(e_data.base);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530455
Naseer Ahmede69031e2016-11-22 20:05:16 -0500456 ColorSpace_t colorSpace = ITU_R_601;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530457 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530458 *handle = hnd;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500459 auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle);
Naseer Ahmedef287dc2017-03-11 23:48:43 -0500460 handles_map_.emplace(std::make_pair(hnd, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530461 return err;
462}
463
464int BufferManager::GetBufferType(int inputFormat) {
465 int buffer_type = BUFFER_TYPE_VIDEO;
466 if (IsUncompressedRGBFormat(inputFormat)) {
467 // RGB formats
468 buffer_type = BUFFER_TYPE_UI;
469 }
470
471 return buffer_type;
472}
473
474int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
475 unsigned int bufferSize) {
476 if (!handle)
477 return -EINVAL;
478
479 int format = descriptor.GetFormat();
480 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
481 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
482
483 // Get implementation defined format
484 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
485
486 bool use_fb_mem = false;
487 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
488 use_fb_mem = true;
489 }
490
491 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
492 prod_usage =
493 (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
494 }
495
496 unsigned int size;
497 unsigned int alignedw, alignedh;
498 int buffer_type = GetBufferType(gralloc_format);
499 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
500
501 size = (bufferSize >= size) ? bufferSize : size;
502
503 int err = 0;
504 if (use_fb_mem) {
505 // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
506 } else {
507 err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
508 descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
509 descriptor.GetConsumerUsage(), handle);
510 }
511
512 if (err < 0) {
513 return err;
514 }
515
516 return 0;
517}
518
519gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
520 switch (operation) {
521 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
522 int fd = va_arg(args, int);
523 unsigned int size = va_arg(args, unsigned int);
524 unsigned int offset = va_arg(args, unsigned int);
525 void *base = va_arg(args, void *);
526 int width = va_arg(args, int);
527 int height = va_arg(args, int);
528 int format = va_arg(args, int);
529
530 native_handle_t **handle = va_arg(args, native_handle_t **);
531 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
532 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
533 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700534 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530535 hnd->magic = private_handle_t::kMagic;
536 hnd->fd = fd;
537 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
538 hnd->size = size;
539 hnd->offset = offset;
540 hnd->base = uint64_t(base) + offset;
541 hnd->gpuaddr = 0;
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700542 BufferDescriptor descriptor(width, height, format);
543 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
544 hnd->unaligned_width = width;
545 hnd->unaligned_height = height;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500546 hnd->width = INT(alignedw);
547 hnd->height = INT(alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530548 hnd->format = format;
549 *handle = reinterpret_cast<native_handle_t *>(hnd);
550 }
551 } break;
552
553 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
554 int width = va_arg(args, int);
555 int format = va_arg(args, int);
556 int *stride = va_arg(args, int *);
557 unsigned int alignedw = 0, alignedh = 0;
558 BufferDescriptor descriptor(width, width, format);
559 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
560 *stride = INT(alignedw);
561 } break;
562
563 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
564 private_handle_t *hnd = va_arg(args, private_handle_t *);
565 int *stride = va_arg(args, int *);
566 if (private_handle_t::validate(hnd) != 0) {
567 return GRALLOC1_ERROR_BAD_HANDLE;
568 }
569
570 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
571 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
572 *stride = metadata->bufferDim.sliceWidth;
573 } else {
574 *stride = hnd->width;
575 }
576 } break;
577
578 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
579 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
580 private_handle_t *hnd = va_arg(args, private_handle_t *);
581 int *stride = va_arg(args, int *);
582 int *height = va_arg(args, int *);
583 if (private_handle_t::validate(hnd) != 0) {
584 return GRALLOC1_ERROR_BAD_HANDLE;
585 }
586
587 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
588 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
589 *stride = metadata->bufferDim.sliceWidth;
590 *height = metadata->bufferDim.sliceHeight;
591 } else {
592 *stride = hnd->width;
593 *height = hnd->height;
594 }
595 } break;
596
597 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
598 // TODO(user): Usage is split now. take care of it from Gfx client.
599 // see if we can directly expect descriptor from gfx client.
600 int width = va_arg(args, int);
601 int height = va_arg(args, int);
602 int format = va_arg(args, int);
603 uint64_t producer_usage = va_arg(args, uint64_t);
604 uint64_t consumer_usage = va_arg(args, uint64_t);
605 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
606 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
607
608 int *aligned_width = va_arg(args, int *);
609 int *aligned_height = va_arg(args, int *);
610 int *tile_enabled = va_arg(args, int *);
611 unsigned int alignedw, alignedh;
612 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
Saurabh Shahc5b2b702016-10-24 17:16:01 -0700613 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530614
615 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
616 *aligned_width = INT(alignedw);
617 *aligned_height = INT(alignedh);
618 } break;
619
620 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
621 private_handle_t *hnd = va_arg(args, private_handle_t *);
622 int *color_space = va_arg(args, int *);
623 if (private_handle_t::validate(hnd) != 0) {
624 return GRALLOC1_ERROR_BAD_HANDLE;
625 }
626 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700627 if (!metadata) {
628 return GRALLOC1_ERROR_BAD_HANDLE;
629#ifdef USE_COLOR_METADATA
630 } else if (metadata->operation & COLOR_METADATA) {
631 ColorMetaData *colorMetadata = &metadata->color;
632 switch (colorMetadata->colorPrimaries) {
633 case ColorPrimaries_BT709_5:
634 *color_space = HAL_CSC_ITU_R_709;
635 break;
636 case ColorPrimaries_BT601_6_525:
637 *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
638 break;
639 case ColorPrimaries_BT2020:
640 *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
641 break;
642 default:
643 ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
644 break;
645 }
646#endif
647 } else if (metadata->operation & UPDATE_COLOR_SPACE) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530648 *color_space = metadata->colorSpace;
649 }
650 } break;
651 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
652 private_handle_t *hnd = va_arg(args, private_handle_t *);
653 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
654 if (private_handle_t::validate(hnd) != 0) {
655 return GRALLOC1_ERROR_BAD_HANDLE;
656 }
657 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
658 return GRALLOC1_ERROR_UNDEFINED;
659 }
660 } break;
661
662 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
663 private_handle_t *hnd = va_arg(args, private_handle_t *);
664 int *map_secure_buffer = va_arg(args, int *);
665 if (private_handle_t::validate(hnd) != 0) {
666 return GRALLOC1_ERROR_BAD_HANDLE;
667 }
668 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
669 if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
670 *map_secure_buffer = metadata->mapSecureBuffer;
671 } else {
672 *map_secure_buffer = 0;
673 }
674 } break;
675
676 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
677 private_handle_t *hnd = va_arg(args, private_handle_t *);
678 int *flag = va_arg(args, int *);
679 if (private_handle_t::validate(hnd) != 0) {
680 return GRALLOC1_ERROR_BAD_HANDLE;
681 }
682 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
683 } break;
684
685 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
686 private_handle_t *hnd = va_arg(args, private_handle_t *);
687 void **rgb_data = va_arg(args, void **);
688 if (private_handle_t::validate(hnd) != 0) {
689 return GRALLOC1_ERROR_BAD_HANDLE;
690 }
691 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
692 return GRALLOC1_ERROR_UNDEFINED;
693 }
694 } break;
695
Naseer Ahmede69031e2016-11-22 20:05:16 -0500696 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
697 int width = va_arg(args, int);
698 int height = va_arg(args, int);
699 int format = va_arg(args, int);
700 uint64_t p_usage = va_arg(args, uint64_t);
701 uint64_t c_usage = va_arg(args, uint64_t);
702 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
703 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
704 uint32_t *aligned_width = va_arg(args, uint32_t *);
705 uint32_t *aligned_height = va_arg(args, uint32_t *);
706 uint32_t *size = va_arg(args, uint32_t *);
707 auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
708 allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
709 // Align size
710 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
711 *size = ALIGN(*size, align);
712 } break;
713
714 // TODO(user): Break out similar functionality, preferably moving to a common lib.
715
716 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
717 int width = va_arg(args, int);
718 int height = va_arg(args, int);
719 int format = va_arg(args, int);
720 uint64_t p_usage = va_arg(args, uint64_t);
721 uint64_t c_usage = va_arg(args, uint64_t);
722 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
723 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
724 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
725 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
726 unsigned int size;
727 unsigned int alignedw, alignedh;
728 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
729 AllocateBuffer(descriptor, hnd, size);
730 } break;
731
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530732 default:
733 break;
734 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530735 return GRALLOC1_ERROR_NONE;
736}
737
Naseer Ahmede69031e2016-11-22 20:05:16 -0500738static bool IsYuvFormat(const private_handle_t *hnd) {
739 switch (hnd->format) {
740 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
741 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
742 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
743 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
744 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
745 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
746 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
747 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
748 case HAL_PIXEL_FORMAT_NV21_ZSL:
749 case HAL_PIXEL_FORMAT_RAW16:
750 case HAL_PIXEL_FORMAT_RAW10:
751 case HAL_PIXEL_FORMAT_YV12:
752 return true;
753 default:
754 return false;
755 }
756}
757
758gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
759 uint32_t *out_num_planes) {
760 if (!IsYuvFormat(hnd)) {
761 return GRALLOC1_ERROR_UNSUPPORTED;
762 } else {
763 *out_num_planes = 3;
764 }
765 return GRALLOC1_ERROR_NONE;
766}
767
768gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
769 struct android_flex_layout *layout) {
770 if (!IsYuvFormat(hnd)) {
771 return GRALLOC1_ERROR_UNSUPPORTED;
772 }
773
774 android_ycbcr ycbcr;
775 int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
776
777 if (err != 0) {
778 return GRALLOC1_ERROR_BAD_HANDLE;
779 }
780
781 layout->format = FLEX_FORMAT_YCbCr;
782 layout->num_planes = 3;
783
784 for (uint32_t i = 0; i < layout->num_planes; i++) {
785 layout->planes[i].bits_per_component = 8;
786 layout->planes[i].bits_used = 8;
787 layout->planes[i].h_increment = 1;
788 layout->planes[i].v_increment = 1;
789 layout->planes[i].h_subsampling = 2;
790 layout->planes[i].v_subsampling = 2;
791 }
792
793 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
794 layout->planes[0].component = FLEX_COMPONENT_Y;
795 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
796
797 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
798 layout->planes[1].component = FLEX_COMPONENT_Cb;
799 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
800 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
801
802 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
803 layout->planes[2].component = FLEX_COMPONENT_Cr;
804 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
805 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
806 return GRALLOC1_ERROR_NONE;
807}
Naseer Ahmeddc918132017-03-07 15:25:14 -0500808
809gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
810 for (auto it : handles_map_) {
811 auto buf = it.second;
812 auto hnd = buf->handle;
813 *os << "handle id: " << std::setw(4) << hnd->id;
814 *os << " fd: " << std::setw(3) << hnd->fd;
815 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
816 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
817 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
818 *os << std::setw(4) << hnd->unaligned_height;
819 *os << " size: " << std::setw(9) << hnd->size;
820 *os << std::hex << std::setfill('0');
821 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
822 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
823 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
824 // TODO(user): get format string from qdutils
825 *os << " format: " << "0x" << std::setw(8) << hnd->format;
826 *os << std::dec << std::setfill(' ') << std::endl;
827 }
828 return GRALLOC1_ERROR_NONE;
829}
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530830} // namespace gralloc1