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