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

Commit e588e318 authored by Ana Krulec's avatar Ana Krulec
Browse files

Moving DispSync into Scheduler.

This change is part of go/surface-flinger-scheduler.

Test: SF tests pass.
Change-Id: I073a54c2111fa3146af3eb68f3294c3c5c95543c
parent 7ecce8c6
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -230,10 +230,13 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                    getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);

    const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
            ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
            : mFlinger->mPrimaryDispSync->expectedPresentTime();
    status_t updateResult =
            mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync->expectedPresentTime(),
                                      &mAutoRefresh, &queuedBuffer, mLastFrameNumberReceived,
                                      releaseFence);
            mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
                                      mLastFrameNumberReceived, releaseFence);
    if (updateResult == BufferQueue::PRESENT_LATER) {
        // Producer doesn't want buffer to be displayed yet.  Signal a
        // layer update so we check again at the next opportunity.
+90 −2
Original line number Diff line number Diff line
@@ -20,15 +20,25 @@
#include <cstdint>
#include <memory>

#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>

#include <gui/ISurfaceComposer.h>
#include <ui/DisplayStatInfo.h>

#include "DispSync.h"
#include "DispSyncSource.h"
#include "EventControlThread.h"
#include "EventThread.h"
#include "InjectVSyncSource.h"

namespace android {

using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;

#define RETURN_VALUE_IF_INVALID(value) \
    if (handle == nullptr || mConnections.count(handle->id) == 0) return value
#define RETURN_IF_INVALID() \
@@ -36,17 +46,34 @@ namespace android {

std::atomic<int64_t> Scheduler::sNextId = 0;

Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function)
      : mHasSyncFramework(
                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasSyncFramework>(true)),
        mDispSyncPresentTimeOffset(
                getInt64<ISurfaceFlingerConfigs,
                         &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0)),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false) {
    // Note: We create a local temporary with the real DispSync implementation
    // type temporarily so we can initialize it with the configured values,
    // before storing it for more generic use using the interface type.
    auto primaryDispSync = std::make_unique<impl::DispSync>("SchedulerDispSync");
    primaryDispSync->init(mHasSyncFramework, mDispSyncPresentTimeOffset);
    mPrimaryDispSync = std::move(primaryDispSync);
    mEventControlThread = std::make_unique<impl::EventControlThread>(function);
}

Scheduler::~Scheduler() = default;

sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
        const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
        const std::string& connectionName, int64_t phaseOffsetNs,
        impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
    const int64_t id = sNextId++;
    ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);

    std::unique_ptr<EventThread> eventThread =
            makeEventThread(connectionName, dispSync, phaseOffsetNs, resyncCallback,
            makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs, resyncCallback,
                            interceptCallback);
    auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
                                                   eventThread->createEventConnection(),
@@ -108,4 +135,65 @@ void Scheduler::setPhaseOffset(const sp<Scheduler::ConnectionHandle>& handle, ns
    RETURN_IF_INVALID();
    mConnections[handle->id]->thread->setPhaseOffset(phaseOffset);
}

void Scheduler::getDisplayStatInfo(DisplayStatInfo* stats) {
    stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
    stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
}

void Scheduler::enableHardwareVsync() {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
        mPrimaryDispSync->beginResync();
        mEventControlThread->setVsyncEnabled(true);
        mPrimaryHWVsyncEnabled = true;
    }
}

void Scheduler::disableHardwareVsync(bool makeUnavailable) {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    if (mPrimaryHWVsyncEnabled) {
        mEventControlThread->setVsyncEnabled(false);
        mPrimaryDispSync->endResync();
        mPrimaryHWVsyncEnabled = false;
    }
    if (makeUnavailable) {
        mHWVsyncAvailable = false;
    }
}

void Scheduler::setVsyncPeriod(const nsecs_t period) {
    mPrimaryDispSync->reset();
    mPrimaryDispSync->setPeriod(period);
    enableHardwareVsync();
}

