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

Commit 79bba0e9 authored by David Sodman's avatar David Sodman
Browse files

SF: move setupHwComposer logic to FE function

One step towards separating FE from BE.  The logic that
traditionally has been in setupHwComposer will be in
a function named calculateWorkingSet as the function
named setUpHwComposer will handle different functionality.

Bug: 112259502
Test: cts -m CtsViewTestCases
      SurfaceFlinger_test
      vrflinger_test

Change-Id: If4c2735898969ab15de42cbd9eb5f08a7a26b545
parent d5f846e4
Loading
Loading
Loading
Loading
+115 −112
Original line number Original line Diff line number Diff line
@@ -1578,7 +1578,7 @@ void SurfaceFlinger::handleMessageRefresh() {


    preComposition(refreshStartTime);
    preComposition(refreshStartTime);
    rebuildLayerStacks();
    rebuildLayerStacks();
    setUpHWComposer();
    calculateWorkingSet();
    doDebugFlashRegions();
    doDebugFlashRegions();
    doTracing("handleRefresh");
    doTracing("handleRefresh");
    logLayerStats();
    logLayerStats();
@@ -1595,6 +1595,120 @@ void SurfaceFlinger::handleMessageRefresh() {
    mLayersWithQueuedFrames.clear();
    mLayersWithQueuedFrames.clear();
}
}


void SurfaceFlinger::calculateWorkingSet() {
    ATRACE_CALL();
    ALOGV(__FUNCTION__);

    for (const auto& [token, display] : mDisplays) {
        bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty();
        bool empty = display->getVisibleLayersSortedByZ().size() == 0;
        bool wasEmpty = !display->lastCompositionHadVisibleLayers;

        // If nothing has changed (!dirty), don't recompose.
        // If something changed, but we don't currently have any visible layers,
        //   and didn't when we last did a composition, then skip it this time.
        // The second rule does two things:
        // - When all layers are removed from a display, we'll emit one black
        //   frame, then nothing more until we get new layers.
        // - When a display is created with a private layer stack, we won't
        //   emit any black frames until a layer is added to the layer stack.
        bool mustRecompose = dirty && !(empty && wasEmpty);

        ALOGV_IF(display->isVirtual(), "Display %d: %s composition (%sdirty %sempty %swasEmpty)",
                 display->getId(), mustRecompose ? "doing" : "skipping", dirty ? "+" : "-",
                 empty ? "+" : "-", wasEmpty ? "+" : "-");

        display->beginFrame(mustRecompose);

        if (mustRecompose) {
            display->lastCompositionHadVisibleLayers = !empty;
        }
    }

    // build the h/w work list
    if (CC_UNLIKELY(mGeometryInvalid)) {
        mGeometryInvalid = false;
        for (const auto& [token, display] : mDisplays) {
            const auto displayId = display->getId();
            if (displayId >= 0) {
                const Vector<sp<Layer>>& currentLayers(
                        display->getVisibleLayersSortedByZ());
                for (size_t i = 0; i < currentLayers.size(); i++) {
                    const auto& layer = currentLayers[i];

                    if (!layer->hasHwcLayer(displayId)) {
                        if (!layer->createHwcLayer(getBE().mHwc.get(), displayId)) {
                            layer->forceClientComposition(displayId);
                            continue;
                        }
                    }

                    layer->setGeometry(display, i);
                    if (mDebugDisableHWC || mDebugRegion) {
                        layer->forceClientComposition(displayId);
                    }
                }
            }
        }
    }

    // Set the per-frame data
    for (const auto& [token, display] : mDisplays) {
        const auto displayId = display->getId();
        if (displayId < 0) {
            continue;
        }

        if (mDrawingState.colorMatrixChanged) {
            display->setColorTransform(mDrawingState.colorMatrix);
            status_t result = getBE().mHwc->setColorTransform(displayId, mDrawingState.colorMatrix);
            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
                    "display %d: %d", displayId, result);
        }
        for (auto& layer : display->getVisibleLayersSortedByZ()) {
            if (layer->isHdrY410()) {
                layer->forceClientComposition(displayId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
                    !display->hasHDR10Support()) {
                layer->forceClientComposition(displayId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
                    !display->hasHLGSupport()) {
                layer->forceClientComposition(displayId);
            }

            if (layer->getForceClientComposition(displayId)) {
                ALOGV("[%s] Requesting Client composition", layer->getName().string());
                layer->setCompositionType(displayId, HWC2::Composition::Client);
                continue;
            }

            layer->setPerFrameData(display);
        }

        if (hasWideColorDisplay) {
            ColorMode  colorMode;
            Dataspace dataSpace;
            RenderIntent renderIntent;
            pickColorMode(display, &colorMode, &dataSpace, &renderIntent);
            setActiveColorModeInternal(display, colorMode, dataSpace, renderIntent);
        }
    }

    mDrawingState.colorMatrixChanged = false;

    for (const auto& [token, display] : mDisplays) {
        if (!display->isPoweredOn()) {
            continue;
        }

        status_t result = display->prepareFrame(*getBE().mHwc);
        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
                 display->getId(), result, strerror(-result));
    }
}

