Merge "SurfaceFlinger: Cache updateInputWindows call" into rvc-dev
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index d7ec868..e4d754c 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -485,6 +485,10 @@
}
}
+ if (recomputeVisibleRegions == true) {
+ maybeDirtyInput();
+ }
+
return true;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 64cfb3d..3765d0d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -993,6 +993,9 @@
commitTransaction(c);
mPendingStatesSnapshot = mPendingStates;
mCurrentState.callbackHandles = {};
+
+ maybeDirtyInput();
+
return flags;
}
@@ -2472,6 +2475,32 @@
}
}
+bool Layer::maybeDirtyInput() {
+ // No sense redirtying input.
+ if (mFlinger->inputDirty()) return true;
+
+ if (hasInput()) {
+ mFlinger->dirtyInput();
+ return true;
+ }
+
+ // If a child or relative dirties the input, no sense continuing to traverse
+ // so we return early and halt the recursion. We traverse ourselves instead
+ // of using traverse() so we can implement this early halt.
+ for (const sp<Layer>& child : mDrawingChildren) {
+ if (child->maybeDirtyInput()) {
+ return true;
+ }
+ }
+ for (const wp<Layer>& weakRelative : mDrawingState.zOrderRelatives) {
+ sp<Layer> relative = weakRelative.promote();
+ if (relative && relative->maybeDirtyInput()) {
+ return true;
+ }
+ }
+ return false;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 20d7232..e21a866 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -997,6 +997,10 @@
// Window types from WindowManager.LayoutParams
const int mWindowType;
+ // Called when mDrawingState has changed. If we or one of our children/relatives hasInput()
+ // then we will dirty the setInputWindows cache.
+ bool maybeDirtyInput();
+
private:
/**
* Returns an unsorted vector of all layers that are part of this tree.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e764d24..ffb8ae9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2779,6 +2779,19 @@
void SurfaceFlinger::updateInputWindowInfo() {
std::vector<InputWindowInfo> inputHandles;
+ // We use a simple caching algorithm here. mInputDirty begins as true,
+ // after we call setInputWindows we set it to false, so
+ // in the future we wont call it again.. We set input dirty to true again
+ // when any layer that hasInput() has a transaction performed on it
+ // or when any parent or relative parent of such a layer has a transaction
+ // performed on it. Not all of these transactions will really result in
+ // input changes but all input changes will spring from these transactions
+ // so the cache is safe but not optimal. It seems like it might be annoyingly
+ // costly to cache and comapre the actual InputWindowHandle vector though.
+ if (!mInputDirty) {
+ return;
+ }
+
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (layer->hasInput()) {
// When calculating the screen bounds we ignore the transparent region since it may
@@ -2790,6 +2803,8 @@
mInputFlinger->setInputWindows(inputHandles,
mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
: nullptr);
+
+ mInputDirty = false;
}
void SurfaceFlinger::commitInputWindowCommands() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e7f9930..a157a06 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1235,6 +1235,11 @@
// janky frames there are.
nsecs_t mMissedFrameJankStart = 0;
int32_t mMissedFrameJankCount = 0;
+
+ // See updateInputWindowInfo() for details
+ std::atomic<bool> mInputDirty = true;
+ void dirtyInput() { mInputDirty = true; }
+ bool inputDirty() { return mInputDirty; }
};
} // namespace android