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:
Arun Kumar K.R
2015-02-20 18:45:58 -08:00
parent a7696ddf86
commit 205df77ece
4 changed files with 60 additions and 25 deletions

View File

@@ -966,7 +966,11 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
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;

View File

@@ -202,7 +202,15 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
"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();

View File

@@ -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();
ctx->mHDMIDisplay = new HDMIDisplay();
uint32_t priW = 0, priH = 0;
@@ -280,15 +298,24 @@ void initContext(hwc_context_t *ctx)
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 @@ void initContext(hwc_context_t *ctx)
// 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 @@ void initContext(hwc_context_t *ctx)
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 @@ void initContext(hwc_context_t *ctx)
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 @@ void handle_online(hwc_context_t* ctx, int dpy) {
// 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;

View File

@@ -280,7 +280,7 @@ inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
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,