• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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