void SurfaceFlinger::doDebugFlashRegions()
void SurfaceFlinger::doDebugFlashRegions()
{
{
    // is debugging enabled
    // is debugging enabled
@@ -1994,117 +2108,6 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& display, ColorMode*
    display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
    display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
}
}


void SurfaceFlinger::setUpHWComposer() {
    ATRACE_CALL();
    ALOGV("setUpHWComposer");

    for (const auto& [token, display] : mDisplays) {
        bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty();
        bool empty = display->getVisibleLayersSortedByZ().size() == 0;
        bool wasEmpty = !display->lastCompositionHadVisibleLayers;

        // If nothing has changed (!dirty), don't recompose.
        // If something changed, but we don't currently have any visible layers,
        //   and didn't when we last did a composition, then skip it this time.
        // The second rule does two things:
        // - When all layers are removed from a display, we'll emit one black
        //   frame, then nothing more until we get new layers.
        // - When a display is created with a private layer stack, we won't
        //   emit any black frames until a layer is added to the layer stack.
        bool mustRecompose = dirty && !(empty && wasEmpty);

        ALOGV_IF(display->isVirtual(), "Display %d: %s composition (%sdirty %sempty %swasEmpty)",
                 display->getId(), mustRecompose ? "doing" : "skipping", dirty ? "+" : "-",
                 empty ? "+" : "-", wasEmpty ? "+" : "-");

        display->beginFrame(mustRecompose);

        if (mustRecompose) {
            display->lastCompositionHadVisibleLayers = !empty;
        }
    }

    // build the h/w work list
    if (CC_UNLIKELY(mGeometryInvalid)) {
        mGeometryInvalid = false;
        for (const auto& [token, display] : mDisplays) {
            const auto displayId = display->getId();
            if (displayId >= 0) {
                const Vector<sp<Layer>>& currentLayers = display->getVisibleLayersSortedByZ();
                for (size_t i = 0; i < currentLayers.size(); i++) {
                    const auto& layer = currentLayers[i];
                    if (!layer->hasHwcLayer(displayId)) {
                        if (!layer->createHwcLayer(getBE().mHwc.get(), displayId)) {
                            layer->forceClientComposition(displayId);
                            continue;
                        }
                    }

                    layer->setGeometry(display, i);
                    if (mDebugDisableHWC || mDebugRegion) {
                        layer->forceClientComposition(displayId);
                    }
                }
            }
        }
    }

    // Set the per-frame data
    for (const auto& [token, display] : mDisplays) {
        const auto displayId = display->getId();
        if (displayId < 0) {
            continue;
        }

        if (mDrawingState.colorMatrixChanged) {
            display->setColorTransform(mDrawingState.colorMatrix);
            status_t result = getBE().mHwc->setColorTransform(displayId, mDrawingState.colorMatrix);
            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display %d: %d",
                     displayId, result);
        }
        for (auto& layer : display->getVisibleLayersSortedByZ()) {
            if (layer->isHdrY410()) {
                layer->forceClientComposition(displayId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
                    !display->hasHDR10Support()) {
                layer->forceClientComposition(displayId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
                    !display->hasHLGSupport()) {
                layer->forceClientComposition(displayId);
            }

            if (layer->getForceClientComposition(displayId)) {
                ALOGV("[%s] Requesting Client composition", layer->getName().string());
                layer->setCompositionType(displayId, HWC2::Composition::Client);
                continue;
            }

            layer->setPerFrameData(display);
        }

        if (hasWideColorDisplay) {
            ColorMode colorMode;
            Dataspace dataSpace;
            RenderIntent renderIntent;
            pickColorMode(display, &colorMode, &dataSpace, &renderIntent);
            setActiveColorModeInternal(display, colorMode, dataSpace, renderIntent);
        }
    }

    mDrawingState.colorMatrixChanged = false;

    for (const auto& [token, display] : mDisplays) {
        if (!display->isPoweredOn()) {
            continue;
        }

        status_t result = display->prepareFrame(*getBE().mHwc);
        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
                 display->getId(), result, strerror(-result));
    }
}


void SurfaceFlinger::doComposition() {
void SurfaceFlinger::doComposition() {
    ATRACE_CALL();
    ATRACE_CALL();
+1 −1
Original line number Original line Diff line number Diff line
@@ -667,7 +667,7 @@ private:
    void pickColorMode(const sp<DisplayDevice>& display, ui::ColorMode* outMode,
    void pickColorMode(const sp<DisplayDevice>& display, ui::ColorMode* outMode,
                       ui::Dataspace* outDataSpace, ui::RenderIntent* outRenderIntent) const;
                       ui::Dataspace* outDataSpace, ui::RenderIntent* outRenderIntent) const;


    void setUpHWComposer();
    void calculateWorkingSet();
    void doComposition();
    void doComposition();
    void doDebugFlashRegions();
    void doDebugFlashRegions();
    void doTracing(const char* where);
    void doTracing(const char* where);