Merge "display: Use fences for all targets"
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index a05ea16..f9ee94c 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, The Linux Foundation. All rights reserved.
@@ -37,37 +36,142 @@
#include "hwc_utils.h"
#include "external.h"
#include "overlayUtils.h"
+#include "overlay.h"
using namespace android;
namespace qhwc {
+#define MAX_FRAME_BUFFER_NAME_SIZE (80)
+#define MAX_DISPLAY_DEVICES (3)
-#define DEVICE_ROOT "/sys/devices/virtual/graphics"
-#define DEVICE_NODE "fb1"
-#define SYSFS_EDID_MODES DEVICE_ROOT "/" DEVICE_NODE "/edid_modes"
-#define SYSFS_HPD DEVICE_ROOT "/" DEVICE_NODE "/hpd"
+const char* msmFbDevicePath[] = { "/dev/graphics/fb1",
+ "/dev/graphics/fb2"};
+/*
+ * Updates extDeviceFbIndex Array with the correct frame buffer indices
+ * of avaiable external devices
+ *
+ */
+void ExternalDisplay::updateExtDispDevFbIndex()
+{
+ FILE *displayDeviceFP = NULL;
+ char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
+ char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
+
+ for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) {
+ sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j);
+ displayDeviceFP = fopen(msmFbTypePath, "r");
+ if(displayDeviceFP){
+ fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
+ displayDeviceFP);
+ if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){
+ ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j);
+ mHdmiFbNum = j;
+ } else if(strncmp(fbType, "writeback panel",
+ strlen("writeback panel")) == 0){
+ ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j);
+ mWfdFbNum = j;
+ }
+ fclose(displayDeviceFP);
+ }
+ }
+ ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__,
+ mHdmiFbNum, mWfdFbNum);
+}
+
+int ExternalDisplay::configureHDMIDisplay() {
+ openFrameBuffer(mHdmiFbNum);
+ if(mFd == -1)
+ return -1;
+ readResolution();
+ //Get the best mode and set
+ // TODO: Move this to activate
+ setResolution(getBestMode());
+ setDpyHdmiAttr();
+ setExternalDisplay(true, mHdmiFbNum);
+ return 0;
+}
+
+int ExternalDisplay::configureWFDDisplay() {
+ int ret = 0;
+ if(mConnectedFbNum == mHdmiFbNum) {
+ ALOGE("%s: Cannot process WFD connection while HDMI is active",
+ __FUNCTION__);
+ return -1;
+ }
+ openFrameBuffer(mWfdFbNum);
+ if(mFd == -1)
+ return -1;
+ ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
+ if(ret < 0) {
+ ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
+ strerror(errno));
+ }
+ setDpyWfdAttr();
+ setExternalDisplay(true, mWfdFbNum);
+ return 0;
+}
+
+int ExternalDisplay::teardownHDMIDisplay() {
+ if(mConnectedFbNum == mHdmiFbNum) {
+ // hdmi offline event..!
+ closeFrameBuffer();
+ resetInfo();
+ setExternalDisplay(false);
+ }
+ return 0;
+}
+
+int ExternalDisplay::teardownWFDDisplay() {
+ if(mConnectedFbNum == mWfdFbNum) {
+ // wfd offline event..!
+ closeFrameBuffer();
+ memset(&mVInfo, 0, sizeof(mVInfo));
+ setExternalDisplay(false);
+ }
+ return 0;
+}
+
+void ExternalDisplay::processUEventOnline(const char *str) {
+ const char *s1 = str + strlen("change@/devices/virtual/switch/");
+ if(!strncmp(s1,"hdmi",strlen(s1))) {
+ // hdmi online event..!
+ configureHDMIDisplay();
+ }else if(!strncmp(s1,"wfd",strlen(s1))) {
+ // wfd online event..!
+ configureWFDDisplay();
+ }
+}
+
+void ExternalDisplay::processUEventOffline(const char *str) {
+ const char *s1 = str + strlen("change@/devices/virtual/switch/");
+ if(!strncmp(s1,"hdmi",strlen(s1))) {
+ teardownHDMIDisplay();
+ }else if(!strncmp(s1,"wfd",strlen(s1))) {
+ teardownWFDDisplay();
+ }
+}
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
- mCurrentMode(-1), mExternalDisplay(0), mModeCount(0), mHwcContext(ctx)
+ mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
+ mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
{
memset(&mVInfo, 0, sizeof(mVInfo));
- //Enable HPD for HDMI
- writeHPDOption(1);
+ //Determine the fb index for external display devices.
+ updateExtDispDevFbIndex();
}
void ExternalDisplay::setEDIDMode(int resMode) {
ALOGD_IF(DEBUG,"resMode=%d ", resMode);
- int extDispType;
{
Mutex::Autolock lock(mExtDispLock);
- extDispType = mExternalDisplay;
- setExternalDisplay(0);
+ setExternalDisplay(false);
+ openFrameBuffer(mHdmiFbNum);
setResolution(resMode);
}
- setExternalDisplay(extDispType);
+ setExternalDisplay(true, mHdmiFbNum);
}
void ExternalDisplay::setHPD(uint32_t startEnd) {
@@ -79,7 +183,7 @@
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
Mutex::Autolock lock(mExtDispLock);
overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
- setExternalDisplay(mExternalDisplay);
+ setExternalDisplay(true, mHdmiFbNum);
}
int ExternalDisplay::getModeCount() const {
@@ -206,12 +310,16 @@
bool ExternalDisplay::readResolution()
{
- int hdmiEDIDFile = open(SYSFS_EDID_MODES, O_RDONLY, 0);
+ char sysFsEDIDFilePath[255];
+ sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes",
+ mHdmiFbNum);
+
+ int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
int len = -1;
if (hdmiEDIDFile < 0) {
ALOGE("%s: edid_modes file '%s' not found",
- __FUNCTION__, SYSFS_EDID_MODES);
+ __FUNCTION__, sysFsEDIDFilePath);
return false;
} else {
len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
@@ -219,7 +327,7 @@
__FUNCTION__, mEDIDs, len);
if ( len <= 0) {
ALOGE("%s: edid_modes file empty '%s'",
- __FUNCTION__, SYSFS_EDID_MODES);
+ __FUNCTION__, sysFsEDIDFilePath);
}
else {
while (len > 1 && isspace(mEDIDs[len-1]))
@@ -229,7 +337,7 @@
}
close(hdmiEDIDFile);
if(len > 0) {
- // GEt EDID modes from the EDID strings
+ // Get EDID modes from the EDID strings
mModeCount = parseResolution(mEDIDs, mEDIDModes);
ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
mModeCount);
@@ -238,15 +346,16 @@
return (strlen(mEDIDs) > 0);
}
-bool ExternalDisplay::openFramebuffer()
+bool ExternalDisplay::openFrameBuffer(int fbNum)
{
if (mFd == -1) {
- mFd = open("/dev/graphics/fb1", O_RDWR);
+ mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
if (mFd < 0)
- ALOGE("%s: /dev/graphics/fb1 not available", __FUNCTION__);
- }
- if(mHwcContext) {
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+ ALOGE("%s: %s is not available", __FUNCTION__,
+ msmFbDevicePath[fbNum-1]);
+ if(mHwcContext) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+ }
}
return (mFd > 0);
}
@@ -341,8 +450,6 @@
{
struct fb_var_screeninfo info;
int ret = 0;
- if (!openFramebuffer())
- return;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
if(ret < 0) {
ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
@@ -384,54 +491,49 @@
}
}
-void ExternalDisplay::setExternalDisplay(int connected)
+void ExternalDisplay::setExternalDisplay(bool connected, int extFbNum)
{
-
hwc_context_t* ctx = mHwcContext;
if(ctx) {
- ALOGD_IF(DEBUG, "%s: status = %d", __FUNCTION__,
- connected);
- if(connected) {
- readResolution();
- //Get the best mode and set
- // TODO: Move this to activate
- setResolution(getBestMode());
- setDpyAttr();
- //enable hdmi vsync
- } else {
- // Disable the hdmi vsync
- closeFrameBuffer();
- resetInfo();
- }
+ ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected);
// Store the external display
- mExternalDisplay = connected;
- const char* prop = (connected) ? "1" : "0";
- // set system property
- property_set("hw.hdmiON", prop);
+ mConnected = connected;
+ mConnectedFbNum = extFbNum;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
+ // Update external fb number in Overlay context
+ overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
}
- return;
+}
+
+int ExternalDisplay::getExtFbNum(int &fbNum) {
+ int ret = -1;
+ if(mConnected) {
+ fbNum = mConnectedFbNum;
+ ret = 0;
+ }
+ return ret;
}
bool ExternalDisplay::writeHPDOption(int userOption) const
{
bool ret = true;
- int hdmiHPDFile = open(SYSFS_HPD,O_RDWR, 0);
+ char sysFsHPDFilePath[255];
+ sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd",
+ mHdmiFbNum);
+ int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0);
if (hdmiHPDFile < 0) {
- ALOGE("%s: state file '%s' not found : ret%d"
- "err str: %s", __FUNCTION__, SYSFS_HPD, hdmiHPDFile,
- strerror(errno));
+ ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__,
+ sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
ret = false;
} else {
int err = -1;
- ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__,
- userOption);
+ ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
if(userOption)
err = write(hdmiHPDFile, "1", 2);
else
err = write(hdmiHPDFile, "0" , 2);
if (err <= 0) {
- ALOGE("%s: file write failed '%s'",
- __FUNCTION__, SYSFS_HPD);
+ ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
ret = false;
}
close(hdmiHPDFile);
@@ -441,25 +543,32 @@
/*
* commits the changes to the external display
- * mExternalDisplay has the mixer number(1-> HDMI 2-> WFD)
*/
bool ExternalDisplay::post()
{
if(mFd == -1)
return false;
-
struct mdp_display_commit ext_commit;
ext_commit.flags |= MDP_DISPLAY_COMMIT_OVERLAY;
if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) {
- ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
- __FUNCTION__, strerror(errno));
- return false;
+ ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
+ __FUNCTION__, strerror(errno));
+ return false;
}
-
return true;
}
-void ExternalDisplay::setDpyAttr() {
+void ExternalDisplay::setDpyWfdAttr() {
+ if(mHwcContext) {
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = mVInfo.xres;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = mVInfo.yres;
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
+ 1000000000l /60;
+ ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
+ }
+}
+
+void ExternalDisplay::setDpyHdmiAttr() {
int width = 0, height = 0, fps = 0;
getAttrForMode(width, height, fps);
if(mHwcContext) {
@@ -471,8 +580,7 @@
}
}
-void ExternalDisplay::getAttrForMode(int& width, int& height,
-int& fps) {
+void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
switch (mCurrentMode) {
case m640x480p60_4_3:
width = 640;
@@ -530,4 +638,3 @@
}
};
-
diff --git a/libexternal/external.h b/libexternal/external.h
index da3ccd5..46c982d 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -28,6 +28,7 @@
namespace qhwc {
+
class ExternalDisplay
{
public:
@@ -35,37 +36,50 @@
~ExternalDisplay();
int getModeCount() const;
void getEDIDModes(int *out) const;
- void setExternalDisplay(int connected);
+ void setExternalDisplay(bool connected, int extFbNum = 0);
+ bool isExternalConnected() { return mConnected;};
bool post();
void setHPD(uint32_t startEnd);
void setEDIDMode(int resMode);
void setActionSafeDimension(int w, int h);
+ void processUEventOnline(const char *str);
+ void processUEventOffline(const char *str);
private:
bool readResolution();
- int parseResolution(char* edidStr, int* edidModes);
+ int parseResolution(char* edidStr, int* edidModes);
void setResolution(int ID);
- bool openFramebuffer();
+ bool openFrameBuffer(int fbNum);
bool closeFrameBuffer();
bool writeHPDOption(int userOption) const;
bool isValidMode(int ID);
void handleUEvent(char* str, int len);
- int getModeOrder(int mode);
- int getBestMode();
+ int getModeOrder(int mode);
+ int getBestMode();
void resetInfo();
- void setDpyAttr();
+ void setDpyHdmiAttr();
+ void setDpyWfdAttr();
void getAttrForMode(int& width, int& height, int& fps);
+ void updateExtDispDevFbIndex();
+ int configureHDMIDisplay();
+ int configureWFDDisplay();
+ int teardownHDMIDisplay();
+ int teardownWFDDisplay();
+ int getExtFbNum(int &fbNum);
mutable android::Mutex mExtDispLock;
int mFd;
int mCurrentMode;
- int mExternalDisplay;
+ int mConnected;
+ int mConnectedFbNum;
int mResolutionMode;
char mEDIDs[128];
int mEDIDModes[64];
int mModeCount;
hwc_context_t *mHwcContext;
fb_var_screeninfo mVInfo;
+ int mHdmiFbNum;
+ int mWfdFbNum;
};
}; //qhwc
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 20ac9a5..23ffa42 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -236,6 +236,9 @@
default:
return -EINVAL;
}
+ // Enable HPD here, as during bootup unblank is called
+ // when SF is completely initialized
+ ctx->mExtDisplay->setHPD(1);
if(ret < 0) {
ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
@@ -451,6 +454,18 @@
return 0;
}
+void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
+{
+ hwc_context_t* ctx = (hwc_context_t*)(dev);
+ android::String8 buf("");
+ dumpsys_log(buf, "Qualcomm HWC state:\n");
+ dumpsys_log(buf, " MDPVersion=%d\n", ctx->mMDP.version);
+ dumpsys_log(buf, " DisplayPanel=%c\n", ctx->mMDP.panel);
+ MDPComp::dump(buf);
+ //XXX: Call Other dump functions
+ strlcpy(buff, buf.string(), buff_len);
+}
+
static int hwc_device_close(struct hw_device_t *dev)
{
if(!dev) {
@@ -487,7 +502,7 @@
dev->device.blank = hwc_blank;
dev->device.query = hwc_query;
dev->device.registerProcs = hwc_registerProcs;
- dev->device.dump = NULL;
+ dev->device.dump = hwc_dump;
dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
*device = &dev->device.common;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 8616719..4200be9 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -628,5 +628,15 @@
return isMDPCompUsed;
}
+
+void MDPComp::dump(android::String8& buf)
+{
+ dumpsys_log(buf, " MDP Composition: ");
+ dumpsys_log(buf, "MDPCompState=%d\n", sMDPCompState);
+ //XXX: Log more info
+
+}
+
+
}; //namespace
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 2821f07..6ff6385 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -82,6 +82,8 @@
/* draw */
static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+ static void dump(android::String8& buf);
+
private:
/* set/reset flags for MDPComp */
static void setMDPCompLayerFlags(hwc_context_t *ctx,
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 89b27aa..78f6788 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -1,3 +1,4 @@
+
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, The Linux Foundation. All rights reserved.
@@ -31,46 +32,47 @@
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
-const char* MSMFB_HDMI_NODE = "fb1";
-
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
{
int vsync = 0;
- char* hdmi;
int64_t timestamp = 0;
const char *str = udata;
- if(!strcasestr(str, "@/devices/virtual/graphics/fb")) {
+ if(!strcasestr(str, "change@/devices/virtual/switch/hdmi") &&
+ !strcasestr(str, "change@/devices/virtual/switch/wfd")) {
ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
return;
}
- hdmi = strcasestr(str, MSMFB_HDMI_NODE);
- // parse HDMI events
+
+ int connected = -1; // initial value - will be set to 1/0 based on hotplug
+ // parse HDMI/WFD switch state for connect/disconnect
+ // for HDMI:
// The event will be of the form:
- // change@/devices/virtual/graphics/fb1 ACTION=change
- // DEVPATH=/devices/virtual/graphics/fb1
- // SUBSYSTEM=graphics HDCP_STATE=FAIL MAJOR=29
- // for now just parsing onlin/offline info is enough
- if (hdmi) {
- str = udata;
- int connected = -1; //some event other than online and offline .. e.g
- if(!(strncmp(str,"online@",strlen("online@")))) {
+ // change@/devices/virtual/switch/hdmi ACTION=change
+ // SWITCH_STATE=1 or SWITCH_STATE=0
+
+ while(*str) {
+ if (!strncmp(str, "SWITCH_STATE=", strlen("SWITCH_STATE="))) {
+ connected = atoi(str + strlen("SWITCH_STATE="));
//Disabled until SF calls unblank
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
- connected = 1;
- } else if(!(strncmp(str,"offline@",strlen("offline@")))) {
- //Disabled until SF calls unblank
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
- connected = 0;
+ break;
}
- if(connected != -1) { //either we got online or offline
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
- ctx->mExtDisplay->setExternalDisplay(connected);
- ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,connected);
- Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
- //TODO ideally should be done on "connected" not "online"
- ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
+ str += strlen(str) + 1;
+ if (str - udata >= len)
+ break;
+ }
+
+ if(connected != -1) { //either we got switch_state connected or disconnect
+ ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
+ if(connected) {
+ ctx->mExtDisplay->processUEventOnline(udata);
+ }else {
+ ctx->mExtDisplay->processUEventOffline(udata);
}
+ ALOGD("%s sending hotplug: connected = %d", __FUNCTION__, connected);
+ Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
+ ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
}
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 3656971..0ae64da 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -92,22 +92,15 @@
pthread_mutex_destroy(&(ctx->vstate.lock));
pthread_cond_destroy(&(ctx->vstate.cond));
-
}
-void dumpLayer(hwc_layer_1_t const* l)
+
+void dumpsys_log(android::String8& buf, const char* fmt, ...)
{
- ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}"
- ", {%d,%d,%d,%d}",
- l->compositionType, l->flags, l->handle, l->transform, l->blending,
- l->sourceCrop.left,
- l->sourceCrop.top,
- l->sourceCrop.right,
- l->sourceCrop.bottom,
- l->displayFrame.left,
- l->displayFrame.top,
- l->displayFrame.right,
- l->displayFrame.bottom);
+ va_list varargs;
+ va_start(varargs, fmt);
+ buf.appendFormatV(fmt, varargs);
+ va_end(varargs);
}
static inline bool isAlphaScaled(hwc_layer_1_t const* layer) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index a7de804..256b840 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -23,6 +23,7 @@
#include <hardware/hwcomposer.h>
#include <gr.h>
#include <gralloc_priv.h>
+#include <utils/String8.h>
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
@@ -125,6 +126,9 @@
bool isSecuring(hwc_context_t* ctx);
bool isExternalActive(hwc_context_t* ctx);
+//Helper function to dump logs
+void dumpsys_log(android::String8& buf, const char* fmt, ...);
+
//Sync point impl.
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy);
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 7b7719c..04deee5 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -220,6 +220,7 @@
}
Overlay* Overlay::sInstance = 0;
+int Overlay::sExtFbIndex = 1;
int Overlay::PipeBook::NUM_PIPES = 0;
int Overlay::PipeBook::sPipeUsageBitmap = 0;
int Overlay::PipeBook::sLastUsageBitmap = 0;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 523e3f7..2378889 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -31,6 +31,7 @@
#define OVERLAY_H
#include "overlayUtils.h"
+#include "utils/threads.h"
namespace overlay {
class GenericPipe;
@@ -72,6 +73,10 @@
static Overlay* getInstance();
/* Returns total of available ("unallocated") pipes */
static int availablePipes();
+ /* set the framebuffer index for external display */
+ void setExtFbNum(int fbNum);
+ /* Returns framebuffer index of the current external display */
+ int getExtFbNum();
private:
/* Ctor setup */
@@ -130,8 +135,11 @@
/* Dump string */
char mDumpStr[256];
+ mutable android::Mutex mOvExtFbLock;
+
/* Singleton Instance*/
static Overlay *sInstance;
+ static int sExtFbIndex;
};
inline void Overlay::validate(int index) {
@@ -145,6 +153,16 @@
return PipeBook::availablePipes();
}
+inline void Overlay::setExtFbNum(int fbNum) {
+ android::Mutex::Autolock lock(mOvExtFbLock);
+ sExtFbIndex = fbNum;
+}
+
+inline int Overlay::getExtFbNum() {
+ android::Mutex::Autolock lock(mOvExtFbLock);
+ return sExtFbIndex;
+}
+
inline int Overlay::PipeBook::availablePipes() {
int used = 0;
int bmp = sAllocatedBitmap;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 207531a..d0f9457 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -153,44 +153,47 @@
/* clears any VG pipes allocated to the fb devices */
int initOverlay() {
- msmfb_mixer_info_req req;
- mdp_mixer_info *minfo = NULL;
- char name[64];
- int fd = -1;
- for(int i = 0; i < NUM_FB_DEVICES; i++) {
- snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
- ALOGD("initoverlay:: opening the device:: %s", name);
- fd = ::open(name, O_RDWR, 0);
- if(fd < 0) {
- ALOGE("cannot open framebuffer(%d)", i);
- return -1;
- }
- //Get the mixer configuration */
- req.mixer_num = i;
- if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
- ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
- close(fd);
- return -1;
- }
- minfo = req.info;
- for (int j = 0; j < req.cnt; j++) {
- ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
- minfo->z_order);
- // except the RGB base layer with z_order of -1, clear any
- // other pipes connected to mixer.
- if((minfo->z_order) != -1) {
- int index = minfo->pndx;
- ALOGD("Unset overlay with index: %d at mixer %d", index, i);
- if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
- ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
- close(fd);
- return -1;
- }
+ int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+ if (mdpVersion < qdutils::MDSS_V5) {
+ msmfb_mixer_info_req req;
+ mdp_mixer_info *minfo = NULL;
+ char name[64];
+ int fd = -1;
+ for(int i = 0; i < NUM_FB_DEVICES; i++) {
+ snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
+ ALOGD("initoverlay:: opening the device:: %s", name);
+ fd = ::open(name, O_RDWR, 0);
+ if(fd < 0) {
+ ALOGE("cannot open framebuffer(%d)", i);
+ return -1;
}
- minfo++;
+ //Get the mixer configuration */
+ req.mixer_num = i;
+ if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
+ ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
+ close(fd);
+ return -1;
+ }
+ minfo = req.info;
+ for (int j = 0; j < req.cnt; j++) {
+ ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
+ minfo->z_order);
+ // except the RGB base layer with z_order of -1, clear any
+ // other pipes connected to mixer.
+ if((minfo->z_order) != -1) {
+ int index = minfo->pndx;
+ ALOGD("Unset overlay with index: %d at mixer %d", index, i);
+ if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
+ ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
+ close(fd);
+ return -1;
+ }
+ }
+ minfo++;
+ }
+ close(fd);
+ fd = -1;
}
- close(fd);
- fd = -1;
}
return 0;
}
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index ecb3b16..9f08c14 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -28,6 +28,7 @@
*/
#include "overlayGenPipe.h"
+#include "overlay.h"
namespace overlay {
@@ -44,6 +45,10 @@
{
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
mRotUsed = false;
+ if(mFbNum)
+ mFbNum = Overlay::getInstance()->getExtFbNum();
+
+ ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, mFbNum);
if(!mCtrlData.ctrl.init(mFbNum)) {
ALOGE("GenericPipe failed to init ctrl");