1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
4 * Not a Contribution, Apache license notifications and license are retained
5 * for attribution purposes only.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include "overlayUtils.h"
21 #include "overlayRotator.h"
22 #include "gr.h"
23
24 namespace ovutils = overlay::utils;
25
26 namespace overlay {
27
MdpRot()28 MdpRot::MdpRot() {
29 reset();
30 init();
31 }
32
~MdpRot()33 MdpRot::~MdpRot() { close(); }
34
enabled() const35 bool MdpRot::enabled() const { return mRotImgInfo.enable; }
36
setRotations(uint32_t r)37 void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = (uint8_t)r; }
38
getDstMemId() const39 int MdpRot::getDstMemId() const {
40 return mRotDataInfo.dst.memory_id;
41 }
42
getDstOffset() const43 uint32_t MdpRot::getDstOffset() const {
44 return mRotDataInfo.dst.offset;
45 }
46
getDstFormat() const47 uint32_t MdpRot::getDstFormat() const {
48 return mRotImgInfo.dst.format;
49 }
50
51 //Added for completeness. Not expected to be called.
getDstWhf() const52 utils::Whf MdpRot::getDstWhf() const {
53 int alW = 0, alH = 0;
54 int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
55 getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
56 halFormat, alW, alH);
57 return utils::Whf(alW, alH, mRotImgInfo.dst.format);
58 }
59
60 //Added for completeness. Not expected to be called.
getDstDimensions() const61 utils::Dim MdpRot::getDstDimensions() const {
62 int alW = 0, alH = 0;
63 int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
64 getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
65 halFormat, alW, alH);
66 return utils::Dim(0, 0, alW, alH);
67 }
68
getSessId() const69 uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; }
70
setDownscale(int ds)71 void MdpRot::setDownscale(int ds) {
72 if ((utils::ROT_DS_EIGHTH == ds) && (mRotImgInfo.src_rect.h & 0xF)) {
73 // Ensure src_rect.h is a multiple of 16 for 1/8 downscaling.
74 // This is an undocumented MDP Rotator constraint.
75 mRotImgInfo.src_rect.h = utils::aligndown(mRotImgInfo.src_rect.h, 16);
76 }
77 mRotImgInfo.downscale_ratio = ds;
78 }
79
save()80 void MdpRot::save() {
81 mLSRotImgInfo = mRotImgInfo;
82 }
83
rotConfChanged() const84 bool MdpRot::rotConfChanged() const {
85 // 0 means same
86 if(0 == ::memcmp(&mRotImgInfo, &mLSRotImgInfo,
87 sizeof (msm_rotator_img_info))) {
88 return false;
89 }
90 return true;
91 }
92
init()93 bool MdpRot::init()
94 {
95 if(!mFd.open(Res::rotPath, O_RDWR)){
96 ALOGE("MdpRot failed to init %s", Res::rotPath);
97 return false;
98 }
99 return true;
100 }
101
setSource(const overlay::utils::Whf & awhf)102 void MdpRot::setSource(const overlay::utils::Whf& awhf) {
103 utils::Whf whf(awhf);
104 mRotImgInfo.src.format = whf.format;
105
106 mRotImgInfo.src.width = whf.w;
107 mRotImgInfo.src.height = whf.h;
108
109 mRotImgInfo.src_rect.w = whf.w;
110 mRotImgInfo.src_rect.h = whf.h;
111
112 mRotImgInfo.dst.width = whf.w;
113 mRotImgInfo.dst.height = whf.h;
114 }
115
setCrop(const utils::Dim &)116 void MdpRot::setCrop(const utils::Dim& /*crop*/) {
117 // NO-OP for non-mdss rotator due to possible h/w limitations
118 }
119
setFlags(const utils::eMdpFlags & flags)120 void MdpRot::setFlags(const utils::eMdpFlags& flags) {
121 mRotImgInfo.secure = 0;
122 if(flags & utils::OV_MDP_SECURE_OVERLAY_SESSION)
123 mRotImgInfo.secure = 1;
124 }
125
setTransform(const utils::eTransform & rot)126 void MdpRot::setTransform(const utils::eTransform& rot)
127 {
128 int r = utils::getMdpOrient(rot);
129 setRotations(r);
130 mOrientation = static_cast<utils::eTransform>(r);
131 ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r);
132 }
133
doTransform()134 void MdpRot::doTransform() {
135 if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90)
136 utils::swap(mRotImgInfo.dst.width, mRotImgInfo.dst.height);
137 }
138
commit()139 bool MdpRot::commit() {
140 doTransform();
141 if(rotConfChanged()) {
142 mRotImgInfo.enable = 1;
143 if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) {
144 ALOGE("MdpRot commit failed");
145 dump();
146 mRotImgInfo.enable = 0;
147 return false;
148 }
149 save();
150 mRotDataInfo.session_id = mRotImgInfo.session_id;
151 }
152 return true;
153 }
154
calcOutputBufSize()155 uint32_t MdpRot::calcOutputBufSize() {
156 ovutils::Whf destWhf(mRotImgInfo.dst.width,
157 mRotImgInfo.dst.height, mRotImgInfo.dst.format);
158 return Rotator::calcOutputBufSize(destWhf);
159 }
160
open_i(uint32_t numbufs,uint32_t bufsz)161 bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
162 {
163 OvMem mem;
164
165 OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
166
167 if(!mem.open(numbufs, bufsz, mRotImgInfo.secure)){
168 ALOGE("%s: Failed to open", __func__);
169 mem.close();
170 return false;
171 }
172
173 OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
174 OVASSERT(mem.getFD() != -1, "getFd is -1");
175
176 mRotDataInfo.dst.memory_id = mem.getFD();
177 mRotDataInfo.dst.offset = 0;
178 mMem.mem = mem;
179 return true;
180 }
181
close()182 bool MdpRot::close() {
183 bool success = true;
184 if(mFd.valid() && (getSessId() != 0)) {
185 if(!mdp_wrapper::endRotator(mFd.getFD(), getSessId())) {
186 ALOGE("Mdp Rot error endRotator, fd=%d sessId=%u",
187 mFd.getFD(), getSessId());
188 success = false;
189 }
190 }
191 if (!mFd.close()) {
192 ALOGE("Mdp Rot error closing fd");
193 success = false;
194 }
195 if (!mMem.close()) {
196 ALOGE("Mdp Rot error closing mem");
197 success = false;
198 }
199 reset();
200 return success;
201 }
202
remap(uint32_t numbufs)203 bool MdpRot::remap(uint32_t numbufs) {
204 // if current size changed, remap
205 uint32_t opBufSize = calcOutputBufSize();
206 if(opBufSize == mMem.size()) {
207 ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
208 return true;
209 }
210
211 if(!mMem.close()) {
212 ALOGE("%s error in closing prev rot mem", __FUNCTION__);
213 return false;
214 }
215
216 ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
217
218 if(!open_i(numbufs, opBufSize)) {
219 ALOGE("%s Error could not open", __FUNCTION__);
220 return false;
221 }
222
223 for (uint32_t i = 0; i < numbufs; ++i) {
224 mMem.mRotOffset[i] = i * opBufSize;
225 }
226
227 return true;
228 }
229
reset()230 void MdpRot::reset() {
231 ovutils::memset0(mRotImgInfo);
232 ovutils::memset0(mLSRotImgInfo);
233 ovutils::memset0(mRotDataInfo);
234 ovutils::memset0(mMem.mRotOffset);
235 mMem.mCurrIndex = 0;
236 mOrientation = utils::OVERLAY_TRANSFORM_0;
237 }
238
queueBuffer(int fd,uint32_t offset)239 bool MdpRot::queueBuffer(int fd, uint32_t offset) {
240 if(enabled()) {
241 mRotDataInfo.src.memory_id = fd;
242 mRotDataInfo.src.offset = offset;
243
244 if(false == remap(RotMem::ROT_NUM_BUFS)) {
245 ALOGE("%s Remap failed, not queueing", __FUNCTION__);
246 return false;
247 }
248
249 mRotDataInfo.dst.offset =
250 mMem.mRotOffset[mMem.mCurrIndex];
251 mMem.mCurrIndex =
252 (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
253
254 if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) {
255 ALOGE("MdpRot failed rotate");
256 dump();
257 return false;
258 }
259 }
260 return true;
261 }
262
dump() const263 void MdpRot::dump() const {
264 ALOGE("== Dump MdpRot start ==");
265 mFd.dump();
266 mMem.mem.dump();
267 mdp_wrapper::dump("mRotImgInfo", mRotImgInfo);
268 mdp_wrapper::dump("mRotDataInfo", mRotDataInfo);
269 ALOGE("== Dump MdpRot end ==");
270 }
271
getDump(char * buf,size_t len) const272 void MdpRot::getDump(char *buf, size_t len) const {
273 ovutils::getDump(buf, len, "MdpRotCtrl", mRotImgInfo);
274 ovutils::getDump(buf, len, "MdpRotData", mRotDataInfo);
275 }
276
277 } // namespace overlay
278