SF Bounds caching 1/3: Defer calls that use layer bounds until the cached bounds are available.
End goal is to calculate the bounds once in the surface flinger loop. The bounds are invalidated
if the visible region changes. The first step is to defer any functions that use the cache to after
the bounds is calculated.
- Defer updating display dirty region when latching buffers.
- Defer updating cursor and input flinger until all the buffers have been latched.
- Recompute visible regions if transformToDisplayInverse flag changes
Test: go/wm-smoke
Test: atest -a libinput_tests inputflinger_tests SurfaceFlinger_test libsurfaceflinger_unittest SurfaceParcelable_test libgui_test
Change-Id: Ife6e0f06939d9f4fb051b68cb2b1c9f5bd180b57
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9d03ae7..753b5ca 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1638,6 +1638,10 @@
bool refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
+
+ updateCursorAsync();
+ updateInputFlinger();
+
refreshNeeded |= mRepaintEverything;
if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
// Signal a refresh if a transaction modified the window state,
@@ -1732,7 +1736,15 @@
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
- return handlePageFlip();
+ bool refreshNeeded = handlePageFlip();
+
+ for (auto& layer : mLayersPendingRefresh) {
+ Region visibleReg;
+ visibleReg.set(layer->computeScreenBounds());
+ invalidateLayerStack(layer, visibleReg);
+ }
+ mLayersPendingRefresh.clear();
+ return refreshNeeded;
}
void SurfaceFlinger::calculateWorkingSet() {
@@ -2844,7 +2856,6 @@
* (perform the transaction for each of them if needed)
*/
- bool inputChanged = false;
if (transactionFlags & eTraversalNeeded) {
mCurrentState.traverseInZOrder([&](Layer* layer) {
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
@@ -2855,7 +2866,7 @@
mVisibleRegionsDirty = true;
if (flags & Layer::eInputInfoChanged) {
- inputChanged = true;
+ mInputInfoChanged = true;
}
});
}
@@ -2967,22 +2978,23 @@
}
commitTransaction();
-
- if (inputChanged || mVisibleRegionsDirty) {
- updateInputWindows();
- }
- executeInputWindowCommands();
-
- updateCursorAsync();
}
-void SurfaceFlinger::updateInputWindows() {
+void SurfaceFlinger::updateInputFlinger() {
ATRACE_CALL();
-
- if (mInputFlinger == nullptr) {
+ if (!mInputFlinger) {
return;
}
+ if (mVisibleRegionsDirty || mInputInfoChanged) {
+ mInputInfoChanged = false;
+ updateInputWindowInfo();
+ }
+
+ executeInputWindowCommands();
+}
+
+void SurfaceFlinger::updateInputWindowInfo() {
Vector<InputWindowInfo> inputHandles;
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
@@ -2996,10 +3008,6 @@
}
void SurfaceFlinger::executeInputWindowCommands() {
- if (!mInputFlinger) {
- return;
- }
-
for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
if (transferTouchFocusCommand.fromToken != nullptr &&
transferTouchFocusCommand.toToken != nullptr &&
@@ -3276,9 +3284,10 @@
Mutex::Autolock lock(mStateLock);
for (auto& layer : mLayersWithQueuedFrames) {
- const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
+ if (layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence)) {
+ mLayersPendingRefresh.push_back(layer);
+ }
layer->useSurfaceDamage();
- invalidateLayerStack(layer, dirty);
if (layer->isBufferLatched()) {
newDataLatched = true;
}
@@ -3292,11 +3301,6 @@
mVisibleRegionsDirty |= visibleRegions;
- if (visibleRegions) {
- // Update input window info if the layer receives its first buffer.
- updateInputWindows();
- }
-
// If we will need to wake up at some time in the future to deal with a
// queued frame that shouldn't be displayed during this vsync period, wake
// up during the next vsync period to check again.