overlay: Add writeback support
Add explicit writeback display type, writeback ioctls, memory mgmt,
writeback class, writeback obj manager class to overlay.
Change-Id: I171e60cea5ed8f6649859e3eb189df37b39962f1
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
index a375284..560b57f 100644
--- a/liboverlay/Android.mk
+++ b/liboverlay/Android.mk
@@ -16,6 +16,7 @@
overlayRotator.cpp \
overlayMdpRot.cpp \
overlayMdssRot.cpp \
+ overlayWriteback.cpp \
pipes/overlayGenPipe.cpp
include $(BUILD_SHARED_LIBRARY)
diff --git a/liboverlay/mdpWrapper.h b/liboverlay/mdpWrapper.h
index 1f4a0be..d96317c 100644
--- a/liboverlay/mdpWrapper.h
+++ b/liboverlay/mdpWrapper.h
@@ -78,6 +78,21 @@
/* MSMFB_OVERLAY_3D */
bool set3D(int fd, msmfb_overlay_3d& ov);
+/* MSMFB_DISPLAY_COMMIT */
+bool displayCommit(int fd);
+
+/* MSMFB_WRITEBACK_INIT, MSMFB_WRITEBACK_START */
+bool wbInitStart(int fbfd);
+
+/* MSMFB_WRITEBACK_STOP, MSMFB_WRITEBACK_TERMINATE */
+bool wbStopTerminate(int fbfd);
+
+/* MSMFB_WRITEBACK_QUEUE_BUFFER */
+bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData);
+
+/* MSMFB_WRITEBACK_DEQUEUE_BUFFER */
+bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData);
+
/* the following are helper functions for dumping
* msm_mdp and friends*/
void dump(const char* const s, const msmfb_overlay_data& ov);
@@ -197,6 +212,61 @@
return true;
}
+inline bool displayCommit(int fd, mdp_display_commit& info) {
+ if(ioctl(fd, MSMFB_DISPLAY_COMMIT, &info) == -1) {
+ ALOGE("Failed to call ioctl MSMFB_DISPLAY_COMMIT err=%s",
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+inline bool wbInitStart(int fbfd) {
+ if(ioctl(fbfd, MSMFB_WRITEBACK_INIT, NULL) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_INIT err=%s",
+ strerror(errno));
+ return false;
+ }
+ if(ioctl(fbfd, MSMFB_WRITEBACK_START, NULL) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_START err=%s",
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+inline bool wbStopTerminate(int fbfd) {
+ if(ioctl(fbfd, MSMFB_WRITEBACK_STOP, NULL) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_STOP err=%s",
+ strerror(errno));
+ return false;
+ }
+ if(ioctl(fbfd, MSMFB_WRITEBACK_TERMINATE, NULL) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_TERMINATE err=%s",
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+inline bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData) {
+ if(ioctl(fbfd, MSMFB_WRITEBACK_QUEUE_BUFFER, &fbData) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_QUEUE_BUFFER err=%s",
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+inline bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData) {
+ if(ioctl(fbfd, MSMFB_WRITEBACK_DEQUEUE_BUFFER, &fbData) < 0) {
+ ALOGE("Failed to call ioctl MSMFB_WRITEBACK_DEQUEUE_BUFFER err=%s",
+ strerror(errno));
+ return false;
+ }
+ return true;
+}
+
/* dump funcs */
inline void dump(const char* const s, const msmfb_overlay_data& ov) {
ALOGE("%s msmfb_overlay_data id=%d",
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index a15d0a8..f449c78 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -89,7 +89,7 @@
if(type == OV_MDP_PIPE_ANY || type == PipeBook::getPipeType((eDest)i)) {
//If the pipe is not allocated to any display or used by the
//requesting display already in previous round.
- if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED ||
+ if((mPipeBook[i].mDisplay == DPY_UNUSED ||
mPipeBook[i].mDisplay == dpy) &&
PipeBook::isNotAllocated(i)) {
//In block mode we don't allow line operations
@@ -127,7 +127,7 @@
bool Overlay::isPipeTypeAttached(eMdpPipeType type) {
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
if(type == PipeBook::getPipeType((eDest)i) &&
- mPipeBook[i].mDisplay != PipeBook::DPY_UNUSED) {
+ mPipeBook[i].mDisplay != DPY_UNUSED) {
return true;
}
}
@@ -252,7 +252,7 @@
mdp_mixer_info *minfo = NULL;
char name[64];
int fd = -1;
- for(int i = 0; i < NUM_FB_DEVICES; i++) {
+ for(int i = 0; i < MAX_FB_DEVICES; i++) {
snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
ALOGD("initoverlay:: opening the device:: %s", name);
fd = ::open(name, O_RDWR, 0);
@@ -288,9 +288,48 @@
fd = -1;
}
}
+
+ FILE *displayDeviceFP = NULL;
+ const int MAX_FRAME_BUFFER_NAME_SIZE = 128;
+ char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+ char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+ const char *strDtvPanel = "dtv panel";
+ const char *strWbPanel = "writeback panel";
+
+ for(int num = 1; num < MAX_FB_DEVICES; num++) {
+ snprintf (msmFbTypePath, sizeof(msmFbTypePath),
+ "/sys/class/graphics/fb%d/msm_fb_type", num);
+ displayDeviceFP = fopen(msmFbTypePath, "r");
+
+ if(displayDeviceFP){
+ fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
+ displayDeviceFP);
+
+ if(strncmp(fbType, strDtvPanel, strlen(strDtvPanel)) == 0) {
+ sDpyFbMap[DPY_EXTERNAL] = num;
+ } else if(strncmp(fbType, strWbPanel, strlen(strWbPanel)) == 0) {
+ sDpyFbMap[DPY_WRITEBACK] = num;
+ }
+
+ fclose(displayDeviceFP);
+ }
+ }
+
return 0;
}
+bool Overlay::displayCommit(const int& fd) {
+ //Commit
+ struct mdp_display_commit info;
+ memset(&info, 0, sizeof(struct mdp_display_commit));
+ info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
+ if(!mdp_wrapper::displayCommit(fd, info)) {
+ ALOGE("%s: commit failed", __func__);
+ return false;
+ }
+ return true;
+}
+
void Overlay::dump() const {
if(strlen(mDumpStr)) { //dump only on state change
ALOGD_IF(PIPE_DEBUG, "%s\n", mDumpStr);
@@ -343,6 +382,7 @@
Overlay* Overlay::sInstance = 0;
int Overlay::sExtFbIndex = 1;
+int Overlay::sDpyFbMap[DPY_MAX] = {0, -1, -1};
int Overlay::sDMAMode = DMA_LINE_MODE;
int Overlay::PipeBook::NUM_PIPES = 0;
int Overlay::PipeBook::sPipeUsageBitmap = 0;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index cfceaff..62cc000 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -41,6 +41,12 @@
class Overlay : utils::NoCopy {
public:
enum { DMA_BLOCK_MODE, DMA_LINE_MODE };
+ //Abstract Display types. Each backed by a LayerMixer,
+ //represented by a fb node.
+ //High res panels can be backed by 2 layer mixers and a single fb node.
+ enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_WRITEBACK, DPY_UNUSED };
+ enum { DPY_MAX = DPY_UNUSED };
+ enum { MAX_FB_DEVICES = DPY_MAX };
/* dtor close */
~Overlay();
@@ -85,6 +91,7 @@
/* set the framebuffer index for external display */
void setExtFbNum(int fbNum);
/* Returns framebuffer index of the current external display */
+ /* TODO Deprecate */
int getExtFbNum();
/* Returns pipe dump. Expects a NULL terminated buffer of big enough size
* to populate.
@@ -94,6 +101,9 @@
void clear(int dpy);
static void setDMAMode(const int& mode);
static int getDMAMode();
+ /* Returns the framebuffer node backing up the display */
+ static int getFbForDpy(const int& dpy);
+ static bool displayCommit(const int& fd);
private:
/* Ctor setup */
@@ -104,8 +114,6 @@
/* Just like a Facebook for pipes, but much less profile info */
struct PipeBook {
- enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_UNUSED };
-
void init();
void destroy();
/* Check if pipe exists and return true, false otherwise */
@@ -157,7 +165,9 @@
/* Singleton Instance*/
static Overlay *sInstance;
+ //TODO Deprecate
static int sExtFbIndex;
+ static int sDpyFbMap[DPY_MAX];
static int sDMAMode;
};
@@ -171,7 +181,7 @@
inline int Overlay::availablePipes(int dpy) {
int avail = 0;
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
- if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED ||
+ if((mPipeBook[i].mDisplay == DPY_UNUSED ||
mPipeBook[i].mDisplay == dpy) && PipeBook::isNotAllocated(i)) {
avail++;
}
@@ -196,6 +206,11 @@
return sDMAMode;
}
+inline int Overlay::getFbForDpy(const int& dpy) {
+ OVASSERT(dpy >= 0 && dpy < DPY_MAX, "Invalid dpy %d", dpy);
+ return sDpyFbMap[dpy];
+}
+
inline bool Overlay::PipeBook::valid() {
return (mPipe != NULL);
}
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 4bb2151..b543018 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -78,7 +78,6 @@
#endif
#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
-#define NUM_FB_DEVICES 3
namespace overlay {
@@ -368,15 +367,8 @@
f = static_cast<eMdpFlags>(clrBit(f, v));
}
-// fb 0/1/2
enum { FB0, FB1, FB2 };
-//Panels could be categorized as primary and external
-enum { PRIMARY, EXTERNAL };
-
-// 2 for rgb0/1 double bufs
-enum { RGB_PIPE_NUM_BUFS = 2 };
-
struct ScreenInfo {
ScreenInfo() : mFBWidth(0),
mFBHeight(0),
diff --git a/liboverlay/overlayWriteback.cpp b/liboverlay/overlayWriteback.cpp
new file mode 100644
index 0000000..b6ed53c
--- /dev/null
+++ b/liboverlay/overlayWriteback.cpp
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "overlay.h"
+#include "overlayWriteback.h"
+#include "mdpWrapper.h"
+
+namespace overlay {
+
+//=========== class WritebackMem ==============================================
+bool WritebackMem::manageMem(uint32_t size, bool isSecure) {
+ if(mBuf.bufSz() == size) {
+ return true;
+ }
+ if(mBuf.valid()) {
+ if(!mBuf.close()) {
+ ALOGE("%s error closing mem", __func__);
+ return false;
+ }
+ }
+ return alloc(size, isSecure);
+}
+
+bool WritebackMem::alloc(uint32_t size, bool isSecure) {
+ if(!mBuf.open(NUM_BUFS, size, isSecure)){
+ ALOGE("%s: Failed to open", __func__);
+ mBuf.close();
+ return false;
+ }
+
+ OVASSERT(MAP_FAILED != mBuf.addr(), "MAP failed");
+ OVASSERT(mBuf.getFD() != -1, "getFd is -1");
+
+ mCurrOffsetIndex = 0;
+ for (uint32_t i = 0; i < NUM_BUFS; i++) {
+ mOffsets[i] = i * size;
+ }
+ return true;
+}
+
+bool WritebackMem::dealloc() {
+ bool ret = true;
+ if(mBuf.valid()) {
+ ret = mBuf.close();
+ }
+ return ret;
+}
+
+//=========== class Writeback =================================================
+Writeback::Writeback() : mXres(0), mYres(0) {
+ int fbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
+ if(!utils::openDev(mFd, fbNum, Res::fbPath, O_RDWR)) {
+ ALOGE("%s failed to init %s", __func__, Res::fbPath);
+ return;
+ }
+ startSession();
+}
+
+Writeback::~Writeback() {
+ stopSession();
+ if (!mFd.close()) {
+ ALOGE("%s error closing fd", __func__);
+ }
+}
+
+bool Writeback::startSession() {
+ if(!mdp_wrapper::wbInitStart(mFd.getFD())) {
+ ALOGE("%s failed", __func__);
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::stopSession() {
+ if(mFd.valid()) {
+ if(!mdp_wrapper::wbStopTerminate(mFd.getFD())) {
+ ALOGE("%s failed", __func__);
+ return false;
+ }
+ } else {
+ ALOGE("%s Invalid fd", __func__);
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::configureDpyInfo(int xres, int yres) {
+ if(mXres != xres || mYres != yres) {
+ fb_var_screeninfo vinfo;
+ memset(&vinfo, 0, sizeof(fb_var_screeninfo));
+ if(!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) {
+ ALOGE("%s failed", __func__);
+ return false;
+ }
+ vinfo.xres = xres;
+ vinfo.yres = yres;
+ vinfo.xres_virtual = xres;
+ vinfo.yres_virtual = yres;
+ vinfo.xoffset = 0;
+ vinfo.yoffset = 0;
+ if(!mdp_wrapper::setVScreenInfo(mFd.getFD(), vinfo)) {
+ ALOGE("%s failed", __func__);
+ return false;
+ }
+ mXres = xres;
+ mYres = yres;
+ }
+ return true;
+}
+
+bool Writeback::configureMemory(uint32_t size, bool isSecure) {
+ if(!mWbMem.manageMem(size, isSecure)) {
+ ALOGE("%s failed, memory failure", __func__);
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::queueBuffer(int opFd, uint32_t opOffset) {
+ memset(&mFbData, 0, sizeof(struct msmfb_data));
+ //Queue
+ mFbData.offset = opOffset;
+ mFbData.memory_id = opFd;
+ mFbData.id = 0;
+ mFbData.flags = 0;
+ if(!mdp_wrapper::wbQueueBuffer(mFd.getFD(), mFbData)) {
+ ALOGE("%s: queuebuffer failed", __func__);
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::dequeueBuffer() {
+ //Dequeue
+ mFbData.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
+ if(!mdp_wrapper::wbDequeueBuffer(mFd.getFD(), mFbData)) {
+ ALOGE("%s: dequeuebuffer failed", __func__);
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::writeSync(int opFd, uint32_t opOffset) {
+ if(!queueBuffer(opFd, opOffset)) {
+ return false;
+ }
+ if(!Overlay::displayCommit(mFd.getFD())) {
+ return false;
+ }
+ if(!dequeueBuffer()) {
+ return false;
+ }
+ return true;
+}
+
+bool Writeback::writeSync() {
+ mWbMem.useNextBuffer();
+ return writeSync(mWbMem.getDstFd(), mWbMem.getOffset());
+}
+
+//static
+
+Writeback *Writeback::getInstance() {
+ if(sWb == NULL) {
+ sWb = new Writeback();
+ }
+ sUsed = true;
+ return sWb;
+}
+
+void Writeback::configDone() {
+ if(sUsed == false && sWb) {
+ delete sWb;
+ sWb = NULL;
+ }
+}
+
+void Writeback::clear() {
+ sUsed = false;
+ if(sWb) {
+ delete sWb;
+ sWb = NULL;
+ }
+}
+
+Writeback *Writeback::sWb = 0;
+bool Writeback::sUsed = false;
+
+} //namespace overlay
diff --git a/liboverlay/overlayWriteback.h b/liboverlay/overlayWriteback.h
new file mode 100644
index 0000000..fbfd889
--- /dev/null
+++ b/liboverlay/overlayWriteback.h
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef OVERLAY_WRITEBACK_H
+#define OVERLAY_WRITEBACK_H
+
+#include "overlayMem.h"
+
+namespace overlay {
+
+class WritebackMgr;
+
+class WritebackMem {
+public:
+ explicit WritebackMem() : mCurrOffsetIndex(0) {
+ memset(&mOffsets, 0, sizeof(mOffsets));
+ }
+ ~WritebackMem() { dealloc(); }
+ bool manageMem(uint32_t size, bool isSecure);
+ void useNextBuffer() {
+ mCurrOffsetIndex = (mCurrOffsetIndex + 1) % NUM_BUFS;
+ }
+ uint32_t getOffset() const { return mOffsets[mCurrOffsetIndex]; }
+ int getDstFd() const { return mBuf.getFD(); }
+private:
+ bool alloc(uint32_t size, bool isSecure);
+ bool dealloc();
+ enum { NUM_BUFS = 2 };
+ OvMem mBuf;
+ uint32_t mOffsets[NUM_BUFS];
+ uint32_t mCurrOffsetIndex;
+};
+
+//Abstracts the WB2 interface of MDP
+//Has modes to either manage memory or work with memory allocated elsewhere
+class Writeback {
+public:
+ ~Writeback();
+ bool configureDpyInfo(int xres, int yres);
+ bool configureMemory(uint32_t size, bool isSecure);
+ /* Blocking write. (queue, commit, dequeue)
+ * This class will do writeback memory management.
+ * This class will call display-commit on writeback mixer.
+ */
+ bool writeSync();
+ /* Blocking write. (queue, commit, dequeue)
+ * Client must do writeback memory management.
+ * Client must not call display-commit on writeback mixer.
+ */
+ bool writeSync(int opFd, uint32_t opOffset);
+ /* Async queue. (Does not write)
+ * Client must do writeback memory management.
+ * Client must call display-commit on their own.
+ * Client must use sync mechanism e.g sync pt.
+ */
+ bool queueBuffer(int opFd, uint32_t opOffset);
+ uint32_t getOffset() const { return mWbMem.getOffset(); }
+ int getDstFd() const { return mWbMem.getDstFd(); }
+
+ static Writeback* getInstance();
+ static void configBegin() { sUsed = false; }
+ static void configDone();
+ static void clear();
+
+private:
+ explicit Writeback();
+ bool startSession();
+ bool stopSession();
+ //Actually block_until_write_done for the usage here.
+ bool dequeueBuffer();
+ OvFD mFd;
+ WritebackMem mWbMem;
+ struct msmfb_data mFbData;
+ int mXres;
+ int mYres;
+
+ static bool sUsed;
+ static Writeback *sWb;
+};
+
+}
+
+#endif
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 3ab0d19..0de7129 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -33,7 +33,7 @@
namespace overlay {
-GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRotDownscaleOpt(false),
+GenericPipe::GenericPipe(int dpy) : mDpy(dpy), mRotDownscaleOpt(false),
pipeState(CLOSED) {
init();
}
@@ -46,17 +46,24 @@
{
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
mRotDownscaleOpt = false;
- if(mFbNum)
- mFbNum = Overlay::getInstance()->getExtFbNum();
- ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, mFbNum);
+ int fbNum = 0;
+ //TODO Remove the if block. What's in else block should be the standard way
+ //EXTERNAL's meaning has been overloaded in hwc to mean WFD also!
+ if(mDpy == Overlay::DPY_EXTERNAL) {
+ fbNum = Overlay::getInstance()->getExtFbNum();
+ } else if(mDpy == Overlay::DPY_WRITEBACK) {
+ fbNum = Overlay::getFbForDpy(mDpy);
+ }
- if(!mCtrlData.ctrl.init(mFbNum)) {
+ ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, fbNum);
+
+ if(!mCtrlData.ctrl.init(fbNum)) {
ALOGE("GenericPipe failed to init ctrl");
return false;
}
- if(!mCtrlData.data.init(mFbNum)) {
+ if(!mCtrlData.data.init(fbNum)) {
ALOGE("GenericPipe failed to init data");
return false;
}
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 9a66632..2472f4e 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -82,7 +82,7 @@
/* set Closed pipe */
bool setClosed();
- int mFbNum;
+ int mDpy;
/* Ctrl/Data aggregator */
CtrlData mCtrlData;
//Whether we will do downscale opt. This is just a request. If the frame is