Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02d86567 authored by Jesse Hall's avatar Jesse Hall
Browse files

Clean up HWC state when releasing a DisplayDevice

DisplayDevices can be released when DisplayManager removes them from
the display list, or (for virtual displays) when the surface is set to
NULL. We were only cleaning up HWC resources associated with the
display in the first case.

Bug: 8384764
Change-Id: Id3d226dd7178fbe6d0a2ac4e2660b864ee073de3
parent 5a557a61
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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(),
+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,9 @@ public:
    bool isScreenAcquired() const;
    bool canDraw() const;

    // release HWC resources (if any) for removable displays
    void disconnect(HWComposer& hwc);

    /* ------------------------------------------------------------------------
     * Debugging
     */
+6 −6
Original line number Diff line number Diff line
@@ -953,17 +953,17 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
        result.appendFormat("  mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync);
        for (size_t i=0 ; i<mNumDisplays ; i++) {
            const DisplayData& disp(mDisplayData[i]);
            if (!disp.connected)
                continue;

            const Vector< sp<Layer> >& 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);
            }

            if (disp.list && disp.connected) {
            if (disp.list) {
                result.appendFormat(
                        "  numHwLayers=%u, flags=%08x\n",
                        disp.list->numHwLayers, disp.list->flags);
+15 −6
Original line number Diff line number Diff line
@@ -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<const DisplayDevice> hw(getDefaultDisplayDevice());
                        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
                        mDisplays.removeItem(draw.keyAt(i));
                        getHwComposer().disconnectDisplay(draw[i].type);
                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
                        DisplayDevice::makeCurrent(mEGLDisplay, defaultDisplay, mEGLContext);
                        sp<DisplayDevice> 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<DisplayDevice> 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<DisplaySurface> 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);
+3 −3
Original line number Diff line number Diff line
@@ -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
     */