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

Commit d5193eb9 authored by Dan Stoza's avatar Dan Stoza Committed by android-build-merger
Browse files

HWC2: Backpressure missed vsyncs into apps

am: 05dacfb6

Change-Id: Ida8034e40f75be3063f06e66f3c8b4b870c2d2cd
parents 2605348b 05dacfb6
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -134,31 +134,12 @@ status_t MessageQueue::postMessage(
}


/* when INVALIDATE_ON_VSYNC is set SF only processes
 * buffer updates on VSYNC and performs a refresh immediately
 * after.
 *
 * when INVALIDATE_ON_VSYNC is set to false, SF will instead
 * perform the buffer updates immediately, but the refresh only
 * at the next VSYNC.
 * THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
 */
#define INVALIDATE_ON_VSYNC 1

void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
    mEvents->requestNextVsync();
#else
    mHandler->dispatchInvalidate();
#endif
}

void MessageQueue::refresh() {
#if INVALIDATE_ON_VSYNC
    mHandler->dispatchRefresh();
#else
    mEvents->requestNextVsync();
#endif
}

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
@@ -172,11 +153,7 @@ int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
        for (int i=0 ; i<n ; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
#if INVALIDATE_ON_VSYNC
                mHandler->dispatchInvalidate();
#else
                mHandler->dispatchRefresh();
#endif
                break;
            }
        }
+18 −27
Original line number Diff line number Diff line
@@ -167,9 +167,6 @@ SurfaceFlinger::SurfaceFlinger()
    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
    mGpuToCpuSupported = !atoi(value);

    property_get("debug.sf.drop_missed_frames", value, "0");
    mDropMissedFrames = atoi(value);

    property_get("debug.sf.showupdates", value, "0");
    mDebugRegion = atoi(value);

@@ -933,6 +930,14 @@ bool SurfaceFlinger::handleMessageTransaction() {

bool SurfaceFlinger::handleMessageInvalidate() {
    ATRACE_CALL();
    bool frameMissed = !mHadClientComposition &&
            mPreviousPresentFence != Fence::NO_FENCE &&
            mPreviousPresentFence->getSignalTime() == INT64_MAX;
    ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
    if (frameMissed) {
        signalLayerUpdate();
        return false;
    }
    return handlePageFlip();
}

@@ -940,36 +945,22 @@ void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
    static nsecs_t previousExpectedPresent = 0;
    nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);
    static bool previousFrameMissed = false;
    bool frameMissed = (expectedPresent == previousExpectedPresent);
    if (frameMissed != previousFrameMissed) {
        ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
    }
    previousFrameMissed = frameMissed;

    if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {
        // Latch buffers, but don't send anything to HWC, then signal another
        // wakeup for the next vsync
        preComposition();
        repaintEverything();
    } else {
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition(refreshStartTime);
    }

    mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
    mHadClientComposition = mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY);

    // Release any buffers which were replaced this frame
    for (auto& layer : mLayersWithQueuedFrames) {
        layer->releasePendingBuffer();
    }
    mLayersWithQueuedFrames.clear();

    previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}

void SurfaceFlinger::doDebugFlashRegions()
+2 −1
Original line number Diff line number Diff line
@@ -468,7 +468,6 @@ private:
    RenderEngine* mRenderEngine;
    nsecs_t mBootTime;
    bool mGpuToCpuSupported;
    bool mDropMissedFrames;
    sp<EventThread> mEventThread;
    sp<EventThread> mSFEventThread;
    sp<EventControlThread> mEventControlThread;
@@ -488,6 +487,8 @@ private:
    bool mAnimCompositionPending;
#ifdef USE_HWC2
    std::vector<sp<Layer>> mLayersWithQueuedFrames;
    sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
    bool mHadClientComposition = false;
#endif

    // this may only be written from the main thread with mStateLock held
+6 −26
Original line number Diff line number Diff line
@@ -166,9 +166,6 @@ SurfaceFlinger::SurfaceFlinger()
    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
    mGpuToCpuSupported = !atoi(value);

    property_get("debug.sf.drop_missed_frames", value, "0");
    mDropMissedFrames = atoi(value);

    property_get("debug.sf.showupdates", value, "0");
    mDebugRegion = atoi(value);

@@ -944,21 +941,7 @@ void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
    static nsecs_t previousExpectedPresent = 0;
    nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);
    static bool previousFrameMissed = false;
    bool frameMissed = (expectedPresent == previousExpectedPresent);
    if (frameMissed != previousFrameMissed) {
        ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
    }
    previousFrameMissed = frameMissed;

    if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {
        // Latch buffers, but don't send anything to HWC, then signal another
        // wakeup for the next vsync
        preComposition();
        repaintEverything();
    } else {

    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
@@ -967,9 +950,6 @@ void SurfaceFlinger::handleMessageRefresh() {
    postComposition(refreshStartTime);
}

    previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}

void SurfaceFlinger::doDebugFlashRegions()
{
    // is debugging enabled