blob: f4e0b517aabb3a6110305951eaa20c845d4691e0 [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
21#undef ALOG_TAG
22#define ALOG_TAG "overlay"
23
24namespace ovutils = overlay::utils;
25namespace overlay {
Saurabh Shahb121e142012-08-20 17:59:13 -070026
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
29static 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
Naseer Ahmedf48aef62012-07-20 09:05:53 -070041bool MdpCtrl::init(uint32_t fbnum) {
42 // FD init
Naseer Ahmed29a26812012-06-14 00:56:20 -070043 if(!utils::openDev(mFd, fbnum,
Naseer Ahmedf48aef62012-07-20 09:05:53 -070044 Res::fbPath, O_RDWR)){
45 ALOGE("Ctrl failed to init fbnum=%d", fbnum);
Naseer Ahmed29a26812012-06-14 00:56:20 -070046 return false;
47 }
48 return true;
49}
50
51void MdpCtrl::reset() {
52 utils::memset0(mOVInfo);
53 utils::memset0(mLkgo);
Naseer Ahmedf48aef62012-07-20 09:05:53 -070054 mOVInfo.id = MSMFB_NEW_REQUEST;
55 mLkgo.id = MSMFB_NEW_REQUEST;
56 mOrientation = utils::OVERLAY_TRANSFORM_0;
57 mRotUsed = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070058}
59
60bool MdpCtrl::close() {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070061 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 }
Naseer Ahmed29a26812012-06-14 00:56:20 -070068 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070069
Naseer Ahmed29a26812012-06-14 00:56:20 -070070 reset();
71 if(!mFd.close()) {
Saurabh Shah8e1ae952012-08-15 12:15:14 -070072 result = false;
Naseer Ahmed29a26812012-06-14 00:56:20 -070073 }
Saurabh Shah8e1ae952012-08-15 12:15:14 -070074
75 return result;
Naseer Ahmed29a26812012-06-14 00:56:20 -070076}
77
Naseer Ahmedf48aef62012-07-20 09:05:53 -070078bool 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
93bool MdpCtrl::setCrop(const utils::Dim& d) {
94 setSrcRectDim(d);
95 return true;
96}
97
98bool 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
117bool MdpCtrl::setTransform(const utils::eTransform& orient,
118 const bool& rotUsed) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700119 int rot = utils::getMdpOrient(orient);
120 setUserData(rot);
Saurabh Shaha73738d2012-08-09 18:15:18 -0700121 //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
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700125 //Rotator can be requested by client even if layer has 0 orientation.
126 mRotUsed = rotUsed;
127 return true;
128}
129
130void 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
146bool MdpCtrl::set() {
147 //deferred calcs, so APIs could be called in any order.
148 doTransform();
Saurabh Shahb121e142012-08-20 17:59:13 -0700149 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
Saurabh Shahfc2acbe2012-08-17 19:47:52 -0700157 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();
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700167 }
Saurabh Shahb121e142012-08-20 17:59:13 -0700168
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700169 return true;
170}
171
Naseer Ahmed29a26812012-06-14 00:56:20 -0700172bool 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
189bool 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
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700200//Adjust width, height, format if rotator is used.
201void 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);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700213 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700214}
215
216void MdpCtrl::dump() const {
217 ALOGE("== Dump MdpCtrl start ==");
Naseer Ahmed29a26812012-06-14 00:56:20 -0700218 mFd.dump();
219 mdp_wrapper::dump("mOVInfo", mOVInfo);
220 ALOGE("== Dump MdpCtrl end ==");
221}
222
223void MdpData::dump() const {
224 ALOGE("== Dump MdpData start ==");
225 mFd.dump();
226 mdp_wrapper::dump("mOvData", mOvData);
227 ALOGE("== Dump MdpData end ==");
228}
229
230void MdpCtrl3D::dump() const {
231 ALOGE("== Dump MdpCtrl start ==");
232 mFd.dump();
233 ALOGE("== Dump MdpCtrl end ==");
234}
235
236} // overlay