1 /*
2 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "overlayGenPipe.h"
31
32 namespace overlay {
33
GenericPipe(int dpy)34 GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRot(0), mRotUsed(false),
35 pipeState(CLOSED) {
36 init();
37 }
38
~GenericPipe()39 GenericPipe::~GenericPipe() {
40 close();
41 }
42
init()43 bool GenericPipe::init()
44 {
45 ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
46 mRotUsed = false;
47
48 if(!mCtrlData.ctrl.init(mFbNum)) {
49 ALOGE("GenericPipe failed to init ctrl");
50 return false;
51 }
52
53 if(!mCtrlData.data.init(mFbNum)) {
54 ALOGE("GenericPipe failed to init data");
55 return false;
56 }
57
58 //get a new rotator object, take ownership
59 mRot = Rotator::getRotator();
60
61 return true;
62 }
63
close()64 bool GenericPipe::close() {
65 bool ret = true;
66
67 if(!mCtrlData.ctrl.close()) {
68 ALOGE("GenericPipe failed to close ctrl");
69 ret = false;
70 }
71 if (!mCtrlData.data.close()) {
72 ALOGE("GenericPipe failed to close data");
73 ret = false;
74 }
75
76 delete mRot;
77 mRot = 0;
78
79 setClosed();
80 return ret;
81 }
82
setSource(const utils::PipeArgs & args)83 bool GenericPipe::setSource(
84 const utils::PipeArgs& args)
85 {
86 utils::PipeArgs newargs(args);
87 //Interlace video handling.
88 if(newargs.whf.format & INTERLACE_MASK) {
89 setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE);
90 }
91 utils::Whf whf(newargs.whf);
92 //Extract HAL format from lower bytes. Deinterlace if interlaced.
93 whf.format = utils::getColorFormat(whf.format);
94 //Get MDP equivalent of HAL format.
95 whf.format = utils::getMdpFormat(whf.format);
96 newargs.whf = whf;
97
98 //Cache if user wants 0-rotation
99 mRotUsed = newargs.rotFlags & utils::ROT_FLAG_ENABLED;
100 mRot->setSource(newargs.whf);
101 mRot->setFlags(newargs.mdpFlags);
102 return mCtrlData.ctrl.setSource(newargs);
103 }
104
setCrop(const overlay::utils::Dim & d)105 bool GenericPipe::setCrop(
106 const overlay::utils::Dim& d) {
107 return mCtrlData.ctrl.setCrop(d);
108 }
109
setTransform(const utils::eTransform & orient)110 bool GenericPipe::setTransform(
111 const utils::eTransform& orient)
112 {
113 //Rotation could be enabled by user for zero-rot or the layer could have
114 //some transform. Mark rotation enabled in either case.
115 mRotUsed |= (orient != utils::OVERLAY_TRANSFORM_0);
116 mRot->setTransform(orient, mRotUsed);
117
118 return mCtrlData.ctrl.setTransform(orient, mRotUsed);
119 }
120
setPosition(const utils::Dim & d)121 bool GenericPipe::setPosition(const utils::Dim& d)
122 {
123 return mCtrlData.ctrl.setPosition(d);
124 }
125
commit()126 bool GenericPipe::commit() {
127 bool ret = false;
128 //If wanting to use rotator, start it.
129 if(mRotUsed) {
130 if(!mRot->commit()) {
131 ALOGE("GenPipe Rotator commit failed");
132 //If rot commit fails, flush rotator session, memory, fd and create
133 //a hollow rotator object
134 delete mRot;
135 mRot = Rotator::getRotator();
136 pipeState = CLOSED;
137 return false;
138 }
139 }
140
141 ret = mCtrlData.ctrl.commit();
142
143 //If mdp commit fails, flush rotator session, memory, fd and create a hollow
144 //rotator object
145 if(ret == false) {
146 delete mRot;
147 mRot = Rotator::getRotator();
148 }
149
150 pipeState = ret ? OPEN : CLOSED;
151 return ret;
152 }
153
queueBuffer(int fd,uint32_t offset)154 bool GenericPipe::queueBuffer(int fd, uint32_t offset) {
155 //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private.
156 OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
157 int pipeId = mCtrlData.ctrl.getPipeId();
158 OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
159 // set pipe id from ctrl to data
160 mCtrlData.data.setPipeId(pipeId);
161
162 int finalFd = fd;
163 uint32_t finalOffset = offset;
164 //If rotator is to be used, queue to it, so it can ROTATE.
165 if(mRotUsed) {
166 if(!mRot->queueBuffer(fd, offset)) {
167 ALOGE("GenPipe Rotator play failed");
168 return false;
169 }
170 //Configure MDP's source buffer as the current output buffer of rotator
171 if(mRot->getDstMemId() != -1) {
172 finalFd = mRot->getDstMemId();
173 finalOffset = mRot->getDstOffset();
174 } else {
175 //Could be -1 for NullRotator, if queue above succeeds.
176 //Need an actual rotator. Modify overlay State Traits.
177 //Not fatal, keep queuing to MDP without rotation.
178 ALOGE("Null rotator in use, where an actual is required");
179 }
180 }
181 return mCtrlData.data.queueBuffer(finalFd, finalOffset);
182 }
183
getCtrlFd() const184 int GenericPipe::getCtrlFd() const {
185 return mCtrlData.ctrl.getFd();
186 }
187
getScreenInfo() const188 utils::ScreenInfo GenericPipe::getScreenInfo() const
189 {
190 return mCtrlData.ctrl.getScreenInfo();
191 }
192
getCrop() const193 utils::Dim GenericPipe::getCrop() const
194 {
195 return mCtrlData.ctrl.getCrop();
196 }
197
dump() const198 void GenericPipe::dump() const
199 {
200 ALOGE("== Dump Generic pipe start ==");
201 ALOGE("pipe state = %d", (int)pipeState);
202 OVASSERT(mRot, "GenericPipe should have a valid Rot");
203 mCtrlData.ctrl.dump();
204 mCtrlData.data.dump();
205 mRot->dump();
206 ALOGE("== Dump Generic pipe end ==");
207 }
208
isClosed() const209 bool GenericPipe::isClosed() const {
210 return (pipeState == CLOSED);
211 }
212
isOpen() const213 bool GenericPipe::isOpen() const {
214 return (pipeState == OPEN);
215 }
216
setClosed()217 bool GenericPipe::setClosed() {
218 pipeState = CLOSED;
219 return true;
220 }
221
222 } //namespace overlay
223