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