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:
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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__);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user