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
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index bf59217..496798a 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -966,7 +966,11 @@
memset(dev, 0, sizeof(*dev));
//Initialize hwc context
- initContext(dev);
+ status = initContext(dev);
+ if (status < 0) {
+ free(dev);
+ return status;
+ }
//Setup HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 4d94647..6a70d06 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -202,7 +202,15 @@
"uevent thread", __FUNCTION__);
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->mDrawLock.lock();
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index d176cd3..8a60f65 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -266,8 +266,26 @@
}
}
-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();
ctx->mHDMIDisplay = new HDMIDisplay();
uint32_t priW = 0, priH = 0;
@@ -280,15 +298,24 @@
if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
int connected = ctx->mHDMIDisplay->getConnectedState();
if(connected == 1) {
- ctx->mHDMIDisplay->configure();
+ error = ctx->mHDMIDisplay->configure();
+ if (error < 0) {
+ goto OpenFBError;
+ }
updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
} else {
- openFramebufferDevice(ctx);
+ error = openFramebufferDevice(ctx);
+ if(error < 0) {
+ goto OpenFBError;
+ }
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
}
} else {
- openFramebufferDevice(ctx);
+ error = openFramebufferDevice(ctx);
+ if(error < 0) {
+ goto OpenFBError;
+ }
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
// Send the primary resolution to the hdmi display class
// to be used for MDP scaling functionality
@@ -314,8 +341,8 @@
// Check if the target supports copybit compostion (dyn/mdp) to
// decide if we need to open the copybit module.
- int compositionType =
- qdutils::QCCompositionType::getInstance().getCompositionType();
+ compositionType =
+ qdutils::QCCompositionType::getInstance().getCompositionType();
// Only MDP copybit is used
if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
@@ -372,21 +399,6 @@
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.
- 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
ctx->deviceOrientation = 0;
ctx->mBufferMirrorMode = false;
@@ -428,6 +440,13 @@
ctx->mHPDEnabled = false;
ALOGI("Initializing Qualcomm Hardware Composer");
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)
@@ -2932,7 +2951,11 @@
// TODO: If HDMI is connected after the display has booted up,
// and the best configuration is different from the default
// 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);
initCompositionResources(ctx, dpy);
ctx->dpyAttr[dpy].connected = true;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 23157d4..ea8d652 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -280,7 +280,7 @@
void dumpLayer(hwc_layer_1_t const* l);
void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy);
-void initContext(hwc_context_t *ctx);
+int initContext(hwc_context_t *ctx);
void closeContext(hwc_context_t *ctx);
//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,