void Scheduler::addResyncSample(const nsecs_t timestamp) {
    bool needsHwVsync = false;
    { // Scope for the lock
        std::lock_guard<std::mutex> lock(mHWVsyncLock);
        if (mPrimaryHWVsyncEnabled) {
            needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
        }
    }

    if (needsHwVsync) {
        enableHardwareVsync();
    } else {
        disableHardwareVsync(false);
    }
}

void Scheduler::addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) {
    if (mPrimaryDispSync->addPresentFence(fenceTime)) {
        enableHardwareVsync();
    } else {
        disableHardwareVsync(false);
    }
}

void Scheduler::setIgnorePresentFences(bool ignore) {
    mPrimaryDispSync->setIgnorePresentFences(ignore);
}

} // namespace android
+46 −2
Original line number Diff line number Diff line
@@ -20,13 +20,17 @@
#include <memory>

#include <gui/ISurfaceComposer.h>
#include <ui/DisplayStatInfo.h>

#include "DispSync.h"
#include "EventControlThread.h"
#include "EventThread.h"
#include "InjectVSyncSource.h"

namespace android {

class EventControlThread;

class Scheduler {
public:
    // Enum to indicate whether to start the transaction early, or at vsync time.
@@ -38,7 +42,9 @@ public:
    class ConnectionHandle : public BBinder {
    public:
        ConnectionHandle(int64_t id) : id(id) {}

        ~ConnectionHandle() = default;

        const int64_t id;
    };

@@ -47,6 +53,7 @@ public:
        Connection(sp<ConnectionHandle> handle, sp<BnDisplayEventConnection> eventConnection,
                   std::unique_ptr<EventThread> eventThread)
              : handle(handle), eventConnection(eventConnection), thread(std::move(eventThread)) {}

        ~Connection() = default;

        sp<ConnectionHandle> handle;
@@ -54,32 +61,48 @@ public:
        const std::unique_ptr<EventThread> thread;
    };

    Scheduler() = default;
    explicit Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function);

    virtual ~Scheduler();

    /** Creates an EventThread connection. */
    sp<ConnectionHandle> createConnection(
            const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
            const std::string& connectionName, int64_t phaseOffsetNs,
            impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
            impl::EventThread::InterceptVSyncsCallback interceptCallback);

    sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle);

    // Getter methods.
    EventThread* getEventThread(const sp<ConnectionHandle>& handle);

    sp<BnDisplayEventConnection> getEventConnection(const sp<ConnectionHandle>& handle);

    // Should be called when receiving a hotplug event.
    void hotplugReceived(const sp<ConnectionHandle>& handle, EventThread::DisplayType displayType,
                         bool connected);

    // Should be called after the screen is turned on.
    void onScreenAcquired(const sp<ConnectionHandle>& handle);

    // Should be called before the screen is turned off.
    void onScreenReleased(const sp<ConnectionHandle>& handle);

    // Should be called when dumpsys command is received.
    void dump(const sp<ConnectionHandle>& handle, String8& result) const;

    // Offers ability to modify phase offset in the event thread.
    void setPhaseOffset(const sp<ConnectionHandle>& handle, nsecs_t phaseOffset);

    void getDisplayStatInfo(DisplayStatInfo* stats);

    void enableHardwareVsync();
    void disableHardwareVsync(bool makeUnavailable);
    void setVsyncPeriod(const nsecs_t period);
    void addResyncSample(const nsecs_t timestamp);
    void addPresentFence(const std::shared_ptr<FenceTime>& fenceTime);
    void setIgnorePresentFences(bool ignore);

protected:
    virtual std::unique_ptr<EventThread> makeEventThread(
            const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
@@ -87,8 +110,29 @@ protected:
            impl::EventThread::InterceptVSyncsCallback interceptCallback);

