libhwcomposer: Add support for 4 layer MDP Comp
This change extends MDP composition to support
upto 4 layers by making border fill as base pipe and
using all MDP h/w pipes in overlay mode.
Conflicts:
libhwcomposer/hwc.cpp
libhwcomposer/hwc_utils.cpp
libhwcomposer/hwc_utils.h
Bug: 7626586
Change-Id: I01a0e53ddfbcf3ed46734f6f3bb0ef7d912ceac6
Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org>
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f331f84..4baf986 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -28,6 +28,7 @@
#include "hwc_utils.h"
#include "hwc_video.h"
#include "hwc_fbupdate.h"
+#include "hwc_mdpcomp.h"
#include "external.h"
using namespace qhwc;
@@ -97,6 +98,20 @@
FBUpdate::reset();
}
+//clear prev layer prop flags and realloc for current frame
+static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
+ int layer_count = ctx->listStats[dpy].numAppLayers;
+
+ if(ctx->layerProp[dpy]) {
+ delete[] ctx->layerProp[dpy];
+ ctx->layerProp[dpy] = NULL;
+ }
+
+ if(layer_count) {
+ ctx->layerProp[dpy] = new LayerProp[layer_count];
+ }
+}
+
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
@@ -109,7 +124,11 @@
if(fbLayer->handle) {
setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
ctx->mLayerCache->updateLayerCache(list);
- VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
+ reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY);
+ if(!MDPComp::configure(ctx, list)) {
+ VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
+ FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY);
+ }
}
}
return 0;
@@ -123,13 +142,14 @@
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
- setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
-
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
- FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
+ setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
+ reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL);
+
VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
+ FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
}
}
return 0;
@@ -145,24 +165,20 @@
ctx->mOverlay->configBegin();
- //If securing of h/w in progress skip comp using overlay.
- //TODO remove from here when sending FB via overlay
- if(ctx->mSecuring == false) {
- for (uint32_t i = 0; i < numDisplays; 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);
- break;
- default:
- ret = -EINVAL;
- }
+ for (int32_t i = numDisplays - 1; 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);
+ break;
+ default:
+ ret = -EINVAL;
}
}
-
ctx->mOverlay->configDone();
return ret;
@@ -269,14 +285,25 @@
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
-
if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) {
ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
ret = -1;
}
+ if (!MDPComp::draw(ctx, list)) {
+ ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
+ ret = -1;
+ }
+
//TODO We dont check for SKIP flag on this layer because we need PAN
//always. Last layer is always FB
- if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) {
+ private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
+ if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
+ if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
+ if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) {
+ ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
+ ret = -1;
+ }
+ }
if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
return -1;