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