Merge "hwc: Get notified on media player death."
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 1c8f170..839d79a 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -168,11 +168,13 @@
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
- mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
+ mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1),
+ mWfdFbNum(-1), mExtDpyNum(HWC_DISPLAY_EXTERNAL)
{
memset(&mVInfo, 0, sizeof(mVInfo));
//Determine the fb index for external display devices.
updateExtDispDevFbIndex();
+
}
void ExternalDisplay::setEDIDMode(int resMode) {
@@ -441,7 +443,7 @@
ALOGE("%s: %s is not available", __FUNCTION__,
msmFbDevicePath[fbNum-1]);
if(mHwcContext) {
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+ mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
}
}
return (mFd > 0);
@@ -450,12 +452,12 @@
bool ExternalDisplay::closeFrameBuffer()
{
int ret = 0;
- if(mFd > 0) {
+ if(mFd >= 0) {
ret = close(mFd);
mFd = -1;
}
if(mHwcContext) {
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
+ mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
}
return (ret == 0);
}
@@ -639,7 +641,7 @@
// Store the external display
mConnected = connected;
mConnectedFbNum = extFbNum;
- mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
+ mHwcContext->dpyAttr[mExtDpyNum].connected = connected;
// Update external fb number in Overlay context
overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
}
@@ -688,6 +690,7 @@
{
if(mFd == -1)
return false;
+
struct mdp_display_commit ext_commit;
memset(&ext_commit, 0, sizeof(struct mdp_display_commit));
ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
@@ -701,9 +704,9 @@
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 =
+ mHwcContext->dpyAttr[mExtDpyNum].xres = mVInfo.xres;
+ mHwcContext->dpyAttr[mExtDpyNum].yres = mVInfo.yres;
+ mHwcContext->dpyAttr[mExtDpyNum].vsync_period =
1000000000l /60;
ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
}
diff --git a/libexternal/external.h b/libexternal/external.h
index baf3598..39f8645 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -46,6 +46,7 @@
bool isCEUnderscanSupported() { return mUnderscanSupported; }
void setExternalDisplay(bool connected, int extFbNum = 0);
bool isExternalConnected() { return mConnected;};
+ void setExtDpyNum(int extDpyNum) { mExtDpyNum = extDpyNum;};
bool post();
void setHPD(uint32_t startEnd);
void setEDIDMode(int resMode);
@@ -92,6 +93,7 @@
fb_var_screeninfo mVInfo;
int mHdmiFbNum;
int mWfdFbNum;
+ int mExtDpyNum;
};
}; //qhwc
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index f4e3834..749a672 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -35,7 +35,7 @@
LOCAL_MODULE := libmemalloc
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libgenlock libqdutils
+LOCAL_SHARED_LIBRARIES := $(common_libs) libgenlock libqdutils libdl
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdmemalloc\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := ionalloc.cpp alloc_controller.cpp
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 5aca758..ebd7e98 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -29,6 +29,7 @@
#include <cutils/log.h>
#include <fcntl.h>
+#include <dlfcn.h>
#include "gralloc_priv.h"
#include "alloc_controller.h"
#include "memalloc.h"
@@ -84,29 +85,72 @@
}
//-------------- AdrenoMemInfo-----------------------//
+AdrenoMemInfo::AdrenoMemInfo()
+{
+ libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
+ if (libadreno_utils) {
+ *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
+ "compute_surface_padding");
+ }
+}
+
+AdrenoMemInfo::~AdrenoMemInfo()
+{
+ if (libadreno_utils) {
+ ::dlclose(libadreno_utils);
+ }
+}
+
int AdrenoMemInfo::getStride(int width, int format)
{
int stride = ALIGN(width, 32);
- switch (format)
- {
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- stride = ALIGN(width, 32);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- stride = ALIGN(width, 128);
- break;
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YV12:
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- stride = ALIGN(width, 16);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
- break;
- default: break;
+ // Currently surface padding is only computed for RGB* surfaces.
+ if (format < 0x7) {
+ int bpp = 4;
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGB_888:
+ bpp = 3;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ bpp = 2;
+ break;
+ default: break;
+ }
+ if ((libadreno_utils) && (LINK_adreno_compute_padding)) {
+ int surface_tile_height = 1; // Linear surface
+ int raster_mode = 1; // Adreno TW raster mode.
+ int padding_threshold = 512; // Threshold for padding surfaces.
+ // the function below expects the width to be a multiple of
+ // 32 pixels, hence we pass stride instead of width.
+ stride = LINK_adreno_compute_padding(stride, bpp,
+ surface_tile_height, raster_mode,
+ padding_threshold);
+ }
+ } else {
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ stride = ALIGN(width, 32);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ stride = ALIGN(width, 128);
+ break;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ stride = ALIGN(width, 16);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ break;
+ default: break;
+ }
}
return stride;
}
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index c6bd137..5343c35 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -84,12 +84,25 @@
class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
{
public:
- AdrenoMemInfo() {}
+ AdrenoMemInfo();
- ~AdrenoMemInfo() {}
+ ~AdrenoMemInfo();
+ /*
+ * Function to compute the adreno stride based on the width and format.
+ *
+ * @return stride.
+ */
int getStride(int width, int format);
private:
+ // Pointer to the padding library.
+ void *libadreno_utils;
+
+ // link to the surface padding library.
+ int (*LINK_adreno_compute_padding) (int width, int bpp,
+ int surface_tile_height,
+ int screen_tile_height,
+ int padding_threshold);
};
#endif /* GR_H_ */
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 6a0e0ee..519126f 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -84,7 +84,7 @@
static void reset(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) {
memset(ctx->listStats, 0, sizeof(ctx->listStats));
- for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
+ for(int i = 0; i < MAX_DISPLAYS; i++) {
hwc_display_contents_1_t *list = displays[i];
// XXX:SurfaceFlinger no longer guarantees that this
// value is reset on every prepare. However, for the layer
@@ -148,25 +148,31 @@
}
static int hwc_prepare_external(hwc_composer_device_1 *dev,
- hwc_display_contents_1_t *list) {
+ hwc_display_contents_1_t *list, int dpy) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
- const int dpy = HWC_DISPLAY_EXTERNAL;
if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected) {
-
uint32_t last = list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- if(fbLayer->handle) {
- setListStats(ctx, list, dpy);
- reset_layer_prop(ctx, dpy);
- VideoOverlay::prepare(ctx, list, dpy);
- ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
- ctx->mLayerCache[dpy]->updateLayerCache(list);
- if(ctx->mCopyBit[dpy])
- ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
- ctx->mExtDispConfiguring = false;
+ if(!ctx->dpyAttr[dpy].isPause) {
+ hwc_layer_1_t *fbLayer = &list->hwLayers[last];
+ if(fbLayer->handle) {
+ setListStats(ctx, list, dpy);
+ reset_layer_prop(ctx, dpy);
+ VideoOverlay::prepare(ctx, list, dpy);
+ ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
+ ctx->mLayerCache[dpy]->updateLayerCache(list);
+ if(ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+ ctx->mExtDispConfiguring = false;
+ }
+ } else {
+ // External Display is in Pause state.
+ // ToDo:
+ // Mark all application layers as OVERLAY so that
+ // GPU will not compose. This is done for power
+ // optimization
}
}
return 0;
@@ -182,14 +188,15 @@
ctx->mOverlay->configBegin();
- for (int32_t i = numDisplays - 1; i >= 0; i--) {
+ for (int32_t i = numDisplays; i >= 0; i--) {
hwc_display_contents_1_t *list = displays[i];
switch(i) {
case HWC_DISPLAY_PRIMARY:
ret = hwc_prepare_primary(dev, list);
break;
case HWC_DISPLAY_EXTERNAL:
- ret = hwc_prepare_external(dev, list);
+ case HWC_DISPLAY_VIRTUAL:
+ ret = hwc_prepare_external(dev, list, i);
break;
default:
ret = -EINVAL;
@@ -244,8 +251,9 @@
}
break;
case HWC_DISPLAY_EXTERNAL:
+ case HWC_DISPLAY_VIRTUAL:
if(blank) {
- // External Display post commits the changes to display
+ // External/Virtual Display post commits the changes to display
// Call this on blank, so that any pipe unsets gets committed
if (!ctx->mExtDisplay->post()) {
ret = -1;
@@ -342,13 +350,12 @@
}
static int hwc_set_external(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
+ hwc_display_contents_1_t* list, int dpy) {
int ret = 0;
- const int dpy = HWC_DISPLAY_EXTERNAL;
-
Locker::Autolock _l(ctx->mExtSetLock);
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
+ !ctx->dpyAttr[dpy].isPause &&
ctx->dpyAttr[dpy].connected) {
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
@@ -388,14 +395,19 @@
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
Locker::Autolock _l(ctx->mBlankLock);
- for (uint32_t i = 0; i < numDisplays; i++) {
+ for (uint32_t i = 0; i <= numDisplays; i++) {
hwc_display_contents_1_t* list = displays[i];
switch(i) {
case HWC_DISPLAY_PRIMARY:
ret = hwc_set_primary(ctx, list);
break;
case HWC_DISPLAY_EXTERNAL:
- ret = hwc_set_external(ctx, list);
+ case HWC_DISPLAY_VIRTUAL:
+ /* ToDo: We are using hwc_set_external path for both External and
+ Virtual displays on HWC1.1. Eventually, we will have
+ separate functions when we move to HWC1.2
+ */
+ ret = hwc_set_external(ctx, list, i);
break;
default:
ret = -EINVAL;
@@ -487,13 +499,15 @@
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);
- ctx->mMDPComp->dump(buf);
- //XXX: Call Other dump functions
- strlcpy(buff, buf.string(), buff_len);
+ android::String8 aBuf("");
+ dumpsys_log(aBuf, "Qualcomm HWC state:\n");
+ dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version);
+ dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel);
+ ctx->mMDPComp->dump(aBuf);
+ char ovDump[2048] = {'\0'};
+ ctx->mOverlay->getDump(ovDump, 2048);
+ dumpsys_log(aBuf, ovDump);
+ strlcpy(buff, aBuf.string(), buff_len);
}
static int hwc_device_close(struct hw_device_t *dev)
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 6b8f4e3..752aaa2 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -35,6 +35,21 @@
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
+/* External Display states */
+enum {
+ EXTERNAL_OFFLINE = 0,
+ EXTERNAL_ONLINE,
+ EXTERNAL_PAUSE,
+ EXTERNAL_RESUME
+};
+
+static bool isHDMI(const char* str)
+{
+ if(strcasestr("change@/devices/virtual/switch/hdmi", str))
+ return true;
+ return false;
+}
+
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
{
int vsync = 0;
@@ -48,7 +63,6 @@
qdutils::COMPOSITION_TYPE_MDP |
qdutils::COMPOSITION_TYPE_C2D)) {
usecopybit = true;
-
}
if(!strcasestr("change@/devices/virtual/switch/hdmi", str) &&
@@ -56,19 +70,35 @@
ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__);
return;
}
-
int connected = -1; // initial value - will be set to 1/0 based on hotplug
+ int extDpyNum = HWC_DISPLAY_EXTERNAL;
+ char property[PROPERTY_VALUE_MAX];
+ if((property_get("persist.sys.wfd.virtual", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ // This means we are using Google API to trigger WFD Display
+ extDpyNum = HWC_DISPLAY_VIRTUAL;
+
+ }
+
+ int dpy = isHDMI(str) ? HWC_DISPLAY_EXTERNAL : extDpyNum;
+
+ // update extDpyNum
+ ctx->mExtDisplay->setExtDpyNum(dpy);
+
// parse HDMI/WFD switch state for connect/disconnect
// for HDMI:
// The event will be of the form:
// 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;
+ //Ignored for Virtual Displays
+ //ToDo: we can do this in a much better way
+ ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = true;
break;
}
str += strlen(str) + 1;
@@ -76,32 +106,63 @@
break;
}
- if(connected != -1) { //either we got switch_state connected or disconnect
- ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
- if (connected) {
- ctx->mExtDispConfiguring = true;
- ctx->mExtDisplay->processUEventOnline(udata);
- ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] =
- IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
- HWC_DISPLAY_EXTERNAL);
- if(usecopybit)
- ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = new CopyBit();
- } else {
- ctx->mExtDisplay->processUEventOffline(udata);
- if(ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL]) {
+ switch(connected) {
+ case EXTERNAL_OFFLINE:
+ { // disconnect event
+ ctx->mExtDisplay->processUEventOffline(udata);
+ if(ctx->mFBUpdate[dpy]) {
+ Locker::Autolock _l(ctx->mExtSetLock);
+ delete ctx->mFBUpdate[dpy];
+ ctx->mFBUpdate[dpy] = NULL;
+ }
+ if(ctx->mCopyBit[dpy]){
+ Locker::Autolock _l(ctx->mExtSetLock);
+ delete ctx->mCopyBit[dpy];
+ ctx->mCopyBit[dpy] = NULL;
+ }
+ ALOGD("%s sending hotplug: connected = %d and dpy:%d",
+ __FUNCTION__, connected, dpy);
+ ctx->dpyAttr[dpy].connected = false;
Locker::Autolock _l(ctx->mExtSetLock);
- delete ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL];
- ctx->mFBUpdate[HWC_DISPLAY_EXTERNAL] = NULL;
+ //hwc comp could be on
+ ctx->proc->hotplug(ctx->proc, dpy, connected);
+ break;
}
- if(ctx->mCopyBit[HWC_DISPLAY_EXTERNAL]){
- Locker::Autolock _l(ctx->mExtSetLock);
- delete ctx->mCopyBit[HWC_DISPLAY_EXTERNAL];
- ctx->mCopyBit[HWC_DISPLAY_EXTERNAL] = NULL;
+ case EXTERNAL_ONLINE:
+ { // connect case
+ ctx->mExtDispConfiguring = true;
+ ctx->mExtDisplay->processUEventOnline(udata);
+ ctx->mFBUpdate[dpy] =
+ IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+ ctx->dpyAttr[dpy].isPause = false;
+ if(usecopybit)
+ ctx->mCopyBit[dpy] = new CopyBit();
+ ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,
+ connected);
+ ctx->dpyAttr[dpy].connected = true;
+ Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
+ ctx->proc->hotplug(ctx->proc, dpy, connected);
+ break;
}
- }
- 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);
+ case EXTERNAL_PAUSE:
+ { // pause case
+ ALOGD("%s Received Pause event",__FUNCTION__);
+ ctx->dpyAttr[dpy].isActive = true;
+ ctx->dpyAttr[dpy].isPause = true;
+ break;
+ }
+ case EXTERNAL_RESUME:
+ { // resume case
+ ALOGD("%s Received resume event",__FUNCTION__);
+ ctx->dpyAttr[dpy].isActive = true;
+ ctx->dpyAttr[dpy].isPause = false;
+ break;
+ }
+ default:
+ {
+ ALOGE("ignore event and connected:%d",connected);
+ break;
+ }
}
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 0c26bda..fe3401b 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -90,7 +90,7 @@
}
ctx->mExtDisplay = new ExternalDisplay(ctx);
- for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++)
+ for (uint32_t i = 0; i < MAX_DISPLAYS; i++)
ctx->mLayerCache[i] = new LayerCache();
ctx->mMDPComp = MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
MDPComp::init(ctx);
@@ -119,7 +119,7 @@
ctx->mOverlay = NULL;
}
- for(int i = 0; i< HWC_NUM_DISPLAY_TYPES; i++) {
+ for(int i = 0; i < MAX_DISPLAYS; i++) {
if(ctx->mCopyBit[i]) {
delete ctx->mCopyBit[i];
ctx->mCopyBit[i] = NULL;
@@ -138,7 +138,7 @@
ctx->mExtDisplay = NULL;
}
- for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+ for(int i = 0; i < MAX_DISPLAYS; i++) {
if(ctx->mFBUpdate[i]) {
delete ctx->mFBUpdate[i];
ctx->mFBUpdate[i] = NULL;
@@ -405,11 +405,11 @@
if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
//Close the acquireFenceFds
- if(list->hwLayers[i].acquireFenceFd > 0) {
+ if(list->hwLayers[i].acquireFenceFd >= 0) {
close(list->hwLayers[i].acquireFenceFd);
list->hwLayers[i].acquireFenceFd = -1;
}
- if(fd > 0) {
+ if(fd >= 0) {
close(fd);
fd = -1;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 525fd75..045ef7f 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -36,6 +36,10 @@
#define MAX_NUM_LAYERS 32
#define MAX_DISPLAY_DIM 2048
+// For support of virtual displays
+#define HWC_DISPLAY_VIRTUAL (HWC_DISPLAY_EXTERNAL+1)
+#define MAX_DISPLAYS (HWC_NUM_DISPLAY_TYPES+1)
+
//Fwrd decls
struct hwc_context_t;
struct framebuffer_device_t;
@@ -70,6 +74,9 @@
//Connected does not mean it ready to use.
//It should be active also. (UNBLANKED)
bool isActive;
+ // In pause state, composition is bypassed
+ // used for WFD displays only
+ bool isPause;
};
struct ListStats {
@@ -221,20 +228,20 @@
framebuffer_device_t *mFbDev;
//CopyBit objects
- qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];
+ qhwc::CopyBit *mCopyBit[MAX_DISPLAYS];
//Overlay object - NULL for non overlay devices
overlay::Overlay *mOverlay;
//Primary and external FB updater
- qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
+ qhwc::IFBUpdate *mFBUpdate[MAX_DISPLAYS];
// External display related information
qhwc::ExternalDisplay *mExtDisplay;
qhwc::MDPInfo mMDP;
- qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
- qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES];
- qhwc::LayerCache *mLayerCache[HWC_NUM_DISPLAY_TYPES];
- qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES];
+ qhwc::DisplayAttributes dpyAttr[MAX_DISPLAYS];
+ qhwc::ListStats listStats[MAX_DISPLAYS];
+ qhwc::LayerCache *mLayerCache[MAX_DISPLAYS];
+ qhwc::LayerProp *layerProp[MAX_DISPLAYS];
qhwc::MDPComp *mMDPComp;
//Securing in progress indicator
diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h
index 3612018..93cdaa5 100644
--- a/libhwcomposer/hwc_video.h
+++ b/libhwcomposer/hwc_video.h
@@ -45,12 +45,12 @@
//Marks layer flags if this feature is used
static void markFlags(hwc_layer_1_t *yuvLayer);
//Flags if this feature is on.
- static bool sIsModeOn[HWC_NUM_DISPLAY_TYPES];
- static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES];
+ static bool sIsModeOn[MAX_DISPLAYS];
+ static ovutils::eDest sDest[MAX_DISPLAYS];
};
inline void VideoOverlay::reset() {
- for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+ for(uint32_t i = 0; i < MAX_DISPLAYS; i++) {
sIsModeOn[i] = false;
sDest[i] = ovutils::OV_INVALID;
}
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 04deee5..441b822 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -202,10 +202,28 @@
void Overlay::dump() const {
if(strlen(mDumpStr)) { //dump only on state change
- ALOGD("%s\n", mDumpStr);
+ ALOGD_IF(PIPE_DEBUG, "%s\n", mDumpStr);
}
}
+void Overlay::getDump(char *buf, size_t len) {
+ int totalPipes = 0;
+ const char *str = "\nOverlay State\n==========================\n";
+ strncat(buf, str, strlen(str));
+ for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
+ if(mPipeBook[i].valid()) {
+ mPipeBook[i].mPipe->getDump(buf, len);
+ char str[64] = {'\0'};
+ snprintf(str, 64, "Attached to dpy=%d\n\n", mPipeBook[i].mDisplay);
+ strncat(buf, str, strlen(str));
+ totalPipes++;
+ }
+ }
+ char str_pipes[64] = {'\0'};
+ snprintf(str_pipes, 64, "Pipes used=%d\n\n", totalPipes);
+ strncat(buf, str_pipes, strlen(str_pipes));
+}
+
void Overlay::PipeBook::init() {
mPipe = NULL;
mDisplay = DPY_UNUSED;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index a470f45..0f15baa 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -77,6 +77,10 @@
void setExtFbNum(int fbNum);
/* Returns framebuffer index of the current external display */
int getExtFbNum();
+ /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
+ * to populate.
+ */
+ void getDump(char *buf, size_t len);
private:
/* Ctor setup */
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 0c49bdd..c9a4949 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -81,9 +81,6 @@
/* retrieve cached crop data */
utils::Dim getCrop() const;
- /* dump the state of the object */
- void dump() const;
-
/* Perform transformation calculations */
void doTransform();
@@ -96,6 +93,12 @@
/* Update the src format */
void updateSrcformat(const uint32_t& inputsrcFormat);
+ /* dump the state of the object */
+ void dump() const;
+
+ /* Return the dump in the specified buffer */
+ void getDump(char *buf, size_t len);
+
private:
/* Retrieve screen info from underlying mdp */
bool getScreenInfo(utils::ScreenInfo& info);
@@ -134,6 +137,9 @@
/* sump the state of the obj */
void dump() const;
+ /* Return the dump in the specified buffer */
+ void getDump(char *buf, size_t len);
+
private:
// mdp data struct
MdpData mMdp;
@@ -213,6 +219,10 @@
return mMdp.getDownscalefactor();
}
+inline void Ctrl::getDump(char *buf, size_t len) {
+ mMdp.getDump(buf, len);
+}
+
inline Data::Data() {
mMdp.reset();
}
@@ -249,6 +259,9 @@
ALOGE("== Dump Data MDP end ==");
}
+inline void Data::getDump(char *buf, size_t len) {
+ mMdp.getDump(buf, len);
+}
} // overlay
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 8bca85f..8f2e2b6 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -241,7 +241,8 @@
return true;
}
-//Adjust width, height, format if rotator is used.
+//Adjust width, height if rotator is used post transform calcs.
+//At this point the format is already updated by updateSrcFormat
void MdpCtrl::adjustSrcWhf(const bool& rotUsed) {
if(rotUsed) {
utils::Whf whf = getSrcWhf();
@@ -250,25 +251,15 @@
whf.w = utils::alignup(whf.w, 64);
whf.h = utils::alignup(whf.h, 32);
}
- /*For example: If original format is tiled, rotator outputs non-tiled,
- *so update mdp's src fmt to that.
- */
- whf.format = utils::getRotOutFmt(whf.format);
setSrcWhf(whf);
- /* The above format will be overwritten in function updateSrcformat
- * after doing rotator start. Format is then set depending on
- * whether the fastyuv mode is used by the rotator.
- */
}
}
+//Update src format if rotator used based on rotator's destination format.
void MdpCtrl::updateSrcformat(const uint32_t& inputformat) {
- int version = qdutils::MDPVersion::getInstance().getMDPVersion();
- if ((version >= qdutils::MDP_V4_2) && (version < qdutils::MDSS_V5)) {
- utils::Whf whf = getSrcWhf();
- whf.format = inputformat;
- setSrcWhf(whf);
- }
+ utils::Whf whf = getSrcWhf();
+ whf.format = inputformat;
+ setSrcWhf(whf);
}
void MdpCtrl::dump() const {
@@ -278,6 +269,10 @@
ALOGE("== Dump MdpCtrl end ==");
}
+void MdpCtrl::getDump(char *buf, size_t len) {
+ ovutils::getDump(buf, len, "Ctrl(mdp_overlay)", mOVInfo);
+}
+
void MdpData::dump() const {
ALOGE("== Dump MdpData start ==");
mFd.dump();
@@ -285,6 +280,10 @@
ALOGE("== Dump MdpData end ==");
}
+void MdpData::getDump(char *buf, size_t len) {
+ ovutils::getDump(buf, len, "Data(msmfb_overlay_data)", mOvData);
+}
+
void MdpCtrl3D::dump() const {
ALOGE("== Dump MdpCtrl start ==");
mFd.dump();
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index c1684fc..55e2787 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -141,9 +141,6 @@
/* using user_data, sets/unsets roationvalue in mdp flags */
void setRotationFlags();
- /* dump state of the object */
- void dump() const;
-
/* Perform transformation calculations */
void doTransform();
@@ -156,6 +153,12 @@
/* Update the src format */
void updateSrcformat(const uint32_t& inputsrcFormat);
+ /* dump state of the object */
+ void dump() const;
+
+ /* Return the dump in the specified buffer */
+ void getDump(char *buf, size_t len);
+
private:
/* helper functions for overlayTransform */
@@ -237,6 +240,10 @@
/* dump state of the object */
void dump() const;
+
+ /* Return the dump in the specified buffer */
+ void getDump(char *buf, size_t len);
+
private:
/* actual overlay mdp data */
diff --git a/liboverlay/overlayMdpRot.cpp b/liboverlay/overlayMdpRot.cpp
old mode 100644
new mode 100755
index d0242d6..c9843f2
--- a/liboverlay/overlayMdpRot.cpp
+++ b/liboverlay/overlayMdpRot.cpp
@@ -58,15 +58,12 @@
}
void MdpRot::setDownscale(int ds) {
- if (mRotImgInfo.src.format == MDP_Y_CR_CB_GH2V2 &&
- (mRotImgInfo.src_rect.h & 0xF)) {
- mRotImgInfo.src_rect.h = utils::aligndown(mRotImgInfo.src_rect.h, 16);
- } else if ((utils::ROT_DS_EIGHTH == ds) && (mRotImgInfo.src_rect.h & 0xF)) {
+ if ((utils::ROT_DS_EIGHTH == ds) && (mRotImgInfo.src_rect.h & 0xF)) {
// Ensure src_rect.h is a multiple of 16 for 1/8 downscaling.
// This is an undocumented MDP Rotator constraint.
// Note that src_rect.h is already ensured to be 32 pixel height aligned
// for MDP_Y_CRCB_H2V2_TILE and MDP_Y_CBCR_H2V2_TILE formats.
- mRotImgInfo.src_rect.h = utils::alignup(mRotImgInfo.src_rect.h, 16);
+ mRotImgInfo.src_rect.h = utils::aligndown(mRotImgInfo.src_rect.h, 16);
}
mRotImgInfo.downscale_ratio = ds;
}
@@ -111,8 +108,6 @@
mRotImgInfo.dst.width = whf.w;
mRotImgInfo.dst.height = whf.h;
-
- mBufSize = awhf.size;
}
inline void MdpRot::setFlags(const utils::eMdpFlags& flags) {
@@ -157,6 +152,12 @@
return true;
}
+uint32_t MdpRot::calcOutputBufSize() {
+ ovutils::Whf destWhf(mRotImgInfo.dst.width,
+ mRotImgInfo.dst.height, mRotImgInfo.dst.format);
+ return Rotator::calcOutputBufSize(destWhf);
+}
+
bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
{
OvMem mem;
@@ -201,8 +202,9 @@
bool MdpRot::remap(uint32_t numbufs) {
// if current size changed, remap
- if(mBufSize == mMem.curr().size()) {
- ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, mBufSize);
+ uint32_t opBufSize = calcOutputBufSize();
+ if(opBufSize == mMem.curr().size()) {
+ ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
return true;
}
@@ -211,12 +213,12 @@
// ++mMem will make curr to be prev, and prev will be curr
++mMem;
- if(!open_i(numbufs, mBufSize)) {
+ if(!open_i(numbufs, opBufSize)) {
ALOGE("%s Error could not open", __FUNCTION__);
return false;
}
for (uint32_t i = 0; i < numbufs; ++i) {
- mMem.curr().mRotOffset[i] = i * mBufSize;
+ mMem.curr().mRotOffset[i] = i * opBufSize;
}
return true;
}
@@ -229,7 +231,6 @@
ovutils::memset0(mMem.prev().mRotOffset);
mMem.curr().mCurrOffset = 0;
mMem.prev().mCurrOffset = 0;
- mBufSize = 0;
mOrientation = utils::OVERLAY_TRANSFORM_0;
}
@@ -275,4 +276,9 @@
ALOGE("== Dump MdpRot end ==");
}
+void MdpRot::getDump(char *buf, size_t len) const {
+ ovutils::getDump(buf, len, "MdpRotCtrl(msm_rotator_img_info)", mRotImgInfo);
+ ovutils::getDump(buf, len, "MdpRotData(msm_rotator_data_info)", mRotDataInfo);
+}
+
} // namespace overlay
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index d9cdc03..fd747dd 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -96,8 +96,6 @@
mRotInfo.dst_rect.w = whf.w;
mRotInfo.dst_rect.h = whf.h;
-
- mBufSize = awhf.size;
}
inline void MdssRot::setDownscale(int ds) {}
@@ -131,7 +129,6 @@
bool MdssRot::commit() {
doTransform();
- setBufSize(mRotInfo.src.format);
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
ALOGE("MdssRot commit failed!");
@@ -199,9 +196,11 @@
}
bool MdssRot::remap(uint32_t numbufs) {
- // if current size changed, remap
- if(mBufSize == mMem.curr().size()) {
- ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, mBufSize);
+ // Calculate the size based on rotator's dst format, w and h.
+ uint32_t opBufSize = calcOutputBufSize();
+ // If current size changed, remap
+ if(opBufSize == mMem.curr().size()) {
+ ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
return true;
}
@@ -210,12 +209,12 @@
// ++mMem will make curr to be prev, and prev will be curr
++mMem;
- if(!open_i(numbufs, mBufSize)) {
+ if(!open_i(numbufs, opBufSize)) {
ALOGE("%s Error could not open", __FUNCTION__);
return false;
}
for (uint32_t i = 0; i < numbufs; ++i) {
- mMem.curr().mRotOffset[i] = i * mBufSize;
+ mMem.curr().mRotOffset[i] = i * opBufSize;
}
return true;
}
@@ -251,7 +250,6 @@
ovutils::memset0(mMem.prev().mRotOffset);
mMem.curr().mCurrOffset = 0;
mMem.prev().mCurrOffset = 0;
- mBufSize = 0;
mOrientation = utils::OVERLAY_TRANSFORM_0;
}
@@ -264,24 +262,22 @@
ALOGE("== Dump MdssRot end ==");
}
-void MdssRot::setBufSize(int format) {
+uint32_t MdssRot::calcOutputBufSize() {
+ uint32_t opBufSize = 0;
+ ovutils::Whf destWhf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
+ mRotInfo.src.format); //mdss src and dst formats are same.
- switch (format) {
- case MDP_Y_CBCR_H2V2_VENUS:
- mBufSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mRotInfo.dst_rect.w,
- mRotInfo.dst_rect.h);
- break;
-
- case MDP_Y_CR_CB_GH2V2:
- int alignedw = utils::align(mRotInfo.dst_rect.w, 16);
- int alignedh = mRotInfo.dst_rect.h;
- mBufSize = (alignedw*alignedh) +
- (utils::align(alignedw/2, 16) * (alignedh/2))*2;
- mBufSize = utils::align(mBufSize, 4096);
- break;
- }
+ opBufSize = Rotator::calcOutputBufSize(destWhf);
if (mRotInfo.flags & utils::OV_MDP_SECURE_OVERLAY_SESSION)
- mBufSize = utils::align(mBufSize, SIZE_1M);
+ opBufSize = utils::align(opBufSize, SIZE_1M);
+
+ return opBufSize;
}
+
+void MdssRot::getDump(char *buf, size_t len) const {
+ ovutils::getDump(buf, len, "MdssRotCtrl(mdp_overlay)", mRotInfo);
+ ovutils::getDump(buf, len, "MdssRotData(msmfb_overlay_data)", mRotData);
+}
+
} // namespace overlay
diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp
index 956ea2b..90a1e7a 100644
--- a/liboverlay/overlayRotator.cpp
+++ b/liboverlay/overlayRotator.cpp
@@ -20,6 +20,7 @@
#include "overlayRotator.h"
#include "overlayUtils.h"
#include "mdp_version.h"
+#include "gr.h"
namespace ovutils = overlay::utils;
@@ -39,6 +40,15 @@
}
}
+uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) {
+ //dummy aligned w & h.
+ int alW = 0, alH = 0;
+ int halFormat = ovutils::getHALFormat(destWhf.format);
+ //A call into gralloc/memalloc
+ return getBufferSizeAndDimensions(
+ destWhf.w, destWhf.h, halFormat, alW, alH);
+}
+
int Rotator::getRotatorHwType() {
int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
if (mdpVersion == qdutils::MDSS_V5)
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index f1a60e1..bd2fd7e 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -62,10 +62,12 @@
virtual uint32_t getSessId() const = 0;
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
virtual void dump() const = 0;
+ virtual void getDump(char *buf, size_t len) const = 0;
static Rotator *getRotator();
protected:
explicit Rotator() {}
+ static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
private:
/*Returns rotator h/w type */
@@ -133,6 +135,7 @@
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
+ virtual void getDump(char *buf, size_t len) const;
private:
explicit MdpRot();
@@ -143,13 +146,14 @@
void doTransform();
/* reset underlying data, basically memset 0 */
void reset();
-
/* return true if current rotator config is different
* than last known config */
bool rotConfChanged() const;
-
/* save mRotImgInfo to be last known good config*/
void save();
+ /* Calculates the rotator's o/p buffer size post the transform calcs and
+ * knowing the o/p format depending on whether fastYuv is enabled or not */
+ uint32_t calcOutputBufSize();
/* rot info*/
msm_rotator_img_info mRotImgInfo;
@@ -163,8 +167,6 @@
OvFD mFd;
/* Rotator memory manager */
RotMem mMem;
- /* Single Rotator buffer size */
- uint32_t mBufSize;
friend Rotator* Rotator::getRotator();
};
@@ -195,6 +197,7 @@
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
+ virtual void getDump(char *buf, size_t len) const;
private:
explicit MdssRot();
@@ -205,7 +208,9 @@
void doTransform();
/* reset underlying data, basically memset 0 */
void reset();
- void setBufSize(int format);
+ /* Calculates the rotator's o/p buffer size post the transform calcs and
+ * knowing the o/p format depending on whether fastYuv is enabled or not */
+ uint32_t calcOutputBufSize();
/* MdssRot info structure */
mdp_overlay mRotInfo;
@@ -217,8 +222,6 @@
OvFD mFd;
/* Rotator memory manager */
RotMem mMem;
- /* Single Rotator buffer size */
- uint32_t mBufSize;
/* Enable/Disable Mdss Rot*/
bool mEnabled;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 9bffff0..de10c9f 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -243,7 +243,50 @@
//HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01
//HAL_PIXEL_FORMAT_R_8 = 0x10D
//HAL_PIXEL_FORMAT_RG_88 = 0x10E
- ALOGE("%s: Unsupported format = 0x%x", __func__, format);
+ ALOGE("%s: Unsupported HAL format = 0x%x", __func__, format);
+ return -1;
+ }
+ // not reached
+ return -1;
+}
+
+//Takes mdp format as input and translates to equivalent HAL format
+//Refer to graphics.h, gralloc_priv.h, msm_mdp.h for formats.
+int getHALFormat(int mdpFormat) {
+ switch (mdpFormat) {
+ //From graphics.h
+ case MDP_RGBA_8888:
+ return HAL_PIXEL_FORMAT_RGBA_8888;
+ case MDP_RGBX_8888:
+ return HAL_PIXEL_FORMAT_RGBX_8888;
+ case MDP_RGB_888:
+ return HAL_PIXEL_FORMAT_RGB_888;
+ case MDP_RGB_565:
+ return HAL_PIXEL_FORMAT_RGB_565;
+ case MDP_BGRA_8888:
+ return HAL_PIXEL_FORMAT_BGRA_8888;
+ case MDP_Y_CR_CB_GH2V2:
+ return HAL_PIXEL_FORMAT_YV12;
+ case MDP_Y_CBCR_H2V1:
+ return HAL_PIXEL_FORMAT_YCbCr_422_SP;
+ case MDP_Y_CRCB_H2V2:
+ return HAL_PIXEL_FORMAT_YCrCb_420_SP;
+
+ //From gralloc_priv.h
+ case MDP_Y_CBCR_H2V2_TILE:
+ return HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
+ case MDP_Y_CBCR_H2V2:
+ return HAL_PIXEL_FORMAT_YCbCr_420_SP;
+ case MDP_Y_CRCB_H2V1:
+ return HAL_PIXEL_FORMAT_YCrCb_422_SP;
+ case MDP_Y_CBCR_H1V1:
+ return HAL_PIXEL_FORMAT_YCbCr_444_SP;
+ case MDP_Y_CRCB_H1V1:
+ return HAL_PIXEL_FORMAT_YCrCb_444_SP;
+ case MDP_Y_CBCR_H2V2_VENUS:
+ return HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
+ default:
+ ALOGE("%s: Unsupported MDP format = 0x%x", __func__, mdpFormat);
return -1;
}
// not reached
@@ -335,6 +378,83 @@
return (mdpVersion >= qdutils::MDSS_V5);
}
+void getDump(char *buf, size_t len, const char *prefix,
+ const mdp_overlay& ov) {
+ char str[256] = {'\0'};
+ snprintf(str, 256,
+ "%s id=%d z=%d fg=%d alpha=%d mask=%d flags=0x%x\n",
+ prefix, ov.id, ov.z_order, ov.is_fg, ov.alpha,
+ ov.transp_mask, ov.flags);
+ strncat(buf, str, strlen(str));
+ getDump(buf, len, "\tsrc(msmfb_img)", ov.src);
+ getDump(buf, len, "\tsrc_rect(mdp_rect)", ov.src_rect);
+ getDump(buf, len, "\tdst_rect(mdp_rect)", ov.dst_rect);
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const msmfb_img& ov) {
+ char str_src[256] = {'\0'};
+ snprintf(str_src, 256,
+ "%s w=%d h=%d format=%d %s\n",
+ prefix, ov.width, ov.height, ov.format,
+ overlay::utils::getFormatString(ov.format));
+ strncat(buf, str_src, strlen(str_src));
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const mdp_rect& ov) {
+ char str_rect[256] = {'\0'};
+ snprintf(str_rect, 256,
+ "%s x=%d y=%d w=%d h=%d\n",
+ prefix, ov.x, ov.y, ov.w, ov.h);
+ strncat(buf, str_rect, strlen(str_rect));
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const msmfb_overlay_data& ov) {
+ char str[256] = {'\0'};
+ snprintf(str, 256,
+ "%s id=%d\n",
+ prefix, ov.id);
+ strncat(buf, str, strlen(str));
+ getDump(buf, len, "\tdata(msmfb_data)", ov.data);
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const msmfb_data& ov) {
+ char str_data[256] = {'\0'};
+ snprintf(str_data, 256,
+ "%s offset=%d memid=%d id=%d flags=0x%x priv=%d\n",
+ prefix, ov.offset, ov.memory_id, ov.id, ov.flags,
+ ov.priv);
+ strncat(buf, str_data, strlen(str_data));
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const msm_rotator_img_info& rot) {
+ char str[256] = {'\0'};
+ snprintf(str, 256, "%s sessid=%u rot=%d, enable=%d downscale=%d\n",
+ prefix, rot.session_id, rot.rotations, rot.enable,
+ rot.downscale_ratio);
+ strncat(buf, str, strlen(str));
+ getDump(buf, len, "\tsrc", rot.src);
+ getDump(buf, len, "\tdst", rot.dst);
+ getDump(buf, len, "\tsrc_rect", rot.src_rect);
+}
+
+void getDump(char *buf, size_t len, const char *prefix,
+ const msm_rotator_data_info& rot) {
+ char str[256] = {'\0'};
+ snprintf(str, 256,
+ "%s sessid=%u verkey=%d\n",
+ prefix, rot.session_id, rot.version_key);
+ strncat(buf, str, strlen(str));
+ getDump(buf, len, "\tsrc", rot.src);
+ getDump(buf, len, "\tdst", rot.dst);
+ getDump(buf, len, "\tsrc_chroma", rot.src_chroma);
+ getDump(buf, len, "\tdst_chroma", rot.dst_chroma);
+}
+
} // utils
} // overlay
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 2f83374..45d1924 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -36,6 +36,7 @@
#include <hardware/hardware.h>
#include <hardware/gralloc.h> // buffer_handle_t
#include <linux/msm_mdp.h> // flags
+#include <linux/msm_rotator.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -412,7 +413,8 @@
};
int getMdpFormat(int format);
-int getRotOutFmt(uint32_t format);
+int getHALFormat(int mdpFormat);
+
/* flip is upside down and such. V, H flip
* rotation is 90, 180 etc
* It returns MDP related enum/define that match rot+flip*/
@@ -587,29 +589,6 @@
return -1;
}
-inline int getRotOutFmt(uint32_t format) {
-
- if (isMdssRotator())
- return format;
-
- switch (format) {
- case MDP_Y_CRCB_H2V2_TILE:
- return MDP_Y_CRCB_H2V2;
- case MDP_Y_CBCR_H2V2_TILE:
- return MDP_Y_CBCR_H2V2;
- case MDP_Y_CB_CR_H2V2:
- return MDP_Y_CBCR_H2V2;
- case MDP_Y_CR_CB_GH2V2:
- return MDP_Y_CRCB_H2V2;
- default:
- return format;
- }
- // not reached
- OVASSERT(false, "%s not reached", __FUNCTION__);
- return -1;
-}
-
-
inline uint32_t getColorFormat(uint32_t format)
{
return (format == HAL_PIXEL_FORMAT_YV12) ?
@@ -774,6 +753,17 @@
return OV_MDP_PIPE_ANY;
}
+void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
+void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
+void getDump(char *buf, size_t len, const char *prefix, const mdp_rect& ov);
+void getDump(char *buf, size_t len, const char *prefix,
+ const msmfb_overlay_data& ov);
+void getDump(char *buf, size_t len, const char *prefix, const msmfb_data& ov);
+void getDump(char *buf, size_t len, const char *prefix,
+ const msm_rotator_img_info& ov);
+void getDump(char *buf, size_t len, const char *prefix,
+ const msm_rotator_data_info& ov);
+
} // namespace utils ends
//--------------------Class Res stuff (namespace overlay only) -----------
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 0b864df..486cfda 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -241,6 +241,13 @@
ALOGE("== Dump Generic pipe end ==");
}
+void GenericPipe::getDump(char *buf, size_t len) {
+ mCtrlData.ctrl.getDump(buf, len);
+ mCtrlData.data.getDump(buf, len);
+ if(mRotUsed && mRot)
+ mRot->getDump(buf, len);
+}
+
bool GenericPipe::isClosed() const {
return (pipeState == CLOSED);
}
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 604529a..1d1be25 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -84,6 +84,10 @@
/* dump the state of the object */
void dump() const;
+
+ /* Return the dump in the specified buffer */
+ void getDump(char *buf, size_t len);
+
private:
/* set Closed pipe */
bool setClosed();