1/*
2* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7*  * Redistributions of source code must retain the above copyright
8*    notice, this list of conditions and the following disclaimer.
9*  * Redistributions in binary form must reproduce the above
10*    copyright notice, this list of conditions and the following
11*    disclaimer in the documentation and/or other materials provided
12*    with the distribution.
13*  * Neither the name of The Linux Foundation nor the names of its
14*    contributors may be used to endorse or promote products derived
15*    from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <gralloc_priv.h>
31
32#include <core/buffer_allocator.h>
33#include <utils/constants.h>
34#include <utils/debug.h>
35
36#include "hwc_buffer_allocator.h"
37#include "hwc_debugger.h"
38#include "gr_utils.h"
39
40#define __CLASS__ "HWCBufferAllocator"
41
42namespace sdm {
43
44HWCBufferAllocator::HWCBufferAllocator() {
45  int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
46  if (err != 0) {
47    DLOGE("FATAL: can not open GRALLOC module");
48  } else {
49    gralloc1_open(module_, &gralloc_device_);
50  }
51  if (gralloc_device_ != nullptr) {
52    ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
53        gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
54    Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
55        gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
56    Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
57        gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
58  }
59}
60
61HWCBufferAllocator::~HWCBufferAllocator() {
62  if (gralloc_device_ != nullptr) {
63    gralloc1_close(gralloc_device_);
64  }
65}
66
67DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
68  const BufferConfig &buffer_config = buffer_info->buffer_config;
69  AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
70  uint32_t width = buffer_config.width;
71  uint32_t height = buffer_config.height;
72  int format;
73  uint64_t alloc_flags = 0;
74  int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
75  if (error != 0) {
76    return kErrorParameters;
77  }
78
79  if (buffer_config.secure) {
80    alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
81  }
82
83  if (!buffer_config.cache) {
84    // Allocate uncached buffers
85    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
86  }
87
88  if (buffer_config.gfx_client) {
89    alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
90  }
91
92  uint64_t producer_usage = alloc_flags;
93  uint64_t consumer_usage = alloc_flags;
94  // CreateBuffer
95  private_handle_t *hnd = nullptr;
96  Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
97           producer_usage, consumer_usage, &hnd);
98
99  if (hnd) {
100    alloc_buffer_info->fd = hnd->fd;
101    alloc_buffer_info->stride = UINT32(hnd->width);
102    alloc_buffer_info->size = hnd->size;
103  } else {
104    DLOGE("Failed to allocate memory");
105    return kErrorMemory;
106  }
107
108  buffer_info->private_data = reinterpret_cast<void *>(hnd);
109  return kErrorNone;
110}
111
112DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
113  DisplayError err = kErrorNone;
114  buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
115  ReleaseBuffer_(gralloc_device_, hnd);
116  AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
117
118  alloc_buffer_info->fd = -1;
119  alloc_buffer_info->stride = 0;
120  alloc_buffer_info->size = 0;
121  buffer_info->private_data = NULL;
122  return err;
123}
124
125void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
126                                                 int *height) {
127  Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle,
128           width, height);
129}
130
131void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
132                                                  uint32_t alloc_type, int *aligned_width,
133                                                  int *aligned_height) {
134  int tile_enabled;
135  gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
136  gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
137  if (alloc_type & GRALLOC_USAGE_HW_FB) {
138    consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
139  }
140  if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
141    producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
142  }
143
144  Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
145           producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
146}
147
148uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
149  const BufferConfig &buffer_config = buffer_info->buffer_config;
150  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
151
152  int width = INT(buffer_config.width);
153  int height = INT(buffer_config.height);
154  int format;
155
156  if (buffer_config.secure) {
157    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
158  }
159
160  if (!buffer_config.cache) {
161    // Allocate uncached buffers
162    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
163  }
164
165  if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
166    return 0;
167  }
168
169  uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
170  gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
171  gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
172  // TODO(user): Currently both flags are treated similarly in gralloc
173  producer_usage = gralloc1_producer_usage_t(alloc_flags);
174  consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
175  gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
176  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
177  return buffer_size;
178}
179
180int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
181  switch (format) {
182    case kFormatRGBA8888:
183      *target = HAL_PIXEL_FORMAT_RGBA_8888;
184      break;
185    case kFormatRGBX8888:
186      *target = HAL_PIXEL_FORMAT_RGBX_8888;
187      break;
188    case kFormatRGB888:
189      *target = HAL_PIXEL_FORMAT_RGB_888;
190      break;
191    case kFormatRGB565:
192      *target = HAL_PIXEL_FORMAT_RGB_565;
193      break;
194    case kFormatBGR565:
195      *target = HAL_PIXEL_FORMAT_BGR_565;
196      break;
197    case kFormatBGR888:
198      *target = HAL_PIXEL_FORMAT_BGR_888;
199      break;
200    case kFormatBGRA8888:
201      *target = HAL_PIXEL_FORMAT_BGRA_8888;
202      break;
203    case kFormatYCrCb420PlanarStride16:
204      *target = HAL_PIXEL_FORMAT_YV12;
205      break;
206    case kFormatYCrCb420SemiPlanar:
207      *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
208      break;
209    case kFormatYCbCr420SemiPlanar:
210      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
211      break;
212    case kFormatYCbCr422H2V1Packed:
213      *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
214      break;
215    case kFormatCbYCrY422H2V1Packed:
216      *target = HAL_PIXEL_FORMAT_CbYCrY_422_I;
217      break;
218    case kFormatYCbCr422H2V1SemiPlanar:
219      *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
220      break;
221    case kFormatYCbCr420SemiPlanarVenus:
222      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
223      break;
224    case kFormatYCrCb420SemiPlanarVenus:
225      *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
226      break;
227    case kFormatYCbCr420SPVenusUbwc:
228      *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
229      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
230      break;
231    case kFormatRGBA5551:
232      *target = HAL_PIXEL_FORMAT_RGBA_5551;
233      break;
234    case kFormatRGBA4444:
235      *target = HAL_PIXEL_FORMAT_RGBA_4444;
236      break;
237    case kFormatRGBA1010102:
238      *target = HAL_PIXEL_FORMAT_RGBA_1010102;
239      break;
240    case kFormatARGB2101010:
241      *target = HAL_PIXEL_FORMAT_ARGB_2101010;
242      break;
243    case kFormatRGBX1010102:
244      *target = HAL_PIXEL_FORMAT_RGBX_1010102;
245      break;
246    case kFormatXRGB2101010:
247      *target = HAL_PIXEL_FORMAT_XRGB_2101010;
248      break;
249    case kFormatBGRA1010102:
250      *target = HAL_PIXEL_FORMAT_BGRA_1010102;
251      break;
252    case kFormatABGR2101010:
253      *target = HAL_PIXEL_FORMAT_ABGR_2101010;
254      break;
255    case kFormatBGRX1010102:
256      *target = HAL_PIXEL_FORMAT_BGRX_1010102;
257      break;
258    case kFormatXBGR2101010:
259      *target = HAL_PIXEL_FORMAT_XBGR_2101010;
260      break;
261    case kFormatYCbCr420P010:
262      *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
263      break;
264    case kFormatYCbCr420TP10Ubwc:
265      *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
266      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
267      break;
268    case kFormatYCbCr420P010Ubwc:
269      *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
270      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
271      break;
272    case kFormatRGBA8888Ubwc:
273      *target = HAL_PIXEL_FORMAT_RGBA_8888;
274      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
275      break;
276    case kFormatRGBX8888Ubwc:
277      *target = HAL_PIXEL_FORMAT_RGBX_8888;
278      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
279      break;
280    case kFormatBGR565Ubwc:
281      *target = HAL_PIXEL_FORMAT_BGR_565;
282      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
283      break;
284    case kFormatRGBA1010102Ubwc:
285      *target = HAL_PIXEL_FORMAT_RGBA_1010102;
286      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
287      break;
288    case kFormatRGBX1010102Ubwc:
289      *target = HAL_PIXEL_FORMAT_RGBX_1010102;
290      *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
291      break;
292    default:
293      DLOGE("Unsupported format = 0x%x", format);
294      return -EINVAL;
295  }
296  return 0;
297}
298
299DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
300    const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
301  // TODO(user): This API should pass the buffer_info of the already allocated buffer
302  // The private_data can then be typecast to the private_handle and used directly.
303  uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
304
305  int width = INT(buffer_config.width);
306  int height = INT(buffer_config.height);
307  int format;
308
309  if (buffer_config.secure) {
310    alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
311  }
312
313  if (!buffer_config.cache) {
314    // Allocate uncached buffers
315    alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
316  }
317
318  if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
319    return kErrorParameters;
320  }
321
322  uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
323  gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
324  gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
325  // TODO(user): Currently both flags are treated similarly in gralloc
326  producer_usage = gralloc1_producer_usage_t(alloc_flags);
327  consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
328  gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
329  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
330  allocated_buffer_info->stride = UINT32(aligned_width);
331  allocated_buffer_info->aligned_width = UINT32(aligned_width);
332  allocated_buffer_info->aligned_height = UINT32(aligned_height);
333  allocated_buffer_info->size = UINT32(buffer_size);
334
335  return kErrorNone;
336}
337
338DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
339                                                 uint32_t stride[4], uint32_t offset[4],
340                                                 uint32_t *num_planes) {
341  // TODO(user): Transition APIs to not need a private handle
342  private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
343  int format = HAL_PIXEL_FORMAT_RGBA_8888;
344  uint64_t flags = 0;
345
346  SetBufferInfo(buf_info.format, &format, &flags);
347  // Setup only the required stuff, skip rest
348  hnd.format = format;
349  hnd.width = INT32(buf_info.aligned_width);
350  hnd.height = INT32(buf_info.aligned_height);
351  if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
352    hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
353  }
354
355  int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes);
356  if (ret < 0) {
357    DLOGE("GetBufferLayout failed");
358    return kErrorParameters;
359  }
360
361  return kErrorNone;
362}
363
364DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
365  void* buffer_ptr = NULL;
366  const gralloc1_rect_t accessRegion = {
367        .left = 0,
368        .top = 0,
369        .width = 0,
370        .height = 0
371  };
372  Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
373        &accessRegion, &buffer_ptr, acquire_fence);
374  if (!buffer_ptr) {
375    return kErrorUndefined;
376  }
377
378  return kErrorNone;
379}
380
381}  // namespace sdm
382