summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishnu Nair <vishnun@google.com>2021-04-21 08:31:27 -0700
committerVishnu Nair <vishnun@google.com>2021-04-21 15:06:19 -0700
commitbeb3b482db3c596a448058ad5e125426255344e9 (patch)
tree1d299062b13e6b3ddade0193369482e6891f345a
parentd78b21c54858a5164fd239097efcd0805f0767ba (diff)
Introduce ASurfaceTransaction_setOnCommit api
Introduce a new callback for SurfaceControl transactions that fire after we commit a transaction in SurfaceFlinger. This will help some clients pace when they should apply the next transaction so it get applied on the next vsync. If they wait for the existing transaction complete callback, there may not be enough time between when the client applies the transaction and surface flinger waking up and apply it on the new vsync. This would mean the update would arrive a frame late. Bug: 185843251 Test: atest ASurfaceControlTest Change-Id: If0d5d01a1d5c2029eb81667356e666d7297376d4
-rw-r--r--native/android/libandroid.map.txt1
-rw-r--r--native/android/surface_control.cpp38
2 files changed, 38 insertions, 1 deletions
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 9729524b47b2..de6db1ae7d23 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -259,6 +259,7 @@ LIBANDROID {
ASurfaceTransaction_setHdrMetadata_cta861_3; # introduced=29
ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29
ASurfaceTransaction_setOnComplete; # introduced=29
+ ASurfaceTransaction_setOnCommit; # introduced=31
ASurfaceTransaction_setPosition; # introduced=31
ASurfaceTransaction_setCrop; # introduced=31
ASurfaceTransaction_setBufferTransform; # introduced=31
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 3d14c425ed4d..087837a5c70f 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -260,6 +260,7 @@ struct ASurfaceTransactionStats {
std::unordered_map<ASurfaceControl*, ASurfaceControlStats> aSurfaceControlStats;
int64_t latchTime;
sp<Fence> presentFence;
+ bool transactionCompleted;
};
int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurfaceTransactionStats) {
@@ -269,6 +270,9 @@ int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurface
int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* aSurfaceTransactionStats) {
CHECK_NOT_NULL(aSurfaceTransactionStats);
+ LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
+ "ASurfaceTransactionStats queried from an incomplete transaction callback");
+
auto& presentFence = aSurfaceTransactionStats->presentFence;
return (presentFence) ? presentFence->dup() : -1;
}
@@ -313,6 +317,8 @@ int ASurfaceTransactionStats_getPreviousReleaseFenceFd(
ASurfaceTransactionStats* aSurfaceTransactionStats, ASurfaceControl* aSurfaceControl) {
CHECK_NOT_NULL(aSurfaceTransactionStats);
CHECK_NOT_NULL(aSurfaceControl);
+ LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
+ "ASurfaceTransactionStats queried from an incomplete transaction callback");
const auto& aSurfaceControlStats =
aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
@@ -334,7 +340,6 @@ void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** aSurface
void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction, void* context,
ASurfaceTransaction_OnComplete func) {
CHECK_NOT_NULL(aSurfaceTransaction);
- CHECK_NOT_NULL(context);
CHECK_NOT_NULL(func);
TransactionCompletedCallbackTakesContext callback = [func](void* callback_context,
@@ -345,6 +350,7 @@ void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction,
aSurfaceTransactionStats.latchTime = latchTime;
aSurfaceTransactionStats.presentFence = presentFence;
+ aSurfaceTransactionStats.transactionCompleted = true;
auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
@@ -695,3 +701,33 @@ void ASurfaceTransaction_setEnableBackPressure(ASurfaceTransaction* aSurfaceTran
layer_state_t::eEnableBackpressure : 0;
transaction->setFlags(surfaceControl, flags, layer_state_t::eEnableBackpressure);
}
+
+void ASurfaceTransaction_setOnCommit(ASurfaceTransaction* aSurfaceTransaction, void* context,
+ ASurfaceTransaction_OnCommit func) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(func);
+
+ TransactionCompletedCallbackTakesContext callback =
+ [func](void* callback_context, nsecs_t latchTime, const sp<Fence>& /* presentFence */,
+ const std::vector<SurfaceControlStats>& surfaceControlStats) {
+ ASurfaceTransactionStats aSurfaceTransactionStats;
+ aSurfaceTransactionStats.latchTime = latchTime;
+ aSurfaceTransactionStats.transactionCompleted = false;
+
+ auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
+ for (const auto&
+ [surfaceControl, latchTime, acquireTime, presentFence,
+ previousReleaseFence, transformHint,
+ frameEvents] : surfaceControlStats) {
+ ASurfaceControl* aSurfaceControl =
+ reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
+ aSurfaceControlStats[aSurfaceControl].acquireTime = acquireTime;
+ }
+
+ (*func)(callback_context, &aSurfaceTransactionStats);
+ };
+
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ transaction->addTransactionCommittedCallback(callback, context);
+} \ No newline at end of file