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
39 #define __CLASS__ "HWCBufferAllocator"
40 namespace sdm {
41
HWCBufferAllocator()42 HWCBufferAllocator::HWCBufferAllocator() {
43 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
44 if (err != 0) {
45 DLOGE("FATAL: can not open GRALLOC module");
46 } else {
47 gralloc1_open(module_, &gralloc_device_);
48 }
49 ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
50 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
51 Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
52 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
53 }
54
~HWCBufferAllocator()55 HWCBufferAllocator::~HWCBufferAllocator() {
56 if (gralloc_device_ != nullptr) {
57 gralloc1_close(gralloc_device_);
58 }
59 }
60
AllocateBuffer(BufferInfo * buffer_info)61 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
62 const BufferConfig &buffer_config = buffer_info->buffer_config;
63 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
64 uint32_t width = buffer_config.width;
65 uint32_t height = buffer_config.height;
66 int format;
67 int alloc_flags = 0;
68 int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
69 if (error != 0) {
70 return kErrorParameters;
71 }
72
73 if (buffer_config.secure) {
74 alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
75 }
76
77 if (!buffer_config.cache) {
78 // Allocate uncached buffers
79 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
80 }
81 uint64_t producer_usage = UINT64(alloc_flags);
82 uint64_t consumer_usage = UINT64(alloc_flags);
83 // CreateBuffer
84 private_handle_t *hnd = nullptr;
85 Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
86 producer_usage, consumer_usage, &hnd);
87
88 if (hnd) {
89 alloc_buffer_info->fd = hnd->fd;
90 alloc_buffer_info->stride = UINT32(hnd->width);
91 alloc_buffer_info->size = hnd->size;
92 } else {
93 DLOGE("Failed to allocate memory");
94 return kErrorMemory;
95 }
96
97 buffer_info->private_data = reinterpret_cast<void *>(hnd);
98 return kErrorNone;
99 }
100
FreeBuffer(BufferInfo * buffer_info)101 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
102 DisplayError err = kErrorNone;
103 buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
104 ReleaseBuffer_(gralloc_device_, hnd);
105 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
106 alloc_buffer_info->fd = -1;
107 alloc_buffer_info->stride = 0;
108 alloc_buffer_info->size = 0;
109 buffer_info->private_data = NULL;
110 return err;
111 }
112
GetCustomWidthAndHeight(const private_handle_t * handle,int * width,int * height)113 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
114 int *height) {
115 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle,
116 width, height);
117 }
118
GetAlignedWidthAndHeight(int width,int height,int format,uint32_t alloc_type,int * aligned_width,int * aligned_height)119 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
120 uint32_t alloc_type, int *aligned_width,
121 int *aligned_height) {
122 int tile_enabled;
123 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
124 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
125 if (alloc_type & GRALLOC_USAGE_HW_FB) {
126 consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
127 }
128
129 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
130 producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
131 }
132
GetBufferSize(BufferInfo * buffer_info)133 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
134 const BufferConfig &buffer_config = buffer_info->buffer_config;
135 int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
136
137 int width = INT(buffer_config.width);
138 int height = INT(buffer_config.height);
139 int format;
140
141 if (buffer_config.secure) {
142 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
143 }
144
145 if (!buffer_config.cache) {
146 // Allocate uncached buffers
147 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
148 }
149
150 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
151 return 0;
152 }
153
154 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
155 uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
156 uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
157 // TODO(user): Currently both flags are treated similarly in gralloc
158 producer_usage = UINT64(alloc_flags);
159 consumer_usage = producer_usage;
160 Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
161 format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
162 return buffer_size;
163 }
164
SetBufferInfo(LayerBufferFormat format,int * target,int * flags)165 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *flags) {
166 switch (format) {
167 case kFormatRGBA8888:
168 *target = HAL_PIXEL_FORMAT_RGBA_8888;
169 break;
170 case kFormatRGBX8888:
171 *target = HAL_PIXEL_FORMAT_RGBX_8888;
172 break;
173 case kFormatRGB888:
174 *target = HAL_PIXEL_FORMAT_RGB_888;
175 break;
176 case kFormatRGB565:
177 *target = HAL_PIXEL_FORMAT_RGB_565;
178 break;
179 case kFormatBGR565:
180 *target = HAL_PIXEL_FORMAT_BGR_565;
181 break;
182 case kFormatBGRA8888:
183 *target = HAL_PIXEL_FORMAT_BGRA_8888;
184 break;
185 case kFormatYCrCb420PlanarStride16:
186 *target = HAL_PIXEL_FORMAT_YV12;
187 break;
188 case kFormatYCrCb420SemiPlanar:
189 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
190 break;
191 case kFormatYCbCr420SemiPlanar:
192 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
193 break;
194 case kFormatYCbCr422H2V1Packed:
195 *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
196 break;
197 case kFormatYCbCr422H2V1SemiPlanar:
198 *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
199 break;
200 case kFormatYCbCr420SemiPlanarVenus:
201 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
202 break;
203 case kFormatYCrCb420SemiPlanarVenus:
204 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
205 break;
206 case kFormatYCbCr420SPVenusUbwc:
207 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
208 break;
209 case kFormatRGBA5551:
210 *target = HAL_PIXEL_FORMAT_RGBA_5551;
211 break;
212 case kFormatRGBA4444:
213 *target = HAL_PIXEL_FORMAT_RGBA_4444;
214 break;
215 case kFormatRGBA1010102:
216 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
217 break;
218 case kFormatARGB2101010:
219 *target = HAL_PIXEL_FORMAT_ARGB_2101010;
220 break;
221 case kFormatRGBX1010102:
222 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
223 break;
224 case kFormatXRGB2101010:
225 *target = HAL_PIXEL_FORMAT_XRGB_2101010;
226 break;
227 case kFormatBGRA1010102:
228 *target = HAL_PIXEL_FORMAT_BGRA_1010102;
229 break;
230 case kFormatABGR2101010:
231 *target = HAL_PIXEL_FORMAT_ABGR_2101010;
232 break;
233 case kFormatBGRX1010102:
234 *target = HAL_PIXEL_FORMAT_BGRX_1010102;
235 break;
236 case kFormatXBGR2101010:
237 *target = HAL_PIXEL_FORMAT_XBGR_2101010;
238 break;
239 case kFormatYCbCr420P010:
240 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
241 break;
242 case kFormatYCbCr420TP10Ubwc:
243 *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
244 break;
245 case kFormatRGBA8888Ubwc:
246 *target = HAL_PIXEL_FORMAT_RGBA_8888;
247 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
248 break;
249 case kFormatRGBX8888Ubwc:
250 *target = HAL_PIXEL_FORMAT_RGBX_8888;
251 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
252 break;
253 case kFormatBGR565Ubwc:
254 *target = HAL_PIXEL_FORMAT_BGR_565;
255 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
256 break;
257 case kFormatRGBA1010102Ubwc:
258 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
259 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
260 break;
261 case kFormatRGBX1010102Ubwc:
262 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
263 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
264 break;
265 default:
266 DLOGE("Unsupported format = 0x%x", format);
267 return -EINVAL;
268 }
269 return 0;
270 }
271
GetAllocatedBufferInfo(const BufferConfig & buffer_config,AllocatedBufferInfo * allocated_buffer_info)272 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
273 const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
274 // TODO(user): This API should pass the buffer_info of the already allocated buffer
275 // The private_data can then be typecast to the private_handle and used directly.
276 int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
277
278 int width = INT(buffer_config.width);
279 int height = INT(buffer_config.height);
280 int format;
281
282 if (buffer_config.secure) {
283 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
284 }
285
286 if (!buffer_config.cache) {
287 // Allocate uncached buffers
288 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
289 }
290
291 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
292 return kErrorParameters;
293 }
294
295 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
296 uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
297 uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
298 // TODO(user): Currently both flags are treated similarly in gralloc
299 producer_usage = UINT64(alloc_flags);
300 consumer_usage = producer_usage;
301 Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
302 format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
303 allocated_buffer_info->stride = UINT32(aligned_width);
304 allocated_buffer_info->size = UINT32(buffer_size);
305
306 return kErrorNone;
307 }
308
309 } // namespace sdm
310