blob: 35c4b02e139a1b4652753d03670538b5405b2b73 [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
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070021
Naseer Ahmeddc918132017-03-07 15:25:14 -050022#include <iomanip>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053023#include <utility>
Naseer Ahmede69031e2016-11-22 20:05:16 -050024#include <vector>
Naseer Ahmeddc918132017-03-07 15:25:14 -050025#include <sstream>
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053026
27#include "qd_utils.h"
28#include "gr_priv_handle.h"
29#include "gr_buf_descriptor.h"
30#include "gr_utils.h"
31#include "gr_buf_mgr.h"
32#include "qdMetaData.h"
33
34namespace gralloc1 {
Naseer Ahmede69031e2016-11-22 20:05:16 -050035std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053036
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070037static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
38 return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
39 descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
40}
41
Naseer Ahmede69031e2016-11-22 20:05:16 -050042BufferManager::BufferManager() : next_id_(0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053043 char property[PROPERTY_VALUE_MAX];
44
45 // Map framebuffer memory
46 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
47 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
48 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
49 map_fb_mem_ = true;
50 }
51
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053052 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) {
Naseer Ahmed378d8582017-03-28 21:56:08 -040060 std::lock_guard<std::mutex> lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -050061 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) {
Naseer Ahmed378d8582017-03-28 21:56:08 -040069 std::lock_guard<std::mutex> lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -050070 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
Naseer Ahmed378d8582017-03-28 21:56:08 -040095 std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -050096 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
Naseer Ahmed378d8582017-03-28 21:56:08 -0400124 std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530125 if (shared && (max_buf_index >= 0)) {
126 // Allocate one and duplicate/copy the handles for each descriptor
Ramkumar Radhakrishnan4f12b502017-09-22 17:13:37 -0700127 if (AllocateBufferLocked(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530128 return GRALLOC1_ERROR_NO_RESOURCES;
129 }
130
131 for (i = 0; i < num_descriptors; i++) {
132 // Create new handle for a given descriptor.
133 // Current assumption is even MetaData memory would be same
134 // Need to revisit if there is a need for own metadata memory
135 if (i != UINT(max_buf_index)) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500136 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530137 }
138 }
139 } else {
140 // Buffer sharing is not feasible.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500141 // Allocate separate buffer for each descriptor
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530142 for (i = 0; i < num_descriptors; i++) {
Ramkumar Radhakrishnan4f12b502017-09-22 17:13:37 -0700143 if (AllocateBufferLocked(*descriptors[i], &out_buffers[i])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530144 return GRALLOC1_ERROR_NO_RESOURCES;
145 }
146 }
147 }
148
149 // Allocation is successful. If backstore is not shared inform the client.
150 if (!shared) {
151 return GRALLOC1_ERROR_NOT_SHARED;
152 }
153
154 return status;
155}
156
157void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
158 buffer_handle_t *outbuffer) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400159 // TODO(user): This path is not verified
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530160 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
161
162 // Get Buffer attributes or dimension
163 unsigned int alignedw = 0, alignedh = 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700164 BufferInfo info = GetBufferInfo(descriptor);
165
166 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530167
168 // create new handle from input reference handle and given descriptor
169 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
170 descriptor.GetConsumerUsage());
171 int buffer_type = GetBufferType(descriptor.GetFormat());
172
173 // Duplicate the fds
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700174 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
Naseer Ahmede69031e2016-11-22 20:05:16 -0500175 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
176 dup(input->fd_metadata),
177 flags,
178 INT(alignedw),
179 INT(alignedh),
180 descriptor.GetWidth(),
181 descriptor.GetHeight(),
182 descriptor.GetFormat(),
183 buffer_type,
184 input->size,
185 descriptor.GetProducerUsage(),
186 descriptor.GetConsumerUsage());
187 out_hnd->id = ++next_id_;
188 // TODO(user): Base address of shared handle and ion handles
Naseer Ahmed378d8582017-03-28 21:56:08 -0400189 RegisterHandleLocked(out_hnd, -1, -1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530190 *outbuffer = out_hnd;
191}
192
Naseer Ahmede69031e2016-11-22 20:05:16 -0500193gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
194 auto hnd = buf->handle;
Naseer Ahmeda186b472017-07-07 18:50:49 -0400195 ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd);
196
197 if (private_handle_t::validate(hnd) != 0) {
198 ALOGE("FreeBuffer: Invalid handle: %p", hnd);
199 return GRALLOC1_ERROR_BAD_HANDLE;
200 }
201
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530202 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500203 hnd->fd, buf->ion_handle_main) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530204 return GRALLOC1_ERROR_BAD_HANDLE;
205 }
206
207 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
208 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500209 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530210 return GRALLOC1_ERROR_BAD_HANDLE;
211 }
212
Naseer Ahmed29a86dd2017-03-16 14:09:46 -0400213 private_handle_t * handle = const_cast<private_handle_t *>(hnd);
214 handle->fd = -1;
215 handle->fd_metadata = -1;
Naseer Ahmed2f8f8d42017-06-09 18:17:26 -0400216 if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
217 delete handle;
218 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530219 return GRALLOC1_ERROR_NONE;
220}
221
Naseer Ahmed378d8582017-03-28 21:56:08 -0400222void BufferManager::RegisterHandleLocked(const private_handle_t *hnd,
223 int ion_handle,
224 int ion_handle_meta) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400225 auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
226 handles_map_.emplace(std::make_pair(hnd, buffer));
227}
228
Naseer Ahmed378d8582017-03-28 21:56:08 -0400229gralloc1_error_t BufferManager::ImportHandleLocked(private_handle_t *hnd) {
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400230 ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400231 int ion_handle = allocator_->ImportBuffer(hnd->fd);
232 if (ion_handle < 0) {
233 ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
234 return GRALLOC1_ERROR_BAD_HANDLE;
235 }
236 int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
237 if (ion_handle_meta < 0) {
238 ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd,
239 hnd->fd, hnd->id);
240 return GRALLOC1_ERROR_BAD_HANDLE;
241 }
242 // Set base pointers to NULL since the data here was received over binder
243 hnd->base = 0;
244 hnd->base_metadata = 0;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400245 RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400246 return GRALLOC1_ERROR_NONE;
247}
248
249std::shared_ptr<BufferManager::Buffer>
Naseer Ahmed378d8582017-03-28 21:56:08 -0400250BufferManager::GetBufferFromHandleLocked(const private_handle_t *hnd) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400251 auto it = handles_map_.find(hnd);
252 if (it != handles_map_.end()) {
253 return it->second;
254 } else {
255 return nullptr;
256 }
257}
258
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530259gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
260 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400261 ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530262
263 hnd->base = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530264 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
265 hnd->fd) != 0) {
266 return GRALLOC1_ERROR_BAD_HANDLE;
267 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530268 return GRALLOC1_ERROR_NONE;
269}
270
271gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
Naseer Ahmed699b4572017-03-09 12:28:45 -0500272 ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400273 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400274 std::lock_guard<std::mutex> lock(buffer_lock_);
275 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400276 if (buf != nullptr) {
277 buf->IncRef();
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530278 } else {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400279 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400280 err = ImportHandleLocked(handle);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530281 }
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400282 return err;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530283}
284
285gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
Naseer Ahmeda186b472017-07-07 18:50:49 -0400286 ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400287 std::lock_guard<std::mutex> lock(buffer_lock_);
288 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400289 if (buf == nullptr) {
290 ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530291 return GRALLOC1_ERROR_BAD_HANDLE;
292 } else {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400293 if (buf->DecRef()) {
294 handles_map_.erase(hnd);
295 // Unmap, close ion handle and close fd
Naseer Ahmede69031e2016-11-22 20:05:16 -0500296 FreeBuffer(buf);
297 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530298 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530299 return GRALLOC1_ERROR_NONE;
300}
301
302gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
303 gralloc1_producer_usage_t prod_usage,
304 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmed378d8582017-03-28 21:56:08 -0400305 std::lock_guard<std::mutex> lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530306 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400307 ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530308
309 // If buffer is not meant for CPU return err
310 if (!CpuCanAccess(prod_usage, cons_usage)) {
311 return GRALLOC1_ERROR_BAD_VALUE;
312 }
313
Naseer Ahmed378d8582017-03-28 21:56:08 -0400314 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400315 if (buf == nullptr) {
316 return GRALLOC1_ERROR_BAD_HANDLE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530317 }
318
Naseer Ahmed67330702017-05-02 15:00:26 -0400319 if (hnd->base == 0) {
320 // we need to map for real
321 err = MapBuffer(hnd);
322 }
323
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530324 // Invalidate if CPU reads in software and there are non-CPU
325 // writers. No need to do this for the metadata buffer as it is
326 // only read/written in software.
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400327
328 // todo use handle here
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530329 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
330 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
331 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400332 buf->ion_handle_main, CACHE_INVALIDATE)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530333 return GRALLOC1_ERROR_BAD_HANDLE;
334 }
335 }
336
337 // Mark the buffer to be flushed after CPU write.
338 if (!err && CpuCanWrite(prod_usage)) {
339 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
340 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
341 }
342
343 return err;
344}
345
346gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
Naseer Ahmed378d8582017-03-28 21:56:08 -0400347 std::lock_guard<std::mutex> lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530348 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
349
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530350 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400351 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400352 if (buf == nullptr) {
353 return GRALLOC1_ERROR_BAD_HANDLE;
354 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530355
356 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
357 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400358 buf->ion_handle_main, CACHE_CLEAN) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530359 status = GRALLOC1_ERROR_BAD_HANDLE;
360 }
361 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
362 }
363
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530364 return status;
365}
366
Naseer Ahmede69031e2016-11-22 20:05:16 -0500367uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530368 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500369 uint32_t align = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530370 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
371 align = 8192;
372 }
373
374 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700375 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
376 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530377 // The alignment here reflects qsee mmu V7L/V8L requirement
378 align = SZ_2M;
379 } else {
380 align = SECURE_ALIGN;
381 }
382 }
383
384 return align;
385}
386
387int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
388 gralloc1_consumer_usage_t cons_usage) {
389 int flags = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530390 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
391 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
392 }
393
394 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
395 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
396 }
397
398 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
399 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
400 }
401
402 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
403 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
404 }
405
406 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
407 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
408 }
409
410 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
411 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
412 }
413
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700414 if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530415 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
416 }
417
418 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
419 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
420 }
421
422 // TODO(user): is this correct???
423 if ((cons_usage &
424 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
425 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
426 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
427 }
428
429 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
430 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
431 }
432
Naseer Ahmedfe6342e2017-04-20 16:52:40 -0400433 if (!allocator_->UseUncached(prod_usage, cons_usage)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530434 flags |= private_handle_t::PRIV_FLAGS_CACHED;
435 }
436
437 return flags;
438}
439
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400440int BufferManager::GetBufferType(int inputFormat) {
441 int buffer_type = BUFFER_TYPE_VIDEO;
442 if (IsUncompressedRGBFormat(inputFormat)) {
443 // RGB formats
444 buffer_type = BUFFER_TYPE_UI;
445 }
446
447 return buffer_type;
448}
449
Ramkumar Radhakrishnan4f12b502017-09-22 17:13:37 -0700450int BufferManager::AllocateBufferLocked(const BufferDescriptor &descriptor, buffer_handle_t *handle,
451 unsigned int bufferSize) {
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400452 if (!handle)
453 return -EINVAL;
454
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400455 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
456 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
Naseer Ahmed95dc2882017-07-26 18:12:12 -0400457 int format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, descriptor.GetFormat());
Naseer Ahmedbaa39c52017-03-27 14:00:07 -0400458 uint32_t layer_count = descriptor.GetLayerCount();
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400459
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400460 unsigned int size;
461 unsigned int alignedw, alignedh;
Naseer Ahmed95dc2882017-07-26 18:12:12 -0400462
463 int buffer_type = GetBufferType(format);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700464 BufferInfo info = GetBufferInfo(descriptor);
465 GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400466 size = (bufferSize >= size) ? bufferSize : size;
467
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530468 int err = 0;
469 int flags = 0;
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400470 auto page_size = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530471 AllocData data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500472 data.align = GetDataAlignment(format, prod_usage, cons_usage);
Naseer Ahmedf8e9c432017-06-13 17:45:12 -0400473 size = ALIGN(size, data.align) * layer_count;
474 data.size = size;
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400475 data.handle = (uintptr_t) handle;
Naseer Ahmedfe6342e2017-04-20 16:52:40 -0400476 data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500477
478 // Allocate buffer memory
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530479 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
480 if (err) {
481 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530482 return err;
483 }
484
Naseer Ahmede69031e2016-11-22 20:05:16 -0500485 // Allocate memory for MetaData
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530486 AllocData e_data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500487 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530488 e_data.handle = data.handle;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500489 e_data.align = page_size;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530490
491 err =
492 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500493 if (err) {
494 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
495 return err;
496 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530497
498 flags = GetHandleFlags(format, prod_usage, cons_usage);
499 flags |= data.alloc_type;
500
501 // Create handle
Naseer Ahmede69031e2016-11-22 20:05:16 -0500502 private_handle_t *hnd = new private_handle_t(data.fd,
503 e_data.fd,
504 flags,
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400505 INT(alignedw),
506 INT(alignedh),
507 descriptor.GetWidth(),
508 descriptor.GetHeight(),
Naseer Ahmede69031e2016-11-22 20:05:16 -0500509 format,
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400510 buffer_type,
Nirmal Abraham6f3dcf82017-09-19 12:29:32 +0530511 data.size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500512 prod_usage,
513 cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530514
Naseer Ahmede69031e2016-11-22 20:05:16 -0500515 hnd->id = ++next_id_;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400516 hnd->base = 0;
517 hnd->base_metadata = 0;
Naseer Ahmedbaa39c52017-03-27 14:00:07 -0400518 hnd->layer_count = layer_count;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530519
Naseer Ahmede69031e2016-11-22 20:05:16 -0500520 ColorSpace_t colorSpace = ITU_R_601;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530521 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530522 *handle = hnd;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400523 RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
Naseer Ahmed699b4572017-03-09 12:28:45 -0500524 ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
525 if (DEBUG) {
526 private_handle_t::Dump(hnd);
527 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530528 return err;
529}
530
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530531gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
532 switch (operation) {
533 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
534 int fd = va_arg(args, int);
535 unsigned int size = va_arg(args, unsigned int);
536 unsigned int offset = va_arg(args, unsigned int);
537 void *base = va_arg(args, void *);
538 int width = va_arg(args, int);
539 int height = va_arg(args, int);
540 int format = va_arg(args, int);
541
542 native_handle_t **handle = va_arg(args, native_handle_t **);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700543 if (!handle) {
544 return GRALLOC1_ERROR_BAD_HANDLE;
545 }
546
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530547 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
548 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
549 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700550 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530551 hnd->magic = private_handle_t::kMagic;
552 hnd->fd = fd;
553 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
554 hnd->size = size;
555 hnd->offset = offset;
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700556 hnd->base = uint64_t(base);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530557 hnd->gpuaddr = 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700558 BufferInfo info(width, height, format);
559 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700560 hnd->unaligned_width = width;
561 hnd->unaligned_height = height;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500562 hnd->width = INT(alignedw);
563 hnd->height = INT(alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530564 hnd->format = format;
565 *handle = reinterpret_cast<native_handle_t *>(hnd);
566 }
567 } break;
568
569 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
570 int width = va_arg(args, int);
571 int format = va_arg(args, int);
572 int *stride = va_arg(args, int *);
573 unsigned int alignedw = 0, alignedh = 0;
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700574
575 if (!stride) {
576 return GRALLOC1_ERROR_BAD_VALUE;
577 }
578
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700579 BufferInfo info(width, width, format);
580 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530581 *stride = INT(alignedw);
582 } break;
583
584 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
585 private_handle_t *hnd = va_arg(args, private_handle_t *);
586 int *stride = va_arg(args, int *);
587 if (private_handle_t::validate(hnd) != 0) {
588 return GRALLOC1_ERROR_BAD_HANDLE;
589 }
590
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700591 if (!stride) {
592 return GRALLOC1_ERROR_BAD_VALUE;
593 }
594
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400595 BufferDim_t buffer_dim;
596 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
597 *stride = buffer_dim.sliceWidth;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530598 } else {
599 *stride = hnd->width;
600 }
601 } break;
602
603 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
604 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
605 private_handle_t *hnd = va_arg(args, private_handle_t *);
606 int *stride = va_arg(args, int *);
607 int *height = va_arg(args, int *);
608 if (private_handle_t::validate(hnd) != 0) {
609 return GRALLOC1_ERROR_BAD_HANDLE;
610 }
611
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700612 if (!stride || !height) {
613 return GRALLOC1_ERROR_BAD_VALUE;
614 }
615
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400616 BufferDim_t buffer_dim;
Rohit Kulkarni70537e02017-06-16 12:01:13 -0700617 int interlaced = 0;
Ramkumar Radhakrishnan05747532017-07-07 16:38:28 -0700618
619 *stride = hnd->width;
620 *height = hnd->height;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400621 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
622 *stride = buffer_dim.sliceWidth;
623 *height = buffer_dim.sliceHeight;
Rohit Kulkarni70537e02017-06-16 12:01:13 -0700624 } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
625 if (interlaced && IsUBwcFormat(hnd->format)) {
626 unsigned int alignedw = 0, alignedh = 0;
627 // Get re-aligned height for single ubwc interlaced field and
628 // multiple by 2 to get frame height.
629 BufferInfo info(hnd->width, ((hnd->height+1)>>1), hnd->format);
630 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
631 *stride = static_cast<int>(alignedw);
632 *height = static_cast<int>(alignedh * 2);
633 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530634 }
635 } break;
636
637 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
638 // TODO(user): Usage is split now. take care of it from Gfx client.
639 // see if we can directly expect descriptor from gfx client.
640 int width = va_arg(args, int);
641 int height = va_arg(args, int);
642 int format = va_arg(args, int);
643 uint64_t producer_usage = va_arg(args, uint64_t);
644 uint64_t consumer_usage = va_arg(args, uint64_t);
645 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
646 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
647
648 int *aligned_width = va_arg(args, int *);
649 int *aligned_height = va_arg(args, int *);
650 int *tile_enabled = va_arg(args, int *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700651 if (!aligned_width || !aligned_height || !tile_enabled) {
652 return GRALLOC1_ERROR_BAD_VALUE;
653 }
654
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530655 unsigned int alignedw, alignedh;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700656 BufferInfo info(width, height, format, prod_usage, cons_usage);
657 *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
658 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530659 *aligned_width = INT(alignedw);
660 *aligned_height = INT(alignedh);
661 } break;
662
663 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
664 private_handle_t *hnd = va_arg(args, private_handle_t *);
665 int *color_space = va_arg(args, int *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700666
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530667 if (private_handle_t::validate(hnd) != 0) {
668 return GRALLOC1_ERROR_BAD_HANDLE;
669 }
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700670
671 if (!color_space) {
672 return GRALLOC1_ERROR_BAD_VALUE;
673 }
674
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400675 *color_space = 0;
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700676#ifdef USE_COLOR_METADATA
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400677 ColorMetaData color_metadata;
678 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
679 switch (color_metadata.colorPrimaries) {
680 case ColorPrimaries_BT709_5:
681 *color_space = HAL_CSC_ITU_R_709;
682 break;
683 case ColorPrimaries_BT601_6_525:
684 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
685 break;
686 case ColorPrimaries_BT2020:
687 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
688 break;
689 default:
690 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
691 break;
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700692 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400693 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530694 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400695 if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
696 *color_space = 0;
697 }
698#endif
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530699 } break;
700 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
701 private_handle_t *hnd = va_arg(args, private_handle_t *);
702 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
703 if (private_handle_t::validate(hnd) != 0) {
704 return GRALLOC1_ERROR_BAD_HANDLE;
705 }
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700706
707 if (!ycbcr) {
708 return GRALLOC1_ERROR_BAD_VALUE;
709 }
710
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700711 if (GetYUVPlaneInfo(hnd, ycbcr)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530712 return GRALLOC1_ERROR_UNDEFINED;
713 }
714 } break;
715
716 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
717 private_handle_t *hnd = va_arg(args, private_handle_t *);
718 int *map_secure_buffer = va_arg(args, int *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700719
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530720 if (private_handle_t::validate(hnd) != 0) {
721 return GRALLOC1_ERROR_BAD_HANDLE;
722 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400723
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700724 if (!map_secure_buffer) {
725 return GRALLOC1_ERROR_BAD_VALUE;
726 }
727
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400728 if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530729 *map_secure_buffer = 0;
730 }
731 } break;
732
733 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
734 private_handle_t *hnd = va_arg(args, private_handle_t *);
735 int *flag = va_arg(args, int *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700736
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530737 if (private_handle_t::validate(hnd) != 0) {
738 return GRALLOC1_ERROR_BAD_HANDLE;
739 }
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700740
741 if (!flag) {
742 return GRALLOC1_ERROR_BAD_VALUE;
743 }
744
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530745 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
Ramakant Singhc7d07792017-07-26 15:36:33 +0530746 int linear_format = 0;
747 if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
Ramakant Singhd3dfe4b2017-08-17 17:04:14 +0530748 if (linear_format) {
Ramakant Singhc7d07792017-07-26 15:36:33 +0530749 *flag = 0;
750 }
751 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530752 } break;
753
754 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
755 private_handle_t *hnd = va_arg(args, private_handle_t *);
756 void **rgb_data = va_arg(args, void **);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700757
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530758 if (private_handle_t::validate(hnd) != 0) {
759 return GRALLOC1_ERROR_BAD_HANDLE;
760 }
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700761
762 if (!rgb_data) {
763 return GRALLOC1_ERROR_BAD_VALUE;
764 }
765
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700766 if (GetRgbDataAddress(hnd, rgb_data)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530767 return GRALLOC1_ERROR_UNDEFINED;
768 }
769 } break;
770
Naseer Ahmede69031e2016-11-22 20:05:16 -0500771 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
772 int width = va_arg(args, int);
773 int height = va_arg(args, int);
774 int format = va_arg(args, int);
775 uint64_t p_usage = va_arg(args, uint64_t);
776 uint64_t c_usage = va_arg(args, uint64_t);
777 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
778 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
779 uint32_t *aligned_width = va_arg(args, uint32_t *);
780 uint32_t *aligned_height = va_arg(args, uint32_t *);
781 uint32_t *size = va_arg(args, uint32_t *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700782
783 if (!aligned_width || !aligned_height || !size) {
784 return GRALLOC1_ERROR_BAD_VALUE;
785 }
786
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700787 auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
788 GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500789 // Align size
790 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
791 *size = ALIGN(*size, align);
792 } break;
793
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700794 case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
795 private_handle_t *hnd = va_arg(args, private_handle_t *);
796 int *flag = va_arg(args, int *);
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700797
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700798 if (private_handle_t::validate(hnd) != 0) {
799 return GRALLOC1_ERROR_BAD_HANDLE;
800 }
Saurabh Shah6e4b3762017-09-21 15:30:15 -0700801
802 if (!flag) {
803 return GRALLOC1_ERROR_BAD_VALUE;
804 }
805
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700806 if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
807 *flag = 0;
808 }
809 } break;
810
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530811 default:
812 break;
813 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530814 return GRALLOC1_ERROR_NONE;
815}
816
Naseer Ahmede69031e2016-11-22 20:05:16 -0500817static bool IsYuvFormat(const private_handle_t *hnd) {
818 switch (hnd->format) {
819 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
820 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
821 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
822 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
823 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
824 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
825 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
826 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
827 case HAL_PIXEL_FORMAT_NV21_ZSL:
828 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530829 case HAL_PIXEL_FORMAT_Y16:
Naseer Ahmed92998622017-03-20 12:39:17 -0400830 case HAL_PIXEL_FORMAT_RAW12:
Naseer Ahmede69031e2016-11-22 20:05:16 -0500831 case HAL_PIXEL_FORMAT_RAW10:
832 case HAL_PIXEL_FORMAT_YV12:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530833 case HAL_PIXEL_FORMAT_Y8:
Naseer Ahmede69031e2016-11-22 20:05:16 -0500834 return true;
835 default:
836 return false;
837 }
838}
839
840gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
841 uint32_t *out_num_planes) {
842 if (!IsYuvFormat(hnd)) {
843 return GRALLOC1_ERROR_UNSUPPORTED;
844 } else {
845 *out_num_planes = 3;
846 }
847 return GRALLOC1_ERROR_NONE;
848}
849
850gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
851 struct android_flex_layout *layout) {
852 if (!IsYuvFormat(hnd)) {
853 return GRALLOC1_ERROR_UNSUPPORTED;
854 }
855
856 android_ycbcr ycbcr;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700857 int err = GetYUVPlaneInfo(hnd, &ycbcr);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500858
859 if (err != 0) {
860 return GRALLOC1_ERROR_BAD_HANDLE;
861 }
862
863 layout->format = FLEX_FORMAT_YCbCr;
864 layout->num_planes = 3;
865
866 for (uint32_t i = 0; i < layout->num_planes; i++) {
867 layout->planes[i].bits_per_component = 8;
868 layout->planes[i].bits_used = 8;
869 layout->planes[i].h_increment = 1;
870 layout->planes[i].v_increment = 1;
871 layout->planes[i].h_subsampling = 2;
872 layout->planes[i].v_subsampling = 2;
873 }
874
875 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
876 layout->planes[0].component = FLEX_COMPONENT_Y;
877 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
878
879 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
880 layout->planes[1].component = FLEX_COMPONENT_Cb;
881 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
882 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
883
884 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
885 layout->planes[2].component = FLEX_COMPONENT_Cr;
886 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
887 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
888 return GRALLOC1_ERROR_NONE;
889}
Naseer Ahmeddc918132017-03-07 15:25:14 -0500890
891gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
892 for (auto it : handles_map_) {
893 auto buf = it.second;
894 auto hnd = buf->handle;
895 *os << "handle id: " << std::setw(4) << hnd->id;
896 *os << " fd: " << std::setw(3) << hnd->fd;
897 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
898 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
899 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
900 *os << std::setw(4) << hnd->unaligned_height;
901 *os << " size: " << std::setw(9) << hnd->size;
902 *os << std::hex << std::setfill('0');
903 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
904 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
905 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
906 // TODO(user): get format string from qdutils
907 *os << " format: " << "0x" << std::setw(8) << hnd->format;
908 *os << std::dec << std::setfill(' ') << std::endl;
909 }
910 return GRALLOC1_ERROR_NONE;
911}
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530912} // namespace gralloc1