Merge changes I91b38c51,Ic62bfb68
* changes:
[SurfaceFlinger] Allow DispSync to be GMock'd
[SurfaceFlinger] Hide SyncFeatures behind RenderEngine
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index d231790..8788d47 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -40,7 +40,6 @@
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
-#include <private/gui/SyncFeatures.h>
#include <utils/Log.h>
#include <utils/String8.h>
@@ -206,7 +205,7 @@
return err;
}
- if (!SyncFeatures::getInstance().useNativeFenceSync()) {
+ if (mRE.useNativeFenceSync()) {
// Bind the new buffer to the GL texture.
//
// Older devices require the "implicit" synchronization provided
@@ -374,7 +373,7 @@
BLC_LOGV("syncForReleaseLocked");
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- if (SyncFeatures::getInstance().useNativeFenceSync()) {
+ if (mRE.useNativeFenceSync()) {
base::unique_fd fenceFd = mRE.flush();
if (fenceFd == -1) {
BLC_LOGE("syncForReleaseLocked: failed to flush RenderEngine");
@@ -512,7 +511,7 @@
}
if (mCurrentFence->isValid()) {
- if (SyncFeatures::getInstance().useWaitSync()) {
+ if (mRE.useWaitSync()) {
base::unique_fd fenceFd(mCurrentFence->dup());
if (fenceFd == -1) {
BLC_LOGE("doFenceWait: error dup'ing fence fd: %d", errno);
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 80f741b..6c339b7 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -245,8 +245,9 @@
LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
getTransformToDisplayInverse(), mFreezeGeometryUpdates);
- status_t updateResult = mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh,
- &queuedBuffer, mLastFrameNumberReceived);
+ status_t updateResult =
+ mConsumer->updateTexImage(&r, *mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
+ mLastFrameNumberReceived);
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/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 829b53d..cdfbba3 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -40,6 +40,10 @@
namespace android {
+DispSync::~DispSync() = default;
+
+namespace impl {
+
// Setting this to true enables verbose tracing that can be used to debug
// vsync event model or phase issues.
static const bool kTraceDetailedInfo = false;
@@ -707,4 +711,6 @@
result.appendFormat("current monotonic time: %" PRId64 "\n", now);
}
+} // namespace impl
+
} // namespace android
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index c00c161..1be131f 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -31,6 +31,36 @@
class String8;
class FenceTime;
+
+class DispSync {
+public:
+ class Callback {
+ public:
+ virtual ~Callback() = default;
+ virtual void onDispSyncEvent(nsecs_t when) = 0;
+ };
+
+ virtual ~DispSync();
+
+ virtual void reset() = 0;
+ virtual bool addPresentFence(const std::shared_ptr<FenceTime>&) = 0;
+ virtual void beginResync() = 0;
+ virtual bool addResyncSample(nsecs_t timestamp) = 0;
+ virtual void endResync() = 0;
+ virtual void setPeriod(nsecs_t period) = 0;
+ virtual nsecs_t getPeriod() = 0;
+ virtual void setRefreshSkipCount(int count) = 0;
+ virtual status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) = 0;
+ virtual status_t removeEventListener(Callback* callback) = 0;
+ virtual status_t changePhaseOffset(Callback* callback, nsecs_t phase) = 0;
+ virtual nsecs_t computeNextRefresh(int periodOffset) const = 0;
+ virtual void setIgnorePresentFences(bool ignore) = 0;
+
+ virtual void dump(String8& result) const = 0;
+};
+
+namespace impl {
+
class DispSyncThread;
// DispSync maintains a model of the periodic hardware-based vsync events of a
@@ -46,21 +76,15 @@
// current model accurately represents the hardware event times it will return
// false to indicate that a resynchronization (via addResyncSample) is not
// needed.
-class DispSync {
+class DispSync : public android::DispSync {
public:
- class Callback {
- public:
- virtual ~Callback(){};
- virtual void onDispSyncEvent(nsecs_t when) = 0;
- };
-
explicit DispSync(const char* name);
- ~DispSync();
+ ~DispSync() override;
void init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset);
// reset clears the resync samples and error value.
- void reset();
+ void reset() override;
// addPresentFence adds a fence for use in validating the current vsync
// event model. The fence need not be signaled at the time
@@ -71,7 +95,7 @@
//
// This method should be called with the retire fence from each HWComposer
// set call that affects the display.
- bool addPresentFence(const std::shared_ptr<FenceTime>& fenceTime);
+ bool addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) override;
// The beginResync, addResyncSample, and endResync methods are used to re-
// synchronize the DispSync's model to the hardware vsync events. The re-
@@ -84,45 +108,45 @@
// is turned on (i.e. once immediately after it's turned on) and whenever
// addPresentFence returns true indicating that the model has drifted away
// from the hardware vsync events.
- void beginResync();
- bool addResyncSample(nsecs_t timestamp);
- void endResync();
+ void beginResync() override;
+ bool addResyncSample(nsecs_t timestamp) override;
+ void endResync() override;
// The setPeriod method sets the vsync event model's period to a specific
// value. This should be used to prime the model when a display is first
// turned on. It should NOT be used after that.
- void setPeriod(nsecs_t period);
+ void setPeriod(nsecs_t period) override;
// The getPeriod method returns the current vsync period.
- nsecs_t getPeriod();
+ nsecs_t getPeriod() override;
// setRefreshSkipCount specifies an additional number of refresh
// cycles to skip. For example, on a 60Hz display, a skip count of 1
// will result in events happening at 30Hz. Default is zero. The idea
// is to sacrifice smoothness for battery life.
- void setRefreshSkipCount(int count);
+ void setRefreshSkipCount(int count) override;
// addEventListener registers a callback to be called repeatedly at the
// given phase offset from the hardware vsync events. The callback is
// called from a separate thread and it should return reasonably quickly
// (i.e. within a few hundred microseconds).
- status_t addEventListener(const char* name, nsecs_t phase, Callback* callback);
+ status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) override;
// removeEventListener removes an already-registered event callback. Once
// this method returns that callback will no longer be called by the
// DispSync object.
- status_t removeEventListener(Callback* callback);
+ status_t removeEventListener(Callback* callback) override;
// changePhaseOffset changes the phase offset of an already-registered event callback. The
// method will make sure that there is no skipping or double-firing on the listener per frame,
// even when changing the offsets multiple times.
- status_t changePhaseOffset(Callback* callback, nsecs_t phase);
+ status_t changePhaseOffset(Callback* callback, nsecs_t phase) override;
// computeNextRefresh computes when the next refresh is expected to begin.
// The periodOffset value can be used to move forward or backward; an
// offset of zero is the next refresh, -1 is the previous refresh, 1 is
// the refresh after next. etc.
- nsecs_t computeNextRefresh(int periodOffset) const;
+ nsecs_t computeNextRefresh(int periodOffset) const override;
// In certain situations the present fences aren't a good indicator of vsync
// time, e.g. when vr flinger is active, or simply aren't available,
@@ -130,10 +154,10 @@
// whether or not DispSync ignores present fences. If present fences are
// ignored, DispSync will always ask for hardware vsync events by returning
// true from addPresentFence() and addResyncSample().
- void setIgnorePresentFences(bool ignore);
+ void setIgnorePresentFences(bool ignore) override;
// dump appends human-readable debug info to the result string.
- void dump(String8& result) const;
+ void dump(String8& result) const override;
private:
void updateModelLocked();
@@ -206,6 +230,8 @@
std::unique_ptr<Callback> mZeroPhaseTracer;
};
+} // namespace impl
+
} // namespace android
#endif // ANDROID_DISPSYNC_H
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 0b8b838..39f7e30 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -29,6 +29,7 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
+#include <private/gui/SyncFeatures.h>
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
@@ -175,6 +176,14 @@
return mEGLConfig;
}
+bool RenderEngine::useNativeFenceSync() const {
+ return SyncFeatures::getInstance().useNativeFenceSync();
+}
+
+bool RenderEngine::useWaitSync() const {
+ return SyncFeatures::getInstance().useWaitSync();
+}
+
bool RenderEngine::isCurrent() const {
return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 95b9ec8..40bc966 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -69,6 +69,9 @@
// dump the extension strings. always call the base class.
virtual void dump(String8& result) = 0;
+ virtual bool useNativeFenceSync() const = 0;
+ virtual bool useWaitSync() const = 0;
+
virtual bool isCurrent() const = 0;
virtual bool setCurrentSurface(const RE::Surface& surface) = 0;
virtual void resetCurrentSurface() = 0;
@@ -190,6 +193,9 @@
// dump the extension strings. always call the base class.
void dump(String8& result) override;
+ bool useNativeFenceSync() const override;
+ bool useWaitSync() const override;
+
bool isCurrent() const;
bool setCurrentSurface(const RE::Surface& surface) override;
void resetCurrentSurface() override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 399fbd8..31e4444 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -264,7 +264,6 @@
mDebugInTransaction(0),
mLastTransactionTime(0),
mForceFullDamage(false),
- mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mHasPoweredOff(false),
@@ -325,7 +324,13 @@
}
ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation);
- mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
+ // 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>("PrimaryDispSync");
+ primaryDispSync->init(SurfaceFlinger::hasSyncFramework,
+ SurfaceFlinger::dispSyncPresentTimeOffset);
+ mPrimaryDispSync = std::move(primaryDispSync);
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
@@ -703,14 +708,14 @@
// start the EventThread
mEventThreadSource =
- std::make_unique<DispSyncSource>(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs,
- true, "app");
+ std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
+ SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
mEventThread = std::make_unique<impl::EventThread>(mEventThreadSource.get(),
[this] { resyncWithRateLimit(); },
impl::EventThread::InterceptVSyncsCallback(),
"appEventThread");
mSfEventThreadSource =
- std::make_unique<DispSyncSource>(&mPrimaryDispSync,
+ std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread =
@@ -996,8 +1001,8 @@
// 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();
+ stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
+ stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
return NO_ERROR;
}
@@ -1295,7 +1300,7 @@
void SurfaceFlinger::enableHardwareVsync() {
Mutex::Autolock _l(mHWVsyncLock);
if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
- mPrimaryDispSync.beginResync();
+ mPrimaryDispSync->beginResync();
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -1320,11 +1325,11 @@
const auto activeConfig = getHwComposer().getActiveConfig(displayId);
const nsecs_t period = activeConfig->getVsyncPeriod();
- mPrimaryDispSync.reset();
- mPrimaryDispSync.setPeriod(period);
+ mPrimaryDispSync->reset();
+ mPrimaryDispSync->setPeriod(period);
if (!mPrimaryHWVsyncEnabled) {
- mPrimaryDispSync.beginResync();
+ mPrimaryDispSync->beginResync();
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -1334,7 +1339,7 @@
Mutex::Autolock _l(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
mEventControlThread->setVsyncEnabled(false);
- mPrimaryDispSync.endResync();
+ mPrimaryDispSync->endResync();
mPrimaryHWVsyncEnabled = false;
}
if (makeUnavailable) {
@@ -1379,7 +1384,7 @@
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
+ needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
}
}
@@ -1506,8 +1511,8 @@
// The present fences returned from vr_hwc are not an accurate
// representation of vsync times.
- mPrimaryDispSync.setIgnorePresentFences(
- getBE().mHwc->isUsingVrComposer() || !hasSyncFramework);
+ 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.
@@ -1770,8 +1775,8 @@
auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
getBE().mDisplayTimeline.push(presentFenceTime);
- nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
- nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
+ nsecs_t vsyncPhase = mPrimaryDispSync->computeNextRefresh(0);
+ nsecs_t vsyncInterval = mPrimaryDispSync->getPeriod();
// We use the refreshStartTime which might be sampled a little later than
// when we started doing work for this frame, but that should be okay
@@ -1794,7 +1799,7 @@
});
if (presentFenceTime->isValid()) {
- if (mPrimaryDispSync.addPresentFence(presentFenceTime)) {
+ if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
@@ -2873,7 +2878,7 @@
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasReadyFrame()) {
frameQueued = true;
- if (layer->shouldPresentNow(mPrimaryDispSync)) {
+ if (layer->shouldPresentNow(*mPrimaryDispSync)) {
mLayersWithQueuedFrames.push_back(layer);
} else {
layer->useEmptyDamage();
@@ -3966,7 +3971,7 @@
if ((index < numArgs) &&
(args[index] == String16("--dispsync"))) {
index++;
- mPrimaryDispSync.dump(result);
+ mPrimaryDispSync->dump(result);
dumpAll = false;
}
@@ -4749,7 +4754,7 @@
// Needs to be shifted to proper binder interface when we productize
case 1016: {
n = data.readInt32();
- mPrimaryDispSync.setRefreshSkipCount(n);
+ mPrimaryDispSync->setRefreshSkipCount(n);
return NO_ERROR;
}
case 1017: {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index eaaf742..12f4185 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -853,7 +853,7 @@
// these are thread safe
mutable std::unique_ptr<MessageQueue> mEventQueue{std::make_unique<impl::MessageQueue>()};
FrameTracker mAnimFrameTracker;
- DispSync mPrimaryDispSync;
+ std::unique_ptr<DispSync> mPrimaryDispSync;
int mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;
// protected by mDestroyedLayerLock;
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 95c54b8..8f1f5e5 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -27,6 +27,7 @@
"mock/DisplayHardware/MockPowerAdvisor.cpp",
"mock/gui/MockGraphicBufferConsumer.cpp",
"mock/gui/MockGraphicBufferProducer.cpp",
+ "mock/MockDispSync.cpp",
"mock/MockEventControlThread.cpp",
"mock/MockEventThread.cpp",
"mock/MockMessageQueue.cpp",
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 58d3879..508875d 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -25,6 +25,7 @@
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/DisplayHardware/MockDisplaySurface.h"
+#include "mock/MockDispSync.h"
#include "mock/MockEventControlThread.h"
#include "mock/MockEventThread.h"
#include "mock/MockMessageQueue.h"
@@ -119,6 +120,7 @@
Hwc2::mock::Composer* mComposer = nullptr;
mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
+ mock::DispSync* mPrimaryDispSync = new mock::DispSync();
// These mocks are created only when expected to be created via a factory.
sp<mock::GraphicBufferConsumer> mConsumer;
@@ -154,6 +156,7 @@
mFlinger.mutableEventQueue().reset(mMessageQueue);
mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
+ mFlinger.mutablePrimaryDispSync().reset(mPrimaryDispSync);
injectMockComposer(0);
}
@@ -961,6 +964,9 @@
// The call clears the current render engine surface
EXPECT_CALL(*mRenderEngine, resetCurrentSurface());
+ // The call ends any display resyncs
+ EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
+
// --------------------------------------------------------------------
// Invocation
@@ -2400,6 +2406,24 @@
}
};
+struct DispSyncIsSupportedVariant {
+ static void setupBeginResyncCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mPrimaryDispSync, reset()).Times(1);
+ EXPECT_CALL(*test->mPrimaryDispSync, setPeriod(DEFAULT_REFRESH_RATE)).Times(1);
+ EXPECT_CALL(*test->mPrimaryDispSync, beginResync()).Times(1);
+ }
+
+ static void setupEndResyncCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mPrimaryDispSync, endResync()).Times(1);
+ }
+};
+
+struct DispSyncNotSupportedVariant {
+ static void setupBeginResyncCallExpectations(DisplayTransactionTest* /* test */) {}
+
+ static void setupEndResyncCallExpectations(DisplayTransactionTest* /* test */) {}
+};
+
// --------------------------------------------------------------------
// Note:
//
@@ -2421,6 +2445,7 @@
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
+ Case::DispSync::setupBeginResyncCallExpectations(test);
Case::setupRepaintEverythingCallExpectations(test);
}
@@ -2450,6 +2475,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
+ Case::DispSync::setupEndResyncCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
}
@@ -2485,6 +2511,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
+ Case::DispSync::setupBeginResyncCallExpectations(test);
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
}
};
@@ -2503,6 +2530,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
+ Case::DispSync::setupBeginResyncCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
}
};
@@ -2512,6 +2540,7 @@
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
+ Case::DispSync::setupEndResyncCallExpectations(test);
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
}
};
@@ -2534,11 +2563,12 @@
// --------------------------------------------------------------------
template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
- typename TransitionVariant>
+ typename DispSyncVariant, typename TransitionVariant>
struct DisplayPowerCase {
using Display = DisplayVariant;
using Doze = DozeVariant;
using EventThread = EventThreadVariant;
+ using DispSync = DispSyncVariant;
using Transition = TransitionVariant;
static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
@@ -2586,15 +2616,16 @@
// In addition to having event thread support, we emulate doze support.
template <typename TransitionVariant>
using PrimaryDisplayPowerCase = DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant,
- EventThreadIsSupportedVariant, TransitionVariant>;
+ EventThreadIsSupportedVariant,
+ DispSyncIsSupportedVariant, TransitionVariant>;
// A sample configuration for the external display.
// In addition to not having event thread support, we emulate not having doze
// support.
template <typename TransitionVariant>
-using ExternalDisplayPowerCase =
- DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant,
- EventThreadNotSupportedVariant, TransitionVariant>;
+using ExternalDisplayPowerCase = DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant,
+ EventThreadNotSupportedVariant,
+ DispSyncNotSupportedVariant, TransitionVariant>;
class SetPowerModeInternalTest : public DisplayTransactionTest {
public:
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 5031148..9df4264 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -126,6 +126,7 @@
auto& mutableInterceptor() { return mFlinger->mInterceptor; }
auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
+ auto& mutablePrimaryDispSync() { return mFlinger->mPrimaryDispSync; }
auto& mutablePrimaryHWVsyncEnabled() { return mFlinger->mPrimaryHWVsyncEnabled; }
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
@@ -144,6 +145,7 @@
mutableEventQueue().reset();
mutableEventThread().reset();
mutableInterceptor().reset();
+ mutablePrimaryDispSync().reset();
mFlinger->getBE().mHwc.reset();
mFlinger->getBE().mRenderEngine.reset();
}
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp b/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp
new file mode 100644
index 0000000..2f7e5ea
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mock/MockDispSync.h"
+
+namespace android {
+namespace mock {
+
+// Explicit default instantiation is recommended.
+DispSync::DispSync() = default;
+DispSync::~DispSync() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
new file mode 100644
index 0000000..4a466ef
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include <utils/String8.h>
+#include "DispSync.h"
+
+namespace android {
+namespace mock {
+
+class DispSync : public android::DispSync {
+public:
+ DispSync();
+ ~DispSync() override;
+
+ MOCK_METHOD0(reset, void());
+ MOCK_METHOD1(addPresentFence, bool(const std::shared_ptr<FenceTime>&));
+ MOCK_METHOD0(beginResync, void());
+ MOCK_METHOD1(addResyncSample, bool(nsecs_t));
+ MOCK_METHOD0(endResync, void());
+ MOCK_METHOD1(setPeriod, void(nsecs_t));
+ MOCK_METHOD0(getPeriod, nsecs_t());
+ MOCK_METHOD1(setRefreshSkipCount, void(int));
+ MOCK_METHOD3(addEventListener, status_t(const char*, nsecs_t, Callback*));
+ MOCK_METHOD1(removeEventListener, status_t(Callback*));
+ MOCK_METHOD2(changePhaseOffset, status_t(Callback*, nsecs_t));
+ MOCK_CONST_METHOD1(computeNextRefresh, nsecs_t(int));
+ MOCK_METHOD1(setIgnorePresentFences, void(bool));
+
+ MOCK_CONST_METHOD1(dump, void(String8&));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 7caf864..7814d32 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -37,6 +37,8 @@
MOCK_METHOD0(createImage, std::unique_ptr<RE::Image>());
MOCK_CONST_METHOD0(primeCache, void());
MOCK_METHOD1(dump, void(String8&));
+ MOCK_CONST_METHOD0(useNativeFenceSync, bool());
+ MOCK_CONST_METHOD0(useWaitSync, bool());
MOCK_CONST_METHOD0(isCurrent, bool());
MOCK_METHOD1(setCurrentSurface, bool(const RE::Surface&));
MOCK_METHOD0(resetCurrentSurface, void());