Moving DispSync into Scheduler.
This change is part of go/surface-flinger-scheduler.
Test: SF tests pass.
Change-Id: I073a54c2111fa3146af3eb68f3294c3c5c95543c
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index ab9a2f8..06e8a98 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -230,10 +230,13 @@
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.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 54e19c7..18a8bb1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -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 @@
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 @@
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
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index d7c9651..fdafe58 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -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 @@
class ConnectionHandle : public BBinder {
public:
ConnectionHandle(int64_t id) : id(id) {}
+
~ConnectionHandle() = default;
+
const int64_t id;
};
@@ -47,6 +53,7 @@
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 @@
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 @@
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
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 23281c2..f0723e8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -584,15 +584,14 @@
// 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 @@
return BAD_VALUE;
}
- // FIXME for now we always return stats for the primary display
- memset(stats, 0, sizeof(*stats));
- stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
- stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
+ // 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,13 +1248,17 @@
const auto activeConfig = getHwComposer().getActiveConfig(displayId);
const nsecs_t period = activeConfig->getVsyncPeriod();
- mPrimaryDispSync->reset();
- mPrimaryDispSync->setPeriod(period);
+ if (mUseScheduler) {
+ mScheduler->setVsyncPeriod(period);
+ } else {
+ mPrimaryDispSync->reset();
+ mPrimaryDispSync->setPeriod(period);
- if (!mPrimaryHWVsyncEnabled) {
- mPrimaryDispSync->beginResync();
- mEventControlThread->setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
+ if (!mPrimaryHWVsyncEnabled) {
+ mPrimaryDispSync->beginResync();
+ mEventControlThread->setVsyncEnabled(true);
+ mPrimaryHWVsyncEnabled = true;
+ }
}
}
@@ -1300,19 +1306,22 @@
return;
}
- bool needsHwVsync = false;
-
- { // Scope for the lock
- Mutex::Autolock _l(mHWVsyncLock);
- if (mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
- }
- }
-
- if (needsHwVsync) {
- enableHardwareVsync();
+ if (mUseScheduler) {
+ mScheduler->addResyncSample(timestamp);
} else {
- disableHardwareVsync(false);
+ bool needsHwVsync = false;
+ { // Scope for the lock
+ Mutex::Autolock _l(mHWVsyncLock);
+ if (mPrimaryHWVsyncEnabled) {
+ needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
+ }
+ }
+
+ if (needsHwVsync) {
+ enableHardwareVsync();
+ } else {
+ disableHardwareVsync(false);
+ }
}
}
@@ -1364,7 +1373,11 @@
// Note: it is assumed the caller holds |mStateLock| when this is called
void SurfaceFlinger::resetDisplayState() {
- disableHardwareVsync(true);
+ 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 @@
// The present fences returned from vr_hwc are not an accurate
// representation of vsync times.
- mPrimaryDispSync->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() ||
- !hasSyncFramework);
+ 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,9 +1754,8 @@
}
}
-void SurfaceFlinger::updateCompositorTiming(
- nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
- std::shared_ptr<FenceTime>& presentFenceTime) {
+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.
getBE().mCompositePresentTimes.push({compositeTime, presentFenceTime});
@@ -1760,21 +1777,20 @@
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 @@
// 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 @@
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,16 +1868,24 @@
});
if (presentFenceTime->isValid()) {
- if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
- enableHardwareVsync();
+ if (mUseScheduler) {
+ mScheduler->addPresentFence(presentFenceTime);
} else {
- disableHardwareVsync(false);
+ if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
+ enableHardwareVsync();
+ } else {
+ disableHardwareVsync(false);
+ }
}
}
if (!hasSyncFramework) {
if (display && getHwComposer().isConnected(display->getId()) && display->isPoweredOn()) {
- enableHardwareVsync();
+ if (mUseScheduler) {
+ mScheduler->enableHardwareVsync();
+ } else {
+ enableHardwareVsync();
+ }
}
}
@@ -1892,7 +1919,7 @@
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 @@
// 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 @@
}
if (display->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
- disableHardwareVsync(true); // also cancels any in-progress resync
-
+ 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 @@
} else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
// Leave display going to doze
if (display->isPrimary()) {
- disableHardwareVsync(true); // also cancels any in-progress resync
+ 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 @@
// 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,9 +5197,17 @@
}
if ((frequencyScaler.multiplier == 1) && (frequencyScaler.divisor == 1)) {
- enableHardwareVsync();
+ if (mUseScheduler) {
+ mScheduler->enableHardwareVsync();
+ } else {
+ enableHardwareVsync();
+ }
} else {
- disableHardwareVsync(true);
+ if (mUseScheduler) {
+ mScheduler->disableHardwareVsync(true);
+ } else {
+ disableHardwareVsync(true);
+ }
}
mPrimaryDispSync->scalePeriod(frequencyScaler);
getBE().mHwc->setDisplayFrequencyScaleParameters(frequencyScaler);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 19dcee7..f535c4e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -662,12 +662,10 @@
void preComposition();
void postComposition();
- void updateCompositorTiming(
- nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
- std::shared_ptr<FenceTime>& presentFenceTime);
- void setCompositorTimingSnapped(
- nsecs_t vsyncPhase, nsecs_t vsyncInterval,
- nsecs_t compositeToPresentLatency);
+ void updateCompositorTiming(const DisplayStatInfo& stats, nsecs_t compositeTime,
+ std::shared_ptr<FenceTime>& presentFenceTime);
+ void setCompositorTimingSnapped(const DisplayStatInfo& stats,
+ nsecs_t compositeToPresentLatency);
void rebuildLayerStacks();
ui::Dataspace getBestDataspace(const sp<const DisplayDevice>& display,
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index df0d982..be91a9c 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -6,8 +6,11 @@
#include <log/log.h>
+#include <mutex>
+
#include "AsyncCallRecorder.h"
#include "Scheduler/DispSync.h"
+#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/Scheduler.h"
#include "mock/MockDispSync.h"
@@ -37,7 +40,7 @@
class MockScheduler : public android::Scheduler {
public:
MockScheduler(std::unique_ptr<EventThread> eventThread)
- : mEventThread(std::move(eventThread)) {}
+ : Scheduler([](bool) {}), mEventThread(std::move(eventThread)) {}
std::unique_ptr<EventThread> makeEventThread(
const std::string& /* connectionName */, DispSync* /* dispSync */,
@@ -81,9 +84,9 @@
EXPECT_CALL(*mEventThread, createEventConnection())
.WillRepeatedly(Return(mEventThreadConnection));
- mConnectionHandle = mScheduler->createConnection("appConnection", mPrimaryDispSync, 16,
- mResyncCallRecorder.getInvocable(),
- mInterceptVSyncCallRecorder.getInvocable());
+ mConnectionHandle =
+ mScheduler->createConnection("appConnection", 16, mResyncCallRecorder.getInvocable(),
+ mInterceptVSyncCallRecorder.getInvocable());
}
SchedulerTest::~SchedulerTest() {