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

Commit 4bfd3972 authored by David Sodman's avatar David Sodman
Browse files

SF: Restructure message refresh

Test: Compile/Run manually
Merged-In: I321a79acd52dc956a0006d0dccd7b17cbf4e2443
Change-Id: I321a79acd52dc956a0006d0dccd7b17cbf4e2443
parent 5a5f148f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -620,7 +620,6 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
    getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
    getBE().compositionInfo.mBuffer = mActiveBuffer;
    getBE().compositionInfo.hwc.fence = acquireFence;
    getBE().compositionInfo.updateBuffer = true;
}

bool BufferLayer::isOpaque(const Layer::State& s) const {
+0 −1
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ struct CompositionInfo {
    sp<GraphicBuffer> mBuffer = nullptr;
    int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
    LayerBE* layer = nullptr;
    bool updateBuffer = false;
    struct {
        std::shared_ptr<LayerContainer> hwcLayer;
        bool skipGeometry = true;
+52 −53
Original line number Diff line number Diff line
@@ -1417,11 +1417,8 @@ void SurfaceFlinger::onMessageReceived(int32_t what) {
            refreshNeeded |= handleMessageInvalidate();
            refreshNeeded |= mRepaintEverything;

            const nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

            preComposition(refreshStartTime);
            preComposition();
            rebuildLayerStacks();

            calculateWorkingSet();

            if (refreshNeeded) {
@@ -1554,14 +1551,20 @@ void SurfaceFlinger::handleMessageRefresh() {

    mRefreshPending = false;

    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

    setUpHWComposer();

    beginFrame();
    for (auto compositionInfo : getBE().mCompositionInfo) {
        setUpHWComposer(compositionInfo);
    }
    prepareFrame();
    doDebugFlashRegions();
    doTracing("handleRefresh");
    logLayerStats();
    doComposition();
    postComposition(refreshStartTime);
    postComposition();

    getBE().mCompositionInfo.clear();

    mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);

@@ -1648,14 +1651,14 @@ void SurfaceFlinger::logLayerStats() {
    }
}

void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
void SurfaceFlinger::preComposition()
{
    ATRACE_CALL();
    ALOGV("preComposition");

    bool needExtraInvalidate = false;
    mDrawingState.traverseInZOrder([&](Layer* layer) {
        if (layer->onPreComposition(refreshStartTime)) {
        if (layer->onPreComposition(mRefreshStartTime)) {
            needExtraInvalidate = true;
        }
    });
@@ -1724,7 +1727,7 @@ void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
    getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
}

void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
void SurfaceFlinger::postComposition()
{
    ATRACE_CALL();
    ALOGV("postComposition");
@@ -1756,11 +1759,11 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
    nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
    nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();

    // We use the refreshStartTime which might be sampled a little later than
    // We use the mRefreshStartTime which might be sampled a little later than
    // when we started doing work for this frame, but that should be okay
    // since updateCompositorTiming has snapping logic.
    updateCompositorTiming(
        vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
        vsyncPhase, vsyncInterval, mRefreshStartTime, presentFenceTime);
    CompositorTiming compositorTiming;
    {
        std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
@@ -2074,18 +2077,16 @@ void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositi
            "[SF] Failed to set surface damage: %s (%d)",
            to_string(error).c_str(), static_cast<int32_t>(error));

    if (compositionInfo.updateBuffer) {
    error = (*compositionInfo.hwc.hwcLayer)->setBuffer(compositionInfo.mBufferSlot,
            compositionInfo.mBuffer, compositionInfo.hwc.fence);
    ALOGE_IF(error != HWC2::Error::None,
            "[SF] Failed to set buffer: %s (%d)",
            to_string(error).c_str(), static_cast<int32_t>(error));
}
}

void SurfaceFlinger::setUpHWComposer() {
    ATRACE_CALL();
    ALOGV("setUpHWComposer");
void SurfaceFlinger::beginFrame()
{
    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
@@ -2115,13 +2116,25 @@ void SurfaceFlinger::setUpHWComposer() {
            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
        }
    }
}

void SurfaceFlinger::prepareFrame()
{
        ATRACE_NAME("Programming_HWCOMPOSER");
        for (auto compositionInfo : getBE().mCompositionInfo) {
            ALOGV("[SF] hwcLayer=%p(%lu), compositionType=%d",
                  static_cast<HWC2::Layer*>(*compositionInfo.hwc.hwcLayer),
                  compositionInfo.hwc.hwcLayer.use_count(), compositionInfo.compositionType);
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        if (!displayDevice->isDisplayOn()) {
            continue;
        }

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

void SurfaceFlinger::setUpHWComposer(const CompositionInfo& compositionInfo) {
    ATRACE_CALL();
    ALOGV("setUpHWComposer");

    switch (compositionInfo.compositionType)
    {
@@ -2144,20 +2157,6 @@ void SurfaceFlinger::setUpHWComposer() {
            break;
    }
}
        getBE().mCompositionInfo.clear();
    }

    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        if (!displayDevice->isDisplayOn()) {
            continue;
        }

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

void SurfaceFlinger::doComposition() {
    ATRACE_CALL();
+15 −3
Original line number Diff line number Diff line
@@ -615,8 +615,8 @@ private:
    void computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
            Region& dirtyRegion, Region& opaqueRegion);

    void preComposition(nsecs_t refreshStartTime);
    void postComposition(nsecs_t refreshStartTime);
    void preComposition();
    void postComposition();
    void updateCompositorTiming(
            nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
            std::shared_ptr<FenceTime>& presentFenceTime);
@@ -634,7 +634,18 @@ private:
    mat4 computeSaturationMatrix() const;

    void calculateWorkingSet();
    void setUpHWComposer();
    /*
     * beginFrame - This function handles any pre-frame processing that needs to be
     * prior to any CompositionInfo handling and is not dependent on data in
     * CompositionInfo
     */
    void beginFrame();
    /* prepareFrame - This function will call into the DisplayDevice to prepare a
     * frame after CompositionInfo has been programmed.   This provides a mechanism
     * to prepare the hardware composer
     */
    void prepareFrame();
    void setUpHWComposer(const CompositionInfo& compositionInfo);
    void doComposition();
    void doDebugFlashRegions();
    void doTracing(const char* where);
@@ -812,6 +823,7 @@ private:
    Mutex mHWVsyncLock;
    bool mPrimaryHWVsyncEnabled;
    bool mHWVsyncAvailable;
    nsecs_t mRefreshStartTime;

    std::atomic<bool> mRefreshPending{false};