Merge "Push existing pending state when deferring transaction" into pi-dev
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 3ae56db..e90cf3b 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -115,7 +115,7 @@
exit(207);
}
{
- std::string vendor_partition = StringPrintf("/dev/block/bootdevice/by-name/vendor%s",
+ std::string vendor_partition = StringPrintf("/dev/block/by-name/vendor%s",
arg[2]);
int vendor_result = mount(vendor_partition.c_str(),
"/postinstall/vendor",
@@ -128,7 +128,7 @@
// Try to mount the product partition. update_engine doesn't do this for us, but we
// want it for product APKs. Same notes as vendor above.
{
- std::string product_partition = StringPrintf("/dev/block/bootdevice/by-name/product%s",
+ std::string product_partition = StringPrintf("/dev/block/by-name/product%s",
arg[2]);
int product_result = mount(product_partition.c_str(),
"/postinstall/product",
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 730bdcd..97edd35 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1549,7 +1549,7 @@
mHadClientComposition = mHadClientComposition ||
getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
}
- mVsyncModulator.setLastFrameUsedRenderEngine(mHadClientComposition);
+ mVsyncModulator.onRefreshed(mHadClientComposition);
mLayersWithQueuedFrames.clear();
}
diff --git a/services/surfaceflinger/VSyncModulator.h b/services/surfaceflinger/VSyncModulator.h
index 3e5800e..d526313 100644
--- a/services/surfaceflinger/VSyncModulator.h
+++ b/services/surfaceflinger/VSyncModulator.h
@@ -28,6 +28,12 @@
* Modulates the vsync-offsets depending on current SurfaceFlinger state.
*/
class VSyncModulator {
+private:
+
+ // Number of frames we'll keep the early phase offsets once they are activated. This acts as a
+ // low-pass filter in case the client isn't quick enough in sending new transactions.
+ const int MIN_EARLY_FRAME_COUNT = 2;
+
public:
enum TransactionStart {
@@ -55,6 +61,11 @@
}
void setTransactionStart(TransactionStart transactionStart) {
+
+ if (transactionStart == TransactionStart::EARLY) {
+ mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT;
+ }
+
// An early transaction stays an early transaction.
if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) {
return;
@@ -69,10 +80,19 @@
updatePhaseOffsets();
}
- void setLastFrameUsedRenderEngine(bool re) {
- if (re == mLastFrameUsedRenderEngine) return;
- mLastFrameUsedRenderEngine = re;
- updatePhaseOffsets();
+ void onRefreshed(bool usedRenderEngine) {
+ bool updatePhaseOffsetsNeeded = false;
+ if (mRemainingEarlyFrameCount > 0) {
+ mRemainingEarlyFrameCount--;
+ updatePhaseOffsetsNeeded = true;
+ }
+ if (usedRenderEngine != mLastFrameUsedRenderEngine) {
+ mLastFrameUsedRenderEngine = usedRenderEngine;
+ updatePhaseOffsetsNeeded = true;
+ }
+ if (updatePhaseOffsetsNeeded) {
+ updatePhaseOffsets();
+ }
}
private:
@@ -82,7 +102,7 @@
// Do not change phase offsets if disabled.
if (mEarlyPhaseOffset == mLatePhaseOffset) return;
- if (mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine) {
+ if (shouldUseEarlyOffset()) {
if (mPhaseOffset != mEarlyPhaseOffset) {
if (mEventThread) {
mEventThread->setPhaseOffset(mEarlyPhaseOffset);
@@ -99,12 +119,18 @@
}
}
+ bool shouldUseEarlyOffset() {
+ return mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine
+ || mRemainingEarlyFrameCount > 0;
+ }
+
nsecs_t mLatePhaseOffset = 0;
nsecs_t mEarlyPhaseOffset = 0;
EventThread* mEventThread = nullptr;
std::atomic<nsecs_t> mPhaseOffset = 0;
std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL;
std::atomic<bool> mLastFrameUsedRenderEngine = false;
+ std::atomic<int> mRemainingEarlyFrameCount = 0;
};
} // namespace android