• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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