blob: 12ff8a9fe3449e43cd8b5ca3ee3d0c6eaef40088 [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
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
Naseer Ahmed29a26812012-06-14 00:56:20 -070021namespace ovutils = overlay::utils;
22namespace overlay {
Saurabh Shahb121e142012-08-20 17:59:13 -070023
24//Helper to even out x,w and y,h pairs
25//x,y are always evened to ceil and w,h are evened to floor
26static void normalizeCrop(uint32_t& xy, uint32_t& wh) {
27 if(xy & 1) {
28 utils::even_ceil(xy);
29 if(wh & 1)
30 utils::even_floor(wh);
31 else
32 wh -= 2;
33 } else {
34 utils::even_floor(wh);
35 }
36}
37
Naseer Ahmedf48aef62012-07-20 09:05:53 -070038bool MdpCtrl::init(uint32_t fbnum) {
39 // FD init
Naseer Ahmed29a26812012-06-14 00:56:20 -070040 if(!utils::openDev(mFd, fbnum,
Naseer Ahmedf48aef62012-07-20 09:05:53 -070041 Res::fbPath, O_RDWR)){
42 ALOGE("Ctrl failed to init fbnum=%d", fbnum);
Naseer Ahmed29a26812012-06-14 00:56:20 -070043 return false;
44 }
45 return true;
46}
47
48void MdpCtrl::reset() {
49 utils::memset0(mOVInfo);
50 utils::memset0(mLkgo);
Naseer Ahmedf48aef62012-07-20 09:05:53 -070051 mOVInfo.id = MSMFB_NEW_REQUEST;
52 mLkgo.id = MSMFB_NEW_REQUEST;
53 mOrientation = utils::OVERLAY_TRANSFORM_0;
54 mRotUsed = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070055}
56
57bool MdpCtrl::close() {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070058 bool result = true;
59
60 if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
61 if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
62 ALOGE("MdpCtrl close error in unset");
63 result = false;
64 }
Naseer Ahmed29a26812012-06-14 00:56:20 -070065 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070066
Naseer Ahmed29a26812012-06-14 00:56:20 -070067 reset();
68 if(!mFd.close()) {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070069 result = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070070 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070071
72 return result;
Naseer Ahmed29a26812012-06-14 00:56:20 -070073}
74
Naseer Ahmedf48aef62012-07-20 09:05:53 -070075bool MdpCtrl::setSource(const utils::PipeArgs& args) {
76
77 setSrcWhf(args.whf);
78
79 //TODO These are hardcoded. Can be moved out of setSource.
80 mOVInfo.alpha = 0xff;
81 mOVInfo.transp_mask = 0xffffffff;
82
83 //TODO These calls should ideally be a part of setPipeParams API
84 setFlags(args.mdpFlags);
85 setZ(args.zorder);
86 setIsFg(args.isFg);
87 return true;
88}
89
90bool MdpCtrl::setCrop(const utils::Dim& d) {
91 setSrcRectDim(d);
92 return true;
93}
94
95bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
96 int fbw, int fbh)
97{
98 ovutils::Dim dim(d);
99 ovutils::Dim ovsrcdim = getSrcRectDim();
100 // Scaling of upto a max of 20 times supported
101 if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
102 dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
103 dim.x = (fbw - dim.w) / 2;
104 }
105 if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
106 dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
107 dim.y = (fbh - dim.h) / 2;
108 }
109
110 setDstRectDim(dim);
111 return true;
112}
113
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800114bool MdpCtrl::setTransform(const utils::eTransform& orient) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700115 int rot = utils::getMdpOrient(orient);
116 setUserData(rot);
Saurabh Shaha73738d2012-08-09 18:15:18 -0700117 //getMdpOrient will switch the flips if the source is 90 rotated.
118 //Clients in Android dont factor in 90 rotation while deciding the flip.
119 mOrientation = static_cast<utils::eTransform>(rot);
120
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700121 return true;
122}
123
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800124void MdpCtrl::setRotatorUsed(const bool& rotUsed) {
125 //rotUsed dictates whether rotator hardware can be used.
126 //It is set if transformation or downscaling is required.
127 mRotUsed = rotUsed;
128}
129
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700130void 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
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800146int MdpCtrl::getDownscalefactor() {
147 int dscale_factor = utils::ROT_DS_NONE;
148 int src_w = mOVInfo.src_rect.w;
149 int src_h = mOVInfo.src_rect.h;
150 int dst_w = mOVInfo.dst_rect.w;
151 int dst_h = mOVInfo.dst_rect.h;
152 // We need this check to engage the rotator whenever possible to assist MDP
153 // in performing video downscale.
154 // This saves bandwidth and avoids causing the driver to make too many panel
155 // -mode switches between BLT (writeback) and non-BLT (Direct) modes.
156 // Use-case: Video playback [with downscaling and rotation].
157
158 if (dst_w && dst_h)
159 {
160 uint32_t dscale = (src_w * src_h) / (dst_w * dst_h);
161
162 if(dscale < 2) {
163 // Down-scale to > 50% of orig.
164 dscale_factor = utils::ROT_DS_NONE;
165 } else if(dscale < 4) {
166 // Down-scale to between > 25% to <= 50% of orig.
167 dscale_factor = utils::ROT_DS_HALF;
168 } else if(dscale < 8) {
169 // Down-scale to between > 12.5% to <= 25% of orig.
170 dscale_factor = utils::ROT_DS_FOURTH;
171 } else {
172 // Down-scale to <= 12.5% of orig.
173 dscale_factor = utils::ROT_DS_EIGHTH;
174 }
175 }
176
177 return dscale_factor;
178}
179
180void MdpCtrl::doDownscale(int dscale_factor) {
181
182 if( dscale_factor ) {
183 mOVInfo.src_rect.x >>= dscale_factor;
184 mOVInfo.src_rect.y >>= dscale_factor;
185 mOVInfo.src_rect.w >>= dscale_factor;
186 mOVInfo.src_rect.h >>= dscale_factor;
187 }
188}
189
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700190bool MdpCtrl::set() {
191 //deferred calcs, so APIs could be called in any order.
Saurabh Shahb121e142012-08-20 17:59:13 -0700192 utils::Whf whf = getSrcWhf();
193 if(utils::isYuv(whf.format)) {
194 normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
195 normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
196 utils::even_floor(mOVInfo.dst_rect.w);
197 utils::even_floor(mOVInfo.dst_rect.h);
198 }
199
Saurabh Shahfc2acbe2012-08-17 19:47:52 -0700200 if(this->ovChanged()) {
201 if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
202 ALOGE("MdpCtrl failed to setOverlay, restoring last known "
203 "good ov info");
204 mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
205 mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
206 this->restore();
207 return false;
208 }
209 this->save();
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700210 }
Saurabh Shahb121e142012-08-20 17:59:13 -0700211
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700212 return true;
213}
214
Naseer Ahmed29a26812012-06-14 00:56:20 -0700215bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) {
216 fb_fix_screeninfo finfo;
217 if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) {
218 return false;
219 }
220
221 fb_var_screeninfo vinfo;
222 if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
223 return false;
224 }
225 info.mFBWidth = vinfo.xres;
226 info.mFBHeight = vinfo.yres;
227 info.mFBbpp = vinfo.bits_per_pixel;
228 info.mFBystride = finfo.line_length;
229 return true;
230}
231
232bool MdpCtrl::get() {
233 mdp_overlay ov;
234 ov.id = mOVInfo.id;
235 if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
236 ALOGE("MdpCtrl get failed");
237 return false;
238 }
239 mOVInfo = ov;
240 return true;
241}
242
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700243//Adjust width, height, format if rotator is used.
244void MdpCtrl::adjustSrcWhf(const bool& rotUsed) {
245 if(rotUsed) {
246 utils::Whf whf = getSrcWhf();
247 if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
248 whf.format == MDP_Y_CBCR_H2V2_TILE) {
249 whf.w = utils::alignup(whf.w, 64);
250 whf.h = utils::alignup(whf.h, 32);
251 }
252 //For example: If original format is tiled, rotator outputs non-tiled,
253 //so update mdp's src fmt to that.
254 whf.format = utils::getRotOutFmt(whf.format);
255 setSrcWhf(whf);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700256 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700257}
258
259void MdpCtrl::dump() const {
260 ALOGE("== Dump MdpCtrl start ==");
Naseer Ahmed29a26812012-06-14 00:56:20 -0700261 mFd.dump();
262 mdp_wrapper::dump("mOVInfo", mOVInfo);
263 ALOGE("== Dump MdpCtrl end ==");
264}
265
266void MdpData::dump() const {
267 ALOGE("== Dump MdpData start ==");
268 mFd.dump();
269 mdp_wrapper::dump("mOvData", mOvData);
270 ALOGE("== Dump MdpData end ==");
271}
272
273void MdpCtrl3D::dump() const {
274 ALOGE("== Dump MdpCtrl start ==");
275 mFd.dump();
276 ALOGE("== Dump MdpCtrl end ==");
277}
278
279} // overlay