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