diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index fb93c477d..302ce8255 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -540,8 +540,13 @@ status_t HWComposer::prepare() { // DO NOT reset the handle field to NULL, because it's possible // that we have nothing to redraw (eg: eglSwapBuffers() not called) // in which case, we should continue to use the same buffer. + LOG_FATAL_IF(disp.list == NULL); disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET; } + if (!disp.connected && disp.list != NULL) { + ALOGW("WARNING: disp %d: connected, non-null list, layers=%d", + i, disp.list->numHwLayers); + } mLists[i] = disp.list; if (mLists[i]) { if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) { @@ -664,6 +669,17 @@ status_t HWComposer::acquire(int disp) const { return NO_ERROR; } +void HWComposer::disconnectDisplay(int disp) { + LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY || + disp >= HWC_NUM_DISPLAY_TYPES); + DisplayData& dd(mDisplayData[disp]); + if (dd.list != NULL) { + free(dd.list); + dd.list = NULL; + dd.framebufferTarget = NULL; // points into dd.list + } +} + int HWComposer::getVisualID() const { if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 633ca9c13..af33999dc 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -97,6 +97,9 @@ public: // acquire hardware resources and unblank screen status_t acquire(int disp) const; + // reset state when an external, non-virtual display is disconnected + void disconnectDisplay(int disp); + // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED. status_t createWorkList(int32_t id, size_t numLayers); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a8d20bb1b..ebec4cb82 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1123,7 +1123,13 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (j < 0) { // in drawing state but not in current state if (!draw[i].isMainDisplay()) { + // Call makeCurrent() on the primary display so we can + // be sure that nothing associated with this display + // is current. + const sp& hw(getDefaultDisplayDevice()); + DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); mDisplays.removeItem(draw.keyAt(i)); + getHwComposer().disconnectDisplay(draw[i].type); } else { ALOGW("trying to remove the main display"); }