1 /*
2 * Copyright (c) 2011-2018 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
22 #include <iomanip>
23 #include <utility>
24 #include <vector>
25 #include <sstream>
26
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
34 namespace gralloc1 {
35 std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
36
GetBufferInfo(const BufferDescriptor & descriptor)37 static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
38 return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
39 descriptor.GetProducerUsage(), descriptor.GetConsumerUsage());
40 }
41
BufferManager()42 BufferManager::BufferManager() : next_id_(0) {
43 char property[PROPERTY_VALUE_MAX];
44
45 // Map framebuffer memory
46 if ((property_get(MAP_FB_MEMORY_PROP, 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 handles_map_.clear();
53 allocator_ = new Allocator();
54 allocator_->Init();
55 }
56
57
CreateBufferDescriptor(gralloc1_buffer_descriptor_t * descriptor_id)58 gralloc1_error_t BufferManager::CreateBufferDescriptor(
59 gralloc1_buffer_descriptor_t *descriptor_id) {
60 std::lock_guard<std::mutex> lock(descriptor_lock_);
61 auto descriptor = std::make_shared<BufferDescriptor>();
62 descriptors_map_.emplace(descriptor->GetId(), descriptor);
63 *descriptor_id = descriptor->GetId();
64 return GRALLOC1_ERROR_NONE;
65 }
66
DestroyBufferDescriptor(gralloc1_buffer_descriptor_t descriptor_id)67 gralloc1_error_t BufferManager::DestroyBufferDescriptor(
68 gralloc1_buffer_descriptor_t descriptor_id) {
69 std::lock_guard<std::mutex> lock(descriptor_lock_);
70 const auto descriptor = descriptors_map_.find(descriptor_id);
71 if (descriptor == descriptors_map_.end()) {
72 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
73 }
74 descriptors_map_.erase(descriptor);
75 return GRALLOC1_ERROR_NONE;
76 }
77
~BufferManager()78 BufferManager::~BufferManager() {
79 if (allocator_) {
80 delete allocator_;
81 }
82 }
83
AllocateBuffers(uint32_t num_descriptors,const gralloc1_buffer_descriptor_t * descriptor_ids,buffer_handle_t * out_buffers)84 gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
85 const gralloc1_buffer_descriptor_t *descriptor_ids,
86 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
94 // Validate descriptors
95 std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
96 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
113 // 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;
116 ssize_t max_buf_index = -1;
117 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
124 std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
125 if (shared && (max_buf_index >= 0)) {
126 // Allocate one and duplicate/copy the handles for each descriptor
127 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
128 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)) {
136 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
137 }
138 }
139 } else {
140 // Buffer sharing is not feasible.
141 // Allocate separate buffer for each descriptor
142 for (i = 0; i < num_descriptors; i++) {
143 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
144 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
CreateSharedHandle(buffer_handle_t inbuffer,const BufferDescriptor & descriptor,buffer_handle_t * outbuffer)157 void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
158 buffer_handle_t *outbuffer) {
159 // TODO(user): This path is not verified
160 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;
164 BufferInfo info = GetBufferInfo(descriptor);
165
166 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
167
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
174 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
175 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
189 RegisterHandleLocked(out_hnd, -1, -1);
190 *outbuffer = out_hnd;
191 }
192
FreeBuffer(std::shared_ptr<Buffer> buf)193 gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
194 auto hnd = buf->handle;
195 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
202 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
203 hnd->fd, buf->ion_handle_main) != 0) {
204 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,
209 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
210 return GRALLOC1_ERROR_BAD_HANDLE;
211 }
212
213 private_handle_t * handle = const_cast<private_handle_t *>(hnd);
214 handle->fd = -1;
215 handle->fd_metadata = -1;
216 if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
217 delete handle;
218 }
219 return GRALLOC1_ERROR_NONE;
220 }
221
RegisterHandleLocked(const private_handle_t * hnd,int ion_handle,int ion_handle_meta)222 void BufferManager::RegisterHandleLocked(const private_handle_t *hnd,
223 int ion_handle,
224 int ion_handle_meta) {
225 auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
226 handles_map_.emplace(std::make_pair(hnd, buffer));
227 }
228
ImportHandleLocked(private_handle_t * hnd)229 gralloc1_error_t BufferManager::ImportHandleLocked(private_handle_t *hnd) {
230 ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
231 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;
245 RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
246 return GRALLOC1_ERROR_NONE;
247 }
248
249 std::shared_ptr<BufferManager::Buffer>
GetBufferFromHandleLocked(const private_handle_t * hnd)250 BufferManager::GetBufferFromHandleLocked(const private_handle_t *hnd) {
251 auto it = handles_map_.find(hnd);
252 if (it != handles_map_.end()) {
253 return it->second;
254 } else {
255 return nullptr;
256 }
257 }
258
MapBuffer(private_handle_t const * handle)259 gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
260 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
261 ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
262
263 hnd->base = 0;
264 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
265 hnd->fd) != 0) {
266 return GRALLOC1_ERROR_BAD_HANDLE;
267 }
268 return GRALLOC1_ERROR_NONE;
269 }
270
RetainBuffer(private_handle_t const * hnd)271 gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
272 ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
273 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
274 std::lock_guard<std::mutex> lock(buffer_lock_);
275 auto buf = GetBufferFromHandleLocked(hnd);
276 if (buf != nullptr) {
277 buf->IncRef();
278 } else {
279 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
280 err = ImportHandleLocked(handle);
281 }
282 return err;
283 }
284
ReleaseBuffer(private_handle_t const * hnd)285 gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
286 ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
287 std::lock_guard<std::mutex> lock(buffer_lock_);
288 auto buf = GetBufferFromHandleLocked(hnd);
289 if (buf == nullptr) {
290 ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
291 return GRALLOC1_ERROR_BAD_HANDLE;
292 } else {
293 if (buf->DecRef()) {
294 handles_map_.erase(hnd);
295 // Unmap, close ion handle and close fd
296 FreeBuffer(buf);
297 }
298 }
299 return GRALLOC1_ERROR_NONE;
300 }
301
LockBuffer(const private_handle_t * hnd,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)302 gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
303 gralloc1_producer_usage_t prod_usage,
304 gralloc1_consumer_usage_t cons_usage) {
305 std::lock_guard<std::mutex> lock(buffer_lock_);
306 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
307 ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
308
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
314 auto buf = GetBufferFromHandleLocked(hnd);
315 if (buf == nullptr) {
316 return GRALLOC1_ERROR_BAD_HANDLE;
317 }
318
319 if (hnd->base == 0) {
320 // we need to map for real
321 err = MapBuffer(hnd);
322 }
323
324 // todo use handle here
325 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
326 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
327
328 // Invalidate if CPU reads in software and there are non-CPU
329 // writers. No need to do this for the metadata buffer as it is
330 // only read/written in software.
331 if ((cons_usage & (GRALLOC1_CONSUMER_USAGE_CPU_READ | GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
332 && (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER)) {
333 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
334 buf->ion_handle_main, CACHE_INVALIDATE)) {
335
336 return GRALLOC1_ERROR_BAD_HANDLE;
337 }
338 }
339 }
340
341 // Mark the buffer to be flushed after CPU write.
342 if (!err && CpuCanWrite(prod_usage)) {
343 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
344 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
345 }
346
347 return err;
348 }
349
UnlockBuffer(const private_handle_t * handle)350 gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
351 std::lock_guard<std::mutex> lock(buffer_lock_);
352 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
353
354 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
355 auto buf = GetBufferFromHandleLocked(hnd);
356 if (buf == nullptr) {
357 return GRALLOC1_ERROR_BAD_HANDLE;
358 }
359
360 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
361 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
362 buf->ion_handle_main, CACHE_CLEAN) != 0) {
363 status = GRALLOC1_ERROR_BAD_HANDLE;
364 }
365 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
366 }
367
368 return status;
369 }
370
GetDataAlignment(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)371 uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
372 gralloc1_consumer_usage_t cons_usage) {
373 uint32_t align = UINT(getpagesize());
374 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
375 align = 8192;
376 }
377
378 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
379 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
380 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
381 // The alignment here reflects qsee mmu V7L/V8L requirement
382 align = SZ_2M;
383 } else {
384 align = SECURE_ALIGN;
385 }
386 }
387
388 return align;
389 }
390
GetHandleFlags(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)391 int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
392 gralloc1_consumer_usage_t cons_usage) {
393 int flags = 0;
394 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
395 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
396 }
397
398 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
399 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
400 }
401
402 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
403 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
404 }
405
406 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
407 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
408 }
409
410 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
411 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
412 }
413
414 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
415 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
416 }
417
418 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
419 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
420 }
421
422 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
423 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
424 }
425
426 if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
427 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
428 }
429
430 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
431 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
432 }
433
434 // TODO(user): is this correct???
435 if ((cons_usage &
436 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
437 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
438 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
439 }
440
441 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
442 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
443 }
444
445 if (!allocator_->UseUncached(prod_usage, cons_usage)) {
446 flags |= private_handle_t::PRIV_FLAGS_CACHED;
447 }
448
449 return flags;
450 }
451
GetBufferType(int inputFormat)452 int BufferManager::GetBufferType(int inputFormat) {
453 int buffer_type = BUFFER_TYPE_VIDEO;
454 if (IsUncompressedRGBFormat(inputFormat)) {
455 // RGB formats
456 buffer_type = BUFFER_TYPE_UI;
457 }
458
459 return buffer_type;
460 }
461
AllocateBuffer(const BufferDescriptor & descriptor,buffer_handle_t * handle,unsigned int bufferSize)462 int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
463 unsigned int bufferSize) {
464 if (!handle)
465 return -EINVAL;
466
467 int format = descriptor.GetFormat();
468 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
469 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
470 uint32_t layer_count = descriptor.GetLayerCount();
471
472 // Get implementation defined format
473 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
474
475 unsigned int size;
476 unsigned int alignedw, alignedh;
477 int buffer_type = GetBufferType(gralloc_format);
478 BufferInfo info = GetBufferInfo(descriptor);
479 GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
480 size = (bufferSize >= size) ? bufferSize : size;
481
482 int err = 0;
483 int flags = 0;
484 auto page_size = UINT(getpagesize());
485 AllocData data;
486 data.align = GetDataAlignment(format, prod_usage, cons_usage);
487 size = ALIGN(size, data.align) * layer_count;
488 data.size = size;
489 data.handle = (uintptr_t) handle;
490 data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
491
492 // Allocate buffer memory
493 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
494 if (err) {
495 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
496 return err;
497 }
498
499 // Allocate memory for MetaData
500 AllocData e_data;
501 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
502 e_data.handle = data.handle;
503 e_data.align = page_size;
504
505 err =
506 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
507 if (err) {
508 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
509 return err;
510 }
511
512 flags = GetHandleFlags(format, prod_usage, cons_usage);
513 flags |= data.alloc_type;
514
515 // Create handle
516 private_handle_t *hnd = new private_handle_t(data.fd,
517 e_data.fd,
518 flags,
519 INT(alignedw),
520 INT(alignedh),
521 descriptor.GetWidth(),
522 descriptor.GetHeight(),
523 format,
524 buffer_type,
525 data.size,
526 prod_usage,
527 cons_usage);
528
529 hnd->id = ++next_id_;
530 hnd->base = 0;
531 hnd->base_metadata = 0;
532 hnd->layer_count = layer_count;
533
534 ColorSpace_t colorSpace = ITU_R_601;
535 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
536 *handle = hnd;
537 RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
538 ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
539 if (DEBUG) {
540 private_handle_t::Dump(hnd);
541 }
542 return err;
543 }
544
Perform(int operation,va_list args)545 gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
546 switch (operation) {
547 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
548 int fd = va_arg(args, int);
549 unsigned int size = va_arg(args, unsigned int);
550 unsigned int offset = va_arg(args, unsigned int);
551 void *base = va_arg(args, void *);
552 int width = va_arg(args, int);
553 int height = va_arg(args, int);
554 int format = va_arg(args, int);
555
556 native_handle_t **handle = va_arg(args, native_handle_t **);
557 if (!handle) {
558 return GRALLOC1_ERROR_BAD_HANDLE;
559 }
560
561 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
562 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
563 if (hnd) {
564 unsigned int alignedw = 0, alignedh = 0;
565 hnd->magic = private_handle_t::kMagic;
566 hnd->fd = fd;
567 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
568 hnd->size = size;
569 hnd->offset = offset;
570 hnd->base = uint64_t(base);
571 hnd->gpuaddr = 0;
572 BufferInfo info(width, height, format);
573 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
574 hnd->unaligned_width = width;
575 hnd->unaligned_height = height;
576 hnd->width = INT(alignedw);
577 hnd->height = INT(alignedh);
578 hnd->format = format;
579 *handle = reinterpret_cast<native_handle_t *>(hnd);
580 }
581 } break;
582
583 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
584 int width = va_arg(args, int);
585 int format = va_arg(args, int);
586 int *stride = va_arg(args, int *);
587 unsigned int alignedw = 0, alignedh = 0;
588
589 if (!stride) {
590 return GRALLOC1_ERROR_BAD_VALUE;
591 }
592
593 BufferInfo info(width, width, format);
594 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
595 *stride = INT(alignedw);
596 } break;
597
598 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
599 private_handle_t *hnd = va_arg(args, private_handle_t *);
600 int *stride = va_arg(args, int *);
601 if (private_handle_t::validate(hnd) != 0) {
602 return GRALLOC1_ERROR_BAD_HANDLE;
603 }
604
605 if (!stride) {
606 return GRALLOC1_ERROR_BAD_VALUE;
607 }
608
609 BufferDim_t buffer_dim;
610 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
611 *stride = buffer_dim.sliceWidth;
612 } else {
613 *stride = hnd->width;
614 }
615 } break;
616
617 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
618 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
619 private_handle_t *hnd = va_arg(args, private_handle_t *);
620 int *stride = va_arg(args, int *);
621 int *height = va_arg(args, int *);
622 if (private_handle_t::validate(hnd) != 0) {
623 return GRALLOC1_ERROR_BAD_HANDLE;
624 }
625
626 if (!stride || !height) {
627 return GRALLOC1_ERROR_BAD_VALUE;
628 }
629
630 BufferDim_t buffer_dim;
631 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
632 *stride = buffer_dim.sliceWidth;
633 *height = buffer_dim.sliceHeight;
634 } else {
635 *stride = hnd->width;
636 *height = hnd->height;
637 }
638 } break;
639
640 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
641 // TODO(user): Usage is split now. take care of it from Gfx client.
642 // see if we can directly expect descriptor from gfx client.
643 int width = va_arg(args, int);
644 int height = va_arg(args, int);
645 int format = va_arg(args, int);
646 uint64_t producer_usage = va_arg(args, uint64_t);
647 uint64_t consumer_usage = va_arg(args, uint64_t);
648 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
649 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
650
651 int *aligned_width = va_arg(args, int *);
652 int *aligned_height = va_arg(args, int *);
653 int *tile_enabled = va_arg(args, int *);
654 if (!aligned_width || !aligned_height || !tile_enabled) {
655 return GRALLOC1_ERROR_BAD_VALUE;
656 }
657
658 unsigned int alignedw, alignedh;
659 BufferInfo info(width, height, format, prod_usage, cons_usage);
660 *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
661 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
662 *aligned_width = INT(alignedw);
663 *aligned_height = INT(alignedh);
664 } break;
665
666 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
667 private_handle_t *hnd = va_arg(args, private_handle_t *);
668 int *color_space = va_arg(args, int *);
669
670 if (private_handle_t::validate(hnd) != 0) {
671 return GRALLOC1_ERROR_BAD_HANDLE;
672 }
673
674 if (!color_space) {
675 return GRALLOC1_ERROR_BAD_VALUE;
676 }
677
678 *color_space = 0;
679 ColorMetaData color_metadata;
680 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
681 switch (color_metadata.colorPrimaries) {
682 case ColorPrimaries_BT709_5:
683 *color_space = HAL_CSC_ITU_R_709;
684 break;
685 case ColorPrimaries_BT601_6_525:
686 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
687 break;
688 case ColorPrimaries_BT2020:
689 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
690 break;
691 default:
692 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
693 break;
694 }
695 break;
696 } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
697 *color_space = 0;
698 }
699 } 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 }
706
707 if (!ycbcr) {
708 return GRALLOC1_ERROR_BAD_VALUE;
709 }
710
711 if (GetYUVPlaneInfo(hnd, ycbcr)) {
712 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 *);
719
720 if (private_handle_t::validate(hnd) != 0) {
721 return GRALLOC1_ERROR_BAD_HANDLE;
722 }
723
724 if (!map_secure_buffer) {
725 return GRALLOC1_ERROR_BAD_VALUE;
726 }
727
728 if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
729 *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 *);
736
737 if (private_handle_t::validate(hnd) != 0) {
738 return GRALLOC1_ERROR_BAD_HANDLE;
739 }
740
741 if (!flag) {
742 return GRALLOC1_ERROR_BAD_VALUE;
743 }
744
745 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
746 int linear_format = 0;
747 if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
748 if (linear_format) {
749 *flag = 0;
750 }
751 }
752 } 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 **);
757
758 if (private_handle_t::validate(hnd) != 0) {
759 return GRALLOC1_ERROR_BAD_HANDLE;
760 }
761
762 if (!rgb_data) {
763 return GRALLOC1_ERROR_BAD_VALUE;
764 }
765
766 if (GetRgbDataAddress(hnd, rgb_data)) {
767 return GRALLOC1_ERROR_UNDEFINED;
768 }
769 } break;
770
771 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 *);
782
783 if (!aligned_width || !aligned_height || !size) {
784 return GRALLOC1_ERROR_BAD_VALUE;
785 }
786
787 auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
788 GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
789 // Align size
790 auto align = GetDataAlignment(format, producer_usage, consumer_usage);
791 *size = ALIGN(*size, align);
792 } break;
793
794 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
795 std::lock_guard<std::mutex> lock(buffer_lock_);
796 int width = va_arg(args, int);
797 int height = va_arg(args, int);
798 int format = va_arg(args, int);
799 uint64_t p_usage = va_arg(args, uint64_t);
800 uint64_t c_usage = va_arg(args, uint64_t);
801 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
802 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
803 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
804 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
805 unsigned int size;
806 unsigned int alignedw, alignedh;
807 GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
808 AllocateBuffer(descriptor, hnd, size);
809 } break;
810
811 case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
812 private_handle_t *hnd = va_arg(args, private_handle_t *);
813 int *flag = va_arg(args, int *);
814
815 if (private_handle_t::validate(hnd) != 0) {
816 return GRALLOC1_ERROR_BAD_HANDLE;
817 }
818
819 if (!flag) {
820 return GRALLOC1_ERROR_BAD_VALUE;
821 }
822
823 if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
824 *flag = 0;
825 }
826 } break;
827
828 default:
829 break;
830 }
831 return GRALLOC1_ERROR_NONE;
832 }
833
IsYuvFormat(const private_handle_t * hnd)834 static bool IsYuvFormat(const private_handle_t *hnd) {
835 switch (hnd->format) {
836 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
837 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
838 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
839 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
840 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
841 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
842 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
843 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
844 case HAL_PIXEL_FORMAT_NV21_ZSL:
845 case HAL_PIXEL_FORMAT_RAW16:
846 case HAL_PIXEL_FORMAT_Y16:
847 case HAL_PIXEL_FORMAT_RAW12:
848 case HAL_PIXEL_FORMAT_RAW10:
849 case HAL_PIXEL_FORMAT_YV12:
850 case HAL_PIXEL_FORMAT_Y8:
851 return true;
852 default:
853 return false;
854 }
855 }
856
GetNumFlexPlanes(const private_handle_t * hnd,uint32_t * out_num_planes)857 gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
858 uint32_t *out_num_planes) {
859 if (!IsYuvFormat(hnd)) {
860 return GRALLOC1_ERROR_UNSUPPORTED;
861 } else {
862 *out_num_planes = 3;
863 }
864 return GRALLOC1_ERROR_NONE;
865 }
866
GetFlexLayout(const private_handle_t * hnd,struct android_flex_layout * layout)867 gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
868 struct android_flex_layout *layout) {
869 if (!IsYuvFormat(hnd)) {
870 return GRALLOC1_ERROR_UNSUPPORTED;
871 }
872
873 android_ycbcr ycbcr;
874 int err = GetYUVPlaneInfo(hnd, &ycbcr);
875
876 if (err != 0) {
877 return GRALLOC1_ERROR_BAD_HANDLE;
878 }
879
880 layout->format = FLEX_FORMAT_YCbCr;
881 layout->num_planes = 3;
882
883 for (uint32_t i = 0; i < layout->num_planes; i++) {
884 layout->planes[i].bits_per_component = 8;
885 layout->planes[i].bits_used = 8;
886 layout->planes[i].h_increment = 1;
887 layout->planes[i].v_increment = 1;
888 layout->planes[i].h_subsampling = 2;
889 layout->planes[i].v_subsampling = 2;
890 }
891
892 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
893 layout->planes[0].component = FLEX_COMPONENT_Y;
894 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
895
896 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
897 layout->planes[1].component = FLEX_COMPONENT_Cb;
898 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
899 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
900
901 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
902 layout->planes[2].component = FLEX_COMPONENT_Cr;
903 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
904 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
905 return GRALLOC1_ERROR_NONE;
906 }
907
Dump(std::ostringstream * os)908 gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
909 for (auto it : handles_map_) {
910 auto buf = it.second;
911 auto hnd = buf->handle;
912 *os << "handle id: " << std::setw(4) << hnd->id;
913 *os << " fd: " << std::setw(3) << hnd->fd;
914 *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
915 *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height;
916 *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
917 *os << std::setw(4) << hnd->unaligned_height;
918 *os << " size: " << std::setw(9) << hnd->size;
919 *os << std::hex << std::setfill('0');
920 *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
921 *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
922 *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
923 // TODO(user): get format string from qdutils
924 *os << " format: " << "0x" << std::setw(8) << hnd->format;
925 *os << std::dec << std::setfill(' ') << std::endl;
926 }
927 return GRALLOC1_ERROR_NONE;
928 }
929 } // namespace gralloc1
930