• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2010-2012, Code Aurora Forum. 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 "overlayUtils.h"
19 #include "overlayMdp.h"
20 
21 #undef ALOG_TAG
22 #define ALOG_TAG "overlay"
23 
24 namespace ovutils = overlay::utils;
25 namespace overlay {
26 
27 //Helper to even out x,w and y,h pairs
28 //x,y are always evened to ceil and w,h are evened to floor
normalizeCrop(uint32_t & xy,uint32_t & wh)29 static void normalizeCrop(uint32_t& xy, uint32_t& wh) {
30     if(xy & 1) {
31         utils::even_ceil(xy);
32         if(wh & 1)
33             utils::even_floor(wh);
34         else
35             wh -= 2;
36     } else {
37         utils::even_floor(wh);
38     }
39 }
40 
init(uint32_t fbnum)41 bool MdpCtrl::init(uint32_t fbnum) {
42     // FD init
43     if(!utils::openDev(mFd, fbnum,
44                 Res::fbPath, O_RDWR)){
45         ALOGE("Ctrl failed to init fbnum=%d", fbnum);
46         return false;
47     }
48     return true;
49 }
50 
reset()51 void MdpCtrl::reset() {
52     utils::memset0(mOVInfo);
53     utils::memset0(mLkgo);
54     mOVInfo.id = MSMFB_NEW_REQUEST;
55     mLkgo.id = MSMFB_NEW_REQUEST;
56     mOrientation = utils::OVERLAY_TRANSFORM_0;
57     mRotUsed = false;
58 }
59 
close()60 bool MdpCtrl::close() {
61     bool result = true;
62 
63     if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
64         if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
65             ALOGE("MdpCtrl close error in unset");
66             result = false;
67         }
68     }
69 
70     reset();
71     if(!mFd.close()) {
72         result = false;
73     }
74 
75     return result;
76 }
77 
setSource(const utils::PipeArgs & args)78 bool MdpCtrl::setSource(const utils::PipeArgs& args) {
79 
80     setSrcWhf(args.whf);
81 
82     //TODO These are hardcoded. Can be moved out of setSource.
83     mOVInfo.alpha = 0xff;
84     mOVInfo.transp_mask = 0xffffffff;
85 
86     //TODO These calls should ideally be a part of setPipeParams API
87     setFlags(args.mdpFlags);
88     setZ(args.zorder);
89     setIsFg(args.isFg);
90     return true;
91 }
92 
setCrop(const utils::Dim & d)93 bool MdpCtrl::setCrop(const utils::Dim& d) {
94     setSrcRectDim(d);
95     return true;
96 }
97 
setPosition(const overlay::utils::Dim & d,int fbw,int fbh)98 bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
99         int fbw, int fbh)
100 {
101     ovutils::Dim dim(d);
102     ovutils::Dim ovsrcdim = getSrcRectDim();
103     // Scaling of upto a max of 20 times supported
104     if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
105         dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
106         dim.x = (fbw - dim.w) / 2;
107     }
108     if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
109         dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
110         dim.y = (fbh - dim.h) / 2;
111     }
112 
113     setDstRectDim(dim);
114     return true;
115 }
116 
setTransform(const utils::eTransform & orient,const bool & rotUsed)117 bool MdpCtrl::setTransform(const utils::eTransform& orient,
118         const bool& rotUsed) {
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     //Rotator can be requested by client even if layer has 0 orientation.
126     mRotUsed = rotUsed;
127     return true;
128 }
129 
doTransform()130 void MdpCtrl::doTransform() {
131     adjustSrcWhf(mRotUsed);
132     setRotationFlags();
133     //180 will be H + V
134     //270 will be H + V + 90
135     if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_H) {
136             overlayTransFlipH();
137     }
138     if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_V) {
139             overlayTransFlipV();
140     }
141     if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90) {
142             overlayTransRot90();
143     }
144 }
145 
set()146 bool MdpCtrl::set() {
147     //deferred calcs, so APIs could be called in any order.
148     doTransform();
149     utils::Whf whf = getSrcWhf();
150     if(utils::isYuv(whf.format)) {
151         normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
152         normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
153         utils::even_floor(mOVInfo.dst_rect.w);
154         utils::even_floor(mOVInfo.dst_rect.h);
155     }
156 
157     if(this->ovChanged()) {
158         if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
159             ALOGE("MdpCtrl failed to setOverlay, restoring last known "
160                   "good ov info");
161             mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
162             mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
163             this->restore();
164             return false;
165         }
166         this->save();
167     }
168 
169     return true;
170 }
171 
getScreenInfo(overlay::utils::ScreenInfo & info)172 bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) {
173     fb_fix_screeninfo finfo;
174     if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) {
175         return false;
176     }
177 
178     fb_var_screeninfo vinfo;
179     if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
180         return false;
181     }
182     info.mFBWidth   = vinfo.xres;
183     info.mFBHeight  = vinfo.yres;
184     info.mFBbpp     = vinfo.bits_per_pixel;
185     info.mFBystride = finfo.line_length;
186     return true;
187 }
188 
get()189 bool MdpCtrl::get() {
190     mdp_overlay ov;
191     ov.id = mOVInfo.id;
192     if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
193         ALOGE("MdpCtrl get failed");
194         return false;
195     }
196     mOVInfo = ov;
197     return true;
198 }
199 
200 //Adjust width, height, format if rotator is used.
adjustSrcWhf(const bool & rotUsed)201 void MdpCtrl::adjustSrcWhf(const bool& rotUsed) {
202     if(rotUsed) {
203         utils::Whf whf = getSrcWhf();
204         if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
205                 whf.format == MDP_Y_CBCR_H2V2_TILE) {
206             whf.w = utils::alignup(whf.w, 64);
207             whf.h = utils::alignup(whf.h, 32);
208         }
209         //For example: If original format is tiled, rotator outputs non-tiled,
210         //so update mdp's src fmt to that.
211         whf.format = utils::getRotOutFmt(whf.format);
212         setSrcWhf(whf);
213     }
214 }
215 
dump() const216 void MdpCtrl::dump() const {
217     ALOGE("== Dump MdpCtrl start ==");
218     mFd.dump();
219     mdp_wrapper::dump("mOVInfo", mOVInfo);
220     ALOGE("== Dump MdpCtrl end ==");
221 }
222 
dump() const223 void MdpData::dump() const {
224     ALOGE("== Dump MdpData start ==");
225     mFd.dump();
226     mdp_wrapper::dump("mOvData", mOvData);
227     ALOGE("== Dump MdpData end ==");
228 }
229 
dump() const230 void MdpCtrl3D::dump() const {
231     ALOGE("== Dump MdpCtrl start ==");
232     mFd.dump();
233     ALOGE("== Dump MdpCtrl end ==");
234 }
235 
236 } // overlay
237