Set priority among various display devices
* When a non-WFD virtual display device (SSD/
screenrecord) is active along with
non-hybrid WFD solution(WFD faked on
external), give preference to non-hybrid WFD
device over non-WFD virtual display device.
* This is needed only in cases when WFD is
enabled via v4l2 rather than using VDS api's.
Change-Id: I63e53baa214bdcdac19430ca30b939cdd7416cbb
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index dcad00b..f6e9729 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -105,17 +105,27 @@
//Helper
static void reset(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) {
+
+ ctx->numActiveDisplays = 0;
for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; 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
// cache we need to reset it.
// We can probably rethink that later on
- if (LIKELY(list && list->numHwLayers > 1)) {
+ if (LIKELY(list && list->numHwLayers > 0)) {
for(uint32_t j = 0; j < list->numHwLayers; j++) {
if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
}
+
+ /* For display devices like SSD and screenrecord, we cannot
+ * rely on isActive and connected attributes of dpyAttr to
+ * determine if the displaydevice is active. Hence in case if
+ * the layer-list is non-null and numHwLayers > 0, we assume
+ * the display device to be active.
+ */
+ ctx->numActiveDisplays += 1;
}
if(ctx->mFBUpdate[i])
@@ -124,6 +134,7 @@
ctx->mCopyBit[i]->reset();
if(ctx->mLayerRotMap[i])
ctx->mLayerRotMap[i]->reset();
+
}
ctx->mAD->reset();
@@ -206,7 +217,7 @@
ctx->mRotMgr->configBegin();
overlay::Writeback::configBegin();
- for (int32_t i = numDisplays; i >= 0; i--) {
+ for (int32_t i = (numDisplays-1); i >= 0; i--) {
hwc_display_contents_1_t *list = displays[i];
int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) {
@@ -538,7 +549,7 @@
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- for (uint32_t i = 0; i <= numDisplays; i++) {
+ for (uint32_t i = 0; i < numDisplays; i++) {
hwc_display_contents_1_t* list = displays[i];
int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) {
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index bec51d6..9430721 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -188,6 +188,7 @@
ctx->vstate.enable = false;
ctx->vstate.fakevsync = false;
ctx->mExtOrientation = 0;
+ ctx->numActiveDisplays = 1;
//Right now hwc starts the service but anybody could do it, or it could be
//independent process as well.
@@ -1910,6 +1911,32 @@
ctx->layerProp[dpy] = new LayerProp[numAppLayers];
}
+/* Since we fake non-Hybrid WFD solution as external display, this
+ * function helps us in determining the priority between external
+ * (hdmi/non-Hybrid WFD display) and virtual display devices(SSD/
+ * screenrecord). This can be removed once wfd-client migrates to
+ * using virtual-display api's.
+ */
+bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
+ const hwc_display_contents_1_t *list) {
+
+ /* We rely on the fact that for pure virtual display solution
+ * list->outbuf will be a non-NULL handle.
+ *
+ * If there are three active displays (which means there is one
+ * primary, one external and one virtual active display)
+ * we give mdss/mdp hw resources(pipes,smp,etc) for external
+ * display(hdmi/non-Hybrid WFD display) rather than for virtual
+ * display(SSD/screenrecord)
+ */
+
+ if(list->outbuf and (ctx->numActiveDisplays == HWC_NUM_DISPLAY_TYPES)) {
+ return false;
+ }
+
+ return true;
+}
+
void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
const hwc_rect_t& dst, const int& transform,
ovutils::eMdpFlags& mdpFlags) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e64f89c..35b680e 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -225,6 +225,9 @@
bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
+bool canUseMDPforVirtualDisplay(hwc_context_t* ctx,
+ const hwc_display_contents_1_t *list);
+
//Helper function to dump logs
void dumpsys_log(android::String8& buf, const char* fmt, ...);
@@ -486,15 +489,14 @@
int mExtOrientation;
//Flags the transition of a video session
bool mVideoTransFlag;
-
//Used for SideSync feature
//which overrides the mExtOrientation
bool mBufferMirrorMode;
-
qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
-
// Panel reset flag will be set if BTA check fails
bool mPanelResetStatus;
+ // number of active Displays
+ int numActiveDisplays;
};
namespace qhwc {
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index b26a733..b1af7ae 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -67,9 +67,7 @@
int dpy = HWC_DISPLAY_VIRTUAL;
//Cleanup virtual display objs, since there is no explicit disconnect
- if(ctx->dpyAttr[dpy].connected &&
- (numDisplays <= HWC_NUM_PHYSICAL_DISPLAY_TYPES ||
- displays[dpy] == NULL)) {
+ if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
ctx->dpyAttr[dpy].connected = false;
if(ctx->mFBUpdate[dpy]) {
@@ -179,7 +177,8 @@
if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive &&
- ctx->dpyAttr[dpy].connected) {
+ ctx->dpyAttr[dpy].connected &&
+ canUseMDPforVirtualDisplay(ctx,list)) {
reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
if(!ctx->dpyAttr[dpy].isPause) {
ctx->dpyAttr[dpy].isConfiguring = false;
@@ -210,7 +209,8 @@
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected &&
- !ctx->dpyAttr[dpy].isPause) {
+ (!ctx->dpyAttr[dpy].isPause) &&
+ canUseMDPforVirtualDisplay(ctx,list)) {
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)