blob: fdead74bb18d56b44f57452dcae2adb5761515bd [file] [log] [blame]
Saurabh Shahc8118ac2013-06-27 10:03:19 -07001/*
2* Copyright (c) 2013 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 "overlay.h"
31#include "overlayWriteback.h"
32#include "mdpWrapper.h"
33
Saurabh Shah885e1442013-09-05 13:27:04 -070034#define SIZE_1M 0x00100000
35
Saurabh Shahc8118ac2013-06-27 10:03:19 -070036namespace overlay {
37
38//=========== class WritebackMem ==============================================
39bool WritebackMem::manageMem(uint32_t size, bool isSecure) {
40 if(mBuf.bufSz() == size) {
41 return true;
42 }
43 if(mBuf.valid()) {
44 if(!mBuf.close()) {
45 ALOGE("%s error closing mem", __func__);
46 return false;
47 }
48 }
49 return alloc(size, isSecure);
50}
51
52bool WritebackMem::alloc(uint32_t size, bool isSecure) {
53 if(!mBuf.open(NUM_BUFS, size, isSecure)){
54 ALOGE("%s: Failed to open", __func__);
55 mBuf.close();
56 return false;
57 }
58
59 OVASSERT(MAP_FAILED != mBuf.addr(), "MAP failed");
60 OVASSERT(mBuf.getFD() != -1, "getFd is -1");
61
62 mCurrOffsetIndex = 0;
63 for (uint32_t i = 0; i < NUM_BUFS; i++) {
64 mOffsets[i] = i * size;
65 }
66 return true;
67}
68
69bool WritebackMem::dealloc() {
70 bool ret = true;
71 if(mBuf.valid()) {
72 ret = mBuf.close();
73 }
74 return ret;
75}
76
77//=========== class Writeback =================================================
Tatenda Chipeperekwa8b1920d2013-10-25 17:38:53 -070078Writeback::Writeback() : mXres(0), mYres(0), mOpFmt(-1), mSecure(false) {
Saurabh Shahc8118ac2013-06-27 10:03:19 -070079 int fbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
80 if(!utils::openDev(mFd, fbNum, Res::fbPath, O_RDWR)) {
81 ALOGE("%s failed to init %s", __func__, Res::fbPath);
82 return;
83 }
84 startSession();
85}
86
87Writeback::~Writeback() {
88 stopSession();
89 if (!mFd.close()) {
90 ALOGE("%s error closing fd", __func__);
91 }
92}
93
94bool Writeback::startSession() {
95 if(!mdp_wrapper::wbInitStart(mFd.getFD())) {
96 ALOGE("%s failed", __func__);
97 return false;
98 }
99 return true;
100}
101
102bool Writeback::stopSession() {
103 if(mFd.valid()) {
104 if(!mdp_wrapper::wbStopTerminate(mFd.getFD())) {
105 ALOGE("%s failed", __func__);
106 return false;
107 }
108 } else {
109 ALOGE("%s Invalid fd", __func__);
110 return false;
111 }
112 return true;
113}
114
115bool Writeback::configureDpyInfo(int xres, int yres) {
116 if(mXres != xres || mYres != yres) {
117 fb_var_screeninfo vinfo;
118 memset(&vinfo, 0, sizeof(fb_var_screeninfo));
119 if(!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
120 ALOGE("%s failed", __func__);
121 return false;
122 }
123 vinfo.xres = xres;
124 vinfo.yres = yres;
125 vinfo.xres_virtual = xres;
126 vinfo.yres_virtual = yres;
127 vinfo.xoffset = 0;
128 vinfo.yoffset = 0;
129 if(!mdp_wrapper::setVScreenInfo(mFd.getFD(), vinfo)) {
130 ALOGE("%s failed", __func__);
131 return false;
132 }
133 mXres = xres;
134 mYres = yres;
135 }
136 return true;
137}
138
Tatenda Chipeperekwa8b1920d2013-10-25 17:38:53 -0700139bool Writeback::configureMemory(uint32_t size) {
140 if(!mWbMem.manageMem(size, mSecure)) {
Saurabh Shahc8118ac2013-06-27 10:03:19 -0700141 ALOGE("%s failed, memory failure", __func__);
142 return false;
143 }
144 return true;
145}
146
147bool Writeback::queueBuffer(int opFd, uint32_t opOffset) {
148 memset(&mFbData, 0, sizeof(struct msmfb_data));
149 //Queue
150 mFbData.offset = opOffset;
151 mFbData.memory_id = opFd;
152 mFbData.id = 0;
153 mFbData.flags = 0;
154 if(!mdp_wrapper::wbQueueBuffer(mFd.getFD(), mFbData)) {
155 ALOGE("%s: queuebuffer failed", __func__);
156 return false;
157 }
158 return true;
159}
160
161bool Writeback::dequeueBuffer() {
162 //Dequeue
163 mFbData.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
164 if(!mdp_wrapper::wbDequeueBuffer(mFd.getFD(), mFbData)) {
165 ALOGE("%s: dequeuebuffer failed", __func__);
166 return false;
167 }
168 return true;
169}
170
171bool Writeback::writeSync(int opFd, uint32_t opOffset) {
172 if(!queueBuffer(opFd, opOffset)) {
173 return false;
174 }
175 if(!Overlay::displayCommit(mFd.getFD())) {
176 return false;
177 }
178 if(!dequeueBuffer()) {
179 return false;
180 }
181 return true;
182}
183
184bool Writeback::writeSync() {
185 mWbMem.useNextBuffer();
186 return writeSync(mWbMem.getDstFd(), mWbMem.getOffset());
187}
188
Saurabh Shahc97e7bc2013-08-15 10:30:25 -0700189bool Writeback::setOutputFormat(int mdpFormat) {
190 if(mdpFormat != mOpFmt) {
191 struct msmfb_metadata metadata;
192 memset(&metadata, 0 , sizeof(metadata));
193 metadata.op = metadata_op_wb_format;
194 metadata.data.mixer_cfg.writeback_format = mdpFormat;
195 if (ioctl(mFd.getFD(), MSMFB_METADATA_SET, &metadata) < 0) {
196 ALOGE("Error setting MDP Writeback format");
197 return false;
198 }
199 mOpFmt = mdpFormat;
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700200 }
Saurabh Shahc97e7bc2013-08-15 10:30:25 -0700201 return true;
202}
203
204int Writeback::getOutputFormat() {
205 if(mOpFmt < 0) {
206 struct msmfb_metadata metadata;
207 memset(&metadata, 0 , sizeof(metadata));
208 metadata.op = metadata_op_wb_format;
209 if (ioctl(mFd.getFD(), MSMFB_METADATA_GET, &metadata) < 0) {
210 ALOGE("Error retrieving MDP Writeback format");
211 return -1;
212 }
213 mOpFmt = metadata.data.mixer_cfg.writeback_format;
214 }
215 return mOpFmt;
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700216}
217
Tatenda Chipeperekwa8b1920d2013-10-25 17:38:53 -0700218bool Writeback::setSecure(bool isSecure) {
219 if(isSecure != mSecure) {
220 // Call IOCTL to set WB interface as secure
221 struct msmfb_metadata metadata;
222 memset(&metadata, 0 , sizeof(metadata));
223 metadata.op = metadata_op_wb_secure;
224 metadata.data.secure_en = isSecure;
225 if (ioctl(mFd.getFD(), MSMFB_METADATA_SET, &metadata) < 0) {
226 ALOGE("Error setting MDP WB secure");
227 return false;
228 }
229 mSecure = isSecure;
230 }
231 return true;
232}
233
Saurabh Shahc8118ac2013-06-27 10:03:19 -0700234//static
235
236Writeback *Writeback::getInstance() {
237 if(sWb == NULL) {
238 sWb = new Writeback();
239 }
240 sUsed = true;
241 return sWb;
242}
243
244void Writeback::configDone() {
245 if(sUsed == false && sWb) {
246 delete sWb;
247 sWb = NULL;
248 }
249}
250
251void Writeback::clear() {
252 sUsed = false;
253 if(sWb) {
254 delete sWb;
255 sWb = NULL;
256 }
257}
258
Saurabh Shah7c8d34f2013-10-30 15:52:29 -0700259bool Writeback::getDump(char *buf, size_t len) {
260 if(sWb) {
261 utils::getDump(buf, len, "WBData", sWb->mFbData);
262 char str[4] = {'\0'};
263 snprintf(str, 4, "\n");
264 strncat(buf, str, strlen(str));
265 return true;
266 }
267 return false;
268}
269
Saurabh Shahc8118ac2013-06-27 10:03:19 -0700270Writeback *Writeback::sWb = 0;
271bool Writeback::sUsed = false;
272
273} //namespace overlay