1 /*
2 * Copyright (c) 2012-2018, 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 <errno.h>
31 #include <string.h>
32 #include <sys/mman.h>
33 #include <log/log.h>
34 #include <cinttypes>
35 #include <gralloc_priv.h>
36 #include "qdMetaData.h"
37
getMetaDataSize()38 unsigned long getMetaDataSize() {
39 return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
40 }
41
validateAndMap(private_handle_t * handle)42 static int validateAndMap(private_handle_t* handle) {
43 if (private_handle_t::validate(handle)) {
44 ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
45 return -1;
46 }
47 if (handle->fd_metadata < 0) {
48 // Silently return, metadata cannot be used
49 return -1;
50 }
51
52 if (!handle->base_metadata) {
53 auto size = getMetaDataSize();
54 void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
55 handle->fd_metadata, 0);
56 if (base == reinterpret_cast<void*>(MAP_FAILED)) {
57 ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
58 __func__, handle, handle->fd_metadata, strerror(errno));
59
60 return -1;
61 }
62 handle->base_metadata = (uintptr_t) base;
63 }
64 return 0;
65 }
66
unmapAndReset(private_handle_t * handle)67 static void unmapAndReset(private_handle_t *handle) {
68 if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
69 munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
70 handle->base_metadata = 0;
71 }
72 }
73
setMetaData(private_handle_t * handle,DispParamType paramType,void * param)74 int setMetaData(private_handle_t *handle, DispParamType paramType,
75 void *param) {
76 auto err = validateAndMap(handle);
77 if (err != 0)
78 return err;
79 return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
80 paramType, param);
81 }
82
setMetaDataVa(MetaData_t * data,DispParamType paramType,void * param)83 int setMetaDataVa(MetaData_t *data, DispParamType paramType,
84 void *param) {
85 if (data == nullptr)
86 return -EINVAL;
87 // If parameter is NULL reset the specific MetaData Key
88 if (!param) {
89 data->operation &= ~paramType;
90 // param unset
91 return 0;
92 }
93
94 data->operation |= paramType;
95 switch (paramType) {
96 case PP_PARAM_INTERLACED:
97 data->interlaced = *((int32_t *)param);
98 break;
99 case UPDATE_BUFFER_GEOMETRY:
100 data->bufferDim = *((BufferDim_t *)param);
101 break;
102 case UPDATE_REFRESH_RATE:
103 data->refreshrate = *((float *)param);
104 break;
105 case UPDATE_COLOR_SPACE:
106 data->colorSpace = *((ColorSpace_t *)param);
107 break;
108 case MAP_SECURE_BUFFER:
109 data->mapSecureBuffer = *((int32_t *)param);
110 break;
111 case S3D_FORMAT:
112 data->s3dFormat = *((uint32_t *)param);
113 break;
114 case LINEAR_FORMAT:
115 data->linearFormat = *((uint32_t *)param);
116 break;
117 case SET_IGC:
118 data->igc = *((IGC_t *)param);
119 break;
120 case SET_SINGLE_BUFFER_MODE:
121 data->isSingleBufferMode = *((uint32_t *)param);
122 break;
123 case SET_S3D_COMP:
124 data->s3dComp = *((S3DGpuComp_t *)param);
125 break;
126 case SET_VT_TIMESTAMP:
127 data->vtTimeStamp = *((uint64_t *)param);
128 break;
129 case COLOR_METADATA:
130 data->color = *((ColorMetaData *)param);
131 break;
132 case SET_UBWC_CR_STATS_INFO: {
133 struct UBWCStats* stats = (struct UBWCStats*)param;
134 int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
135 for (int i = 0; i < numelems; i++) {
136 data->ubwcCRStats[i] = stats[i];
137 }
138 break;
139 }
140 case SET_VIDEO_PERF_MODE:
141 data->isVideoPerfMode = *((uint32_t *)param);
142 break;
143 case SET_GRAPHICS_METADATA: {
144 GraphicsMetadata payload = *((GraphicsMetadata*)(param));
145 data->graphics_metadata.size = payload.size;
146 memcpy(data->graphics_metadata.data, payload.data,
147 sizeof(data->graphics_metadata.data));
148 break;
149 }
150 default:
151 ALOGE("Unknown paramType %d", paramType);
152 break;
153 }
154 return 0;
155 }
156
clearMetaData(private_handle_t * handle,DispParamType paramType)157 int clearMetaData(private_handle_t *handle, DispParamType paramType) {
158 auto err = validateAndMap(handle);
159 if (err != 0)
160 return err;
161 return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
162 paramType);
163 }
164
clearMetaDataVa(MetaData_t * data,DispParamType paramType)165 int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
166 if (data == nullptr)
167 return -EINVAL;
168 data->operation &= ~paramType;
169 switch (paramType) {
170 case SET_S3D_COMP:
171 data->s3dComp.displayId = -1;
172 data->s3dComp.s3dMode = 0;
173 break;
174 default:
175 ALOGE("Unknown paramType %d", paramType);
176 break;
177 }
178 return 0;
179 }
180
getMetaData(private_handle_t * handle,DispFetchParamType paramType,void * param)181 int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
182 void *param) {
183 int ret = validateAndMap(handle);
184 if (ret != 0)
185 return ret;
186 return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
187 paramType, param);
188 }
189
getMetaDataVa(MetaData_t * data,DispFetchParamType paramType,void * param)190 int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
191 void *param) {
192 // Make sure we send 0 only if the operation queried is present
193 int ret = -EINVAL;
194 if (data == nullptr)
195 return ret;
196 if (param == nullptr)
197 return ret;
198
199 switch (paramType) {
200 case GET_PP_PARAM_INTERLACED:
201 if (data->operation & PP_PARAM_INTERLACED) {
202 *((int32_t *)param) = data->interlaced;
203 ret = 0;
204 }
205 break;
206 case GET_BUFFER_GEOMETRY:
207 if (data->operation & UPDATE_BUFFER_GEOMETRY) {
208 *((BufferDim_t *)param) = data->bufferDim;
209 ret = 0;
210 }
211 break;
212 case GET_REFRESH_RATE:
213 if (data->operation & UPDATE_REFRESH_RATE) {
214 *((float *)param) = data->refreshrate;
215 ret = 0;
216 }
217 break;
218 case GET_COLOR_SPACE:
219 if (data->operation & UPDATE_COLOR_SPACE) {
220 *((ColorSpace_t *)param) = data->colorSpace;
221 ret = 0;
222 }
223 break;
224 case GET_MAP_SECURE_BUFFER:
225 if (data->operation & MAP_SECURE_BUFFER) {
226 *((int32_t *)param) = data->mapSecureBuffer;
227 ret = 0;
228 }
229 break;
230 case GET_S3D_FORMAT:
231 if (data->operation & S3D_FORMAT) {
232 *((uint32_t *)param) = data->s3dFormat;
233 ret = 0;
234 }
235 break;
236 case GET_LINEAR_FORMAT:
237 if (data->operation & LINEAR_FORMAT) {
238 *((uint32_t *)param) = data->linearFormat;
239 ret = 0;
240 }
241 break;
242 case GET_IGC:
243 if (data->operation & SET_IGC) {
244 *((IGC_t *)param) = data->igc;
245 ret = 0;
246 }
247 break;
248 case GET_SINGLE_BUFFER_MODE:
249 if (data->operation & SET_SINGLE_BUFFER_MODE) {
250 *((uint32_t *)param) = data->isSingleBufferMode;
251 ret = 0;
252 }
253 break;
254 case GET_S3D_COMP:
255 if (data->operation & SET_S3D_COMP) {
256 *((S3DGpuComp_t *)param) = data->s3dComp;
257 ret = 0;
258 }
259 break;
260 case GET_VT_TIMESTAMP:
261 if (data->operation & SET_VT_TIMESTAMP) {
262 *((uint64_t *)param) = data->vtTimeStamp;
263 ret = 0;
264 }
265 break;
266 case GET_COLOR_METADATA:
267 if (data->operation & COLOR_METADATA) {
268 *((ColorMetaData *)param) = data->color;
269 ret = 0;
270 }
271 break;
272 case GET_UBWC_CR_STATS_INFO:
273 if (data->operation & SET_UBWC_CR_STATS_INFO) {
274 struct UBWCStats* stats = (struct UBWCStats*)param;
275 int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
276 for (int i = 0; i < numelems; i++) {
277 stats[i] = data->ubwcCRStats[i];
278 }
279 ret = 0;
280 }
281 break;
282 case GET_VIDEO_PERF_MODE:
283 if (data->operation & SET_VIDEO_PERF_MODE) {
284 *((uint32_t *)param) = data->isVideoPerfMode;
285 ret = 0;
286 }
287 break;
288 case GET_GRAPHICS_METADATA:
289 if (data->operation & SET_GRAPHICS_METADATA) {
290 memcpy(param, data->graphics_metadata.data, sizeof(data->graphics_metadata.data));
291 ret = 0;
292 }
293 break;
294 default:
295 ALOGE("Unknown paramType %d", paramType);
296 break;
297 }
298 return ret;
299 }
300
copyMetaData(struct private_handle_t * src,struct private_handle_t * dst)301 int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
302 auto err = validateAndMap(src);
303 if (err != 0)
304 return err;
305
306 err = validateAndMap(dst);
307 if (err != 0)
308 return err;
309
310 MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
311 MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
312 *dst_data = *src_data;
313 return 0;
314 }
315
copyMetaDataVaToHandle(MetaData_t * src_data,struct private_handle_t * dst)316 int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
317 int err = -EINVAL;
318 if (src_data == nullptr)
319 return err;
320
321 err = validateAndMap(dst);
322 if (err != 0)
323 return err;
324
325 MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
326 *dst_data = *src_data;
327 return 0;
328 }
329
copyMetaDataHandleToVa(struct private_handle_t * src,MetaData_t * dst_data)330 int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
331 int err = -EINVAL;
332 if (dst_data == nullptr)
333 return err;
334
335 err = validateAndMap(src);
336 if (err != 0)
337 return err;
338
339 MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
340 *dst_data = *src_data;
341 return 0;
342 }
343
copyMetaDataVaToVa(MetaData_t * src_data,MetaData_t * dst_data)344 int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
345 int err = -EINVAL;
346 if (src_data == nullptr)
347 return err;
348
349 if (dst_data == nullptr)
350 return err;
351
352 *dst_data = *src_data;
353 return 0;
354 }
355
setMetaDataAndUnmap(struct private_handle_t * handle,enum DispParamType paramType,void * param)356 int setMetaDataAndUnmap(struct private_handle_t *handle, enum DispParamType paramType,
357 void *param) {
358 auto ret = setMetaData(handle, paramType, param);
359 unmapAndReset(handle);
360 return ret;
361 }
362
getMetaDataAndUnmap(struct private_handle_t * handle,enum DispFetchParamType paramType,void * param)363 int getMetaDataAndUnmap(struct private_handle_t *handle,
364 enum DispFetchParamType paramType,
365 void *param) {
366 auto ret = getMetaData(handle, paramType, param);
367 unmapAndReset(handle);
368 return ret;
369 }
370
371