blob: 9f08c14fcd71884733b3605be09a63fe5b264f2d [file] [log] [blame]
Naseer Ahmed758bfc52012-11-28 17:02:08 -05001/*
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"
Amara Venkata Mastan Manoj Kumar5182a782012-12-03 12:08:48 -080031#include "overlay.h"
Naseer Ahmed758bfc52012-11-28 17:02:08 -050032
33namespace overlay {
34
35GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRot(0), mRotUsed(false),
36 pipeState(CLOSED) {
37 init();
38}
39
40GenericPipe::~GenericPipe() {
41 close();
42}
43
44bool GenericPipe::init()
45{
46 ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
47 mRotUsed = false;
Amara Venkata Mastan Manoj Kumar5182a782012-12-03 12:08:48 -080048 if(mFbNum)
49 mFbNum = Overlay::getInstance()->getExtFbNum();
50
51 ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, mFbNum);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050052
53 if(!mCtrlData.ctrl.init(mFbNum)) {
54 ALOGE("GenericPipe failed to init ctrl");
55 return false;
56 }
57
58 if(!mCtrlData.data.init(mFbNum)) {
59 ALOGE("GenericPipe failed to init data");
60 return false;
61 }
62
63 //get a new rotator object, take ownership
64 mRot = Rotator::getRotator();
65
66 return true;
67}
68
69bool GenericPipe::close() {
70 bool ret = true;
71
72 if(!mCtrlData.ctrl.close()) {
73 ALOGE("GenericPipe failed to close ctrl");
74 ret = false;
75 }
76 if (!mCtrlData.data.close()) {
77 ALOGE("GenericPipe failed to close data");
78 ret = false;
79 }
80
81 delete mRot;
82 mRot = 0;
83
84 setClosed();
85 return ret;
86}
87
88bool GenericPipe::setSource(
89 const utils::PipeArgs& args)
90{
91 utils::PipeArgs newargs(args);
92 //Interlace video handling.
93 if(newargs.whf.format & INTERLACE_MASK) {
94 setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE);
95 }
96 utils::Whf whf(newargs.whf);
97 //Extract HAL format from lower bytes. Deinterlace if interlaced.
98 whf.format = utils::getColorFormat(whf.format);
99 //Get MDP equivalent of HAL format.
100 whf.format = utils::getMdpFormat(whf.format);
101 newargs.whf = whf;
102
103 //Cache if user wants 0-rotation
104 mRotUsed = newargs.rotFlags & utils::ROT_FLAG_ENABLED;
105 mRot->setSource(newargs.whf);
106 mRot->setFlags(newargs.mdpFlags);
107 return mCtrlData.ctrl.setSource(newargs);
108}
109
110bool GenericPipe::setCrop(
111 const overlay::utils::Dim& d) {
112 return mCtrlData.ctrl.setCrop(d);
113}
114
115bool GenericPipe::setTransform(
116 const utils::eTransform& orient)
117{
118 //Rotation could be enabled by user for zero-rot or the layer could have
119 //some transform. Mark rotation enabled in either case.
120 mRotUsed |= (orient != utils::OVERLAY_TRANSFORM_0);
121 mRot->setTransform(orient, mRotUsed);
122
123 return mCtrlData.ctrl.setTransform(orient, mRotUsed);
124}
125
126bool GenericPipe::setPosition(const utils::Dim& d)
127{
128 return mCtrlData.ctrl.setPosition(d);
129}
130
131bool GenericPipe::commit() {
132 bool ret = false;
133 //If wanting to use rotator, start it.
134 if(mRotUsed) {
135 if(!mRot->commit()) {
136 ALOGE("GenPipe Rotator commit failed");
137 //If rot commit fails, flush rotator session, memory, fd and create
138 //a hollow rotator object
139 delete mRot;
140 mRot = Rotator::getRotator();
141 pipeState = CLOSED;
142 return false;
143 }
144 }
145
146 ret = mCtrlData.ctrl.commit();
147
148 //If mdp commit fails, flush rotator session, memory, fd and create a hollow
149 //rotator object
150 if(ret == false) {
151 delete mRot;
152 mRot = Rotator::getRotator();
153 }
154
155 pipeState = ret ? OPEN : CLOSED;
156 return ret;
157}
158
159bool GenericPipe::queueBuffer(int fd, uint32_t offset) {
160 //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private.
161 OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
162 int pipeId = mCtrlData.ctrl.getPipeId();
163 OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
164 // set pipe id from ctrl to data
165 mCtrlData.data.setPipeId(pipeId);
166
167 int finalFd = fd;
168 uint32_t finalOffset = offset;
169 //If rotator is to be used, queue to it, so it can ROTATE.
170 if(mRotUsed) {
171 if(!mRot->queueBuffer(fd, offset)) {
172 ALOGE("GenPipe Rotator play failed");
173 return false;
174 }
175 //Configure MDP's source buffer as the current output buffer of rotator
176 if(mRot->getDstMemId() != -1) {
177 finalFd = mRot->getDstMemId();
178 finalOffset = mRot->getDstOffset();
179 } else {
180 //Could be -1 for NullRotator, if queue above succeeds.
181 //Need an actual rotator. Modify overlay State Traits.
182 //Not fatal, keep queuing to MDP without rotation.
183 ALOGE("Null rotator in use, where an actual is required");
184 }
185 }
186 return mCtrlData.data.queueBuffer(finalFd, finalOffset);
187}
188
189int GenericPipe::getCtrlFd() const {
190 return mCtrlData.ctrl.getFd();
191}
192
193utils::ScreenInfo GenericPipe::getScreenInfo() const
194{
195 return mCtrlData.ctrl.getScreenInfo();
196}
197
198utils::Dim GenericPipe::getCrop() const
199{
200 return mCtrlData.ctrl.getCrop();
201}
202
203void GenericPipe::dump() const
204{
205 ALOGE("== Dump Generic pipe start ==");
206 ALOGE("pipe state = %d", (int)pipeState);
207 OVASSERT(mRot, "GenericPipe should have a valid Rot");
208 mCtrlData.ctrl.dump();
209 mCtrlData.data.dump();
210 mRot->dump();
211 ALOGE("== Dump Generic pipe end ==");
212}
213
214bool GenericPipe::isClosed() const {
215 return (pipeState == CLOSED);
216}
217
218bool GenericPipe::isOpen() const {
219 return (pipeState == OPEN);
220}
221
222bool GenericPipe::setClosed() {
223 pipeState = CLOSED;
224 return true;
225}
226
227} //namespace overlay