blob: 955f14b6d472759e07f73431a3a9289ee4fbd416 [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
52 // Enable UBWC for framebuffer
53 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
54 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
55 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
56 ubwc_for_fb_ = true;
57 }
58
59 handles_map_.clear();
Naseer Ahmede69031e2016-11-22 20:05:16 -050060 allocator_ = new Allocator();
61 allocator_->Init();
62}
63
64
65gralloc1_error_t BufferManager::CreateBufferDescriptor(
66 gralloc1_buffer_descriptor_t *descriptor_id) {
Naseer Ahmed378d8582017-03-28 21:56:08 -040067 std::lock_guard<std::mutex> lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -050068 auto descriptor = std::make_shared<BufferDescriptor>();
69 descriptors_map_.emplace(descriptor->GetId(), descriptor);
70 *descriptor_id = descriptor->GetId();
71 return GRALLOC1_ERROR_NONE;
72}
73
74gralloc1_error_t BufferManager::DestroyBufferDescriptor(
75 gralloc1_buffer_descriptor_t descriptor_id) {
Naseer Ahmed378d8582017-03-28 21:56:08 -040076 std::lock_guard<std::mutex> lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -050077 const auto descriptor = descriptors_map_.find(descriptor_id);
78 if (descriptor == descriptors_map_.end()) {
79 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
80 }
81 descriptors_map_.erase(descriptor);
82 return GRALLOC1_ERROR_NONE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053083}
84
85BufferManager::~BufferManager() {
86 if (allocator_) {
87 delete allocator_;
88 }
89}
90
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053091gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
Naseer Ahmede69031e2016-11-22 20:05:16 -050092 const gralloc1_buffer_descriptor_t *descriptor_ids,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053093 buffer_handle_t *out_buffers) {
94 bool shared = true;
95 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
96
97 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
98 // client can ask to test the allocation by passing NULL out_buffers
99 bool test_allocate = !out_buffers;
100
Naseer Ahmede69031e2016-11-22 20:05:16 -0500101 // Validate descriptors
Naseer Ahmed378d8582017-03-28 21:56:08 -0400102 std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500103 std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
104 for (uint32_t i = 0; i < num_descriptors; i++) {
105 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
106 if (map_descriptor == descriptors_map_.end()) {
107 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
108 } else {
109 descriptors.push_back(map_descriptor->second);
110 }
111 }
112
113 // Resolve implementation defined formats
114 for (auto &descriptor : descriptors) {
115 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
116 descriptor->GetConsumerUsage(),
117 descriptor->GetFormat()));
118 }
119
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530120 // Check if input descriptors can be supported AND
121 // Find out if a single buffer can be shared for all the given input descriptors
122 uint32_t i = 0;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500123 ssize_t max_buf_index = -1;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530124 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
125
126 if (test_allocate) {
127 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
128 return status;
129 }
130
Naseer Ahmed378d8582017-03-28 21:56:08 -0400131 std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530132 if (shared && (max_buf_index >= 0)) {
133 // Allocate one and duplicate/copy the handles for each descriptor
Naseer Ahmede69031e2016-11-22 20:05:16 -0500134 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530135 return GRALLOC1_ERROR_NO_RESOURCES;
136 }
137
138 for (i = 0; i < num_descriptors; i++) {
139 // Create new handle for a given descriptor.
140 // Current assumption is even MetaData memory would be same
141 // Need to revisit if there is a need for own metadata memory
142 if (i != UINT(max_buf_index)) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500143 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530144 }
145 }
146 } else {
147 // Buffer sharing is not feasible.
Naseer Ahmede69031e2016-11-22 20:05:16 -0500148 // Allocate separate buffer for each descriptor
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530149 for (i = 0; i < num_descriptors; i++) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500150 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530151 return GRALLOC1_ERROR_NO_RESOURCES;
152 }
153 }
154 }
155
156 // Allocation is successful. If backstore is not shared inform the client.
157 if (!shared) {
158 return GRALLOC1_ERROR_NOT_SHARED;
159 }
160
161 return status;
162}
163
164void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
165 buffer_handle_t *outbuffer) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400166 // TODO(user): This path is not verified
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530167 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
168
169 // Get Buffer attributes or dimension
170 unsigned int alignedw = 0, alignedh = 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700171 BufferInfo info = GetBufferInfo(descriptor);
172
173 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530174
175 // create new handle from input reference handle and given descriptor
176 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
177 descriptor.GetConsumerUsage());
178 int buffer_type = GetBufferType(descriptor.GetFormat());
179
180 // Duplicate the fds
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700181 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
Naseer Ahmede69031e2016-11-22 20:05:16 -0500182 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
183 dup(input->fd_metadata),
184 flags,
185 INT(alignedw),
186 INT(alignedh),
187 descriptor.GetWidth(),
188 descriptor.GetHeight(),
189 descriptor.GetFormat(),
190 buffer_type,
191 input->size,
192 descriptor.GetProducerUsage(),
193 descriptor.GetConsumerUsage());
194 out_hnd->id = ++next_id_;
195 // TODO(user): Base address of shared handle and ion handles
Naseer Ahmed378d8582017-03-28 21:56:08 -0400196 RegisterHandleLocked(out_hnd, -1, -1);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530197 *outbuffer = out_hnd;
198}
199
Naseer Ahmede69031e2016-11-22 20:05:16 -0500200gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
201 auto hnd = buf->handle;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400202 ALOGD_IF(DEBUG, "FreeBuffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530203 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500204 hnd->fd, buf->ion_handle_main) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530205 return GRALLOC1_ERROR_BAD_HANDLE;
206 }
207
208 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
209 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500210 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530211 return GRALLOC1_ERROR_BAD_HANDLE;
212 }
213
Naseer Ahmed29a86dd2017-03-16 14:09:46 -0400214 private_handle_t * handle = const_cast<private_handle_t *>(hnd);
215 handle->fd = -1;
216 handle->fd_metadata = -1;
Naseer Ahmed67330702017-05-02 15:00:26 -0400217 delete handle;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530218 return GRALLOC1_ERROR_NONE;
219}
220
Naseer Ahmed378d8582017-03-28 21:56:08 -0400221void BufferManager::RegisterHandleLocked(const private_handle_t *hnd,
222 int ion_handle,
223 int ion_handle_meta) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400224 auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
225 handles_map_.emplace(std::make_pair(hnd, buffer));
226}
227
Naseer Ahmed378d8582017-03-28 21:56:08 -0400228gralloc1_error_t BufferManager::ImportHandleLocked(private_handle_t *hnd) {
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400229 ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400230 int ion_handle = allocator_->ImportBuffer(hnd->fd);
231 if (ion_handle < 0) {
232 ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
233 return GRALLOC1_ERROR_BAD_HANDLE;
234 }
235 int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
236 if (ion_handle_meta < 0) {
237 ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd,
238 hnd->fd, hnd->id);
239 return GRALLOC1_ERROR_BAD_HANDLE;
240 }
241 // Set base pointers to NULL since the data here was received over binder
242 hnd->base = 0;
243 hnd->base_metadata = 0;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400244 RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400245 return GRALLOC1_ERROR_NONE;
246}
247
248std::shared_ptr<BufferManager::Buffer>
Naseer Ahmed378d8582017-03-28 21:56:08 -0400249BufferManager::GetBufferFromHandleLocked(const private_handle_t *hnd) {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400250 auto it = handles_map_.find(hnd);
251 if (it != handles_map_.end()) {
252 return it->second;
253 } else {
254 return nullptr;
255 }
256}
257
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530258gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
259 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400260 ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530261
262 hnd->base = 0;
263 hnd->base_metadata = 0;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400264
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530265 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
266 hnd->fd) != 0) {
267 return GRALLOC1_ERROR_BAD_HANDLE;
268 }
269
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400270 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530271 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
272 hnd->offset_metadata, hnd->fd_metadata) != 0) {
273 return GRALLOC1_ERROR_BAD_HANDLE;
274 }
275
276 return GRALLOC1_ERROR_NONE;
277}
278
279gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
Naseer Ahmed67330702017-05-02 15:00:26 -0400280 if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
281 return GRALLOC1_ERROR_NONE;
282 }
283
Naseer Ahmed699b4572017-03-09 12:28:45 -0500284 ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400285 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400286 std::lock_guard<std::mutex> lock(buffer_lock_);
287 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400288 if (buf != nullptr) {
289 buf->IncRef();
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530290 } else {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400291 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400292 err = ImportHandleLocked(handle);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400293 if (err == GRALLOC1_ERROR_NONE) {
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400294 // TODO(user): See bug 35955598
295 if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
296 return GRALLOC1_ERROR_NONE; // Don't map secure buffer
297 }
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400298 err = MapBuffer(hnd);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530299 }
300 }
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400301 return err;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530302}
303
304gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
Naseer Ahmed67330702017-05-02 15:00:26 -0400305 if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
306 return GRALLOC1_ERROR_NONE;
307 }
308
Naseer Ahmed699b4572017-03-09 12:28:45 -0500309 ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400310 std::lock_guard<std::mutex> lock(buffer_lock_);
311 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400312 if (buf == nullptr) {
313 ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530314 return GRALLOC1_ERROR_BAD_HANDLE;
315 } else {
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400316 if (buf->DecRef()) {
317 handles_map_.erase(hnd);
318 // Unmap, close ion handle and close fd
Naseer Ahmede69031e2016-11-22 20:05:16 -0500319 FreeBuffer(buf);
320 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530321 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530322 return GRALLOC1_ERROR_NONE;
323}
324
325gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
326 gralloc1_producer_usage_t prod_usage,
327 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmed378d8582017-03-28 21:56:08 -0400328 std::lock_guard<std::mutex> lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530329 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400330 ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530331
332 // If buffer is not meant for CPU return err
333 if (!CpuCanAccess(prod_usage, cons_usage)) {
334 return GRALLOC1_ERROR_BAD_VALUE;
335 }
336
Naseer Ahmed378d8582017-03-28 21:56:08 -0400337 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400338 if (buf == nullptr) {
339 return GRALLOC1_ERROR_BAD_HANDLE;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530340 }
341
Naseer Ahmed67330702017-05-02 15:00:26 -0400342 if (hnd->base == 0) {
343 // we need to map for real
344 err = MapBuffer(hnd);
345 }
346
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530347 // Invalidate if CPU reads in software and there are non-CPU
348 // writers. No need to do this for the metadata buffer as it is
349 // only read/written in software.
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400350
351 // todo use handle here
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530352 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
353 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
354 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400355 buf->ion_handle_main, CACHE_INVALIDATE)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530356 return GRALLOC1_ERROR_BAD_HANDLE;
357 }
358 }
359
360 // Mark the buffer to be flushed after CPU write.
361 if (!err && CpuCanWrite(prod_usage)) {
362 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
363 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
364 }
365
366 return err;
367}
368
369gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
Naseer Ahmed378d8582017-03-28 21:56:08 -0400370 std::lock_guard<std::mutex> lock(buffer_lock_);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530371 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
372
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530373 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
Naseer Ahmed378d8582017-03-28 21:56:08 -0400374 auto buf = GetBufferFromHandleLocked(hnd);
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400375 if (buf == nullptr) {
376 return GRALLOC1_ERROR_BAD_HANDLE;
377 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530378
379 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
380 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
Naseer Ahmed3a9d53a2017-03-15 19:21:40 -0400381 buf->ion_handle_main, CACHE_CLEAN) != 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530382 status = GRALLOC1_ERROR_BAD_HANDLE;
383 }
384 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
385 }
386
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530387 return status;
388}
389
Naseer Ahmede69031e2016-11-22 20:05:16 -0500390uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530391 gralloc1_consumer_usage_t cons_usage) {
Naseer Ahmede69031e2016-11-22 20:05:16 -0500392 uint32_t align = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530393 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
394 align = 8192;
395 }
396
397 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700398 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
399 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530400 // The alignment here reflects qsee mmu V7L/V8L requirement
401 align = SZ_2M;
402 } else {
403 align = SECURE_ALIGN;
404 }
405 }
406
407 return align;
408}
409
410int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
411 gralloc1_consumer_usage_t cons_usage) {
412 int flags = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530413 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
414 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
415 }
416
417 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
418 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
419 }
420
421 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
422 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
423 }
424
425 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
426 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
427 }
428
429 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
430 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
431 }
432
433 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
434 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
435 }
436
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700437 if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530438 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
439 }
440
441 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
442 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
443 }
444
445 // TODO(user): is this correct???
446 if ((cons_usage &
447 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
448 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
449 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
450 }
451
452 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
453 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
454 }
455
Naseer Ahmedfe6342e2017-04-20 16:52:40 -0400456 if (!allocator_->UseUncached(prod_usage, cons_usage)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530457 flags |= private_handle_t::PRIV_FLAGS_CACHED;
458 }
459
460 return flags;
461}
462
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400463int BufferManager::GetBufferType(int inputFormat) {
464 int buffer_type = BUFFER_TYPE_VIDEO;
465 if (IsUncompressedRGBFormat(inputFormat)) {
466 // RGB formats
467 buffer_type = BUFFER_TYPE_UI;
468 }
469
470 return buffer_type;
471}
472
473int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
474 unsigned int bufferSize) {
475 if (!handle)
476 return -EINVAL;
477
478 int format = descriptor.GetFormat();
479 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
480 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
Naseer Ahmedbaa39c52017-03-27 14:00:07 -0400481 uint32_t layer_count = descriptor.GetLayerCount();
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400482
483 // Get implementation defined format
484 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
485
486 unsigned int size;
487 unsigned int alignedw, alignedh;
488 int buffer_type = GetBufferType(gralloc_format);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700489 BufferInfo info = GetBufferInfo(descriptor);
490 GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400491 size = (bufferSize >= size) ? bufferSize : size;
492
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530493 int err = 0;
494 int flags = 0;
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400495 auto page_size = UINT(getpagesize());
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530496 AllocData data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500497 data.align = GetDataAlignment(format, prod_usage, cons_usage);
Naseer Ahmedf8e9c432017-06-13 17:45:12 -0400498 size = ALIGN(size, data.align) * layer_count;
499 data.size = size;
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400500 data.handle = (uintptr_t) handle;
Naseer Ahmedfe6342e2017-04-20 16:52:40 -0400501 data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500502
503 // Allocate buffer memory
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530504 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
505 if (err) {
506 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530507 return err;
508 }
509
Naseer Ahmede69031e2016-11-22 20:05:16 -0500510 // Allocate memory for MetaData
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530511 AllocData e_data;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500512 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530513 e_data.handle = data.handle;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500514 e_data.align = page_size;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530515
516 err =
517 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500518 if (err) {
519 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
520 return err;
521 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530522
523 flags = GetHandleFlags(format, prod_usage, cons_usage);
524 flags |= data.alloc_type;
525
526 // Create handle
Naseer Ahmede69031e2016-11-22 20:05:16 -0500527 private_handle_t *hnd = new private_handle_t(data.fd,
528 e_data.fd,
529 flags,
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400530 INT(alignedw),
531 INT(alignedh),
532 descriptor.GetWidth(),
533 descriptor.GetHeight(),
Naseer Ahmede69031e2016-11-22 20:05:16 -0500534 format,
Naseer Ahmed4c0eec92017-03-27 16:51:48 -0400535 buffer_type,
Naseer Ahmede69031e2016-11-22 20:05:16 -0500536 size,
537 prod_usage,
538 cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530539
Naseer Ahmede69031e2016-11-22 20:05:16 -0500540 hnd->id = ++next_id_;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400541 hnd->base = 0;
542 hnd->base_metadata = 0;
Naseer Ahmedbaa39c52017-03-27 14:00:07 -0400543 hnd->layer_count = layer_count;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530544
Naseer Ahmede69031e2016-11-22 20:05:16 -0500545 ColorSpace_t colorSpace = ITU_R_601;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530546 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530547 *handle = hnd;
Naseer Ahmed378d8582017-03-28 21:56:08 -0400548 RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
Naseer Ahmed699b4572017-03-09 12:28:45 -0500549 ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
550 if (DEBUG) {
551 private_handle_t::Dump(hnd);
552 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530553 return err;
554}
555
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530556gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
557 switch (operation) {
558 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
559 int fd = va_arg(args, int);
560 unsigned int size = va_arg(args, unsigned int);
561 unsigned int offset = va_arg(args, unsigned int);
562 void *base = va_arg(args, void *);
563 int width = va_arg(args, int);
564 int height = va_arg(args, int);
565 int format = va_arg(args, int);
566
567 native_handle_t **handle = va_arg(args, native_handle_t **);
568 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
569 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
570 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700571 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530572 hnd->magic = private_handle_t::kMagic;
573 hnd->fd = fd;
574 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
575 hnd->size = size;
576 hnd->offset = offset;
577 hnd->base = uint64_t(base) + offset;
578 hnd->gpuaddr = 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700579 BufferInfo info(width, height, format);
580 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700581 hnd->unaligned_width = width;
582 hnd->unaligned_height = height;
Naseer Ahmede69031e2016-11-22 20:05:16 -0500583 hnd->width = INT(alignedw);
584 hnd->height = INT(alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530585 hnd->format = format;
586 *handle = reinterpret_cast<native_handle_t *>(hnd);
587 }
588 } break;
589
590 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
591 int width = va_arg(args, int);
592 int format = va_arg(args, int);
593 int *stride = va_arg(args, int *);
594 unsigned int alignedw = 0, alignedh = 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700595 BufferInfo info(width, width, format);
596 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530597 *stride = INT(alignedw);
598 } break;
599
600 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
601 private_handle_t *hnd = va_arg(args, private_handle_t *);
602 int *stride = va_arg(args, int *);
603 if (private_handle_t::validate(hnd) != 0) {
604 return GRALLOC1_ERROR_BAD_HANDLE;
605 }
606
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400607 BufferDim_t buffer_dim;
608 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
609 *stride = buffer_dim.sliceWidth;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530610 } else {
611 *stride = hnd->width;
612 }
613 } break;
614
615 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
616 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
617 private_handle_t *hnd = va_arg(args, private_handle_t *);
618 int *stride = va_arg(args, int *);
619 int *height = va_arg(args, int *);
620 if (private_handle_t::validate(hnd) != 0) {
621 return GRALLOC1_ERROR_BAD_HANDLE;
622 }
623
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400624 BufferDim_t buffer_dim;
Rohit Kulkarni70537e02017-06-16 12:01:13 -0700625 int interlaced = 0;
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400626 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
627 *stride = buffer_dim.sliceWidth;
628 *height = buffer_dim.sliceHeight;
Rohit Kulkarni70537e02017-06-16 12:01:13 -0700629 } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
630 if (interlaced && IsUBwcFormat(hnd->format)) {
631 unsigned int alignedw = 0, alignedh = 0;
632 // Get re-aligned height for single ubwc interlaced field and
633 // multiple by 2 to get frame height.
634 BufferInfo info(hnd->width, ((hnd->height+1)>>1), hnd->format);
635 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
636 *stride = static_cast<int>(alignedw);
637 *height = static_cast<int>(alignedh * 2);
638 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530639 } else {
640 *stride = hnd->width;
641 *height = hnd->height;
642 }
643 } break;
644
645 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
646 // TODO(user): Usage is split now. take care of it from Gfx client.
647 // see if we can directly expect descriptor from gfx client.
648 int width = va_arg(args, int);
649 int height = va_arg(args, int);
650 int format = va_arg(args, int);
651 uint64_t producer_usage = va_arg(args, uint64_t);
652 uint64_t consumer_usage = va_arg(args, uint64_t);
653 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
654 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
655
656 int *aligned_width = va_arg(args, int *);
657 int *aligned_height = va_arg(args, int *);
658 int *tile_enabled = va_arg(args, int *);
659 unsigned int alignedw, alignedh;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700660 BufferInfo info(width, height, format, prod_usage, cons_usage);
661 *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
662 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530663 *aligned_width = INT(alignedw);
664 *aligned_height = INT(alignedh);
665 } break;
666
667 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
668 private_handle_t *hnd = va_arg(args, private_handle_t *);
669 int *color_space = va_arg(args, int *);
670 if (private_handle_t::validate(hnd) != 0) {
671 return GRALLOC1_ERROR_BAD_HANDLE;
672 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400673 *color_space = 0;
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700674#ifdef USE_COLOR_METADATA
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400675 ColorMetaData color_metadata;
676 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
677 switch (color_metadata.colorPrimaries) {
678 case ColorPrimaries_BT709_5:
679 *color_space = HAL_CSC_ITU_R_709;
680 break;
681 case ColorPrimaries_BT601_6_525:
682 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
683 break;
684 case ColorPrimaries_BT2020:
685 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
686 break;
687 default:
688 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
689 break;
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700690 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400691 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530692 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400693 if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
694 *color_space = 0;
695 }
696#endif
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530697 } break;
698 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
699 private_handle_t *hnd = va_arg(args, private_handle_t *);
700 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
701 if (private_handle_t::validate(hnd) != 0) {
702 return GRALLOC1_ERROR_BAD_HANDLE;
703 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700704 if (GetYUVPlaneInfo(hnd, ycbcr)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530705 return GRALLOC1_ERROR_UNDEFINED;
706 }
707 } break;
708
709 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
710 private_handle_t *hnd = va_arg(args, private_handle_t *);
711 int *map_secure_buffer = va_arg(args, int *);
712 if (private_handle_t::validate(hnd) != 0) {
713 return GRALLOC1_ERROR_BAD_HANDLE;
714 }
Naseer Ahmed49f2e9c2017-03-23 22:13:17 -0400715
716 if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530717 *map_secure_buffer = 0;
718 }
719 } break;
720
721 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
722 private_handle_t *hnd = va_arg(args, private_handle_t *);
723 int *flag = va_arg(args, int *);
724 if (private_handle_t::validate(hnd) != 0) {
725 return GRALLOC1_ERROR_BAD_HANDLE;
726 }
727 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
728 } break;
729
730 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
731 private_handle_t *hnd = va_arg(args, private_handle_t *);
732 void **rgb_data = va_arg(args, void **);
733 if (private_handle_t::validate(hnd) != 0) {
734 return GRALLOC1_ERROR_BAD_HANDLE;
735 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700736 if (GetRgbDataAddress(hnd, rgb_data)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530737 return GRALLOC1_ERROR_UNDEFINED;
738 }
739 } break;
740
Naseer Ahmede69031e2016-11-22 20:05:16 -0500741 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
742 int width = va_arg(args, int);
743 int height = va_arg(args, int);
744 int format = va_arg(args, int);
745 uint64_t p_usage = va_arg(args, uint64_t);
746 uint64_t c_usage = va_arg(args, uint64_t);
747 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
748 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
749 uint32_t *aligned_width = va_arg(args, uint32_t *);
750 uint32_t *aligned_height = va_arg(args, uint32_t *);
751 uint32_t *size = va_arg(args, uint32_t *);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700752 auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
753 GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500754 // Align size
755 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
756 *size = ALIGN(*size, align);
757 } break;
758
759 // TODO(user): Break out similar functionality, preferably moving to a common lib.
760
761 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
762 int width = va_arg(args, int);
763 int height = va_arg(args, int);
764 int format = va_arg(args, int);
765 uint64_t p_usage = va_arg(args, uint64_t);
766 uint64_t c_usage = va_arg(args, uint64_t);
767 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
768 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
769 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
770 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
771 unsigned int size;
772 unsigned int alignedw, alignedh;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700773 GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500774 AllocateBuffer(descriptor, hnd, size);
775 } break;
776
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700777 case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
778 private_handle_t *hnd = va_arg(args, private_handle_t *);
779 int *flag = va_arg(args, int *);
780 if (private_handle_t::validate(hnd) != 0) {
781 return GRALLOC1_ERROR_BAD_HANDLE;
782 }
783 if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
784 *flag = 0;
785 }
786 } break;
787
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530788 default:
789 break;
790 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530791 return GRALLOC1_ERROR_NONE;
792}
793
Naseer Ahmede69031e2016-11-22 20:05:16 -0500794static bool IsYuvFormat(const private_handle_t *hnd) {
795 switch (hnd->format) {
796 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
797 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
798 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
799 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
800 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
801 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
802 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
803 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
804 case HAL_PIXEL_FORMAT_NV21_ZSL:
805 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530806 case HAL_PIXEL_FORMAT_Y16:
Naseer Ahmed92998622017-03-20 12:39:17 -0400807 case HAL_PIXEL_FORMAT_RAW12:
Naseer Ahmede69031e2016-11-22 20:05:16 -0500808 case HAL_PIXEL_FORMAT_RAW10:
809 case HAL_PIXEL_FORMAT_YV12:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530810 case HAL_PIXEL_FORMAT_Y8:
Naseer Ahmede69031e2016-11-22 20:05:16 -0500811 return true;
812 default:
813 return false;
814 }
815}
816
817gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
818 uint32_t *out_num_planes) {
819 if (!IsYuvFormat(hnd)) {
820 return GRALLOC1_ERROR_UNSUPPORTED;
821 } else {
822 *out_num_planes = 3;
823 }
824 return GRALLOC1_ERROR_NONE;
825}
826
827gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
828 struct android_flex_layout *layout) {
829 if (!IsYuvFormat(hnd)) {
830 return GRALLOC1_ERROR_UNSUPPORTED;
831 }
832
833 android_ycbcr ycbcr;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700834 int err = GetYUVPlaneInfo(hnd, &ycbcr);
Naseer Ahmede69031e2016-11-22 20:05:16 -0500835
836 if (err != 0) {
837 return GRALLOC1_ERROR_BAD_HANDLE;
838 }
839
840 layout->format = FLEX_FORMAT_YCbCr;
841 layout->num_planes = 3;
842
843 for (uint32_t i = 0; i < layout->num_planes; i++) {
844 layout->planes[i].bits_per_component = 8;
845 layout->planes[i].bits_used = 8;
846 layout->planes[i].h_increment = 1;
847 layout->planes[i].v_increment = 1;
848 layout->planes[i].h_subsampling = 2;
849 layout->planes[i].v_subsampling = 2;
850 }
851
852 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
853 layout->planes[0].component = FLEX_COMPONENT_Y;
854 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
855
856 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
857 layout->planes[1].component = FLEX_COMPONENT_Cb;
858 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
859 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
860
861 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
862 layout->planes[2].component = FLEX_COMPONENT_Cr;
863 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
864 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
865 return GRALLOC1_ERROR_NONE;
866}
Naseer Ahmeddc918132017-03-07 15:25:14 -0500867
868gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
869 for (auto it : handles_map_) {
870 auto buf = it.second;
871 auto hnd = buf->handle;
872 *os << "handle id: " << std::setw(4) << hnd->id;
873 *os << " fd: " << std::setw(3) << hnd->fd;
874 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
875 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
876 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
877 *os << std::setw(4) << hnd->unaligned_height;
878 *os << " size: " << std::setw(9) << hnd->size;
879 *os << std::hex << std::setfill('0');
880 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
881 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
882 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
883 // TODO(user): get format string from qdutils
884 *os << " format: " << "0x" << std::setw(8) << hnd->format;
885 *os << std::dec << std::setfill(' ') << std::endl;
886 }
887 return GRALLOC1_ERROR_NONE;
888}
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530889} // namespace gralloc1