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