1 /*
2 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
3 * 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 #define DEBUG 0
21 #include <iomanip>
22 #include <utility>
23 #include <vector>
24 #include <sstream>
25
26 #include "qd_utils.h"
27 #include "gr_priv_handle.h"
28 #include "gr_buf_descriptor.h"
29 #include "gr_utils.h"
30 #include "gr_buf_mgr.h"
31 #include "qdMetaData.h"
32
33 namespace gralloc1 {
34 std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
35
BufferManager()36 BufferManager::BufferManager() : next_id_(0) {
37 char property[PROPERTY_VALUE_MAX];
38
39 // Map framebuffer memory
40 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
41 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
42 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
43 map_fb_mem_ = true;
44 }
45
46 // Enable UBWC for framebuffer
47 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
48 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
49 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
50 ubwc_for_fb_ = true;
51 }
52
53 handles_map_.clear();
54 allocator_ = new Allocator();
55 allocator_->Init();
56 }
57
58
CreateBufferDescriptor(gralloc1_buffer_descriptor_t * descriptor_id)59 gralloc1_error_t BufferManager::CreateBufferDescriptor(
60 gralloc1_buffer_descriptor_t *descriptor_id) {
61 std::lock_guard<std::mutex> lock(descriptor_lock_);
62 auto descriptor = std::make_shared<BufferDescriptor>();
63 descriptors_map_.emplace(descriptor->GetId(), descriptor);
64 *descriptor_id = descriptor->GetId();
65 return GRALLOC1_ERROR_NONE;
66 }
67
DestroyBufferDescriptor(gralloc1_buffer_descriptor_t descriptor_id)68 gralloc1_error_t BufferManager::DestroyBufferDescriptor(
69 gralloc1_buffer_descriptor_t descriptor_id) {
70 std::lock_guard<std::mutex> lock(descriptor_lock_);
71 const auto descriptor = descriptors_map_.find(descriptor_id);
72 if (descriptor == descriptors_map_.end()) {
73 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
74 }
75 descriptors_map_.erase(descriptor);
76 return GRALLOC1_ERROR_NONE;
77 }
78
~BufferManager()79 BufferManager::~BufferManager() {
80 if (allocator_) {
81 delete allocator_;
82 }
83 }
84
AllocateBuffers(uint32_t num_descriptors,const gralloc1_buffer_descriptor_t * descriptor_ids,buffer_handle_t * out_buffers)85 gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
86 const gralloc1_buffer_descriptor_t *descriptor_ids,
87 buffer_handle_t *out_buffers) {
88 bool shared = true;
89 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
90
91 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
92 // client can ask to test the allocation by passing NULL out_buffers
93 bool test_allocate = !out_buffers;
94
95 // Validate descriptors
96 std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
97 std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
98 for (uint32_t i = 0; i < num_descriptors; i++) {
99 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
100 if (map_descriptor == descriptors_map_.end()) {
101 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
102 } else {
103 descriptors.push_back(map_descriptor->second);
104 }
105 }
106
107 // Resolve implementation defined formats
108 for (auto &descriptor : descriptors) {
109 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
110 descriptor->GetConsumerUsage(),
111 descriptor->GetFormat()));
112 }
113
114 // Check if input descriptors can be supported AND
115 // Find out if a single buffer can be shared for all the given input descriptors
116 uint32_t i = 0;
117 ssize_t max_buf_index = -1;
118 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
119
120 if (test_allocate) {
121 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
122 return status;
123 }
124
125 std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
126 if (shared && (max_buf_index >= 0)) {
127 // Allocate one and duplicate/copy the handles for each descriptor
128 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
129 return GRALLOC1_ERROR_NO_RESOURCES;
130 }
131
132 for (i = 0; i < num_descriptors; i++) {
133 // Create new handle for a given descriptor.
134 // Current assumption is even MetaData memory would be same
135 // Need to revisit if there is a need for own metadata memory
136 if (i != UINT(max_buf_index)) {
137 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
138 }
139 }
140 } else {
141 // Buffer sharing is not feasible.
142 // Allocate separate buffer for each descriptor
143 for (i = 0; i < num_descriptors; i++) {
144 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
145 return GRALLOC1_ERROR_NO_RESOURCES;
146 }
147 }
148 }
149
150 // Allocation is successful. If backstore is not shared inform the client.
151 if (!shared) {
152 return GRALLOC1_ERROR_NOT_SHARED;
153 }
154
155 return status;
156 }
157
CreateSharedHandle(buffer_handle_t inbuffer,const BufferDescriptor & descriptor,buffer_handle_t * outbuffer)158 void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
159 buffer_handle_t *outbuffer) {
160 // TODO(user): This path is not verified
161 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
162
163 // Get Buffer attributes or dimension
164 unsigned int alignedw = 0, alignedh = 0;
165 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
166
167 // create new handle from input reference handle and given descriptor
168 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
169 descriptor.GetConsumerUsage());
170 int buffer_type = GetBufferType(descriptor.GetFormat());
171
172 // Duplicate the fds
173 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
174 private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
175 dup(input->fd_metadata),
176 flags,
177 INT(alignedw),
178 INT(alignedh),
179 descriptor.GetWidth(),
180 descriptor.GetHeight(),
181 descriptor.GetFormat(),
182 buffer_type,
183 input->size,
184 descriptor.GetProducerUsage(),
185 descriptor.GetConsumerUsage());
186 out_hnd->id = ++next_id_;
187 // TODO(user): Base address of shared handle and ion handles
188 RegisterHandleLocked(out_hnd, -1, -1);
189 *outbuffer = out_hnd;
190 }
191
FreeBuffer(std::shared_ptr<Buffer> buf)192 gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
193 auto hnd = buf->handle;
194 ALOGD_IF(DEBUG, "FreeBuffer handle:%p id: %" PRIu64, hnd, hnd->id);
195 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
196 hnd->fd, buf->ion_handle_main) != 0) {
197 return GRALLOC1_ERROR_BAD_HANDLE;
198 }
199
200 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
201 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
202 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
203 return GRALLOC1_ERROR_BAD_HANDLE;
204 }
205
206 private_handle_t * handle = const_cast<private_handle_t *>(hnd);
207 handle->fd = -1;
208 handle->fd_metadata = -1;
209 delete handle;
210 return GRALLOC1_ERROR_NONE;
211 }
212
RegisterHandleLocked(const private_handle_t * hnd,int ion_handle,int ion_handle_meta)213 void BufferManager::RegisterHandleLocked(const private_handle_t *hnd,
214 int ion_handle,
215 int ion_handle_meta) {
216 auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
217 handles_map_.emplace(std::make_pair(hnd, buffer));
218 }
219
ImportHandleLocked(private_handle_t * hnd)220 gralloc1_error_t BufferManager::ImportHandleLocked(private_handle_t *hnd) {
221 ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
222 int ion_handle = allocator_->ImportBuffer(hnd->fd);
223 if (ion_handle < 0) {
224 ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
225 return GRALLOC1_ERROR_BAD_HANDLE;
226 }
227 int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
228 if (ion_handle_meta < 0) {
229 ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd,
230 hnd->fd, hnd->id);
231 return GRALLOC1_ERROR_BAD_HANDLE;
232 }
233 // Set base pointers to NULL since the data here was received over binder
234 hnd->base = 0;
235 hnd->base_metadata = 0;
236 RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
237 return GRALLOC1_ERROR_NONE;
238 }
239
240 std::shared_ptr<BufferManager::Buffer>
GetBufferFromHandleLocked(const private_handle_t * hnd)241 BufferManager::GetBufferFromHandleLocked(const private_handle_t *hnd) {
242 if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
243 return nullptr;
244 }
245
246 auto it = handles_map_.find(hnd);
247 if (it != handles_map_.end()) {
248 return it->second;
249 } else {
250 return nullptr;
251 }
252 }
253
MapBuffer(private_handle_t const * handle)254 gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
255 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
256 ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
257
258 hnd->base = 0;
259 hnd->base_metadata = 0;
260
261 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
262 hnd->fd) != 0) {
263 return GRALLOC1_ERROR_BAD_HANDLE;
264 }
265
266 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize());
267 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
268 hnd->offset_metadata, hnd->fd_metadata) != 0) {
269 return GRALLOC1_ERROR_BAD_HANDLE;
270 }
271
272 return GRALLOC1_ERROR_NONE;
273 }
274
RetainBuffer(private_handle_t const * hnd)275 gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
276 if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
277 return GRALLOC1_ERROR_NONE;
278 }
279 ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
280 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
281 std::lock_guard<std::mutex> lock(buffer_lock_);
282 auto buf = GetBufferFromHandleLocked(hnd);
283 if (buf != nullptr) {
284 buf->IncRef();
285 } else {
286 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
287 err = ImportHandleLocked(handle);
288 }
289 return err;
290 }
291
ReleaseBuffer(private_handle_t const * hnd)292 gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
293 if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
294 return GRALLOC1_ERROR_NONE;
295 }
296 ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
297 std::lock_guard<std::mutex> lock(buffer_lock_);
298 auto buf = GetBufferFromHandleLocked(hnd);
299 if (buf == nullptr) {
300 ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
301 return GRALLOC1_ERROR_BAD_HANDLE;
302 } else {
303 if (buf->DecRef()) {
304 handles_map_.erase(hnd);
305 // Unmap, close ion handle and close fd
306 FreeBuffer(buf);
307 }
308 }
309 return GRALLOC1_ERROR_NONE;
310 }
311
LockBuffer(const private_handle_t * hnd,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)312 gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
313 gralloc1_producer_usage_t prod_usage,
314 gralloc1_consumer_usage_t cons_usage) {
315 std::lock_guard<std::mutex> lock(buffer_lock_);
316 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
317 ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
318
319 // If buffer is not meant for CPU return err
320 if (!CpuCanAccess(prod_usage, cons_usage)) {
321 return GRALLOC1_ERROR_BAD_VALUE;
322 }
323
324 if (hnd->base == 0) {
325 // we need to map for real
326 err = MapBuffer(hnd);
327 }
328
329 auto buf = GetBufferFromHandleLocked(hnd);
330 if (buf == nullptr) {
331 return GRALLOC1_ERROR_BAD_HANDLE;
332 }
333
334 // Invalidate if CPU reads in software and there are non-CPU
335 // writers. No need to do this for the metadata buffer as it is
336 // only read/written in software.
337
338 // todo use handle here
339 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
340 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
341 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
342 buf->ion_handle_main, CACHE_INVALIDATE)) {
343 return GRALLOC1_ERROR_BAD_HANDLE;
344 }
345 }
346
347 // Mark the buffer to be flushed after CPU write.
348 if (!err && CpuCanWrite(prod_usage)) {
349 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
350 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
351 }
352
353 return err;
354 }
355
UnlockBuffer(const private_handle_t * handle)356 gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
357 std::lock_guard<std::mutex> lock(buffer_lock_);
358 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
359
360 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
361 auto buf = GetBufferFromHandleLocked(hnd);
362 if (buf == nullptr) {
363 return GRALLOC1_ERROR_BAD_HANDLE;
364 }
365
366 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
367 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
368 buf->ion_handle_main, CACHE_CLEAN) != 0) {
369 status = GRALLOC1_ERROR_BAD_HANDLE;
370 }
371 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
372 }
373
374 return status;
375 }
376
GetHandleFlags(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)377 int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
378 gralloc1_consumer_usage_t cons_usage) {
379 int flags = 0;
380 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
381 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
382 }
383
384 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
385 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
386 }
387
388 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
389 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
390 }
391
392 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
393 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
394 }
395
396 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
397 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
398 }
399
400 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
401 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
402 }
403
404 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
405 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
406 }
407
408 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
409 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
410 }
411
412 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
413 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
414 }
415
416 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
417 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
418 }
419
420 // TODO(user): is this correct???
421 if ((cons_usage &
422 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
423 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
424 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
425 }
426
427 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
428 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
429 }
430
431 if (!allocator_->UseUncached(prod_usage, cons_usage)) {
432 flags |= private_handle_t::PRIV_FLAGS_CACHED;
433 }
434
435 return flags;
436 }
437
GetBufferType(int inputFormat)438 int BufferManager::GetBufferType(int inputFormat) {
439 int buffer_type = BUFFER_TYPE_VIDEO;
440 if (IsUncompressedRGBFormat(inputFormat)) {
441 // RGB formats
442 buffer_type = BUFFER_TYPE_UI;
443 }
444
445 return buffer_type;
446 }
447
AllocateBuffer(const BufferDescriptor & descriptor,buffer_handle_t * handle,unsigned int bufferSize)448 int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
449 unsigned int bufferSize) {
450 if (!handle)
451 return -EINVAL;
452
453 int format = descriptor.GetFormat();
454 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
455 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
456 uint32_t layer_count = descriptor.GetLayerCount();
457
458 // Get implementation defined format
459 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
460
461 unsigned int size;
462 unsigned int alignedw, alignedh;
463 int buffer_type = GetBufferType(gralloc_format);
464 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
465 size = (bufferSize >= size) ? bufferSize : size;
466
467 int err = 0;
468 int flags = 0;
469 auto page_size = UINT(getpagesize());
470 AllocData data;
471 data.align = allocator_->GetDataAlignment(format, prod_usage, cons_usage);
472 data.size = size;
473 data.handle = (uintptr_t) handle;
474 data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
475
476 // Allocate buffer memory
477 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
478 if (err) {
479 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
480 return err;
481 }
482
483 // Allocate memory for MetaData
484 AllocData e_data;
485 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
486 e_data.handle = data.handle;
487 e_data.align = page_size;
488
489 err =
490 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
491 if (err) {
492 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
493 return err;
494 }
495
496 flags = GetHandleFlags(format, prod_usage, cons_usage);
497 flags |= data.alloc_type;
498
499 // Create handle
500 private_handle_t *hnd = new private_handle_t(data.fd,
501 e_data.fd,
502 flags,
503 INT(alignedw),
504 INT(alignedh),
505 descriptor.GetWidth(),
506 descriptor.GetHeight(),
507 format,
508 buffer_type,
509 size,
510 prod_usage,
511 cons_usage);
512
513 hnd->id = ++next_id_;
514 hnd->base = 0;
515 hnd->base_metadata = 0;
516 hnd->layer_count = layer_count;
517
518 ColorSpace_t colorSpace = ITU_R_601;
519 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
520 *handle = hnd;
521 RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
522 ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
523 if (DEBUG) {
524 private_handle_t::Dump(hnd);
525 }
526 return err;
527 }
528
Perform(int operation,va_list args)529 gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
530 switch (operation) {
531 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
532 int fd = va_arg(args, int);
533 unsigned int size = va_arg(args, unsigned int);
534 unsigned int offset = va_arg(args, unsigned int);
535 void *base = va_arg(args, void *);
536 int width = va_arg(args, int);
537 int height = va_arg(args, int);
538 int format = va_arg(args, int);
539
540 native_handle_t **handle = va_arg(args, native_handle_t **);
541 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
542 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
543 if (hnd) {
544 unsigned int alignedw = 0, alignedh = 0;
545 hnd->magic = private_handle_t::kMagic;
546 hnd->fd = fd;
547 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
548 hnd->size = size;
549 hnd->offset = offset;
550 hnd->base = uint64_t(base) + offset;
551 hnd->gpuaddr = 0;
552 BufferDescriptor descriptor(width, height, format);
553 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
554 hnd->unaligned_width = width;
555 hnd->unaligned_height = height;
556 hnd->width = INT(alignedw);
557 hnd->height = INT(alignedh);
558 hnd->format = format;
559 *handle = reinterpret_cast<native_handle_t *>(hnd);
560 }
561 } break;
562
563 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
564 int width = va_arg(args, int);
565 int format = va_arg(args, int);
566 int *stride = va_arg(args, int *);
567 unsigned int alignedw = 0, alignedh = 0;
568 BufferDescriptor descriptor(width, width, format);
569 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
570 *stride = INT(alignedw);
571 } break;
572
573 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
574 private_handle_t *hnd = va_arg(args, private_handle_t *);
575 int *stride = va_arg(args, int *);
576 if (private_handle_t::validate(hnd) != 0) {
577 return GRALLOC1_ERROR_BAD_HANDLE;
578 }
579
580 BufferDim_t buffer_dim;
581 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
582 *stride = buffer_dim.sliceWidth;
583 } else {
584 *stride = hnd->width;
585 }
586 } break;
587
588 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
589 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
590 private_handle_t *hnd = va_arg(args, private_handle_t *);
591 int *stride = va_arg(args, int *);
592 int *height = va_arg(args, int *);
593 if (private_handle_t::validate(hnd) != 0) {
594 return GRALLOC1_ERROR_BAD_HANDLE;
595 }
596
597 BufferDim_t buffer_dim;
598 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
599 *stride = buffer_dim.sliceWidth;
600 *height = buffer_dim.sliceHeight;
601 } else {
602 *stride = hnd->width;
603 *height = hnd->height;
604 }
605 } break;
606
607 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
608 // TODO(user): Usage is split now. take care of it from Gfx client.
609 // see if we can directly expect descriptor from gfx client.
610 int width = va_arg(args, int);
611 int height = va_arg(args, int);
612 int format = va_arg(args, int);
613 uint64_t producer_usage = va_arg(args, uint64_t);
614 uint64_t consumer_usage = va_arg(args, uint64_t);
615 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
616 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
617
618 int *aligned_width = va_arg(args, int *);
619 int *aligned_height = va_arg(args, int *);
620 int *tile_enabled = va_arg(args, int *);
621 unsigned int alignedw, alignedh;
622 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
623 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
624
625 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
626 *aligned_width = INT(alignedw);
627 *aligned_height = INT(alignedh);
628 } break;
629
630 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
631 private_handle_t *hnd = va_arg(args, private_handle_t *);
632 int *color_space = va_arg(args, int *);
633 if (private_handle_t::validate(hnd) != 0) {
634 return GRALLOC1_ERROR_BAD_HANDLE;
635 }
636 #ifdef USE_COLOR_METADATA
637 ColorMetaData color_metadata;
638 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
639 switch (color_metadata.colorPrimaries) {
640 case ColorPrimaries_BT709_5:
641 *color_space = HAL_CSC_ITU_R_709;
642 break;
643 case ColorPrimaries_BT601_6_525:
644 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
645 break;
646 case ColorPrimaries_BT2020:
647 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
648 break;
649 default:
650 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
651 break;
652 }
653 break;
654 }
655 if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
656 *color_space = 0;
657 }
658 #else
659 *color_space = 0;
660 #endif
661 } break;
662 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
663 private_handle_t *hnd = va_arg(args, private_handle_t *);
664 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
665 if (private_handle_t::validate(hnd) != 0) {
666 return GRALLOC1_ERROR_BAD_HANDLE;
667 }
668 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
669 return GRALLOC1_ERROR_UNDEFINED;
670 }
671 } break;
672
673 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
674 private_handle_t *hnd = va_arg(args, private_handle_t *);
675 int *map_secure_buffer = va_arg(args, int *);
676 if (private_handle_t::validate(hnd) != 0) {
677 return GRALLOC1_ERROR_BAD_HANDLE;
678 }
679
680 if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
681 *map_secure_buffer = 0;
682 }
683 } break;
684
685 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
686 private_handle_t *hnd = va_arg(args, private_handle_t *);
687 int *flag = va_arg(args, int *);
688 if (private_handle_t::validate(hnd) != 0) {
689 return GRALLOC1_ERROR_BAD_HANDLE;
690 }
691 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
692 } break;
693
694 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
695 private_handle_t *hnd = va_arg(args, private_handle_t *);
696 void **rgb_data = va_arg(args, void **);
697 if (private_handle_t::validate(hnd) != 0) {
698 return GRALLOC1_ERROR_BAD_HANDLE;
699 }
700 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
701 return GRALLOC1_ERROR_UNDEFINED;
702 }
703 } break;
704
705 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
706 int width = va_arg(args, int);
707 int height = va_arg(args, int);
708 int format = va_arg(args, int);
709 uint64_t p_usage = va_arg(args, uint64_t);
710 uint64_t c_usage = va_arg(args, uint64_t);
711 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
712 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
713 uint32_t *aligned_width = va_arg(args, uint32_t *);
714 uint32_t *aligned_height = va_arg(args, uint32_t *);
715 uint32_t *size = va_arg(args, uint32_t *);
716 auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
717 allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
718 } break;
719
720 // TODO(user): Break out similar functionality, preferably moving to a common lib.
721
722 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
723 int width = va_arg(args, int);
724 int height = va_arg(args, int);
725 int format = va_arg(args, int);
726 uint64_t p_usage = va_arg(args, uint64_t);
727 uint64_t c_usage = va_arg(args, uint64_t);
728 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
729 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
730 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
731 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
732 unsigned int size;
733 unsigned int alignedw, alignedh;
734 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
735 AllocateBuffer(descriptor, hnd, size);
736 } break;
737
738 default:
739 break;
740 }
741 return GRALLOC1_ERROR_NONE;
742 }
743
IsYuvFormat(const private_handle_t * hnd)744 static bool IsYuvFormat(const private_handle_t *hnd) {
745 switch (hnd->format) {
746 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
747 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
748 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
749 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
750 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
751 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
752 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
753 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
754 case HAL_PIXEL_FORMAT_NV21_ZSL:
755 case HAL_PIXEL_FORMAT_RAW16:
756 case HAL_PIXEL_FORMAT_RAW12:
757 case HAL_PIXEL_FORMAT_RAW10:
758 case HAL_PIXEL_FORMAT_YV12:
759 return true;
760 default:
761 return false;
762 }
763 }
764
GetNumFlexPlanes(const private_handle_t * hnd,uint32_t * out_num_planes)765 gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
766 uint32_t *out_num_planes) {
767 if (!IsYuvFormat(hnd)) {
768 return GRALLOC1_ERROR_UNSUPPORTED;
769 } else {
770 *out_num_planes = 3;
771 }
772 return GRALLOC1_ERROR_NONE;
773 }
774
GetFlexLayout(const private_handle_t * hnd,struct android_flex_layout * layout)775 gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
776 struct android_flex_layout *layout) {
777 if (!IsYuvFormat(hnd)) {
778 return GRALLOC1_ERROR_UNSUPPORTED;
779 }
780
781 android_ycbcr ycbcr;
782 int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
783
784 if (err != 0) {
785 return GRALLOC1_ERROR_BAD_HANDLE;
786 }
787
788 layout->format = FLEX_FORMAT_YCbCr;
789 layout->num_planes = 3;
790
791 for (uint32_t i = 0; i < layout->num_planes; i++) {
792 layout->planes[i].bits_per_component = 8;
793 layout->planes[i].bits_used = 8;
794 layout->planes[i].h_increment = 1;
795 layout->planes[i].v_increment = 1;
796 layout->planes[i].h_subsampling = 2;
797 layout->planes[i].v_subsampling = 2;
798 }
799
800 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
801 layout->planes[0].component = FLEX_COMPONENT_Y;
802 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
803
804 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
805 layout->planes[1].component = FLEX_COMPONENT_Cb;
806 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
807 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
808
809 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
810 layout->planes[2].component = FLEX_COMPONENT_Cr;
811 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
812 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
813 return GRALLOC1_ERROR_NONE;
814 }
815
Dump(std::ostringstream * os)816 gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
817 for (auto it : handles_map_) {
818 auto buf = it.second;
819 auto hnd = buf->handle;
820 *os << "handle id: " << std::setw(4) << hnd->id;
821 *os << " fd: " << std::setw(3) << hnd->fd;
822 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
823 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
824 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
825 *os << std::setw(4) << hnd->unaligned_height;
826 *os << " size: " << std::setw(9) << hnd->size;
827 *os << std::hex << std::setfill('0');
828 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
829 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
830 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
831 // TODO(user): get format string from qdutils
832 *os << " format: " << "0x" << std::setw(8) << hnd->format;
833 *os << std::dec << std::setfill(' ') << std::endl;
834 }
835 return GRALLOC1_ERROR_NONE;
836 }
837
IsBufferImported(const private_handle_t * hnd)838 gralloc1_error_t BufferManager::IsBufferImported(const private_handle_t *hnd) {
839 std::lock_guard<std::mutex> lock(buffer_lock_);
840 auto buf = GetBufferFromHandleLocked(hnd);
841 if (buf != NULL) {
842 return GRALLOC1_ERROR_NONE;
843 }
844 return GRALLOC1_ERROR_BAD_HANDLE;
845 }
846
ValidateBufferSize(private_handle_t const * hnd,BufferDescriptor descriptor)847 gralloc1_error_t BufferManager::ValidateBufferSize(private_handle_t const *hnd,
848 BufferDescriptor descriptor) {
849 unsigned int size, alignedw, alignedh;
850 const int format = allocator_->GetImplDefinedFormat(descriptor.GetProducerUsage(),
851 descriptor.GetConsumerUsage(),
852 descriptor.GetFormat());
853 descriptor.SetColorFormat(format);
854 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
855
856 auto ion_fd_size = static_cast<unsigned int>(lseek(hnd->fd, 0, SEEK_END));
857 if (size != ion_fd_size) {
858 return GRALLOC1_ERROR_BAD_VALUE;
859 }
860 return GRALLOC1_ERROR_NONE;
861 }
862 } // namespace gralloc1
863