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
33namespace gralloc1 {
34std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
35
36BufferManager::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
59gralloc1_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
68gralloc1_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
79BufferManager::~BufferManager() {
80  if (allocator_) {
81    delete allocator_;
82  }
83}
84
85gralloc1_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
158void 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
192gralloc1_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
213void 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
220gralloc1_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
240std::shared_ptr<BufferManager::Buffer>
241BufferManager::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
254gralloc1_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
275gralloc1_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
292gralloc1_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
312gralloc1_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
356gralloc1_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
377uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
378                                    gralloc1_consumer_usage_t cons_usage) {
379  uint32_t align = UINT(getpagesize());
380  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
381    align = 8192;
382  }
383
384  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
385    if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
386        (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
387      // The alignment here reflects qsee mmu V7L/V8L requirement
388      align = SZ_2M;
389    } else {
390      align = SECURE_ALIGN;
391    }
392  }
393
394  return align;
395}
396
397int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
398                                  gralloc1_consumer_usage_t cons_usage) {
399  int flags = 0;
400  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
401    flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
402  }
403
404  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
405    flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
406  }
407
408  if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
409    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
410  }
411
412  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
413    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
414  }
415
416  if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
417    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
418  }
419
420  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
421    flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
422  }
423
424  if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
425    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
426  }
427
428  if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
429    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
430  }
431
432  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
433    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
434  }
435
436  if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
437    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
438  }
439
440  // TODO(user): is this correct???
441  if ((cons_usage &
442       (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
443      (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
444    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
445  }
446
447  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
448    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
449  }
450
451  if (!allocator_->UseUncached(prod_usage, cons_usage)) {
452    flags |= private_handle_t::PRIV_FLAGS_CACHED;
453  }
454
455  return flags;
456}
457
458int BufferManager::GetBufferType(int inputFormat) {
459  int buffer_type = BUFFER_TYPE_VIDEO;
460  if (IsUncompressedRGBFormat(inputFormat)) {
461    // RGB formats
462    buffer_type = BUFFER_TYPE_UI;
463  }
464
465  return buffer_type;
466}
467
468int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
469                                  unsigned int bufferSize) {
470  if (!handle)
471    return -EINVAL;
472
473  int format = descriptor.GetFormat();
474  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
475  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
476  uint32_t layer_count = descriptor.GetLayerCount();
477
478  // Get implementation defined format
479  int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
480
481  unsigned int size;
482  unsigned int alignedw, alignedh;
483  int buffer_type = GetBufferType(gralloc_format);
484  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
485  size = (bufferSize >= size) ? bufferSize : size;
486
487  int err = 0;
488  int flags = 0;
489  auto page_size = UINT(getpagesize());
490  AllocData data;
491  data.align = GetDataAlignment(format, prod_usage, cons_usage);
492  size = ALIGN(size, data.align) * layer_count;
493  data.size = size;
494  data.handle = (uintptr_t) handle;
495  data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
496
497  // Allocate buffer memory
498  err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
499  if (err) {
500    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
501    return err;
502  }
503
504  // Allocate memory for MetaData
505  AllocData e_data;
506  e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
507  e_data.handle = data.handle;
508  e_data.align = page_size;
509
510  err =
511      allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
512  if (err) {
513    ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
514    return err;
515  }
516
517  flags = GetHandleFlags(format, prod_usage, cons_usage);
518  flags |= data.alloc_type;
519
520  // Create handle
521  private_handle_t *hnd = new private_handle_t(data.fd,
522                                               e_data.fd,
523                                               flags,
524                                               INT(alignedw),
525                                               INT(alignedh),
526                                               descriptor.GetWidth(),
527                                               descriptor.GetHeight(),
528                                               format,
529                                               buffer_type,
530                                               size,
531                                               prod_usage,
532                                               cons_usage);
533
534  hnd->id = ++next_id_;
535  hnd->base = 0;
536  hnd->base_metadata = 0;
537  hnd->layer_count = layer_count;
538
539  ColorSpace_t colorSpace = ITU_R_601;
540  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
541  *handle = hnd;
542  RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
543  ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
544  if (DEBUG) {
545    private_handle_t::Dump(hnd);
546  }
547  return err;
548}
549
550gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
551  switch (operation) {
552    case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
553      int fd = va_arg(args, int);
554      unsigned int size = va_arg(args, unsigned int);
555      unsigned int offset = va_arg(args, unsigned int);
556      void *base = va_arg(args, void *);
557      int width = va_arg(args, int);
558      int height = va_arg(args, int);
559      int format = va_arg(args, int);
560
561      native_handle_t **handle = va_arg(args, native_handle_t **);
562      private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
563          native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
564      if (hnd) {
565        unsigned int alignedw = 0, alignedh = 0;
566        hnd->magic = private_handle_t::kMagic;
567        hnd->fd = fd;
568        hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
569        hnd->size = size;
570        hnd->offset = offset;
571        hnd->base = uint64_t(base) + offset;
572        hnd->gpuaddr = 0;
573        BufferDescriptor descriptor(width, height, format);
574        allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
575        hnd->unaligned_width = width;
576        hnd->unaligned_height = height;
577        hnd->width = INT(alignedw);
578        hnd->height = INT(alignedh);
579        hnd->format = format;
580        *handle = reinterpret_cast<native_handle_t *>(hnd);
581      }
582    } break;
583
584    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
585      int width = va_arg(args, int);
586      int format = va_arg(args, int);
587      int *stride = va_arg(args, int *);
588      unsigned int alignedw = 0, alignedh = 0;
589      BufferDescriptor descriptor(width, width, format);
590      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
591      *stride = INT(alignedw);
592    } break;
593
594    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
595      private_handle_t *hnd = va_arg(args, private_handle_t *);
596      int *stride = va_arg(args, int *);
597      if (private_handle_t::validate(hnd) != 0) {
598        return GRALLOC1_ERROR_BAD_HANDLE;
599      }
600
601      BufferDim_t buffer_dim;
602      if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
603        *stride = buffer_dim.sliceWidth;
604      } else {
605        *stride = hnd->width;
606      }
607    } break;
608
609    // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
610    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
611      private_handle_t *hnd = va_arg(args, private_handle_t *);
612      int *stride = va_arg(args, int *);
613      int *height = va_arg(args, int *);
614      if (private_handle_t::validate(hnd) != 0) {
615        return GRALLOC1_ERROR_BAD_HANDLE;
616      }
617
618      BufferDim_t buffer_dim;
619      if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
620        *stride = buffer_dim.sliceWidth;
621        *height = buffer_dim.sliceHeight;
622      } else {
623        *stride = hnd->width;
624        *height = hnd->height;
625      }
626    } break;
627
628    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
629      // TODO(user): Usage is split now. take care of it from Gfx client.
630      // see if we can directly expect descriptor from gfx client.
631      int width = va_arg(args, int);
632      int height = va_arg(args, int);
633      int format = va_arg(args, int);
634      uint64_t producer_usage = va_arg(args, uint64_t);
635      uint64_t consumer_usage = va_arg(args, uint64_t);
636      gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
637      gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
638
639      int *aligned_width = va_arg(args, int *);
640      int *aligned_height = va_arg(args, int *);
641      int *tile_enabled = va_arg(args, int *);
642      unsigned int alignedw, alignedh;
643      BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
644      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
645
646      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
647      *aligned_width = INT(alignedw);
648      *aligned_height = INT(alignedh);
649    } break;
650
651    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
652      private_handle_t *hnd = va_arg(args, private_handle_t *);
653      int *color_space = va_arg(args, int *);
654      if (private_handle_t::validate(hnd) != 0) {
655        return GRALLOC1_ERROR_BAD_HANDLE;
656      }
657#ifdef USE_COLOR_METADATA
658      ColorMetaData color_metadata;
659      if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
660        switch (color_metadata.colorPrimaries) {
661          case ColorPrimaries_BT709_5:
662            *color_space = HAL_CSC_ITU_R_709;
663            break;
664          case ColorPrimaries_BT601_6_525:
665            *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
666            break;
667          case ColorPrimaries_BT2020:
668            *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
669            break;
670          default:
671            ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
672            break;
673        }
674        break;
675      }
676      if (getMetaData(hnd, GET_COLOR_SPACE, &color_metadata) != 0) {
677          *color_space = 0;
678      }
679#else
680          *color_space = 0;
681#endif
682    } break;
683    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
684      private_handle_t *hnd = va_arg(args, private_handle_t *);
685      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
686      if (private_handle_t::validate(hnd) != 0) {
687        return GRALLOC1_ERROR_BAD_HANDLE;
688      }
689      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
690        return GRALLOC1_ERROR_UNDEFINED;
691      }
692    } break;
693
694    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
695      private_handle_t *hnd = va_arg(args, private_handle_t *);
696      int *map_secure_buffer = va_arg(args, int *);
697      if (private_handle_t::validate(hnd) != 0) {
698        return GRALLOC1_ERROR_BAD_HANDLE;
699      }
700
701      if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
702        *map_secure_buffer = 0;
703      }
704    } break;
705
706    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
707      private_handle_t *hnd = va_arg(args, private_handle_t *);
708      int *flag = va_arg(args, int *);
709      if (private_handle_t::validate(hnd) != 0) {
710        return GRALLOC1_ERROR_BAD_HANDLE;
711      }
712      *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
713    } break;
714
715    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
716      private_handle_t *hnd = va_arg(args, private_handle_t *);
717      void **rgb_data = va_arg(args, void **);
718      if (private_handle_t::validate(hnd) != 0) {
719        return GRALLOC1_ERROR_BAD_HANDLE;
720      }
721      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
722        return GRALLOC1_ERROR_UNDEFINED;
723      }
724    } break;
725
726    case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
727      int width = va_arg(args, int);
728      int height = va_arg(args, int);
729      int format = va_arg(args, int);
730      uint64_t p_usage = va_arg(args, uint64_t);
731      uint64_t c_usage = va_arg(args, uint64_t);
732      gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
733      gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
734      uint32_t *aligned_width = va_arg(args, uint32_t *);
735      uint32_t *aligned_height = va_arg(args, uint32_t *);
736      uint32_t *size = va_arg(args, uint32_t *);
737      auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
738      allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
739      // Align size
740      auto align = GetDataAlignment(format, producer_usage, consumer_usage);
741      *size = ALIGN(*size, align);
742    } break;
743
744      // TODO(user): Break out similar functionality, preferably moving to a common lib.
745
746    case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
747      int width = va_arg(args, int);
748      int height = va_arg(args, int);
749      int format = va_arg(args, int);
750      uint64_t p_usage = va_arg(args, uint64_t);
751      uint64_t c_usage = va_arg(args, uint64_t);
752      buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
753      gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
754      gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
755      BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
756      unsigned int size;
757      unsigned int alignedw, alignedh;
758      allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
759      AllocateBuffer(descriptor, hnd, size);
760    } break;
761
762    default:
763      break;
764  }
765  return GRALLOC1_ERROR_NONE;
766}
767
768static bool IsYuvFormat(const private_handle_t *hnd) {
769  switch (hnd->format) {
770    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
771    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
772    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
773    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:   // Same as YCbCr_420_SP_VENUS
774    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
775    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
776    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
777    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
778    case HAL_PIXEL_FORMAT_NV21_ZSL:
779    case HAL_PIXEL_FORMAT_RAW16:
780    case HAL_PIXEL_FORMAT_RAW12:
781    case HAL_PIXEL_FORMAT_RAW10:
782    case HAL_PIXEL_FORMAT_YV12:
783      return true;
784    default:
785      return false;
786  }
787}
788
789gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
790                                                 uint32_t *out_num_planes) {
791  if (!IsYuvFormat(hnd)) {
792    return GRALLOC1_ERROR_UNSUPPORTED;
793  } else {
794    *out_num_planes = 3;
795  }
796  return GRALLOC1_ERROR_NONE;
797}
798
799gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
800                                              struct android_flex_layout *layout) {
801  if (!IsYuvFormat(hnd)) {
802    return GRALLOC1_ERROR_UNSUPPORTED;
803  }
804
805  android_ycbcr ycbcr;
806  int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
807
808  if (err != 0) {
809    return GRALLOC1_ERROR_BAD_HANDLE;
810  }
811
812  layout->format = FLEX_FORMAT_YCbCr;
813  layout->num_planes = 3;
814
815  for (uint32_t i = 0; i < layout->num_planes; i++) {
816    layout->planes[i].bits_per_component = 8;
817    layout->planes[i].bits_used = 8;
818    layout->planes[i].h_increment = 1;
819    layout->planes[i].v_increment = 1;
820    layout->planes[i].h_subsampling = 2;
821    layout->planes[i].v_subsampling = 2;
822  }
823
824  layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
825  layout->planes[0].component = FLEX_COMPONENT_Y;
826  layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
827
828  layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
829  layout->planes[1].component = FLEX_COMPONENT_Cb;
830  layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
831  layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
832
833  layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
834  layout->planes[2].component = FLEX_COMPONENT_Cr;
835  layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
836  layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
837  return GRALLOC1_ERROR_NONE;
838}
839
840gralloc1_error_t BufferManager::Dump(std::ostringstream *os) {
841  for (auto it : handles_map_) {
842    auto buf = it.second;
843    auto hnd = buf->handle;
844    *os << "handle id: " << std::setw(4) << hnd->id;
845    *os << " fd: "       << std::setw(3) << hnd->fd;
846    *os << " fd_meta: "  << std::setw(3) << hnd->fd_metadata;
847    *os << " wxh: "      << std::setw(4) << hnd->width <<" x " << std::setw(4) <<  hnd->height;
848    *os << " uwxuh: "    << std::setw(4) << hnd->unaligned_width << " x ";
849    *os << std::setw(4)  <<  hnd->unaligned_height;
850    *os << " size: "     << std::setw(9) << hnd->size;
851    *os << std::hex << std::setfill('0');
852    *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags;
853    *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage;
854    *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage;
855    // TODO(user): get format string from qdutils
856    *os << " format: "     << "0x" << std::setw(8) << hnd->format;
857    *os << std::dec  << std::setfill(' ') << std::endl;
858  }
859  return GRALLOC1_ERROR_NONE;
860}
861}  //  namespace gralloc1
862