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
This commit is contained in:
Raj Kamal
2014-01-27 19:35:13 +05:30
parent 8bb48d3314
commit 52b4fdbdbd
6 changed files with 54 additions and 14 deletions

View File

@@ -105,17 +105,27 @@ static void hwc_registerProcs(struct hwc_composer_device_1* dev,
//Helper //Helper
static void reset(hwc_context_t *ctx, int numDisplays, static void reset(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) { hwc_display_contents_1_t** displays) {
ctx->numActiveDisplays = 0;
for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
hwc_display_contents_1_t *list = displays[i]; hwc_display_contents_1_t *list = displays[i];
// XXX:SurfaceFlinger no longer guarantees that this // XXX:SurfaceFlinger no longer guarantees that this
// value is reset on every prepare. However, for the layer // value is reset on every prepare. However, for the layer
// cache we need to reset it. // cache we need to reset it.
// We can probably rethink that later on // 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++) { for(uint32_t j = 0; j < list->numHwLayers; j++) {
if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; 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]) if(ctx->mFBUpdate[i])
@@ -124,6 +134,7 @@ static void reset(hwc_context_t *ctx, int numDisplays,
ctx->mCopyBit[i]->reset(); ctx->mCopyBit[i]->reset();
if(ctx->mLayerRotMap[i]) if(ctx->mLayerRotMap[i])
ctx->mLayerRotMap[i]->reset(); ctx->mLayerRotMap[i]->reset();
} }
ctx->mAD->reset(); ctx->mAD->reset();
@@ -206,7 +217,7 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
ctx->mRotMgr->configBegin(); ctx->mRotMgr->configBegin();
overlay::Writeback::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]; hwc_display_contents_1_t *list = displays[i];
int dpy = getDpyforExternalDisplay(ctx, i); int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) { switch(dpy) {
@@ -538,7 +549,7 @@ static int hwc_set(hwc_composer_device_1 *dev,
{ {
int ret = 0; int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev); 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]; hwc_display_contents_1_t* list = displays[i];
int dpy = getDpyforExternalDisplay(ctx, i); int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) { switch(dpy) {

View File

@@ -188,6 +188,7 @@ void initContext(hwc_context_t *ctx)
ctx->vstate.enable = false; ctx->vstate.enable = false;
ctx->vstate.fakevsync = false; ctx->vstate.fakevsync = false;
ctx->mExtOrientation = 0; ctx->mExtOrientation = 0;
ctx->numActiveDisplays = 1;
//Right now hwc starts the service but anybody could do it, or it could be //Right now hwc starts the service but anybody could do it, or it could be
//independent process as well. //independent process as well.
@@ -1910,6 +1911,32 @@ void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
ctx->layerProp[dpy] = new LayerProp[numAppLayers]; 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, void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
const hwc_rect_t& dst, const int& transform, const hwc_rect_t& dst, const int& transform,
ovutils::eMdpFlags& mdpFlags) { ovutils::eMdpFlags& mdpFlags) {

View File

@@ -225,6 +225,9 @@ int getBlending(int blending);
bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy); bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers); 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 //Helper function to dump logs
void dumpsys_log(android::String8& buf, const char* fmt, ...); void dumpsys_log(android::String8& buf, const char* fmt, ...);
@@ -486,15 +489,14 @@ struct hwc_context_t {
int mExtOrientation; int mExtOrientation;
//Flags the transition of a video session //Flags the transition of a video session
bool mVideoTransFlag; bool mVideoTransFlag;
//Used for SideSync feature //Used for SideSync feature
//which overrides the mExtOrientation //which overrides the mExtOrientation
bool mBufferMirrorMode; bool mBufferMirrorMode;
qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES]; qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
// Panel reset flag will be set if BTA check fails // Panel reset flag will be set if BTA check fails
bool mPanelResetStatus; bool mPanelResetStatus;
// number of active Displays
int numActiveDisplays;
}; };
namespace qhwc { namespace qhwc {

View File

@@ -67,9 +67,7 @@ void HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t numDisplays,
int dpy = HWC_DISPLAY_VIRTUAL; int dpy = HWC_DISPLAY_VIRTUAL;
//Cleanup virtual display objs, since there is no explicit disconnect //Cleanup virtual display objs, since there is no explicit disconnect
if(ctx->dpyAttr[dpy].connected && if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
(numDisplays <= HWC_NUM_PHYSICAL_DISPLAY_TYPES ||
displays[dpy] == NULL)) {
ctx->dpyAttr[dpy].connected = false; ctx->dpyAttr[dpy].connected = false;
if(ctx->mFBUpdate[dpy]) { if(ctx->mFBUpdate[dpy]) {
@@ -179,7 +177,8 @@ int HWCVirtualV4L2::prepare(hwc_composer_device_1 *dev,
if (LIKELY(list && list->numHwLayers > 1) && if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive && ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected) { ctx->dpyAttr[dpy].connected &&
canUseMDPforVirtualDisplay(ctx,list)) {
reset_layer_prop(ctx, dpy, list->numHwLayers - 1); reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
if(!ctx->dpyAttr[dpy].isPause) { if(!ctx->dpyAttr[dpy].isPause) {
ctx->dpyAttr[dpy].isConfiguring = false; ctx->dpyAttr[dpy].isConfiguring = false;
@@ -210,7 +209,8 @@ int HWCVirtualV4L2::set(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
ctx->dpyAttr[dpy].connected && ctx->dpyAttr[dpy].connected &&
!ctx->dpyAttr[dpy].isPause) { (!ctx->dpyAttr[dpy].isPause) &&
canUseMDPforVirtualDisplay(ctx,list)) {
uint32_t last = list->numHwLayers - 1; uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_layer_1_t *fbLayer = &list->hwLayers[last];
int fd = -1; //FenceFD from the Copybit(valid in async mode) int fd = -1; //FenceFD from the Copybit(valid in async mode)

View File

@@ -31,7 +31,6 @@
#define MAX_FRAME_BUFFER_NAME_SIZE (80) #define MAX_FRAME_BUFFER_NAME_SIZE (80)
#define MAX_DISPLAY_DEVICES (3)
int getHDMINode(void) int getHDMINode(void)
{ {
@@ -40,7 +39,7 @@ int getHDMINode(void)
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE]; char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
int j = 0; int j = 0;
for(j = 0; j < MAX_DISPLAY_DEVICES; j++) { for(j = 0; j < HWC_NUM_DISPLAY_TYPES; j++) {
snprintf (msmFbTypePath, sizeof(msmFbTypePath), snprintf (msmFbTypePath, sizeof(msmFbTypePath),
"/sys/class/graphics/fb%d/msm_fb_type", j); "/sys/class/graphics/fb%d/msm_fb_type", j);
displayDeviceFP = fopen(msmFbTypePath, "r"); displayDeviceFP = fopen(msmFbTypePath, "r");
@@ -58,7 +57,7 @@ int getHDMINode(void)
} }
} }
if (j < MAX_DISPLAY_DEVICES) if (j < HWC_NUM_DISPLAY_TYPES)
return j; return j;
else else
ALOGE("%s: Failed to find HDMI node", __func__); ALOGE("%s: Failed to find HDMI node", __func__);

View File

@@ -42,6 +42,7 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <cutils/properties.h> #include <cutils/properties.h>
#include <hardware/hwcomposer.h>
#define EDID_RAW_DATA_SIZE 640 #define EDID_RAW_DATA_SIZE 640