hwc: Return failure from hwc_device_open when fb open fails
- When fb open fails during hwc initialization, it should be flagged as a fatal error and HAL should return error. - Without this, the SF would make calls to HWC that would fail, and display being blank. Change-Id: I20f08bdcb283d4805449c74a8214b871c2f1c80b
This commit is contained in:
@@ -966,7 +966,11 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
|
|||||||
memset(dev, 0, sizeof(*dev));
|
memset(dev, 0, sizeof(*dev));
|
||||||
|
|
||||||
//Initialize hwc context
|
//Initialize hwc context
|
||||||
initContext(dev);
|
status = initContext(dev);
|
||||||
|
if (status < 0) {
|
||||||
|
free(dev);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
//Setup HWC methods
|
//Setup HWC methods
|
||||||
dev->device.common.tag = HARDWARE_DEVICE_TAG;
|
dev->device.common.tag = HARDWARE_DEVICE_TAG;
|
||||||
|
|||||||
@@ -202,7 +202,15 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
|
|||||||
"uevent thread", __FUNCTION__);
|
"uevent thread", __FUNCTION__);
|
||||||
ctx->mWfdSyncLock.unlock();
|
ctx->mWfdSyncLock.unlock();
|
||||||
}
|
}
|
||||||
ctx->mHDMIDisplay->configure();
|
// If FB open fails ignore this hotplug event
|
||||||
|
int error = ctx->mHDMIDisplay->configure();
|
||||||
|
if (error < 0) {
|
||||||
|
ALOGE("%s: Open Framebuffer for dpy = %d", __FUNCTION__, dpy);
|
||||||
|
ctx->mDrawLock.lock();
|
||||||
|
ctx->dpyAttr[dpy].isConfiguring = false;
|
||||||
|
ctx->mDrawLock.unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
ctx->mHDMIDisplay->activateDisplay();
|
ctx->mHDMIDisplay->activateDisplay();
|
||||||
|
|
||||||
ctx->mDrawLock.lock();
|
ctx->mDrawLock.lock();
|
||||||
|
|||||||
@@ -266,8 +266,26 @@ static void changeDefaultAppBufferCount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initContext(hwc_context_t *ctx)
|
int initContext(hwc_context_t *ctx)
|
||||||
{
|
{
|
||||||
|
int error = -1;
|
||||||
|
int compositionType = 0;
|
||||||
|
|
||||||
|
//Right now hwc starts the service but anybody could do it, or it could be
|
||||||
|
//independent process as well.
|
||||||
|
QService::init();
|
||||||
|
sp<IQClient> client = new QClient(ctx);
|
||||||
|
sp<IQService> iqs = interface_cast<IQService>(
|
||||||
|
defaultServiceManager()->getService(
|
||||||
|
String16("display.qservice")));
|
||||||
|
if (iqs.get()) {
|
||||||
|
iqs->connect(client);
|
||||||
|
ctx->mQService = reinterpret_cast<QService* >(iqs.get());
|
||||||
|
} else {
|
||||||
|
ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
overlay::Overlay::initOverlay();
|
overlay::Overlay::initOverlay();
|
||||||
ctx->mHDMIDisplay = new HDMIDisplay();
|
ctx->mHDMIDisplay = new HDMIDisplay();
|
||||||
uint32_t priW = 0, priH = 0;
|
uint32_t priW = 0, priH = 0;
|
||||||
@@ -280,15 +298,24 @@ void initContext(hwc_context_t *ctx)
|
|||||||
if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
|
if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
|
||||||
int connected = ctx->mHDMIDisplay->getConnectedState();
|
int connected = ctx->mHDMIDisplay->getConnectedState();
|
||||||
if(connected == 1) {
|
if(connected == 1) {
|
||||||
ctx->mHDMIDisplay->configure();
|
error = ctx->mHDMIDisplay->configure();
|
||||||
|
if (error < 0) {
|
||||||
|
goto OpenFBError;
|
||||||
|
}
|
||||||
updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
|
updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
|
||||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
|
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
|
||||||
} else {
|
} else {
|
||||||
openFramebufferDevice(ctx);
|
error = openFramebufferDevice(ctx);
|
||||||
|
if(error < 0) {
|
||||||
|
goto OpenFBError;
|
||||||
|
}
|
||||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
|
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
openFramebufferDevice(ctx);
|
error = openFramebufferDevice(ctx);
|
||||||
|
if(error < 0) {
|
||||||
|
goto OpenFBError;
|
||||||
|
}
|
||||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
|
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
|
||||||
// Send the primary resolution to the hdmi display class
|
// Send the primary resolution to the hdmi display class
|
||||||
// to be used for MDP scaling functionality
|
// to be used for MDP scaling functionality
|
||||||
@@ -314,7 +341,7 @@ void initContext(hwc_context_t *ctx)
|
|||||||
|
|
||||||
// Check if the target supports copybit compostion (dyn/mdp) to
|
// Check if the target supports copybit compostion (dyn/mdp) to
|
||||||
// decide if we need to open the copybit module.
|
// decide if we need to open the copybit module.
|
||||||
int compositionType =
|
compositionType =
|
||||||
qdutils::QCCompositionType::getInstance().getCompositionType();
|
qdutils::QCCompositionType::getInstance().getCompositionType();
|
||||||
|
|
||||||
// Only MDP copybit is used
|
// Only MDP copybit is used
|
||||||
@@ -372,21 +399,6 @@ void initContext(hwc_context_t *ctx)
|
|||||||
ctx->mExtOrientation = 0;
|
ctx->mExtOrientation = 0;
|
||||||
ctx->numActiveDisplays = 1;
|
ctx->numActiveDisplays = 1;
|
||||||
|
|
||||||
//Right now hwc starts the service but anybody could do it, or it could be
|
|
||||||
//independent process as well.
|
|
||||||
QService::init();
|
|
||||||
sp<IQClient> client = new QClient(ctx);
|
|
||||||
sp<IQService> iqs = interface_cast<IQService>(
|
|
||||||
defaultServiceManager()->getService(
|
|
||||||
String16("display.qservice")));
|
|
||||||
if (iqs.get()) {
|
|
||||||
iqs->connect(client);
|
|
||||||
ctx->mQService = reinterpret_cast<QService* >(iqs.get());
|
|
||||||
} else {
|
|
||||||
ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize device orientation to its default orientation
|
// Initialize device orientation to its default orientation
|
||||||
ctx->deviceOrientation = 0;
|
ctx->deviceOrientation = 0;
|
||||||
ctx->mBufferMirrorMode = false;
|
ctx->mBufferMirrorMode = false;
|
||||||
@@ -428,6 +440,13 @@ void initContext(hwc_context_t *ctx)
|
|||||||
ctx->mHPDEnabled = false;
|
ctx->mHPDEnabled = false;
|
||||||
ALOGI("Initializing Qualcomm Hardware Composer");
|
ALOGI("Initializing Qualcomm Hardware Composer");
|
||||||
ALOGI("MDP version: %d", ctx->mMDP.version);
|
ALOGI("MDP version: %d", ctx->mMDP.version);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
OpenFBError:
|
||||||
|
ALOGE("%s: Fatal Error: FB Open failed!!!", __FUNCTION__);
|
||||||
|
delete ctx->mHDMIDisplay;
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeContext(hwc_context_t *ctx)
|
void closeContext(hwc_context_t *ctx)
|
||||||
@@ -2932,7 +2951,11 @@ void handle_online(hwc_context_t* ctx, int dpy) {
|
|||||||
// TODO: If HDMI is connected after the display has booted up,
|
// TODO: If HDMI is connected after the display has booted up,
|
||||||
// and the best configuration is different from the default
|
// and the best configuration is different from the default
|
||||||
// then we need to deal with this appropriately.
|
// then we need to deal with this appropriately.
|
||||||
ctx->mHDMIDisplay->configure();
|
int error = ctx->mHDMIDisplay->configure();
|
||||||
|
if (error < 0) {
|
||||||
|
ALOGE("Error opening FrameBuffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateDisplayInfo(ctx, dpy);
|
updateDisplayInfo(ctx, dpy);
|
||||||
initCompositionResources(ctx, dpy);
|
initCompositionResources(ctx, dpy);
|
||||||
ctx->dpyAttr[dpy].connected = true;
|
ctx->dpyAttr[dpy].connected = true;
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
|
|||||||
void dumpLayer(hwc_layer_1_t const* l);
|
void dumpLayer(hwc_layer_1_t const* l);
|
||||||
void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
||||||
int dpy);
|
int dpy);
|
||||||
void initContext(hwc_context_t *ctx);
|
int initContext(hwc_context_t *ctx);
|
||||||
void closeContext(hwc_context_t *ctx);
|
void closeContext(hwc_context_t *ctx);
|
||||||
//Crops source buffer against destination and FB boundaries
|
//Crops source buffer against destination and FB boundaries
|
||||||
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
||||||
|
|||||||
Reference in New Issue
Block a user