blob: 8bca85fa6bbe8ba47964d79d680d77aefe257c52 [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2* Copyright (C) 2008 The Android Open Source Project
Raj kamal23f69b22012-11-17 00:20:55 +05303* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
Naseer Ahmed29a26812012-06-14 00:56:20 -07004*
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
Raj kamal23f69b22012-11-17 00:20:55 +053018#include <mdp_version.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070019#include "overlayUtils.h"
20#include "overlayMdp.h"
21
Naseer Ahmed29a26812012-06-14 00:56:20 -070022namespace ovutils = overlay::utils;
23namespace overlay {
Saurabh Shahb121e142012-08-20 17:59:13 -070024
25//Helper to even out x,w and y,h pairs
26//x,y are always evened to ceil and w,h are evened to floor
27static void normalizeCrop(uint32_t& xy, uint32_t& wh) {
28 if(xy & 1) {
29 utils::even_ceil(xy);
30 if(wh & 1)
31 utils::even_floor(wh);
32 else
33 wh -= 2;
34 } else {
35 utils::even_floor(wh);
36 }
37}
38
Naseer Ahmedf48aef62012-07-20 09:05:53 -070039bool MdpCtrl::init(uint32_t fbnum) {
40 // FD init
Naseer Ahmed29a26812012-06-14 00:56:20 -070041 if(!utils::openDev(mFd, fbnum,
Naseer Ahmedf48aef62012-07-20 09:05:53 -070042 Res::fbPath, O_RDWR)){
43 ALOGE("Ctrl failed to init fbnum=%d", fbnum);
Naseer Ahmed29a26812012-06-14 00:56:20 -070044 return false;
45 }
46 return true;
47}
48
49void MdpCtrl::reset() {
50 utils::memset0(mOVInfo);
51 utils::memset0(mLkgo);
Naseer Ahmedf48aef62012-07-20 09:05:53 -070052 mOVInfo.id = MSMFB_NEW_REQUEST;
53 mLkgo.id = MSMFB_NEW_REQUEST;
54 mOrientation = utils::OVERLAY_TRANSFORM_0;
55 mRotUsed = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070056}
57
58bool MdpCtrl::close() {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070059 bool result = true;
60
61 if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
62 if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
63 ALOGE("MdpCtrl close error in unset");
64 result = false;
65 }
Naseer Ahmed29a26812012-06-14 00:56:20 -070066 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070067
Naseer Ahmed29a26812012-06-14 00:56:20 -070068 reset();
69 if(!mFd.close()) {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070070 result = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070071 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070072
73 return result;
Naseer Ahmed29a26812012-06-14 00:56:20 -070074}
75
Naseer Ahmedf48aef62012-07-20 09:05:53 -070076bool MdpCtrl::setSource(const utils::PipeArgs& args) {
77
78 setSrcWhf(args.whf);
79
80 //TODO These are hardcoded. Can be moved out of setSource.
81 mOVInfo.alpha = 0xff;
82 mOVInfo.transp_mask = 0xffffffff;
83
84 //TODO These calls should ideally be a part of setPipeParams API
85 setFlags(args.mdpFlags);
86 setZ(args.zorder);
87 setIsFg(args.isFg);
88 return true;
89}
90
91bool MdpCtrl::setCrop(const utils::Dim& d) {
92 setSrcRectDim(d);
93 return true;
94}
95
96bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
97 int fbw, int fbh)
98{
99 ovutils::Dim dim(d);
100 ovutils::Dim ovsrcdim = getSrcRectDim();
101 // Scaling of upto a max of 20 times supported
102 if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
103 dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
104 dim.x = (fbw - dim.w) / 2;
105 }
106 if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
107 dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
108 dim.y = (fbh - dim.h) / 2;
109 }
110
111 setDstRectDim(dim);
112 return true;
113}
114
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800115bool MdpCtrl::setTransform(const utils::eTransform& orient) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700116 int rot = utils::getMdpOrient(orient);
117 setUserData(rot);
Saurabh Shaha73738d2012-08-09 18:15:18 -0700118 //getMdpOrient will switch the flips if the source is 90 rotated.
119 //Clients in Android dont factor in 90 rotation while deciding the flip.
120 mOrientation = static_cast<utils::eTransform>(rot);
121
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700122 return true;
123}
124
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800125void MdpCtrl::setRotatorUsed(const bool& rotUsed) {
126 //rotUsed dictates whether rotator hardware can be used.
127 //It is set if transformation or downscaling is required.
128 mRotUsed = rotUsed;
129}
130
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700131void MdpCtrl::doTransform() {
132 adjustSrcWhf(mRotUsed);
133 setRotationFlags();
134 //180 will be H + V
135 //270 will be H + V + 90
136 if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_H) {
137 overlayTransFlipH();
138 }
139 if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_V) {
140 overlayTransFlipV();
141 }
142 if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90) {
143 overlayTransRot90();
144 }
145}
146
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800147int MdpCtrl::getDownscalefactor() {
148 int dscale_factor = utils::ROT_DS_NONE;
149 int src_w = mOVInfo.src_rect.w;
150 int src_h = mOVInfo.src_rect.h;
151 int dst_w = mOVInfo.dst_rect.w;
152 int dst_h = mOVInfo.dst_rect.h;
153 // We need this check to engage the rotator whenever possible to assist MDP
154 // in performing video downscale.
155 // This saves bandwidth and avoids causing the driver to make too many panel
156 // -mode switches between BLT (writeback) and non-BLT (Direct) modes.
157 // Use-case: Video playback [with downscaling and rotation].
158
159 if (dst_w && dst_h)
160 {
161 uint32_t dscale = (src_w * src_h) / (dst_w * dst_h);
162
163 if(dscale < 2) {
164 // Down-scale to > 50% of orig.
165 dscale_factor = utils::ROT_DS_NONE;
166 } else if(dscale < 4) {
167 // Down-scale to between > 25% to <= 50% of orig.
168 dscale_factor = utils::ROT_DS_HALF;
169 } else if(dscale < 8) {
170 // Down-scale to between > 12.5% to <= 25% of orig.
171 dscale_factor = utils::ROT_DS_FOURTH;
172 } else {
173 // Down-scale to <= 12.5% of orig.
174 dscale_factor = utils::ROT_DS_EIGHTH;
175 }
176 }
177
178 return dscale_factor;
179}
180
181void MdpCtrl::doDownscale(int dscale_factor) {
182
183 if( dscale_factor ) {
184 mOVInfo.src_rect.x >>= dscale_factor;
185 mOVInfo.src_rect.y >>= dscale_factor;
186 mOVInfo.src_rect.w >>= dscale_factor;
187 mOVInfo.src_rect.h >>= dscale_factor;
188 }
189}
190
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700191bool MdpCtrl::set() {
192 //deferred calcs, so APIs could be called in any order.
Saurabh Shahb121e142012-08-20 17:59:13 -0700193 utils::Whf whf = getSrcWhf();
194 if(utils::isYuv(whf.format)) {
195 normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
196 normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
197 utils::even_floor(mOVInfo.dst_rect.w);
198 utils::even_floor(mOVInfo.dst_rect.h);
199 }
200
Saurabh Shahfc2acbe2012-08-17 19:47:52 -0700201 if(this->ovChanged()) {
202 if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
203 ALOGE("MdpCtrl failed to setOverlay, restoring last known "
204 "good ov info");
205 mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
206 mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
207 this->restore();
208 return false;
209 }
210 this->save();
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700211 }
Saurabh Shahb121e142012-08-20 17:59:13 -0700212
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700213 return true;
214}
215
Naseer Ahmed29a26812012-06-14 00:56:20 -0700216bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) {
217 fb_fix_screeninfo finfo;
218 if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) {
219 return false;
220 }
221
222 fb_var_screeninfo vinfo;
223 if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
224 return false;
225 }
226 info.mFBWidth = vinfo.xres;
227 info.mFBHeight = vinfo.yres;
228 info.mFBbpp = vinfo.bits_per_pixel;
229 info.mFBystride = finfo.line_length;
230 return true;
231}
232
233bool MdpCtrl::get() {
234 mdp_overlay ov;
235 ov.id = mOVInfo.id;
236 if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) {
237 ALOGE("MdpCtrl get failed");
238 return false;
239 }
240 mOVInfo = ov;
241 return true;
242}
243
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700244//Adjust width, height, format if rotator is used.
245void MdpCtrl::adjustSrcWhf(const bool& rotUsed) {
246 if(rotUsed) {
247 utils::Whf whf = getSrcWhf();
248 if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
249 whf.format == MDP_Y_CBCR_H2V2_TILE) {
250 whf.w = utils::alignup(whf.w, 64);
251 whf.h = utils::alignup(whf.h, 32);
252 }
Raj kamal23f69b22012-11-17 00:20:55 +0530253 /*For example: If original format is tiled, rotator outputs non-tiled,
254 *so update mdp's src fmt to that.
255 */
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700256 whf.format = utils::getRotOutFmt(whf.format);
257 setSrcWhf(whf);
Raj kamal23f69b22012-11-17 00:20:55 +0530258 /* The above format will be overwritten in function updateSrcformat
259 * after doing rotator start. Format is then set depending on
260 * whether the fastyuv mode is used by the rotator.
261 */
262 }
263}
264
265void MdpCtrl::updateSrcformat(const uint32_t& inputformat) {
266 int version = qdutils::MDPVersion::getInstance().getMDPVersion();
267 if ((version >= qdutils::MDP_V4_2) && (version < qdutils::MDSS_V5)) {
268 utils::Whf whf = getSrcWhf();
269 whf.format = inputformat;
270 setSrcWhf(whf);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700271 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700272}
273
274void MdpCtrl::dump() const {
275 ALOGE("== Dump MdpCtrl start ==");
Naseer Ahmed29a26812012-06-14 00:56:20 -0700276 mFd.dump();
277 mdp_wrapper::dump("mOVInfo", mOVInfo);
278 ALOGE("== Dump MdpCtrl end ==");
279}
280
281void MdpData::dump() const {
282 ALOGE("== Dump MdpData start ==");
283 mFd.dump();
284 mdp_wrapper::dump("mOvData", mOvData);
285 ALOGE("== Dump MdpData end ==");
286}
287
288void MdpCtrl3D::dump() const {
289 ALOGE("== Dump MdpCtrl start ==");
290 mFd.dump();
291 ALOGE("== Dump MdpCtrl end ==");
292}
293
294} // overlay