• 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 
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("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
47       (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
48        (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
49     map_fb_mem_ = true;
50   }
51 
52   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 id: %" PRIu64, hnd, hnd->id);
196   if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
197                              hnd->fd, buf->ion_handle_main) != 0) {
198     return GRALLOC1_ERROR_BAD_HANDLE;
199   }
200 
201   unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
202   if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
203                              hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
204     return GRALLOC1_ERROR_BAD_HANDLE;
205   }
206 
207   private_handle_t * handle = const_cast<private_handle_t *>(hnd);
208   handle->fd = -1;
209   handle->fd_metadata = -1;
210   if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
211       delete handle;
212   }
213   return GRALLOC1_ERROR_NONE;
214 }
215 
RegisterHandleLocked(const private_handle_t * hnd,int ion_handle,int ion_handle_meta)216 void BufferManager::RegisterHandleLocked(const private_handle_t *hnd,
217                                          int ion_handle,
218                                          int ion_handle_meta) {
219   auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
220   handles_map_.emplace(std::make_pair(hnd, buffer));
221 }
222 
ImportHandleLocked(private_handle_t * hnd)223 gralloc1_error_t BufferManager::ImportHandleLocked(private_handle_t *hnd) {
224   ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
225   int ion_handle = allocator_->ImportBuffer(hnd->fd);
226   if (ion_handle < 0) {
227     ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
228     return GRALLOC1_ERROR_BAD_HANDLE;
229   }
230   int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
231   if (ion_handle_meta < 0) {
232     ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd,
233           hnd->fd, hnd->id);
234     return GRALLOC1_ERROR_BAD_HANDLE;
235   }
236   // Set base pointers to NULL since the data here was received over binder
237   hnd->base = 0;
238   hnd->base_metadata = 0;
239   RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
240   return GRALLOC1_ERROR_NONE;
241 }
242 
243 std::shared_ptr<BufferManager::Buffer>
GetBufferFromHandleLocked(const private_handle_t * hnd)244 BufferManager::GetBufferFromHandleLocked(const private_handle_t *hnd) {
245   auto it = handles_map_.find(hnd);
246   if (it != handles_map_.end()) {
247     return it->second;
248   } else {
249     return nullptr;
250   }
251 }
252 
MapBuffer(private_handle_t const * handle)253 gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
254   private_handle_t *hnd = const_cast<private_handle_t *>(handle);
255   ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
256 
257   hnd->base = 0;
258   if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
259                             hnd->fd) != 0) {
260     return GRALLOC1_ERROR_BAD_HANDLE;
261   }
262   return GRALLOC1_ERROR_NONE;
263 }
264 
RetainBuffer(private_handle_t const * hnd)265 gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
266   ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
267   gralloc1_error_t err = GRALLOC1_ERROR_NONE;
268   std::lock_guard<std::mutex> lock(buffer_lock_);
269   auto buf = GetBufferFromHandleLocked(hnd);
270   if (buf != nullptr) {
271     buf->IncRef();
272   } else {
273     private_handle_t *handle = const_cast<private_handle_t *>(hnd);
274     err = ImportHandleLocked(handle);
275     if (err == GRALLOC1_ERROR_NONE) {
276       // TODO(user): See bug 35955598
277       if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
278         return GRALLOC1_ERROR_NONE;  // Don't map secure buffer
279       }
280       err = MapBuffer(hnd);
281     }
282   }
283   return err;
284 }
285 
ReleaseBuffer(private_handle_t const * hnd)286 gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
287   ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
288   std::lock_guard<std::mutex> lock(buffer_lock_);
289   auto buf = GetBufferFromHandleLocked(hnd);
290   if (buf == nullptr) {
291     ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
292     return GRALLOC1_ERROR_BAD_HANDLE;
293   } else {
294     if (buf->DecRef()) {
295       handles_map_.erase(hnd);
296       // Unmap, close ion handle and close fd
297       FreeBuffer(buf);
298     }
299   }
300   return GRALLOC1_ERROR_NONE;
301 }
302 
LockBuffer(const private_handle_t * hnd,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)303 gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
304                                            gralloc1_producer_usage_t prod_usage,
305                                            gralloc1_consumer_usage_t cons_usage) {
306   std::lock_guard<std::mutex> lock(buffer_lock_);
307   gralloc1_error_t err = GRALLOC1_ERROR_NONE;
308   ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
309 
310   // If buffer is not meant for CPU return err
311   if (!CpuCanAccess(prod_usage, cons_usage)) {
312     return GRALLOC1_ERROR_BAD_VALUE;
313   }
314 
315   auto buf = GetBufferFromHandleLocked(hnd);
316   if (buf == nullptr) {
317     return GRALLOC1_ERROR_BAD_HANDLE;
318   }
319 
320   if (hnd->base == 0) {
321     // we need to map for real
322     err = MapBuffer(hnd);
323   }
324 
325   // Invalidate if CPU reads in software and there are non-CPU
326   // writers. No need to do this for the metadata buffer as it is
327   // only read/written in software.
328 
329   // todo use handle here
330   if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
331       (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
332     if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
333                                 buf->ion_handle_main, CACHE_INVALIDATE)) {
334       return GRALLOC1_ERROR_BAD_HANDLE;
335     }
336   }
337 
338   // Mark the buffer to be flushed after CPU write.
339   if (!err && CpuCanWrite(prod_usage)) {
340     private_handle_t *handle = const_cast<private_handle_t *>(hnd);
341     handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
342   }
343 
344   return err;
345 }
346 
UnlockBuffer(const private_handle_t * handle)347 gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
348   std::lock_guard<std::mutex> lock(buffer_lock_);
349   gralloc1_error_t status = GRALLOC1_ERROR_NONE;
350 
351   private_handle_t *hnd = const_cast<private_handle_t *>(handle);
352   auto buf = GetBufferFromHandleLocked(hnd);
353   if (buf == nullptr) {
354     return GRALLOC1_ERROR_BAD_HANDLE;
355   }
356 
357   if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
358     if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
359                                 buf->ion_handle_main, CACHE_CLEAN) != 0) {
360       status = GRALLOC1_ERROR_BAD_HANDLE;
361     }
362     hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
363   }
364 
365   return status;
366 }
367 
GetDataAlignment(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)368 uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
369                                     gralloc1_consumer_usage_t cons_usage) {
370   uint32_t align = UINT(getpagesize());
371   if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
372     align = 8192;
373   }
374 
375   if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
376     if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
377         (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
378       // The alignment here reflects qsee mmu V7L/V8L requirement
379       align = SZ_2M;
380     } else {
381       align = SECURE_ALIGN;
382     }
383   }
384 
385   return align;
386 }
387 
GetHandleFlags(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)388 int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
389                                   gralloc1_consumer_usage_t cons_usage) {
390   int flags = 0;
391   if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
392     flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
393   }
394 
395   if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
396     flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
397   }
398 
399   if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
400     flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
401   }
402 
403   if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
404     flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
405   }
406 
407   if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
408     flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
409   }
410 
411   if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
412     flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
413   }
414 
415   if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
416     flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
417   }
418 
419   if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
420     flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
421   }
422 
423   if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
424     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
425   }
426 
427   if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
428     flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
429   }
430 
431   // TODO(user): is this correct???
432   if ((cons_usage &
433        (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
434       (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
435     flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
436   }
437 
438   if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
439     flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
440   }
441 
442   if (!allocator_->UseUncached(prod_usage, cons_usage)) {
443     flags |= private_handle_t::PRIV_FLAGS_CACHED;
444   }
445 
446   return flags;
447 }
448 
GetBufferType(int inputFormat)449 int BufferManager::GetBufferType(int inputFormat) {
450   int buffer_type = BUFFER_TYPE_VIDEO;
451   if (IsUncompressedRGBFormat(inputFormat)) {
452     // RGB formats
453     buffer_type = BUFFER_TYPE_UI;
454   }
455 
456   return buffer_type;
457 }
458 
AllocateBuffer(const BufferDescriptor & descriptor,buffer_handle_t * handle,unsigned int bufferSize)459 int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
460                                   unsigned int bufferSize) {
461   if (!handle)
462     return -EINVAL;
463 
464   int format = descriptor.GetFormat();
465   gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
466   gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
467   uint32_t layer_count = descriptor.GetLayerCount();
468 
469   // Get implementation defined format
470   int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
471 
472   unsigned int size;
473   unsigned int alignedw, alignedh;
474   int buffer_type = GetBufferType(gralloc_format);
475   BufferInfo info = GetBufferInfo(descriptor);
476   GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
477   size = (bufferSize >= size) ? bufferSize : size;
478   size = size * layer_count;
479 
480   int err = 0;
481   int flags = 0;
482   auto page_size = UINT(getpagesize());
483   AllocData data;
484   data.align = GetDataAlignment(format, prod_usage, cons_usage);
485   data.size = ALIGN(size, data.align);
486   data.handle = (uintptr_t) handle;
487   data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
488 
489   // Allocate buffer memory
490   err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
491   if (err) {
492     ALOGE("gralloc failed to allocate err=%s", strerror(-err));
493     return err;
494   }
495 
496   // Allocate memory for MetaData
497   AllocData e_data;
498   e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
499   e_data.handle = data.handle;
500   e_data.align = page_size;
501 
502   err =
503       allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
504   if (err) {
505     ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
506     return err;
507   }
508 
509   flags = GetHandleFlags(format, prod_usage, cons_usage);
510   flags |= data.alloc_type;
511 
512   // Create handle
513   private_handle_t *hnd = new private_handle_t(data.fd,
514                                                e_data.fd,
515                                                flags,
516                                                INT(alignedw),
517                                                INT(alignedh),
518                                                descriptor.GetWidth(),
519                                                descriptor.GetHeight(),
520                                                format,
521                                                buffer_type,
522                                                size,
523                                                prod_usage,
524                                                cons_usage);
525 
526   hnd->id = ++next_id_;
527   hnd->base = 0;
528   hnd->base_metadata = 0;
529   hnd->layer_count = layer_count;
530 
531   ColorSpace_t colorSpace = ITU_R_601;
532   setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
533   *handle = hnd;
534   RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
535   ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
536   if (DEBUG) {
537     private_handle_t::Dump(hnd);
538   }
539   return err;
540 }
541 
Perform(int operation,va_list args)542 gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
543   switch (operation) {
544     case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
545       int fd = va_arg(args, int);
546       unsigned int size = va_arg(args, unsigned int);
547       unsigned int offset = va_arg(args, unsigned int);
548       void *base = va_arg(args, void *);
549       int width = va_arg(args, int);
550       int height = va_arg(args, int);
551       int format = va_arg(args, int);
552 
553       native_handle_t **handle = va_arg(args, native_handle_t **);
554       if (!handle) {
555         return GRALLOC1_ERROR_BAD_HANDLE;
556       }
557 
558       private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
559           native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
560       if (hnd) {
561         unsigned int alignedw = 0, alignedh = 0;
562         hnd->magic = private_handle_t::kMagic;
563         hnd->fd = fd;
564         hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
565         hnd->size = size;
566         hnd->offset = offset;
567         hnd->base = uint64_t(base);
568         hnd->gpuaddr = 0;
569         BufferInfo info(width, height, format);
570         GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
571         hnd->unaligned_width = width;
572         hnd->unaligned_height = height;
573         hnd->width = INT(alignedw);
574         hnd->height = INT(alignedh);
575         hnd->format = format;
576         *handle = reinterpret_cast<native_handle_t *>(hnd);
577       }
578     } break;
579 
580     case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
581       int width = va_arg(args, int);
582       int format = va_arg(args, int);
583       int *stride = va_arg(args, int *);
584       unsigned int alignedw = 0, alignedh = 0;
585 
586       if (!stride) {
587         return GRALLOC1_ERROR_BAD_VALUE;
588       }
589 
590       BufferInfo info(width, width, format);
591       GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
592       *stride = INT(alignedw);
593     } break;
594 
595     case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
596       private_handle_t *hnd = va_arg(args, private_handle_t *);
597       int *stride = va_arg(args, int *);
598       if (private_handle_t::validate(hnd) != 0) {
599         return GRALLOC1_ERROR_BAD_HANDLE;
600       }
601 
602       if (!stride) {
603         return GRALLOC1_ERROR_BAD_VALUE;
604       }
605 
606       BufferDim_t buffer_dim;
607       if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
608         *stride = buffer_dim.sliceWidth;
609       } else {
610         *stride = hnd->width;
611       }
612     } break;
613 
614     // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
615     case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
616       private_handle_t *hnd = va_arg(args, private_handle_t *);
617       int *stride = va_arg(args, int *);
618       int *height = va_arg(args, int *);
619       if (private_handle_t::validate(hnd) != 0) {
620         return GRALLOC1_ERROR_BAD_HANDLE;
621       }
622 
623       if (!stride || !height) {
624         return GRALLOC1_ERROR_BAD_VALUE;
625       }
626 
627       BufferDim_t buffer_dim;
628       if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
629         *stride = buffer_dim.sliceWidth;
630         *height = buffer_dim.sliceHeight;
631       } else {
632         *stride = hnd->width;
633         *height = hnd->height;
634       }
635     } break;
636 
637     case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
638       // TODO(user): Usage is split now. take care of it from Gfx client.
639       // see if we can directly expect descriptor from gfx client.
640       int width = va_arg(args, int);
641       int height = va_arg(args, int);
642       int format = va_arg(args, int);
643       uint64_t producer_usage = va_arg(args, uint64_t);
644       uint64_t consumer_usage = va_arg(args, uint64_t);
645       gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
646       gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
647 
648       int *aligned_width = va_arg(args, int *);
649       int *aligned_height = va_arg(args, int *);
650       int *tile_enabled = va_arg(args, int *);
651       if (!aligned_width || !aligned_height || !tile_enabled) {
652         return GRALLOC1_ERROR_BAD_VALUE;
653       }
654 
655       unsigned int alignedw, alignedh;
656       BufferInfo info(width, height, format, prod_usage, cons_usage);
657       *tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
658       GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
659       *aligned_width = INT(alignedw);
660       *aligned_height = INT(alignedh);
661     } break;
662 
663     case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
664       private_handle_t *hnd = va_arg(args, private_handle_t *);
665       int *color_space = va_arg(args, int *);
666 
667       if (private_handle_t::validate(hnd) != 0) {
668         return GRALLOC1_ERROR_BAD_HANDLE;
669       }
670 
671       if (!color_space) {
672         return GRALLOC1_ERROR_BAD_VALUE;
673       }
674 
675       *color_space = 0;
676 #ifdef USE_COLOR_METADATA
677       ColorMetaData color_metadata;
678       if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
679         switch (color_metadata.colorPrimaries) {
680           case ColorPrimaries_BT709_5:
681             *color_space = HAL_CSC_ITU_R_709;
682             break;
683           case ColorPrimaries_BT601_6_525:
684             *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
685             break;
686           case ColorPrimaries_BT2020:
687             *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
688             break;
689           default:
690             ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
691             break;
692         }
693         break;
694       }
695       if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
696           *color_space = 0;
697       }
698 #endif
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       int width = va_arg(args, int);
796       int height = va_arg(args, int);
797       int format = va_arg(args, int);
798       uint64_t p_usage = va_arg(args, uint64_t);
799       uint64_t c_usage = va_arg(args, uint64_t);
800       buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
801       gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
802       gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
803       BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
804       unsigned int size;
805       unsigned int alignedw, alignedh;
806       GetBufferSizeAndDimensions(GetBufferInfo(descriptor), &size, &alignedw, &alignedh);
807       AllocateBuffer(descriptor, hnd, size);
808     } break;
809 
810     case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
811       private_handle_t *hnd = va_arg(args, private_handle_t *);
812       int *flag = va_arg(args, int *);
813 
814       if (private_handle_t::validate(hnd) != 0) {
815         return GRALLOC1_ERROR_BAD_HANDLE;
816       }
817 
818       if (!flag) {
819         return GRALLOC1_ERROR_BAD_VALUE;
820       }
821 
822       if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
823         *flag = 0;
824       }
825     } break;
826 
827     default:
828       break;
829   }
830   return GRALLOC1_ERROR_NONE;
831 }
832 
IsYuvFormat(const private_handle_t * hnd)833 static bool IsYuvFormat(const private_handle_t *hnd) {
834   switch (hnd->format) {
835     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
836     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
837     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
838     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:   // Same as YCbCr_420_SP_VENUS
839     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
840     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
841     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
842     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
843     case HAL_PIXEL_FORMAT_NV21_ZSL:
844     case HAL_PIXEL_FORMAT_RAW16:
845     case HAL_PIXEL_FORMAT_Y16:
846     case HAL_PIXEL_FORMAT_RAW12:
847     case HAL_PIXEL_FORMAT_RAW10:
848     case HAL_PIXEL_FORMAT_YV12:
849     case HAL_PIXEL_FORMAT_Y8:
850       return true;
851     default:
852       return false;
853   }
854 }
855 
GetNumFlexPlanes(const private_handle_t * hnd,uint32_t * out_num_planes)856 gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
857                                                  uint32_t *out_num_planes) {
858   if (!IsYuvFormat(hnd)) {
859     return GRALLOC1_ERROR_UNSUPPORTED;
860   } else {
861     *out_num_planes = 3;
862   }
863   return GRALLOC1_ERROR_NONE;
864 }
865 
GetFlexLayout(const private_handle_t * hnd,struct android_flex_layout * layout)866 gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
867                                               struct android_flex_layout *layout) {
868   if (!IsYuvFormat(hnd)) {
869     return GRALLOC1_ERROR_UNSUPPORTED;
870   }
871 
872   android_ycbcr ycbcr;
873   int err = GetYUVPlaneInfo(hnd, &ycbcr);
874 
875   if (err != 0) {
876     return GRALLOC1_ERROR_BAD_HANDLE;
877   }
878 
879   layout->format = FLEX_FORMAT_YCbCr;
880   layout->num_planes = 3;
881 
882   for (uint32_t i = 0; i < layout->num_planes; i++) {
883     layout->planes[i].bits_per_component = 8;
884     layout->planes[i].bits_used = 8;
885     layout->planes[i].h_increment = 1;
886     layout->planes[i].v_increment = 1;
887     layout->planes[i].h_subsampling = 2;
888     layout->planes[i].v_subsampling = 2;
889   }
890 
891   layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
892   layout->planes[0].component = FLEX_COMPONENT_Y;
893   layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
894 
895   layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
896   layout->planes[1].component = FLEX_COMPONENT_Cb;
897   layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
898   layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
899 
900   layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
901   layout->planes[2].component = FLEX_COMPONENT_Cr;
902   layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
903   layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
904   return GRALLOC1_ERROR_NONE;
905 }
906 
Dump(std::ostringstream * os)907 gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
908   for (auto it : handles_map_) {
909     auto buf = it.second;
910     auto hnd = buf->handle;
911     *os << "handle id: " << std::setw(4) << hnd->id;
912     *os << " fd: "       << std::setw(3) << hnd->fd;
913     *os << " fd_meta: "  << std::setw(3) << hnd->fd_metadata;
914     *os << " wxh: "      << std::setw(4) << hnd->width <<" x " << std::setw(4) <<  hnd->height;
915     *os << " uwxuh: "    << std::setw(4) << hnd->unaligned_width << " x ";
916     *os << std::setw(4)  <<  hnd->unaligned_height;
917     *os << " size: "     << std::setw(9) << hnd->size;
918     *os << std::hex << std::setfill('0');
919     *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
920     *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
921     *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
922     // TODO(user): get format string from qdutils
923     *os << " format: "     << "0x" << std::setw(8) << hnd->format;
924     *os << std::dec  << std::setfill(' ') << std::endl;
925   }
926   return GRALLOC1_ERROR_NONE;
927 }
928 }  //  namespace gralloc1
929