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

Commit b38c1e0c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "b:140112642:2" into qt-surfaceflinger-dev

* changes:
  [SurfaceFlinger] correct present time for negative phase offsets
  SurfaceFlinger: HWVsync when display is off
parents 7b6c15f8 746654af
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ bool BufferQueueLayer::framePresentTimeIsCurrent() const {
    }

    Mutex::Autolock lock(mQueueItemLock);
    return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime();
    return mQueueItems[0].mTimestamp <= mFlinger->getExpectedPresentTime();
}

nsecs_t BufferQueueLayer::getDesiredPresentTime() {
+1 −1
Original line number Diff line number Diff line
@@ -380,7 +380,7 @@ bool BufferStateLayer::framePresentTimeIsCurrent() const {
        return true;
    }

    return mDesiredPresentTime <= mFlinger->mScheduler->expectedPresentTime();
    return mDesiredPresentTime <= mFlinger->getExpectedPresentTime();
}

nsecs_t BufferStateLayer::getDesiredPresentTime() {
+36 −5
Original line number Diff line number Diff line
@@ -1543,10 +1543,25 @@ void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDispl

void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) {
    ATRACE_CALL();
    Mutex::Autolock lock(mStateLock);

    // Enable / Disable HWVsync from the main thread to avoid race conditions with
    // display power state.
    postMessageAsync(new LambdaMessage(
            [=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); }));
}

void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) {
    ATRACE_CALL();

    if (const auto displayId = getInternalDisplayIdLocked()) {
        sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
        if (display && display->isPoweredOn()) {
            getHwComposer().setVsyncEnabled(*displayId,
                                            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
        } else {
            // Cache the latest vsync state and apply it when screen is on again
            mEnableHWVsyncScreenOn = enabled;
        }
    }
}

@@ -1656,6 +1671,18 @@ bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
    return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
}

nsecs_t SurfaceFlinger::getExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
    DisplayStatInfo stats;
    mScheduler->getDisplayStatInfo(&stats);
    const nsecs_t presentTime = mScheduler->expectedPresentTime();
    // Inflate the expected present time if we're targetting the next vsync.
    const nsecs_t correctedTime =
            mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
            ? presentTime
            : presentTime + stats.vsyncPeriod;
    return correctedTime;
}

void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
    switch (what) {
@@ -3264,8 +3291,7 @@ bool SurfaceFlinger::handlePageFlip()
    mDrawingState.traverseInZOrder([&](Layer* layer) {
        if (layer->hasReadyFrame()) {
            frameQueued = true;
            nsecs_t expectedPresentTime;
            expectedPresentTime = mScheduler->expectedPresentTime();
            const nsecs_t expectedPresentTime = getExpectedPresentTime();
            if (layer->shouldPresentNow(expectedPresentTime)) {
                mLayersWithQueuedFrames.push_back(layer);
            } else {
@@ -4451,6 +4477,11 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
        // Turn on the display
        getHwComposer().setPowerMode(*displayId, mode);
        if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
            if (mEnableHWVsyncScreenOn) {
                setPrimaryVsyncEnabledInternal(mEnableHWVsyncScreenOn);
                mEnableHWVsyncScreenOn = false;
            }

            mScheduler->onScreenAcquired(mAppConnectionHandle);
            mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
        }
+11 −0
Original line number Diff line number Diff line
@@ -293,11 +293,19 @@ public:
    // TODO: this should be made accessible only to EventThread
    void setPrimaryVsyncEnabled(bool enabled);

    // main thread function to enable/disable h/w composer event
    void setPrimaryVsyncEnabledInternal(bool enabled);

    // called on the main thread by MessageQueue when an internal message
    // is received
    // TODO: this should be made accessible only to MessageQueue
    void onMessageReceived(int32_t what);

    // Returns the expected present time for this frame.
    // When we are in negative offsets, we perform a correction so that the
    // predicted vsync for the *next* frame is used instead.
    nsecs_t getExpectedPresentTime();

    // for debugging only
    // TODO: this should be made accessible only to HWComposer
    const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);
@@ -1169,6 +1177,9 @@ private:
    // The Layer pointer is removed from the set when the destructor is called so there shouldn't
    // be any issues with a raw pointer referencing an invalid object.
    std::unordered_set<Layer*> mOffscreenLayers;

    // Flag to indicate whether to re-enable HWVsync when screen is on
    bool mEnableHWVsyncScreenOn = false;
};

} // namespace android