diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 6936a7f86..68b0b7f15 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -143,6 +143,15 @@ DisplayDevice::~DisplayDevice() { } } +void DisplayDevice::disconnect(HWComposer& hwc) { + if (mHwcDisplayId >= 0) { + hwc.disconnectDisplay(mHwcDisplayId); + if (mHwcDisplayId >= DISPLAY_VIRTUAL) + hwc.freeDisplayId(mHwcDisplayId); + mHwcDisplayId = -1; + } +} + bool DisplayDevice::isValid() const { return mFlinger != NULL; } @@ -419,11 +428,11 @@ void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const { const Transform& tr(mGlobalTransform); snprintf(buffer, SIZE, "+ DisplayDevice: %s\n" - " type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " + " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n" " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", - mDisplayName.string(), mType, + mDisplayName.string(), mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), mOrientation, tr.getType(), getPageFlipCount(), mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(), diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index d4a6daaeb..377d924ef 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -146,6 +146,9 @@ public: bool isScreenAcquired() const; bool canDraw() const; + // release HWC resources (if any) for removable displays + void disconnect(HWComposer& hwc); + /* ------------------------------------------------------------------------ * Debugging */ diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index a68ddd83f..a29c06844 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -954,17 +954,17 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const { result.appendFormat(" mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync); for (size_t i=0 ; i >& visibleLayersSortedByZ = mFlinger->getLayerSortedByZForHwcDisplay(i); - if (disp.connected) { - result.appendFormat( - " Display[%d] : %ux%u, xdpi=%f, ydpi=%f, refresh=%lld\n", - i, disp.width, disp.height, disp.xdpi, disp.ydpi, disp.refresh); - } + result.appendFormat( + " Display[%d] : %ux%u, xdpi=%f, ydpi=%f, refresh=%lld\n", + i, disp.width, disp.height, disp.xdpi, disp.ydpi, disp.refresh); - if (disp.list && disp.connected) { + if (disp.list) { result.appendFormat( " numHwLayers=%u, flags=%08x\n", disp.list->numHwLayers, disp.list->flags); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5c7cf0758..9102f5c1f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1102,12 +1102,14 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // 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); + const sp defaultDisplay(getDefaultDisplayDevice()); + DisplayDevice::makeCurrent(mEGLDisplay, defaultDisplay, mEGLContext); + sp hw(getDisplayDevice(draw.keyAt(i))); + if (hw != NULL) + hw->disconnect(getHwComposer()); if (draw[i].type < DisplayDevice::NUM_DISPLAY_TYPES) mEventThread->onHotplugReceived(draw[i].type, false); + mDisplays.removeItem(draw.keyAt(i)); } else { ALOGW("trying to remove the main display"); } @@ -1120,6 +1122,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // recreating the DisplayDevice, so we just remove it // from the drawing state, so that it get re-added // below. + sp hw(getDisplayDevice(display)); + if (hw != NULL) + hw->disconnect(getHwComposer()); mDisplays.removeItem(display); mDrawingState.displays.removeItemsAt(i); dc--; i--; @@ -1150,9 +1155,13 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const DisplayDeviceState& state(curr[i]); sp dispSurface; - int32_t hwcDisplayId = allocateHwcDisplayId(state.type); + int32_t hwcDisplayId = -1; if (state.isVirtualDisplay()) { + // Virtual displays without a surface are dormant: + // they have external state (layer stack, projection, + // etc.) but no internal state (i.e. a DisplayDevice). if (state.surface != NULL) { + hwcDisplayId = allocateHwcDisplayId(state.type); dispSurface = new VirtualDisplaySurface( *mHwc, hwcDisplayId, state.surface, state.displayName); @@ -1162,7 +1171,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) "adding a supported display, but rendering " "surface is provided (%p), ignoring it", state.surface.get()); - + hwcDisplayId = allocateHwcDisplayId(state.type); // for supported (by hwc) displays we provide our // own rendering surface dispSurface = new FramebufferSurface(*mHwc, state.type); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f0e6deb1a..57ee8b92e 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -108,9 +108,6 @@ public: // utility function to delete a texture on the main thread void deleteTextureAsync(GLuint texture); - // allocate a h/w composer display id - int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type); - // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread void eventControl(int disp, int event, int enabled); @@ -338,6 +335,9 @@ private: // region of all screens presenting this layer stack. void invalidateLayerStack(uint32_t layerStack, const Region& dirty); + // allocate a h/w composer display id + int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type); + /* ------------------------------------------------------------------------ * H/W composer */