hwc: clean up overlay for external from the draw thread only
Cleanup overlay for external from the draw thread. If done from the uevent thread, its possible that the object being used by draw thread is deleted by uevent thread. This also removes unnecessary side-effects where libexternal sets states in hwc, whereas, it could be set from hwc itself. There should be no need for libexternal to modify states in hwc. Bug: 7335863 (partial fix) Change-Id: If07483e640abae2ced2418e0d5c8f278f8c6ec33 Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
committed by
Iliyan Malchev
parent
f83d4480f2
commit
1a8cda0b2c
@@ -408,16 +408,6 @@ void ExternalDisplay::setExternalDisplay(int connected)
|
||||
const char* prop = (connected) ? "1" : "0";
|
||||
// set system property
|
||||
property_set("hw.hdmiON", prop);
|
||||
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,connected);
|
||||
//Inform SF. Disabled until SF calls unblank
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
|
||||
|
||||
//TODO ideally should be done on "connected" not "online"
|
||||
ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
|
||||
|
||||
if(connected == false)
|
||||
ctx->priv_proc.onExtDisconnect(ctx->priv_proc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ static void hwc_registerProcs(struct hwc_composer_device_1* dev,
|
||||
//Helper
|
||||
static void reset(hwc_context_t *ctx, int numDisplays) {
|
||||
memset(ctx->listStats, 0, sizeof(ctx->listStats));
|
||||
for(int i = 0; i < numDisplays; i++){
|
||||
for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
|
||||
ctx->overlayInUse[i] = false;
|
||||
ctx->listStats[i].yuvIndex = -1;
|
||||
}
|
||||
}
|
||||
@@ -87,10 +88,13 @@ static void reset(hwc_context_t *ctx, int numDisplays) {
|
||||
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
|
||||
hwc_display_contents_1_t *list) {
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false;
|
||||
if (LIKELY(list && list->numHwLayers > 1)) {
|
||||
|
||||
if (LIKELY(list && list->numHwLayers > 1) &&
|
||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
|
||||
|
||||
uint32_t last = list->numHwLayers - 1;
|
||||
hwc_layer_1_t *fblayer = &list->hwLayers[last];
|
||||
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
|
||||
if(fbLayer->handle) {
|
||||
setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
|
||||
if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) {
|
||||
ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true;
|
||||
@@ -100,14 +104,13 @@ static int hwc_prepare_primary(hwc_composer_device_1 *dev,
|
||||
ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hwc_prepare_external(hwc_composer_device_1 *dev,
|
||||
hwc_display_contents_1_t *list) {
|
||||
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = false;
|
||||
|
||||
if (LIKELY(list && list->numHwLayers > 1) &&
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
|
||||
@@ -116,15 +119,18 @@ static int hwc_prepare_external(hwc_composer_device_1 *dev,
|
||||
setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
|
||||
|
||||
uint32_t last = list->numHwLayers - 1;
|
||||
hwc_layer_1_t *fblayer = &list->hwLayers[last];
|
||||
if(UIMirrorOverlay::prepare(ctx, fblayer)) {
|
||||
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
|
||||
if(fbLayer->handle) {
|
||||
if(UIMirrorOverlay::prepare(ctx, fbLayer)) {
|
||||
ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
|
||||
}
|
||||
|
||||
if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL)) {
|
||||
ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
|
||||
} else {
|
||||
ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(ovutils::OV_UI_MIRROR);
|
||||
ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(
|
||||
ovutils::OV_UI_MIRROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -135,7 +141,6 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
|
||||
{
|
||||
int ret = 0;
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
|
||||
reset(ctx, numDisplays);
|
||||
|
||||
//If securing of h/w in progress skip comp using overlay.
|
||||
@@ -143,9 +148,6 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
|
||||
|
||||
for (uint32_t i = 0; i < numDisplays; i++) {
|
||||
hwc_display_contents_1_t *list = displays[i];
|
||||
if(list && list->numHwLayers) {
|
||||
uint32_t last = list->numHwLayers - 1;
|
||||
if(list->hwLayers[last].handle != NULL) {
|
||||
switch(i) {
|
||||
case HWC_DISPLAY_PRIMARY:
|
||||
ret = hwc_prepare_primary(dev, list);
|
||||
@@ -157,8 +159,6 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -254,9 +254,6 @@ static int hwc_query(struct hwc_composer_device_1* dev,
|
||||
}
|
||||
|
||||
static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||
if(!ctx->overlayInUse[HWC_DISPLAY_PRIMARY])
|
||||
ctx->mOverlay[HWC_DISPLAY_PRIMARY]->setState(ovutils::OV_CLOSED);
|
||||
|
||||
if (LIKELY(list && list->numHwLayers > 1) &&
|
||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
|
||||
uint32_t last = list->numHwLayers - 1;
|
||||
@@ -279,8 +276,6 @@ static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||
static int hwc_set_external(hwc_context_t *ctx,
|
||||
hwc_display_contents_1_t* list) {
|
||||
Locker::Autolock _l(ctx->mExtSetLock);
|
||||
if(!ctx->overlayInUse[HWC_DISPLAY_EXTERNAL])
|
||||
ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(ovutils::OV_CLOSED);
|
||||
|
||||
if (LIKELY(list && list->numHwLayers > 1) &&
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
|
||||
@@ -310,6 +305,11 @@ static int hwc_set(hwc_composer_device_1 *dev,
|
||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||
Locker::Autolock _l(ctx->mBlankLock);
|
||||
|
||||
for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
|
||||
if(!ctx->overlayInUse[i])
|
||||
ctx->mOverlay[i]->setState(ovutils::OV_CLOSED);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numDisplays; i++) {
|
||||
hwc_display_contents_1_t* list = displays[i];
|
||||
switch(i) {
|
||||
|
||||
@@ -53,14 +53,23 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
||||
// for now just parsing onlin/offline info is enough
|
||||
if (hdmi) {
|
||||
str = udata;
|
||||
int connected = 0;
|
||||
int connected = -1; //some event other than online and offline .. e.g
|
||||
if(!(strncmp(str,"online@",strlen("online@")))) {
|
||||
//Disabled until SF calls unblank
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
|
||||
connected = 1;
|
||||
ctx->mExtDisplay->setExternalDisplay(connected);;
|
||||
} else if(!(strncmp(str,"offline@",strlen("offline@")))) {
|
||||
//Disabled until SF calls unblank
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
|
||||
connected = 0;
|
||||
Locker::Autolock _l(ctx->mExtSetLock);
|
||||
ctx->mExtDisplay->setExternalDisplay(connected);;
|
||||
}
|
||||
if(connected != -1) { //either we got online or offline
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = connected;
|
||||
ctx->mExtDisplay->setExternalDisplay(connected);
|
||||
ALOGD("%s sending hotplug: connected = %d", __FUNCTION__,connected);
|
||||
Locker::Autolock _l(ctx->mExtSetLock); //hwc comp could be on
|
||||
//TODO ideally should be done on "connected" not "online"
|
||||
ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +48,6 @@ static void openFramebufferDevice(hwc_context_t *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static void onExtDisconnect(const hwc_context_t::Callbacks& priv_proc) {
|
||||
hwc_context_t *ctx = priv_proc.ctx;
|
||||
overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
|
||||
// Set overlay state
|
||||
ov.setState(ovutils::OV_CLOSED);
|
||||
}
|
||||
|
||||
void initContext(hwc_context_t *ctx)
|
||||
{
|
||||
openFramebufferDevice(ctx);
|
||||
@@ -73,9 +66,6 @@ void initContext(hwc_context_t *ctx)
|
||||
pthread_cond_init(&(ctx->vstate.cond), NULL);
|
||||
ctx->vstate.enable = false;
|
||||
|
||||
ctx->priv_proc.onExtDisconnect = onExtDisconnect;
|
||||
ctx->priv_proc.ctx = ctx;
|
||||
|
||||
ALOGI("Initializing Qualcomm Hardware Composer");
|
||||
ALOGI("MDP version: %d", ctx->mMDP.version);
|
||||
}
|
||||
|
||||
@@ -176,14 +176,6 @@ struct hwc_context_t {
|
||||
hwc_composer_device_1_t device;
|
||||
const hwc_procs_t* proc;
|
||||
|
||||
//Private hwc handlers
|
||||
struct Callbacks {
|
||||
void (*onExtDisconnect)(const Callbacks& priv_proc);
|
||||
hwc_context_t *ctx;
|
||||
};
|
||||
|
||||
Callbacks priv_proc;
|
||||
|
||||
int overlayInUse[HWC_NUM_DISPLAY_TYPES];
|
||||
|
||||
//Framebuffer device
|
||||
|
||||
Reference in New Issue
Block a user