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
38static 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
65int 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
126int 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
145int 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
236int 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