private:
    // TODO(b/113612090): Instead of letting BufferQueueLayer to access mDispSync directly, it
    // should make request to Scheduler to compute next refresh.
    friend class BufferQueueLayer;

    // If fences from sync Framework are supported.
    const bool mHasSyncFramework;

    // The offset in nanoseconds to use, when DispSync timestamps present fence
    // signaling time.
    const nsecs_t mDispSyncPresentTimeOffset;

    // Each connection has it's own ID. This variable keeps track of the count.
    static std::atomic<int64_t> sNextId;

    // Connections are stored in a map <connection ID, connection> for easy retrieval.
    std::unordered_map<int64_t, std::unique_ptr<Connection>> mConnections;

    std::mutex mHWVsyncLock;
    bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock);
    bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock);

    std::unique_ptr<DispSync> mPrimaryDispSync;
    std::unique_ptr<EventControlThread> mEventControlThread;
};

} // namespace android
 No newline at end of file
+107 −63
Original line number Diff line number Diff line
@@ -584,15 +584,14 @@ void SurfaceFlinger::init() {

    // start the EventThread
    if (mUseScheduler) {
        mScheduler = std::make_unique<Scheduler>();
        mScheduler = std::make_unique<Scheduler>(
                [this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); });
        mAppConnectionHandle =
                mScheduler->createConnection("appConnection", mPrimaryDispSync.get(),
                                             SurfaceFlinger::vsyncPhaseOffsetNs,
                mScheduler->createConnection("appConnection", SurfaceFlinger::vsyncPhaseOffsetNs,
                                             [this] { resyncWithRateLimit(); },
                                             impl::EventThread::InterceptVSyncsCallback());
        mSfConnectionHandle =
                mScheduler->createConnection("sfConnection", mPrimaryDispSync.get(),
                                             SurfaceFlinger::sfVsyncPhaseOffsetNs,
                mScheduler->createConnection("sfConnection", SurfaceFlinger::sfVsyncPhaseOffsetNs,
                                             [this] { resyncWithRateLimit(); },
                                             [this](nsecs_t timestamp) {
                                                 mInterceptor->saveVSyncEvent(timestamp);
@@ -912,10 +911,13 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>&, DisplayStatInfo* st
        return BAD_VALUE;
    }

    // FIXME for now we always return stats for the primary display
    memset(stats, 0, sizeof(*stats));
    // FIXME for now we always return stats for the primary display.
    if (mUseScheduler) {
        mScheduler->getDisplayStatInfo(stats);
    } else {
        stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
        stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
    }
    return NO_ERROR;
}

@@ -1246,6 +1248,9 @@ void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
    const auto activeConfig = getHwComposer().getActiveConfig(displayId);
    const nsecs_t period = activeConfig->getVsyncPeriod();

    if (mUseScheduler) {
        mScheduler->setVsyncPeriod(period);
    } else {
        mPrimaryDispSync->reset();
        mPrimaryDispSync->setPeriod(period);

@@ -1255,6 +1260,7 @@ void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
            mPrimaryHWVsyncEnabled = true;
        }
    }
}

void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
    Mutex::Autolock _l(mHWVsyncLock);
@@ -1300,8 +1306,10 @@ void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDispl
        return;
    }

    if (mUseScheduler) {
        mScheduler->addResyncSample(timestamp);
    } else {
        bool needsHwVsync = false;

        { // Scope for the lock
            Mutex::Autolock _l(mHWVsyncLock);
            if (mPrimaryHWVsyncEnabled) {
@@ -1315,6 +1323,7 @@ void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDispl
            disableHardwareVsync(false);
        }
    }
}

void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
    std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
