blob: 51166d8b629b7731f380b5a52f6d128b957158a2 [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
20#include <utility>
Naseer Ahmede69031e2016-11-22 20:05:16 -050021#include <vector>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053022
23#include "qd_utils.h"
24#include "gr_priv_handle.h"
25#include "gr_buf_descriptor.h"
26#include "gr_utils.h"
27#include "gr_buf_mgr.h"
28#include "qdMetaData.h"
29
30namespace gralloc1 {
Naseer Ahmede69031e2016-11-22 20:05:16 -050031std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053032
Naseer Ahmede69031e2016-11-22 20:05:16 -050033BufferManager::BufferManager() : next_id_(0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053034 char property[PROPERTY_VALUE_MAX];
35
36 // Map framebuffer memory
37 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
38 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
39 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
40 map_fb_mem_ = true;
41 }
42
43 // Enable UBWC for framebuffer
44 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
45 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
46 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
47 ubwc_for_fb_ = true;
48 }
49
50 handles_map_.clear();
Naseer Ahmede69031e2016-11-22 20:05:16 -050051 allocator_ = new Allocator();
52 allocator_->Init();
53}
54
55
56gralloc1_error_t BufferManager::CreateBufferDescriptor(
57 gralloc1_buffer_descriptor_t *descriptor_id) {
58 std::lock_guard<std::mutex> lock(locker_);
59 auto descriptor = std::make_shared<BufferDescriptor>();
60 descriptors_map_.emplace(descriptor->GetId(), descriptor);
61 *descriptor_id = descriptor->GetId();
62 return GRALLOC1_ERROR_NONE;
63}
64
65gralloc1_error_t BufferManager::DestroyBufferDescriptor(
66 gralloc1_buffer_descriptor_t descriptor_id) {
67 std::lock_guard<std::mutex> lock(locker_);
68 const auto descriptor = descriptors_map_.find(descriptor_id);
69 if (descriptor == descriptors_map_.end()) {
70 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
71 }
72 descriptors_map_.erase(descriptor);
73 return GRALLOC1_ERROR_NONE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053074}
75
76BufferManager::~BufferManager() {
77 if (allocator_) {
78 delete allocator_;
79 }
80}
81
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053082gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
Naseer Ahmede69031e2016-11-22 20:05:16 -050083 const gralloc1_buffer_descriptor_t *descriptor_ids,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053084 buffer_handle_t *out_buffers) {
85 bool shared = true;
86 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
87
88 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
89 // client can ask to test the allocation by passing NULL out_buffers
90 bool test_allocate = !out_buffers;
91
Naseer Ahmede69031e2016-11-22 20:05:16 -050092 // Validate descriptors
93 std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
94 for (uint32_t i = 0; i < num_descriptors; i++) {
95 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
96 if (map_descriptor == descriptors_map_.end()) {
97 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
98 } else {
99 descriptors.push_back(map_descriptor->second);
100 }
101 }
102
103 // Resolve implementation defined formats
104 for (auto &descriptor : descriptors) {
105 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
106 descriptor->GetConsumerUsage(),
107 descriptor->GetFormat()));
108 }
109
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530110 // Check if input descriptors can be supported AND
111 // Find out if a single buffer can be shared for all the given input descriptors
112 uint32_t i = 0;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500113 ssize_t max_buf_index = -1;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530114 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
115
116 if (test_allocate) {
117 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
118 return status;
119 }
120
121 if (shared && (max_buf_index >= 0)) {
122 // Allocate one and duplicate/copy the handles for each descriptor
Naseer Ahmede69031e2016-11-22 20:05:16 -0500123 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530124 return GRALLOC1_ERROR_NO_RESOURCES;
125 }
126
127 for (i = 0; i < num_descriptors; i++) {
128 // Create new handle for a given descriptor.
129 // Current assumption is even MetaData memory would be same
130 // Need to revisit if there is a need for own metadata memory
131 if (i != UINT(max_buf_index)) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500132 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530133 }
134 }
135 } else {
136 // Buffer sharing is not feasible.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500137 // Allocate separate buffer for each descriptor
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530138 for (i = 0; i < num_descriptors; i++) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500139 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530140 return GRALLOC1_ERROR_NO_RESOURCES;
141 }
142 }
143 }
144
145 // Allocation is successful. If backstore is not shared inform the client.
146 if (!shared) {
147 return GRALLOC1_ERROR_NOT_SHARED;
148 }
149
150 return status;
151}
152
153void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
154 buffer_handle_t *outbuffer) {
155 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
156
157 // Get Buffer attributes or dimension
158 unsigned int alignedw = 0, alignedh = 0;
159 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
160
161 // create new handle from input reference handle and given descriptor
162 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
163 descriptor.GetConsumerUsage());
164 int buffer_type = GetBufferType(descriptor.GetFormat());
165
166 // Duplicate the fds
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700167 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
Naseer Ahmede69031e2016-11-22 20:05:16 -0500168 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
169 dup(input->fd_metadata),
170 flags,
171 INT(alignedw),
172 INT(alignedh),
173 descriptor.GetWidth(),
174 descriptor.GetHeight(),
175 descriptor.GetFormat(),
176 buffer_type,
177 input->size,
178 descriptor.GetProducerUsage(),
179 descriptor.GetConsumerUsage());
180 out_hnd->id = ++next_id_;
181 // TODO(user): Base address of shared handle and ion handles
182 auto buffer = std::make_shared<Buffer>(out_hnd);
183 handles_map_.emplace(std::make_pair(out_hnd->id, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530184 *outbuffer = out_hnd;
185}
186
Naseer Ahmede69031e2016-11-22 20:05:16 -0500187gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
188 auto hnd = buf->handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530189 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500190 hnd->fd, buf->ion_handle_main) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530191 return GRALLOC1_ERROR_BAD_HANDLE;
192 }
193
194 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
195 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500196 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530197 return GRALLOC1_ERROR_BAD_HANDLE;
198 }
199
Naseer Ahmede69031e2016-11-22 20:05:16 -0500200 // TODO(user): delete handle once framework bug around this is confirmed
201 // to be resolved
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530202 return GRALLOC1_ERROR_NONE;
203}
204
205gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
206 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
207
208 hnd->base = 0;
209 hnd->base_metadata = 0;
210 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
211 hnd->fd) != 0) {
212 return GRALLOC1_ERROR_BAD_HANDLE;
213 }
214
215 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
216 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
217 hnd->offset_metadata, hnd->fd_metadata) != 0) {
218 return GRALLOC1_ERROR_BAD_HANDLE;
219 }
220
221 return GRALLOC1_ERROR_NONE;
222}
223
224gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500225 std::lock_guard<std::mutex> lock(locker_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530226
227 // find if this handle is already in map
Naseer Ahmede69031e2016-11-22 20:05:16 -0500228 auto it = handles_map_.find(hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530229 if (it != handles_map_.end()) {
230 // It's already in map, Just increment refcnt
231 // No need to mmap the memory.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500232 auto buf = it->second;
233 buf->ref_count++;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530234 } else {
235 // not present in the map. mmap and then add entry to map
236 if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500237 auto buffer = std::make_shared<Buffer>(hnd);
238 handles_map_.emplace(std::make_pair(hnd->id, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530239 }
240 }
241
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530242 return GRALLOC1_ERROR_NONE;
243}
244
245gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500246 std::lock_guard<std::mutex> lock(locker_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530247 // find if this handle is already in map
Naseer Ahmede69031e2016-11-22 20:05:16 -0500248 auto it = handles_map_.find(hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530249 if (it == handles_map_.end()) {
250 // Corrupt handle or map.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500251 ALOGE("Could not find handle");
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530252 return GRALLOC1_ERROR_BAD_HANDLE;
253 } else {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500254 auto buf = it->second;
255 buf->ref_count--;
256 if (buf->ref_count == 0) {
257 handles_map_.erase(it);
258 FreeBuffer(buf);
259 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530260 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530261 return GRALLOC1_ERROR_NONE;
262}
263
264gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
265 gralloc1_producer_usage_t prod_usage,
266 gralloc1_consumer_usage_t cons_usage) {
267 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
268
269 // If buffer is not meant for CPU return err
270 if (!CpuCanAccess(prod_usage, cons_usage)) {
271 return GRALLOC1_ERROR_BAD_VALUE;
272 }
273
274 if (hnd->base == 0) {
275 // we need to map for real
276 locker_.lock();
277 err = MapBuffer(hnd);
278 locker_.unlock();
279 }
280
281 // Invalidate if CPU reads in software and there are non-CPU
282 // writers. No need to do this for the metadata buffer as it is
283 // only read/written in software.
284 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
285 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
286 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
287 hnd->fd, CACHE_INVALIDATE)) {
288 return GRALLOC1_ERROR_BAD_HANDLE;
289 }
290 }
291
292 // Mark the buffer to be flushed after CPU write.
293 if (!err && CpuCanWrite(prod_usage)) {
294 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
295 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
296 }
297
298 return err;
299}
300
301gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
302 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
303
304 locker_.lock();
305 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
306
307 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
308 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
309 hnd->fd, CACHE_CLEAN) != 0) {
310 status = GRALLOC1_ERROR_BAD_HANDLE;
311 }
312 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
313 }
314
315 locker_.unlock();
316 return status;
317}
318
Naseer Ahmede69031e2016-11-22 20:05:16 -0500319uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530320 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500321 uint32_t align = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530322 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
323 align = 8192;
324 }
325
326 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700327 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
328 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530329 // The alignment here reflects qsee mmu V7L/V8L requirement
330 align = SZ_2M;
331 } else {
332 align = SECURE_ALIGN;
333 }
334 }
335
336 return align;
337}
338
339int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
340 gralloc1_consumer_usage_t cons_usage) {
341 int flags = 0;
342 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
343 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
344 }
345
346 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
347 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
348 }
349
350 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
351 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
352 }
353
354 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
355 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
356 }
357
358 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
359 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
360 }
361
362 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
363 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
364 }
365
366 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
367 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
368 }
369
370 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
371 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
372 }
373
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530374 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
375 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
376 }
377
378 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
379 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
380 }
381
382 // TODO(user): is this correct???
383 if ((cons_usage &
384 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
385 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
386 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
387 }
388
389 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
390 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
391 }
392
393 if (!allocator_->UseUncached(prod_usage)) {
394 flags |= private_handle_t::PRIV_FLAGS_CACHED;
395 }
396
397 return flags;
398}
399
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700400int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
401 int unaligned_h, int format, int bufferType,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530402 gralloc1_producer_usage_t prod_usage,
403 gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500404 auto page_size = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530405 int err = 0;
406 int flags = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530407 AllocData data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500408 data.align = GetDataAlignment(format, prod_usage, cons_usage);
409 data.size = ALIGN(size, data.align);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530410 data.handle = (uintptr_t)handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530411 data.uncached = allocator_->UseUncached(prod_usage);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500412
413 // Allocate buffer memory
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530414 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
415 if (err) {
416 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530417 return err;
418 }
419
Naseer Ahmede69031e2016-11-22 20:05:16 -0500420 // Allocate memory for MetaData
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530421 AllocData e_data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500422 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530423 e_data.handle = data.handle;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500424 e_data.align = page_size;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530425
426 err =
427 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500428 if (err) {
429 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
430 return err;
431 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530432
433 flags = GetHandleFlags(format, prod_usage, cons_usage);
434 flags |= data.alloc_type;
435
436 // Create handle
Naseer Ahmede69031e2016-11-22 20:05:16 -0500437 private_handle_t *hnd = new private_handle_t(data.fd,
438 e_data.fd,
439 flags,
440 aligned_w,
441 aligned_h,
442 unaligned_w,
443 unaligned_h,
444 format,
445 bufferType,
446 size,
447 prod_usage,
448 cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530449
Naseer Ahmede69031e2016-11-22 20:05:16 -0500450 hnd->id = ++next_id_;
451 hnd->base = reinterpret_cast<uint64_t >(data.base);
452 hnd->base_metadata = reinterpret_cast<uint64_t >(e_data.base);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530453
Naseer Ahmede69031e2016-11-22 20:05:16 -0500454 ColorSpace_t colorSpace = ITU_R_601;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530455 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530456 *handle = hnd;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500457 auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle);
458 handles_map_.emplace(std::make_pair(hnd->id, buffer));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530459 return err;
460}
461
462int BufferManager::GetBufferType(int inputFormat) {
463 int buffer_type = BUFFER_TYPE_VIDEO;
464 if (IsUncompressedRGBFormat(inputFormat)) {
465 // RGB formats
466 buffer_type = BUFFER_TYPE_UI;
467 }
468
469 return buffer_type;
470}
471
472int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
473 unsigned int bufferSize) {
474 if (!handle)
475 return -EINVAL;
476
477 int format = descriptor.GetFormat();
478 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
479 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
480
481 // Get implementation defined format
482 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
483
484 bool use_fb_mem = false;
485 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
486 use_fb_mem = true;
487 }
488
489 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
490 prod_usage =
491 (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
492 }
493
494 unsigned int size;
495 unsigned int alignedw, alignedh;
496 int buffer_type = GetBufferType(gralloc_format);
497 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
498
499 size = (bufferSize >= size) ? bufferSize : size;
500
501 int err = 0;
502 if (use_fb_mem) {
503 // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
504 } else {
505 err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
506 descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
507 descriptor.GetConsumerUsage(), handle);
508 }
509
510 if (err < 0) {
511 return err;
512 }
513
514 return 0;
515}
516
517gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
518 switch (operation) {
519 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
520 int fd = va_arg(args, int);
521 unsigned int size = va_arg(args, unsigned int);
522 unsigned int offset = va_arg(args, unsigned int);
523 void *base = va_arg(args, void *);
524 int width = va_arg(args, int);
525 int height = va_arg(args, int);
526 int format = va_arg(args, int);
527
528 native_handle_t **handle = va_arg(args, native_handle_t **);
529 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
530 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
531 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700532 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530533 hnd->magic = private_handle_t::kMagic;
534 hnd->fd = fd;
535 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
536 hnd->size = size;
537 hnd->offset = offset;
538 hnd->base = uint64_t(base) + offset;
539 hnd->gpuaddr = 0;
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700540 BufferDescriptor descriptor(width, height, format);
541 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
542 hnd->unaligned_width = width;
543 hnd->unaligned_height = height;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500544 hnd->width = INT(alignedw);
545 hnd->height = INT(alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530546 hnd->format = format;
547 *handle = reinterpret_cast<native_handle_t *>(hnd);
548 }
549 } break;
550
551 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
552 int width = va_arg(args, int);
553 int format = va_arg(args, int);
554 int *stride = va_arg(args, int *);
555 unsigned int alignedw = 0, alignedh = 0;
556 BufferDescriptor descriptor(width, width, format);
557 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
558 *stride = INT(alignedw);
559 } break;
560
561 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
562 private_handle_t *hnd = va_arg(args, private_handle_t *);
563 int *stride = va_arg(args, int *);
564 if (private_handle_t::validate(hnd) != 0) {
565 return GRALLOC1_ERROR_BAD_HANDLE;
566 }
567
568 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
569 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
570 *stride = metadata->bufferDim.sliceWidth;
571 } else {
572 *stride = hnd->width;
573 }
574 } break;
575
576 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
577 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
578 private_handle_t *hnd = va_arg(args, private_handle_t *);
579 int *stride = va_arg(args, int *);
580 int *height = va_arg(args, int *);
581 if (private_handle_t::validate(hnd) != 0) {
582 return GRALLOC1_ERROR_BAD_HANDLE;
583 }
584
585 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
586 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
587 *stride = metadata->bufferDim.sliceWidth;
588 *height = metadata->bufferDim.sliceHeight;
589 } else {
590 *stride = hnd->width;
591 *height = hnd->height;
592 }
593 } break;
594
595 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
596 // TODO(user): Usage is split now. take care of it from Gfx client.
597 // see if we can directly expect descriptor from gfx client.
598 int width = va_arg(args, int);
599 int height = va_arg(args, int);
600 int format = va_arg(args, int);
601 uint64_t producer_usage = va_arg(args, uint64_t);
602 uint64_t consumer_usage = va_arg(args, uint64_t);
603 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
604 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
605
606 int *aligned_width = va_arg(args, int *);
607 int *aligned_height = va_arg(args, int *);
608 int *tile_enabled = va_arg(args, int *);
609 unsigned int alignedw, alignedh;
610 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
Saurabh Shahc5b2b702016-10-24 17:16:01 -0700611 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530612
613 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
614 *aligned_width = INT(alignedw);
615 *aligned_height = INT(alignedh);
616 } break;
617
618 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
619 private_handle_t *hnd = va_arg(args, private_handle_t *);
620 int *color_space = va_arg(args, int *);
621 if (private_handle_t::validate(hnd) != 0) {
622 return GRALLOC1_ERROR_BAD_HANDLE;
623 }
624 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700625 if (!metadata) {
626 return GRALLOC1_ERROR_BAD_HANDLE;
627#ifdef USE_COLOR_METADATA
628 } else if (metadata->operation & COLOR_METADATA) {
629 ColorMetaData *colorMetadata = &metadata->color;
630 switch (colorMetadata->colorPrimaries) {
631 case ColorPrimaries_BT709_5:
632 *color_space = HAL_CSC_ITU_R_709;
633 break;
634 case ColorPrimaries_BT601_6_525:
635 *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
636 break;
637 case ColorPrimaries_BT2020:
638 *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
639 break;
640 default:
641 ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
642 break;
643 }
644#endif
645 } else if (metadata->operation & UPDATE_COLOR_SPACE) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530646 *color_space = metadata->colorSpace;
647 }
648 } break;
649 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
650 private_handle_t *hnd = va_arg(args, private_handle_t *);
651 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
652 if (private_handle_t::validate(hnd) != 0) {
653 return GRALLOC1_ERROR_BAD_HANDLE;
654 }
655 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
656 return GRALLOC1_ERROR_UNDEFINED;
657 }
658 } break;
659
660 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
661 private_handle_t *hnd = va_arg(args, private_handle_t *);
662 int *map_secure_buffer = va_arg(args, int *);
663 if (private_handle_t::validate(hnd) != 0) {
664 return GRALLOC1_ERROR_BAD_HANDLE;
665 }
666 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
667 if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
668 *map_secure_buffer = metadata->mapSecureBuffer;
669 } else {
670 *map_secure_buffer = 0;
671 }
672 } break;
673
674 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
675 private_handle_t *hnd = va_arg(args, private_handle_t *);
676 int *flag = va_arg(args, int *);
677 if (private_handle_t::validate(hnd) != 0) {
678 return GRALLOC1_ERROR_BAD_HANDLE;
679 }
680 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
681 } break;
682
683 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
684 private_handle_t *hnd = va_arg(args, private_handle_t *);
685 void **rgb_data = va_arg(args, void **);
686 if (private_handle_t::validate(hnd) != 0) {
687 return GRALLOC1_ERROR_BAD_HANDLE;
688 }
689 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
690 return GRALLOC1_ERROR_UNDEFINED;
691 }
692 } break;
693
Naseer Ahmede69031e2016-11-22 20:05:16 -0500694 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
695 int width = va_arg(args, int);
696 int height = va_arg(args, int);
697 int format = va_arg(args, int);
698 uint64_t p_usage = va_arg(args, uint64_t);
699 uint64_t c_usage = va_arg(args, uint64_t);
700 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
701 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
702 uint32_t *aligned_width = va_arg(args, uint32_t *);
703 uint32_t *aligned_height = va_arg(args, uint32_t *);
704 uint32_t *size = va_arg(args, uint32_t *);
705 auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
706 allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
707 // Align size
708 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
709 *size = ALIGN(*size, align);
710 } break;
711
712 // TODO(user): Break out similar functionality, preferably moving to a common lib.
713
714 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
715 int width = va_arg(args, int);
716 int height = va_arg(args, int);
717 int format = va_arg(args, int);
718 uint64_t p_usage = va_arg(args, uint64_t);
719 uint64_t c_usage = va_arg(args, uint64_t);
720 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
721 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
722 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
723 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
724 unsigned int size;
725 unsigned int alignedw, alignedh;
726 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
727 AllocateBuffer(descriptor, hnd, size);
728 } break;
729
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530730 default:
731 break;
732 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530733 return GRALLOC1_ERROR_NONE;
734}
735
Naseer Ahmede69031e2016-11-22 20:05:16 -0500736static bool IsYuvFormat(const private_handle_t *hnd) {
737 switch (hnd->format) {
738 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
739 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
740 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
741 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
742 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
743 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
744 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
745 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
746 case HAL_PIXEL_FORMAT_NV21_ZSL:
747 case HAL_PIXEL_FORMAT_RAW16:
748 case HAL_PIXEL_FORMAT_RAW10:
749 case HAL_PIXEL_FORMAT_YV12:
750 return true;
751 default:
752 return false;
753 }
754}
755
756gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
757 uint32_t *out_num_planes) {
758 if (!IsYuvFormat(hnd)) {
759 return GRALLOC1_ERROR_UNSUPPORTED;
760 } else {
761 *out_num_planes = 3;
762 }
763 return GRALLOC1_ERROR_NONE;
764}
765
766gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
767 struct android_flex_layout *layout) {
768 if (!IsYuvFormat(hnd)) {
769 return GRALLOC1_ERROR_UNSUPPORTED;
770 }
771
772 android_ycbcr ycbcr;
773 int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
774
775 if (err != 0) {
776 return GRALLOC1_ERROR_BAD_HANDLE;
777 }
778
779 layout->format = FLEX_FORMAT_YCbCr;
780 layout->num_planes = 3;
781
782 for (uint32_t i = 0; i < layout->num_planes; i++) {
783 layout->planes[i].bits_per_component = 8;
784 layout->planes[i].bits_used = 8;
785 layout->planes[i].h_increment = 1;
786 layout->planes[i].v_increment = 1;
787 layout->planes[i].h_subsampling = 2;
788 layout->planes[i].v_subsampling = 2;
789 }
790
791 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
792 layout->planes[0].component = FLEX_COMPONENT_Y;
793 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
794
795 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
796 layout->planes[1].component = FLEX_COMPONENT_Cb;
797 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
798 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
799
800 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
801 layout->planes[2].component = FLEX_COMPONENT_Cr;
802 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
803 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
804 return GRALLOC1_ERROR_NONE;
805}
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530806} // namespace gralloc1