blob: f1f0eb5432fd7d90f7596b8c01f24b3a38ef50f6 [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) {
Saurabh Shah885e1442013-09-05 13:27:04 -070040 if(isSecure) {
41 size = utils::align(size, SIZE_1M);
42 }
Saurabh Shahc8118ac2013-06-27 10:03:19 -070043 if(mBuf.bufSz() == size) {
44 return true;
45 }
46 if(mBuf.valid()) {
47 if(!mBuf.close()) {
48 ALOGE("%s error closing mem", __func__);
49 return false;
50 }
51 }
52 return alloc(size, isSecure);
53}
54
55bool WritebackMem::alloc(uint32_t size, bool isSecure) {
56 if(!mBuf.open(NUM_BUFS, size, isSecure)){
57 ALOGE("%s: Failed to open", __func__);
58 mBuf.close();
59 return false;
60 }
61
62 OVASSERT(MAP_FAILED != mBuf.addr(), "MAP failed");
63 OVASSERT(mBuf.getFD() != -1, "getFd is -1");
64
65 mCurrOffsetIndex = 0;
66 for (uint32_t i = 0; i < NUM_BUFS; i++) {
67 mOffsets[i] = i * size;
68 }
69 return true;
70}
71
72bool WritebackMem::dealloc() {
73 bool ret = true;
74 if(mBuf.valid()) {
75 ret = mBuf.close();
76 }
77 return ret;
78}
79
80//=========== class Writeback =================================================
Saurabh Shaha9da08f2013-07-03 13:27:53 -070081Writeback::Writeback() : mXres(0), mYres(0), mOpFmt(-1) {
Saurabh Shahc8118ac2013-06-27 10:03:19 -070082 int fbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
83 if(!utils::openDev(mFd, fbNum, Res::fbPath, O_RDWR)) {
84 ALOGE("%s failed to init %s", __func__, Res::fbPath);
85 return;
86 }
87 startSession();
88}
89
90Writeback::~Writeback() {
91 stopSession();
92 if (!mFd.close()) {
93 ALOGE("%s error closing fd", __func__);
94 }
95}
96
97bool Writeback::startSession() {
98 if(!mdp_wrapper::wbInitStart(mFd.getFD())) {
99 ALOGE("%s failed", __func__);
100 return false;
101 }
102 return true;
103}
104
105bool Writeback::stopSession() {
106 if(mFd.valid()) {
107 if(!mdp_wrapper::wbStopTerminate(mFd.getFD())) {
108 ALOGE("%s failed", __func__);
109 return false;
110 }
111 } else {
112 ALOGE("%s Invalid fd", __func__);
113 return false;
114 }
115 return true;
116}
117
118bool Writeback::configureDpyInfo(int xres, int yres) {
119 if(mXres != xres || mYres != yres) {
120 fb_var_screeninfo vinfo;
121 memset(&vinfo, 0, sizeof(fb_var_screeninfo));
122 if(!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
123 ALOGE("%s failed", __func__);
124 return false;
125 }
126 vinfo.xres = xres;
127 vinfo.yres = yres;
128 vinfo.xres_virtual = xres;
129 vinfo.yres_virtual = yres;
130 vinfo.xoffset = 0;
131 vinfo.yoffset = 0;
132 if(!mdp_wrapper::setVScreenInfo(mFd.getFD(), vinfo)) {
133 ALOGE("%s failed", __func__);
134 return false;
135 }
136 mXres = xres;
137 mYres = yres;
138 }
139 return true;
140}
141
142bool Writeback::configureMemory(uint32_t size, bool isSecure) {
143 if(!mWbMem.manageMem(size, isSecure)) {
144 ALOGE("%s failed, memory failure", __func__);
145 return false;
146 }
147 return true;
148}
149
150bool Writeback::queueBuffer(int opFd, uint32_t opOffset) {
151 memset(&mFbData, 0, sizeof(struct msmfb_data));
152 //Queue
153 mFbData.offset = opOffset;
154 mFbData.memory_id = opFd;
155 mFbData.id = 0;
156 mFbData.flags = 0;
157 if(!mdp_wrapper::wbQueueBuffer(mFd.getFD(), mFbData)) {
158 ALOGE("%s: queuebuffer failed", __func__);
159 return false;
160 }
161 return true;
162}
163
164bool Writeback::dequeueBuffer() {
165 //Dequeue
166 mFbData.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
167 if(!mdp_wrapper::wbDequeueBuffer(mFd.getFD(), mFbData)) {
168 ALOGE("%s: dequeuebuffer failed", __func__);
169 return false;
170 }
171 return true;
172}
173
174bool Writeback::writeSync(int opFd, uint32_t opOffset) {
175 if(!queueBuffer(opFd, opOffset)) {
176 return false;
177 }
178 if(!Overlay::displayCommit(mFd.getFD())) {
179 return false;
180 }
181 if(!dequeueBuffer()) {
182 return false;
183 }
184 return true;
185}
186
187bool Writeback::writeSync() {
188 mWbMem.useNextBuffer();
189 return writeSync(mWbMem.getDstFd(), mWbMem.getOffset());
190}
191
Saurabh Shahc97e7bc2013-08-15 10:30:25 -0700192bool Writeback::setOutputFormat(int mdpFormat) {
193 if(mdpFormat != mOpFmt) {
194 struct msmfb_metadata metadata;
195 memset(&metadata, 0 , sizeof(metadata));
196 metadata.op = metadata_op_wb_format;
197 metadata.data.mixer_cfg.writeback_format = mdpFormat;
198 if (ioctl(mFd.getFD(), MSMFB_METADATA_SET, &metadata) < 0) {
199 ALOGE("Error setting MDP Writeback format");
200 return false;
201 }
202 mOpFmt = mdpFormat;
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700203 }
Saurabh Shahc97e7bc2013-08-15 10:30:25 -0700204 return true;
205}
206
207int Writeback::getOutputFormat() {
208 if(mOpFmt < 0) {
209 struct msmfb_metadata metadata;
210 memset(&metadata, 0 , sizeof(metadata));
211 metadata.op = metadata_op_wb_format;
212 if (ioctl(mFd.getFD(), MSMFB_METADATA_GET, &metadata) < 0) {
213 ALOGE("Error retrieving MDP Writeback format");
214 return -1;
215 }
216 mOpFmt = metadata.data.mixer_cfg.writeback_format;
217 }
218 return mOpFmt;
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700219}
220
Saurabh Shahc8118ac2013-06-27 10:03:19 -0700221//static
222
223Writeback *Writeback::getInstance() {
224 if(sWb == NULL) {
225 sWb = new Writeback();
226 }
227 sUsed = true;
228 return sWb;
229}
230
231void Writeback::configDone() {
232 if(sUsed == false && sWb) {
233 delete sWb;
234 sWb = NULL;
235 }
236}
237
238void Writeback::clear() {
239 sUsed = false;
240 if(sWb) {
241 delete sWb;
242 sWb = NULL;
243 }
244}
245
246Writeback *Writeback::sWb = 0;
247bool Writeback::sUsed = false;
248
249} //namespace overlay