1 /*
2  * Copyright (c) 2012-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 <errno.h>
31 #include <string.h>
32 #include <sys/mman.h>
33 #include <cutils/log.h>
34 #include <cinttypes>
35 #include <gralloc_priv.h>
36 #include "qdMetaData.h"
37 
validateAndMap(private_handle_t * handle)38 static int validateAndMap(private_handle_t* handle) {
39     if (private_handle_t::validate(handle)) {
40         ALOGE("%s: Private handle is invalid - handle:%p",
41                 __func__, handle);
42         return -1;
43     }
44     if (handle->fd_metadata == -1) {
45         ALOGE("%s: Invalid metadata fd - handle:%p id: %" PRIu64 "fd: %d",
46                 __func__, handle, handle->id, handle->fd_metadata);
47         return -1;
48     }
49 
50     if (!handle->base_metadata) {
51         unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
52         void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
53                 handle->fd_metadata, 0);
54         if (base == reinterpret_cast<void*>(MAP_FAILED)) {
55             ALOGE("%s: metadata mmap failed - handle:%p id: %" PRIu64  "fd: %d err: %s",
56                 __func__, handle, handle->id, handle->fd_metadata, strerror(errno));
57 
58             return -1;
59         }
60         handle->base_metadata = (uintptr_t) base;
61     }
62     return 0;
63 }
64 
setMetaData(private_handle_t * handle,DispParamType paramType,void * param)65 int setMetaData(private_handle_t *handle, DispParamType paramType,
66                                                     void *param) {
67     auto err = validateAndMap(handle);
68     if (err != 0)
69         return err;
70 
71     MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
72     // If parameter is NULL reset the specific MetaData Key
73     if (!param) {
74        data->operation &= ~paramType;
75        // param unset
76        return 0;
77     }
78 
79     data->operation |= paramType;
80     switch (paramType) {
81         case PP_PARAM_INTERLACED:
82             data->interlaced = *((int32_t *)param);
83             break;
84         case UPDATE_BUFFER_GEOMETRY:
85             data->bufferDim = *((BufferDim_t *)param);
86             break;
87         case UPDATE_REFRESH_RATE:
88             data->refreshrate = *((float *)param);
89             break;
90         case UPDATE_COLOR_SPACE:
91             data->colorSpace = *((ColorSpace_t *)param);
92             break;
93         case MAP_SECURE_BUFFER:
94             data->mapSecureBuffer = *((int32_t *)param);
95             break;
96         case S3D_FORMAT:
97             data->s3dFormat = *((uint32_t *)param);
98             break;
99         case LINEAR_FORMAT:
100             data->linearFormat = *((uint32_t *)param);
101             break;
102         case SET_IGC:
103             data->igc = *((IGC_t *)param);
104             break;
105         case SET_SINGLE_BUFFER_MODE:
106             data->isSingleBufferMode = *((uint32_t *)param);
107             break;
108         case SET_S3D_COMP:
109             data->s3dComp = *((S3DGpuComp_t *)param);
110             break;
111         case SET_VT_TIMESTAMP:
112             data->vtTimeStamp = *((uint64_t *)param);
113             break;
114 #ifdef USE_COLOR_METADATA
115         case COLOR_METADATA:
116             data->color = *((ColorMetaData *)param);
117 #endif
118             break;
119         default:
120             ALOGE("Unknown paramType %d", paramType);
121             break;
122     }
123     return 0;
124 }
125 
clearMetaData(private_handle_t * handle,DispParamType paramType)126 int clearMetaData(private_handle_t *handle, DispParamType paramType) {
127     auto err = validateAndMap(handle);
128     if (err != 0)
129         return err;
130 
131     MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
132     data->operation &= ~paramType;
133     switch (paramType) {
134         case SET_S3D_COMP:
135             data->s3dComp.displayId = -1;
136             data->s3dComp.s3dMode = 0;
137             break;
138         default:
139             ALOGE("Unknown paramType %d", paramType);
140             break;
141     }
142     return 0;
143 }
144 
getMetaData(private_handle_t * handle,DispFetchParamType paramType,void * param)145 int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
146                                                     void *param) {
147     int ret = validateAndMap(handle);
148     if (ret != 0)
149         return ret;
150     MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
151     // Make sure we send 0 only if the operation queried is present
152     ret = -EINVAL;
153 
154     switch (paramType) {
155         case GET_PP_PARAM_INTERLACED:
156             if (data->operation & PP_PARAM_INTERLACED) {
157                 *((int32_t *)param) = data->interlaced;
158                 ret = 0;
159             }
160             break;
161         case GET_BUFFER_GEOMETRY:
162             if (data->operation & UPDATE_BUFFER_GEOMETRY) {
163                 *((BufferDim_t *)param) = data->bufferDim;
164                 ret = 0;
165             }
166             break;
167         case GET_REFRESH_RATE:
168             if (data->operation & UPDATE_REFRESH_RATE) {
169                 *((float *)param) = data->refreshrate;
170                 ret = 0;
171             }
172             break;
173         case GET_COLOR_SPACE:
174             if (data->operation & UPDATE_COLOR_SPACE) {
175                 *((ColorSpace_t *)param) = data->colorSpace;
176                 ret = 0;
177             }
178             break;
179         case GET_MAP_SECURE_BUFFER:
180             if (data->operation & MAP_SECURE_BUFFER) {
181                 *((int32_t *)param) = data->mapSecureBuffer;
182                 ret = 0;
183             }
184             break;
185         case GET_S3D_FORMAT:
186             if (data->operation & S3D_FORMAT) {
187                 *((uint32_t *)param) = data->s3dFormat;
188                 ret = 0;
189             }
190             break;
191         case GET_LINEAR_FORMAT:
192             if (data->operation & LINEAR_FORMAT) {
193                 *((uint32_t *)param) = data->linearFormat;
194                 ret = 0;
195             }
196             break;
197         case GET_IGC:
198             if (data->operation & SET_IGC) {
199                 *((IGC_t *)param) = data->igc;
200                 ret = 0;
201             }
202             break;
203         case GET_SINGLE_BUFFER_MODE:
204             if (data->operation & SET_SINGLE_BUFFER_MODE) {
205                 *((uint32_t *)param) = data->isSingleBufferMode;
206                 ret = 0;
207             }
208             break;
209         case GET_S3D_COMP:
210             if (data->operation & SET_S3D_COMP) {
211                 *((S3DGpuComp_t *)param) = data->s3dComp;
212                 ret = 0;
213             }
214             break;
215         case GET_VT_TIMESTAMP:
216             if (data->operation & SET_VT_TIMESTAMP) {
217                 *((uint64_t *)param) = data->vtTimeStamp;
218                 ret = 0;
219             }
220             break;
221 #ifdef USE_COLOR_METADATA
222         case GET_COLOR_METADATA:
223             if (data->operation & COLOR_METADATA) {
224                 *((ColorMetaData *)param) = data->color;
225                 ret = 0;
226             }
227 #endif
228             break;
229         default:
230             ALOGE("Unknown paramType %d", paramType);
231             break;
232     }
233     return ret;
234 }
235 
copyMetaData(struct private_handle_t * src,struct private_handle_t * dst)236 int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
237     auto err = validateAndMap(src);
238     if (err != 0)
239         return err;
240 
241     err = validateAndMap(dst);
242     if (err != 0)
243         return err;
244 
245     unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
246     MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
247     MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
248     memcpy(src_data, dst_data, size);
249     return 0;
250 }
251