overlayMdp.cpp revision 513ddc2124abf90c63af41999201f0d2031af0c8
1/*
2* Copyright (C) 2008 The Android Open Source Project
3* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
4*
5* Licensed under the Apache License, Version 2.0 (the "License");
6* you may not use this file except in compliance with the License.
7* You may obtain a copy of the License at
8*
9*      http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*/
17
18#include <mdp_version.h>
19#include "overlayUtils.h"
20#include "overlayMdp.h"
21#include "mdp_version.h"
22
23#define HSIC_SETTINGS_DEBUG 0
24
25static inline bool isEqual(float f1, float f2) {
26        return ((int)(f1*100) == (int)(f2*100)) ? true : false;
27}
28
29namespace ovutils = overlay::utils;
30namespace overlay {
31
32//Helper to even out x,w and y,h pairs
33//x,y are always evened to ceil and w,h are evened to floor
34static void normalizeCrop(uint32_t& xy, uint32_t& wh) {
35    if(xy & 1) {
36        utils::even_ceil(xy);
37        if(wh & 1)
38            utils::even_floor(wh);
39        else
40            wh -= 2;
41    } else {
42        utils::even_floor(wh);
43    }
44}
45
46bool MdpCtrl::init(uint32_t fbnum) {
47    // FD init
48    if(!utils::openDev(mFd, fbnum,
49                Res::fbPath, O_RDWR)){
50        ALOGE("Ctrl failed to init fbnum=%d", fbnum);
51        return false;
52    }
53    return true;
54}
55
56void MdpCtrl::reset() {
57    utils::memset0(mOVInfo);
58    utils::memset0(mLkgo);
59    mOVInfo.id = MSMFB_NEW_REQUEST;
60    mLkgo.id = MSMFB_NEW_REQUEST;
61    mOrientation = utils::OVERLAY_TRANSFORM_0;
62    mDownscale = 0;
63#ifdef USES_POST_PROCESSING
64    mPPChanged = false;
65    memset(&mParams, 0, sizeof(struct compute_params));
66    mParams.params.conv_params.order = hsic_order_hsc_i;
67    mParams.params.conv_params.interface = interface_rec601;
68    mParams.params.conv_params.cc_matrix[0][0] = 1;
69    mParams.params.conv_params.cc_matrix[1][1] = 1;
70    mParams.params.conv_params.cc_matrix[2][2] = 1;
71#endif
72}
73
74bool MdpCtrl::close() {
75    bool result = true;
76    if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
77        if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
78            ALOGE("MdpCtrl close error in unset");
79            result = false;
80        }
81    }
82#ifdef USES_POST_PROCESSING
83    /* free allocated memory in PP */
84    if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data)
85            free(mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data);
86#endif
87    reset();
88
89    if(!mFd.close()) {
90        result = false;
91    }
92
93    return result;
94}
95
96void MdpCtrl::setSource(const utils::PipeArgs& args) {
97    setSrcWhf(args.whf);
98
99    //TODO These are hardcoded. Can be moved out of setSource.
100    mOVInfo.transp_mask = 0xffffffff;
101
102    //TODO These calls should ideally be a part of setPipeParams API
103    setFlags(args.mdpFlags);
104    setZ(args.zorder);
105    setIsFg(args.isFg);
106    setPlaneAlpha(args.planeAlpha);
107    setBlending(args.blending);
108}
109
110void MdpCtrl::setCrop(const utils::Dim& d) {
111    setSrcRectDim(d);
112}
113
114void MdpCtrl::setPosition(const overlay::utils::Dim& d) {
115    setDstRectDim(d);
116}
117
118void MdpCtrl::setTransform(const utils::eTransform& orient) {
119    int rot = utils::getMdpOrient(orient);
120    setUserData(rot);
121    //getMdpOrient will switch the flips if the source is 90 rotated.
122    //Clients in Android dont factor in 90 rotation while deciding the flip.
123    mOrientation = static_cast<utils::eTransform>(rot);
124}
125
126void MdpCtrl::doTransform() {
127    setRotationFlags();
128    utils::Whf whf = getSrcWhf();
129    utils::Dim dim = getSrcRectDim();
130    utils::preRotateSource(mOrientation, whf, dim);
131    setSrcWhf(whf);
132    setSrcRectDim(dim);
133}
134
135void MdpCtrl::doDownscale() {
136    mOVInfo.src_rect.x >>= mDownscale;
137    mOVInfo.src_rect.y >>= mDownscale;
138    mOVInfo.src_rect.w >>= mDownscale;
139    mOVInfo.src_rect.h >>= mDownscale;
140}
141
142bool MdpCtrl::set() {
143    //deferred calcs, so APIs could be called in any order.
144    doTransform();
145    doDownscale();
146    utils::Whf whf = getSrcWhf();
147    if(utils::isYuv(whf.format)) {
148        normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
149        normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
150        utils::even_floor(mOVInfo.dst_rect.w);
151        utils::even_floor(mOVInfo.dst_rect.h);
152    }
153
154    if(this->ovChanged()) {
155        if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
156            ALOGE("MdpCtrl failed to setOverlay, restoring last known "
157                  "good ov info");
158            mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
159            mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
160            this->restore();
161            return false;
162        }
163        this->save();
164    }
165
166    return true;
167}
168
169bool MdpCtrl::get() {
170    mdp_overlay ov;
171    ov.id = mOVInfo.id;
172    if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
173        ALOGE("MdpCtrl get failed");
174        return false;
175    }
176    mOVInfo = ov;
177    return true;
178}
179
180//Update src format based on rotator's destination format.
181void MdpCtrl::updateSrcFormat(const uint32_t& rotDestFmt) {
182    utils::Whf whf = getSrcWhf();
183    whf.format =  rotDestFmt;
184    setSrcWhf(whf);
185}
186
187void MdpCtrl::dump() const {
188    ALOGE("== Dump MdpCtrl start ==");
189    mFd.dump();
190    mdp_wrapper::dump("mOVInfo", mOVInfo);
191    ALOGE("== Dump MdpCtrl end ==");
192}
193
194void MdpCtrl::getDump(char *buf, size_t len) {
195    ovutils::getDump(buf, len, "Ctrl(mdp_overlay)", mOVInfo);
196}
197
198void MdpData::dump() const {
199    ALOGE("== Dump MdpData start ==");
200    mFd.dump();
201    mdp_wrapper::dump("mOvData", mOvData);
202    ALOGE("== Dump MdpData end ==");
203}
204
205void MdpData::getDump(char *buf, size_t len) {
206    ovutils::getDump(buf, len, "Data(msmfb_overlay_data)", mOvData);
207}
208
209void MdpCtrl3D::dump() const {
210    ALOGE("== Dump MdpCtrl start ==");
211    mFd.dump();
212    ALOGE("== Dump MdpCtrl end ==");
213}
214
215bool MdpCtrl::setVisualParams(const MetaData_t& data) {
216    bool needUpdate = false;
217#ifdef USES_POST_PROCESSING
218    /* calculate the data */
219    if (data.operation & PP_PARAM_HSIC) {
220        if (mParams.params.pa_params.hue != data.hsicData.hue) {
221            ALOGD_IF(HSIC_SETTINGS_DEBUG,
222                "Hue has changed from %d to %d",
223                mParams.params.pa_params.hue,data.hsicData.hue);
224            needUpdate = true;
225        }
226
227        if (!isEqual(mParams.params.pa_params.sat,
228            data.hsicData.saturation)) {
229            ALOGD_IF(HSIC_SETTINGS_DEBUG,
230                "Saturation has changed from %f to %f",
231                mParams.params.pa_params.sat,
232                data.hsicData.saturation);
233            needUpdate = true;
234        }
235
236        if (mParams.params.pa_params.intensity != data.hsicData.intensity) {
237            ALOGD_IF(HSIC_SETTINGS_DEBUG,
238                "Intensity has changed from %d to %d",
239                mParams.params.pa_params.intensity,
240                data.hsicData.intensity);
241            needUpdate = true;
242        }
243
244        if (!isEqual(mParams.params.pa_params.contrast,
245            data.hsicData.contrast)) {
246            ALOGD_IF(HSIC_SETTINGS_DEBUG,
247                "Contrast has changed from %f to %f",
248                mParams.params.pa_params.contrast,
249                data.hsicData.contrast);
250            needUpdate = true;
251        }
252
253        if (needUpdate) {
254            mParams.params.pa_params.hue = data.hsicData.hue;
255            mParams.params.pa_params.sat = data.hsicData.saturation;
256            mParams.params.pa_params.intensity = data.hsicData.intensity;
257            mParams.params.pa_params.contrast = data.hsicData.contrast;
258            mParams.params.pa_params.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
259            mParams.operation |= PP_OP_PA;
260        }
261    }
262
263    if (data.operation & PP_PARAM_SHARP2) {
264        if (mParams.params.sharp_params.strength != data.Sharp2Data.strength) {
265            needUpdate = true;
266        }
267        if (mParams.params.sharp_params.edge_thr != data.Sharp2Data.edge_thr) {
268            needUpdate = true;
269        }
270        if (mParams.params.sharp_params.smooth_thr !=
271                data.Sharp2Data.smooth_thr) {
272            needUpdate = true;
273        }
274        if (mParams.params.sharp_params.noise_thr !=
275                data.Sharp2Data.noise_thr) {
276            needUpdate = true;
277        }
278
279        if (needUpdate) {
280            mParams.params.sharp_params.strength = data.Sharp2Data.strength;
281            mParams.params.sharp_params.edge_thr = data.Sharp2Data.edge_thr;
282            mParams.params.sharp_params.smooth_thr =
283                data.Sharp2Data.smooth_thr;
284            mParams.params.sharp_params.noise_thr = data.Sharp2Data.noise_thr;
285            mParams.params.sharp_params.ops =
286                MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
287            mParams.operation |= PP_OP_SHARP;
288        }
289    }
290
291    if (data.operation & PP_PARAM_IGC) {
292        if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data == NULL){
293            uint32_t *igcData
294                = (uint32_t *)malloc(2 * MAX_IGC_LUT_ENTRIES * sizeof(uint32_t));
295            if (!igcData) {
296                ALOGE("IGC storage allocated failed");
297                return false;
298            }
299            mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data = igcData;
300            mOVInfo.overlay_pp_cfg.igc_cfg.c2_data
301                = igcData + MAX_IGC_LUT_ENTRIES;
302        }
303
304        memcpy(mParams.params.igc_lut_params.c0,
305            data.igcData.c0, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
306        memcpy(mParams.params.igc_lut_params.c1,
307            data.igcData.c1, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
308        memcpy(mParams.params.igc_lut_params.c2,
309            data.igcData.c2, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
310
311        mParams.params.igc_lut_params.ops
312            = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
313        mParams.operation |= PP_OP_IGC;
314        needUpdate = true;
315    }
316
317    if (data.operation & PP_PARAM_VID_INTFC) {
318        mParams.params.conv_params.interface =
319            (interface_type) data.video_interface;
320        needUpdate = true;
321    }
322
323    if (needUpdate) {
324        display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg);
325        mPPChanged = true;
326    }
327#endif
328    return true;
329}
330
331} // overlay
332