Merge "Always enable backpressure propagation during GPU composition" into qt-dev
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index e69b99f..e21128c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -50,6 +50,9 @@
// Returns the bounds of the surface
virtual const ui::Size& getSize() const = 0;
+ // Returns whether the surface is protected.
+ virtual bool isProtected() const = 0;
+
// Gets the latest fence to pass to the HWC to signal that the surface
// buffer is done rendering
virtual const sp<Fence>& getClientTargetAcquireFence() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 3c79084..0f57315 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -45,6 +45,7 @@
bool isValid() const override;
void initialize() override;
const ui::Size& getSize() const override;
+ bool isProtected() const override { return mProtected; }
const sp<Fence>& getClientTargetAcquireFence() const override;
void setBufferDataspace(ui::Dataspace) override;
@@ -78,6 +79,7 @@
sp<GraphicBuffer> mGraphicBuffer;
const sp<DisplaySurface> mDisplaySurface;
ui::Size mSize;
+ bool mProtected{false};
std::uint32_t mPageFlipCount{0};
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index 1562f58..ca2299a 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -31,6 +31,7 @@
MOCK_CONST_METHOD0(isValid, bool());
MOCK_METHOD0(initialize, void());
MOCK_CONST_METHOD0(getSize, const ui::Size&());
+ MOCK_CONST_METHOD0(isProtected, bool());
MOCK_CONST_METHOD0(getClientTargetAcquireFence, const sp<Fence>&());
MOCK_METHOD1(setDisplaySize, void(const ui::Size&));
MOCK_METHOD1(setProtected, void(bool));
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index b5a6678..3fcd9d1 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -101,6 +101,9 @@
}
const int status = native_window_set_usage(mNativeWindow.get(), usageFlags);
ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for protected content: %d", status);
+ if (status == NO_ERROR) {
+ mProtected = useProtected;
+ }
}
status_t RenderSurface::beginFrame(bool mustRecompose) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 9960478..f75a4dc 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -143,16 +143,40 @@
*/
TEST_F(RenderSurfaceTest, setProtectedTrueEnablesProtection) {
+ EXPECT_FALSE(mSurface.isProtected());
EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_PROTECTED))
.WillOnce(Return(NO_ERROR));
mSurface.setProtected(true);
+ EXPECT_TRUE(mSurface.isProtected());
}
TEST_F(RenderSurfaceTest, setProtectedFalseDisablesProtection) {
+ EXPECT_FALSE(mSurface.isProtected());
EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER)).WillOnce(Return(NO_ERROR));
mSurface.setProtected(false);
+ EXPECT_FALSE(mSurface.isProtected());
+}
+
+TEST_F(RenderSurfaceTest, setProtectedEnableAndDisable) {
+ EXPECT_FALSE(mSurface.isProtected());
+ EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_PROTECTED))
+ .WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER)).WillOnce(Return(NO_ERROR));
+
+ mSurface.setProtected(true);
+ EXPECT_TRUE(mSurface.isProtected());
+ mSurface.setProtected(false);
+ EXPECT_FALSE(mSurface.isProtected());
+}
+
+TEST_F(RenderSurfaceTest, setProtectedEnableWithError) {
+ EXPECT_FALSE(mSurface.isProtected());
+ EXPECT_CALL(*mNativeWindow, setUsage(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_PROTECTED))
+ .WillOnce(Return(INVALID_OPERATION));
+ mSurface.setProtected(true);
+ EXPECT_FALSE(mSurface.isProtected());
}
/* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index 871f556..abf7b71 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -210,17 +210,14 @@
const nsecs_t baseTime = now - mReferenceTime;
const nsecs_t numPeriodsSinceReference = baseTime / mPeriod;
const nsecs_t predictedReference = mReferenceTime + numPeriodsSinceReference * mPeriod;
- listener.mLastEventTime = predictedReference + mPhase + listener.mPhase;
- // If we're very close in time to the predicted last event time,
- // and we're not very close to the next predicted last event time
- // then we need to back up the last event time so that we can
- // attempt to fire an event immediately.
- //
- // Otherwise, keep the last event time that we predicted so that
- // we don't wake up early.
- if (isShorterThanPeriod(now - listener.mLastEventTime) &&
- !isShorterThanPeriod(listener.mLastEventTime + mPeriod - now)) {
- listener.mLastEventTime -= mPeriod;
+ const nsecs_t phaseCorrection = mPhase + listener.mPhase;
+ const nsecs_t predictedLastEventTime = predictedReference + phaseCorrection;
+ if (predictedLastEventTime >= now) {
+ // Make sure that the last event time does not exceed the current time.
+ // If it would, then back the last event time by a period.
+ listener.mLastEventTime = predictedLastEventTime - mPeriod;
+ } else {
+ listener.mLastEventTime = predictedLastEventTime;
}
} else {
listener.mLastEventTime = now + mPhase - mWakeupLatency;
@@ -316,7 +313,7 @@
// Sanity check that the duration is close enough in length to a period without
// falling into double-rate vsyncs.
- bool isShorterThanPeriod(nsecs_t duration) {
+ bool isCloseToPeriod(nsecs_t duration) {
// Ratio of 3/5 is arbitrary, but it must be greater than 1/2.
return duration < (3 * mPeriod) / 5;
}
@@ -332,7 +329,7 @@
nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo);
if (t < now) {
- if (isShorterThanPeriod(now - eventListener.mLastCallbackTime)) {
+ if (isCloseToPeriod(now - eventListener.mLastCallbackTime)) {
eventListener.mLastEventTime = t;
ALOGV("[%s] [%s] Skipping event due to model error", mName,
eventListener.mName);
@@ -392,7 +389,7 @@
// Check that it's been slightly more than half a period since the last
// event so that we don't accidentally fall into double-rate vsyncs
- if (isShorterThanPeriod(t - listener.mLastEventTime)) {
+ if (isCloseToPeriod(t - listener.mLastEventTime)) {
t += mPeriod;
ALOGV("[%s] Modifying t -> %" PRId64, mName, ns2us(t));
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bac5bf0..f8745f7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3301,8 +3301,11 @@
break;
}
}
- if (needsProtected != renderEngine.isProtected() &&
- renderEngine.useProtectedContext(needsProtected)) {
+ if (needsProtected != renderEngine.isProtected()) {
+ renderEngine.useProtectedContext(needsProtected);
+ }
+ if (needsProtected != display->getRenderSurface()->isProtected() &&
+ needsProtected == renderEngine.isProtected()) {
display->getRenderSurface()->setProtected(needsProtected);
}
}