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