@@ -1364,7 +1373,11 @@ void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {

// Note: it is assumed the caller holds |mStateLock| when this is called
void SurfaceFlinger::resetDisplayState() {
    if (mUseScheduler) {
        mScheduler->disableHardwareVsync(true);
    } else {
        disableHardwareVsync(true);
    }
    // Clear the drawing state so that the logic inside of
    // handleTransactionLocked will fire. It will determine the delta between
    // mCurrentState and mDrawingState and re-apply all changes when we make the
@@ -1432,12 +1445,17 @@ void SurfaceFlinger::updateVrFlinger() {

    // The present fences returned from vr_hwc are not an accurate
    // representation of vsync times.
    if (mUseScheduler) {
        mScheduler->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() || !hasSyncFramework);
    } else {
        mPrimaryDispSync->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() ||
                                                 !hasSyncFramework);
    }

    // Use phase of 0 since phase is not known.
    // Use latency of 0, which will snap to the ideal latency.
    setCompositorTimingSnapped(0, period, 0);
    DisplayStatInfo stats{0 /* vsyncTime */, period /* vsyncPeriod */};
    setCompositorTimingSnapped(stats, 0);

    resyncToHardwareVsync(false);

@@ -1736,8 +1754,7 @@ void SurfaceFlinger::preComposition()
    }
}

