Merge "libhwcomposer: Add check for MDP comp dump"
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 6c7f26d..ea6711b 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -141,18 +141,6 @@
}
}
-static int display_commit(hwc_context_t *ctx, int dpy) {
- struct mdp_display_commit commit_info;
- memset(&commit_info, 0, sizeof(struct mdp_display_commit));
- commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
- if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_DISPLAY_COMMIT, &commit_info) < 0){
- ALOGE("%s: MSMFB_DISPLAY_COMMIT for dpy %d failed", __FUNCTION__,
- dpy);
- return -errno;
- }
- return 0;
-}
-
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
@@ -373,14 +361,22 @@
* activate/deactive VIRTUAL DISPLAY */
if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
- if(blank)
- display_commit(ctx, HWC_DISPLAY_VIRTUAL);
+ if(blank) {
+ int dpy = HWC_DISPLAY_VIRTUAL;
+ if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
+ ret = -1;
+ }
+ }
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
}
break;
case HWC_DISPLAY_EXTERNAL:
if(blank) {
- display_commit(ctx, HWC_DISPLAY_EXTERNAL);
+ if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail for external!", __FUNCTION__);
+ ret = -1;
+ }
}
break;
default:
@@ -391,7 +387,7 @@
ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
blank ? "blanking":"unblanking", dpy);
- return 0;
+ return ret;
}
static int hwc_query(struct hwc_composer_device_1* dev,
@@ -455,8 +451,8 @@
}
}
- if (display_commit(ctx, dpy) < 0) {
- ALOGE("%s: display commit fail!", __FUNCTION__);
+ if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
ret = -1;
}
}
@@ -475,49 +471,47 @@
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected) {
+ ctx->dpyAttr[dpy].connected &&
+ !ctx->dpyAttr[dpy].isPause) {
+ uint32_t last = list->numHwLayers - 1;
+ hwc_layer_1_t *fbLayer = &list->hwLayers[last];
+ int fd = -1; //FenceFD from the Copybit(valid in async mode)
+ bool copybitDone = false;
+ if(ctx->mCopyBit[dpy])
+ copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
- if(!ctx->dpyAttr[dpy].isPause) {
- uint32_t last = list->numHwLayers - 1;
- hwc_layer_1_t *fbLayer = &list->hwLayers[last];
- int fd = -1; //FenceFD from the Copybit(valid in async mode)
- bool copybitDone = false;
- if(ctx->mCopyBit[dpy])
- copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
+ if(list->numHwLayers > 1)
+ hwc_sync(ctx, list, dpy, fd);
- if(list->numHwLayers > 1)
- hwc_sync(ctx, list, dpy, fd);
+ // Dump the layers for external
+ if(ctx->mHwcDebug[dpy])
+ ctx->mHwcDebug[dpy]->dumpLayers(list);
- // Dump the layers for external
- if(ctx->mHwcDebug[dpy])
- ctx->mHwcDebug[dpy]->dumpLayers(list);
+ if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
+ ALOGE("%s: MDPComp draw failed", __FUNCTION__);
+ ret = -1;
+ }
- if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
- ALOGE("%s: MDPComp draw failed", __FUNCTION__);
+ int extOnlyLayerIndex =
+ ctx->listStats[dpy].extOnlyLayerIndex;
+
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
+ if(extOnlyLayerIndex!= -1) {
+ hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
+ hnd = (private_handle_t *)extLayer->handle;
+ } else if(copybitDone) {
+ hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
+ }
+
+ if(hnd && !isYuvBuffer(hnd)) {
+ if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
+ ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
ret = -1;
}
-
- int extOnlyLayerIndex =
- ctx->listStats[dpy].extOnlyLayerIndex;
-
- private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
- if(extOnlyLayerIndex!= -1) {
- hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
- hnd = (private_handle_t *)extLayer->handle;
- } else if(copybitDone) {
- hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
- }
-
- if(hnd && !isYuvBuffer(hnd)) {
- if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
- ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
- ret = -1;
- }
- }
}
- if (display_commit(ctx, dpy) < 0) {
- ALOGE("%s: display commit fail!", __FUNCTION__);
+ if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
ret = -1;
}
}
@@ -574,8 +568,8 @@
}
}
- if (display_commit(ctx, dpy) < 0) {
- ALOGE("%s: display commit fail!", __FUNCTION__);
+ if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
ret = -1;
}
}
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 068e28a..a395ee0 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -127,6 +127,20 @@
return renderArea;
}
+bool checkNonWormholeRegion(private_handle_t* hnd, hwc_rect_t& rect)
+{
+ unsigned int height = rect.bottom - rect.top;
+ unsigned int width = rect.right - rect.left;
+ copybit_image_t buf;
+ buf.w = ALIGN(hnd->width, 32);
+ buf.h = hnd->height;
+
+ if (buf.h != height || buf.w != width)
+ return false;
+
+ return true;
+}
+
bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy) {
@@ -181,6 +195,15 @@
if (layer->planeAlpha != 0xFF)
return true;
}
+ /*
+ * Fallback to GPU in MDP3 when NonWormholeRegion is not of frame buffer
+ * size as artifact is seen in WormholeRegion of previous frame.
+ */
+ hwc_rect_t nonWormHoleRegion;
+ getNonWormholeRegion(list, nonWormHoleRegion);
+ if(!checkNonWormholeRegion(fbHnd, nonWormHoleRegion))
+ return true;
+
}
//Allocate render buffers if they're not allocated
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 1158a16..f2217b9 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -442,11 +442,15 @@
hwc_layer_1_t* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
- ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
- return false;
+ if(layer->transform & HWC_TRANSFORM_ROT_90) {
+ if(!isYuvBuffer(hnd) ) {
+ ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
+ return false;
+ }else if(!canUseRotator(ctx, mDpy)) {
+ ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
+ return false;
+ }
}
-
if(!isValidDimension(ctx,layer)) {
ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
__FUNCTION__);
@@ -560,6 +564,11 @@
return false;
}
+ if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
+ ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
+ return false;
+ }
+
if(isSecuring(ctx, layer)) {
ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
return false;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 916b346..5590798 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -33,7 +33,7 @@
#include "external.h"
#include "virtual.h"
#include "mdp_version.h"
-
+using namespace overlay;
namespace qhwc {
#define HWC_UEVENT_SWITCH_STR "change@/devices/virtual/switch/"
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
@@ -233,7 +233,6 @@
* surface for the same. */
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = true;
}
-
if(dpy == HWC_DISPLAY_EXTERNAL ||
ctx->mVirtualonExtActive) {
ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL_OFFLINE ONLINE"
@@ -243,33 +242,51 @@
}
break;
}
- case EXTERNAL_PAUSE:
- {
- ctx->dpyAttr[dpy].isActive = true;
- ctx->dpyAttr[dpy].isPause = true;
- break;
- }
- case EXTERNAL_RESUME:
- {
- //Treat Resume as Online event
- //Since external didnt have any pipes, force primary to give up
- //its pipes; we don't allow inter-mixer pipe transfers.
- {
- Locker::Autolock _l(ctx->mDrawLock);
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->dpyAttr[dpy].isActive = true;
- ctx->proc->invalidate(ctx->proc);
+ case EXTERNAL_PAUSE:
+ { // pause case
+ ALOGD("%s Received Pause event",__FUNCTION__);
+ {
+ Locker::Autolock _l(ctx->mDrawLock);
+ ctx->dpyAttr[dpy].isActive = true;
+ ctx->dpyAttr[dpy].isPause = true;
+ ctx->proc->invalidate(ctx->proc);
+ }
+ usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+ * 2 / 1000);
+ // At this point all the pipes used by External have been
+ // marked as UNSET.
+ {
+ Locker::Autolock _l(ctx->mDrawLock);
+ // Perform commit to unstage the pipes.
+ if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+ ALOGE("%s: display commit fail! for %d dpy",
+ __FUNCTION__, dpy);
+ }
+ }
+ break;
}
- usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
- * 2 / 1000);
- {
- //At this point external has all the pipes it would need.
- Locker::Autolock _l(ctx->mDrawLock);
- ctx->dpyAttr[dpy].isPause = false;
- ctx->proc->invalidate(ctx->proc);
+ case EXTERNAL_RESUME:
+ { // resume case
+ ALOGD("%s Received resume event",__FUNCTION__);
+ //Treat Resume as Online event
+ //Since external didnt have any pipes, force primary to give up
+ //its pipes; we don't allow inter-mixer pipe transfers.
+ {
+ Locker::Autolock _l(ctx->mDrawLock);
+ ctx->dpyAttr[dpy].isConfiguring = true;
+ ctx->dpyAttr[dpy].isActive = true;
+ ctx->proc->invalidate(ctx->proc);
+ }
+ usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+ * 2 / 1000);
+ //At this point external has all the pipes it would need.
+ {
+ Locker::Autolock _l(ctx->mDrawLock);
+ ctx->dpyAttr[dpy].isPause = false;
+ ctx->proc->invalidate(ctx->proc);
+ }
+ break;
}
- break;
- }
default:
{
ALOGE("%s: Invalid state to swtich:%d", __FUNCTION__, switch_state);
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 34ed842..35e724d 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -530,8 +530,9 @@
yuvCount++;
if((layer->transform & HWC_TRANSFORM_ROT_90) &&
- canUseRotator(ctx)) {
- if(ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
+ canUseRotator(ctx, dpy)) {
+ if( (dpy == HWC_DISPLAY_PRIMARY) &&
+ ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
ctx->isPaddingRound = true;
}
Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
@@ -1295,10 +1296,15 @@
return 0;
}
-bool canUseRotator(hwc_context_t *ctx) {
+bool canUseRotator(hwc_context_t *ctx, int dpy) {
if(qdutils::MDPVersion::getInstance().is8x26() &&
- ctx->mVirtualDisplay->isConnected()) {
- return false;
+ ctx->mVirtualDisplay->isConnected() &&
+ !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) {
+ // Allow if YUV needs rotation and DMA is configured to BLOCK mode for
+ // primary. For portrait videos usecase on WFD, Driver supports
+ // multiplexing of DMA pipe in LINE and BLOCK mode.
+ if(dpy == HWC_DISPLAY_PRIMARY)
+ return false;
}
if(ctx->mMDP.version == qdutils::MDP_V3_0_4)
return false;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 50c6a7a..8e70a91 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -235,7 +235,7 @@
//extreme unavailability of pipes. This can also be done via hybrid calculations
//also involving many more variables like number of write-back interfaces etc,
//but the variety of scenarios is too high to warrant that.
-bool canUseRotator(hwc_context_t *ctx);
+bool canUseRotator(hwc_context_t *ctx, int dpy);
int getLeftSplit(hwc_context_t *ctx, const int& dpy);
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index ea25358..afe62e2 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -63,8 +63,6 @@
}
void Overlay::configDone() {
- if(PipeBook::pipeUsageUnchanged()) return;
-
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
if(PipeBook::isNotUsed(i)) {
//Forces UNSET on pipes, flushes rotator memory and session, closes
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index c3d00f1..927e7e9 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -119,6 +119,9 @@
case HAL_PIXEL_FORMAT_YCrCb_444_SP:
return MDP_Y_CRCB_H1V1;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ //NV12 encodeable format maps to the venus format on
+ //B-Family targets
return MDP_Y_CBCR_H2V2_VENUS;
default:
//Unsupported by MDP