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