void SurfaceFlinger::updateCompositorTiming(
        nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
void SurfaceFlinger::updateCompositorTiming(const DisplayStatInfo& stats, nsecs_t compositeTime,
                                            std::shared_ptr<FenceTime>& presentFenceTime) {
    // Update queue of past composite+present times and determine the
    // most recently known composite to present latency.
@@ -1760,21 +1777,20 @@ void SurfaceFlinger::updateCompositorTiming(
        getBE().mCompositePresentTimes.pop();
    }

    setCompositorTimingSnapped(
            vsyncPhase, vsyncInterval, compositeToPresentLatency);
    setCompositorTimingSnapped(stats, compositeToPresentLatency);
}

void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
void SurfaceFlinger::setCompositorTimingSnapped(const DisplayStatInfo& stats,
                                                nsecs_t compositeToPresentLatency) {
    // Integer division and modulo round toward 0 not -inf, so we need to
    // treat negative and positive offsets differently.
    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
            (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
            ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0)
            ? (stats.vsyncPeriod - (sfVsyncPhaseOffsetNs % stats.vsyncPeriod))
            : ((-sfVsyncPhaseOffsetNs) % stats.vsyncPeriod);

    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
    if (idealLatency <= 0) {
        idealLatency = vsyncInterval;
        idealLatency = stats.vsyncPeriod;
    }

    // Snap the latency to a value that removes scheduling jitter from the
@@ -1783,15 +1799,14 @@ void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
    // something (such as user input) to an accurate diasplay time.
    // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
    // with (presentLatency % interval).
    nsecs_t bias = vsyncInterval / 2;
    int64_t extraVsyncs =
            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
    nsecs_t bias = stats.vsyncPeriod / 2;
    int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / stats.vsyncPeriod;
    nsecs_t snappedCompositeToPresentLatency =
            (extraVsyncs > 0) ? idealLatency + (extraVsyncs * stats.vsyncPeriod) : idealLatency;

    std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
    getBE().mCompositorTiming.deadline = vsyncPhase - idealLatency;
    getBE().mCompositorTiming.interval = vsyncInterval;
    getBE().mCompositorTiming.deadline = stats.vsyncTime - idealLatency;
    getBE().mCompositorTiming.interval = stats.vsyncPeriod;
    getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
}

@@ -1825,14 +1840,18 @@ void SurfaceFlinger::postComposition()
    auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
    getBE().mDisplayTimeline.push(presentFenceTime);

    nsecs_t vsyncPhase = mPrimaryDispSync->computeNextRefresh(0);
    nsecs_t vsyncInterval = mPrimaryDispSync->getPeriod();
    DisplayStatInfo stats;
    if (mUseScheduler) {
        mScheduler->getDisplayStatInfo(&stats);
    } else {
        stats.vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
        stats.vsyncPeriod = mPrimaryDispSync->getPeriod();
    }

    // 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, mRefreshStartTime, presentFenceTime);
    updateCompositorTiming(stats, mRefreshStartTime, presentFenceTime);
    CompositorTiming compositorTiming;
    {
        std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
@@ -1849,18 +1868,26 @@ void SurfaceFlinger::postComposition()
    });

    if (presentFenceTime->isValid()) {
        if (mUseScheduler) {
            mScheduler->addPresentFence(presentFenceTime);
        } else {
            if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
                enableHardwareVsync();
            } else {
                disableHardwareVsync(false);
            }
        }
    }

    if (!hasSyncFramework) {
        if (display && getHwComposer().isConnected(display->getId()) && display->isPoweredOn()) {
            if (mUseScheduler) {
                mScheduler->enableHardwareVsync();
            } else {
                enableHardwareVsync();
            }
        }
    }

    if (mAnimCompositionPending) {
        mAnimCompositionPending = false;
@@ -1892,7 +1919,7 @@ void SurfaceFlinger::postComposition()
        mHasPoweredOff = false;
    } else {
        nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime;
        size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
        size_t numPeriods = static_cast<size_t>(elapsedTime / stats.vsyncPeriod);
        if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) {
            getBE().mFrameBuckets[numPeriods] += elapsedTime;
        } else {
@@ -3991,7 +4018,8 @@ void SurfaceFlinger::onInitializeDisplays() {

    // Use phase of 0 since phase is not known.
    // Use latency of 0, which will snap to the ideal latency.
    setCompositorTimingSnapped(0, period, 0);
    DisplayStatInfo stats{0 /* vsyncTime */, period /* vsyncPeriod */};
    setCompositorTimingSnapped(stats, 0);
}

void SurfaceFlinger::initializeDisplays() {
@@ -4057,8 +4085,11 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
        }

        if (display->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
            if (mUseScheduler) {
                mScheduler->disableHardwareVsync(true);
            } else {
                disableHardwareVsync(true); // also cancels any in-progress resync

            }
            // FIXME: eventthread only knows about the main display right now
            if (mUseScheduler) {
                mScheduler->onScreenReleased(mAppConnectionHandle);
@@ -4086,7 +4117,11 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
    } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
        // Leave display going to doze
        if (display->isPrimary()) {
            if (mUseScheduler) {
                mScheduler->disableHardwareVsync(true);
            } else {
                disableHardwareVsync(true); // also cancels any in-progress resync
            }
            // FIXME: eventthread only knows about the main display right now
            if (mUseScheduler) {
                mScheduler->onScreenReleased(mAppConnectionHandle);
@@ -5033,6 +5068,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
            // Needs to be shifted to proper binder interface when we productize
            case 1016: {
                n = data.readInt32();
                // TODO(b/113612090): Evaluate if this can be removed.
                mPrimaryDispSync->setRefreshSkipCount(n);
                return NO_ERROR;
            }
@@ -5161,10 +5197,18 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
                }

                if ((frequencyScaler.multiplier == 1) && (frequencyScaler.divisor == 1)) {
                    if (mUseScheduler) {
                        mScheduler->enableHardwareVsync();
                    } else {
                        enableHardwareVsync();
                    }
                } else {
                    if (mUseScheduler) {
                        mScheduler->disableHardwareVsync(true);
                    } else {
                        disableHardwareVsync(true);
                    }
                }
                mPrimaryDispSync->scalePeriod(frequencyScaler);
                getBE().mHwc->setDisplayFrequencyScaleParameters(frequencyScaler);

+4 −6
Original line number Diff line number Diff line
@@ -662,11 +662,9 @@ private:

    void preComposition();
    void postComposition();
    void updateCompositorTiming(
            nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
    void updateCompositorTiming(const DisplayStatInfo& stats, nsecs_t compositeTime,
                                std::shared_ptr<FenceTime>& presentFenceTime);
    void setCompositorTimingSnapped(
            nsecs_t vsyncPhase, nsecs_t vsyncInterval,
    void setCompositorTimingSnapped(const DisplayStatInfo& stats,
                                    nsecs_t compositeToPresentLatency);
    void rebuildLayerStacks();

Loading