diff options
| author | 2020-03-06 04:14:54 +0000 | |
|---|---|---|
| committer | 2020-03-06 04:14:54 +0000 | |
| commit | 1d2d8b03657e6cc4bc13f7b4014cee4dad25f37f (patch) | |
| tree | 9dae17cf0ce54ce63a588da2f96a069b1312b468 | |
| parent | 24e9660ce414a5f4a1fcf9900db2be9b718de2c1 (diff) | |
| parent | a125784e31c6be4441c5f17bed40510a85bd4540 (diff) | |
Merge "SurfaceFlinger: Cache updateInputWindows call" into rvc-dev
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 29 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 15 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 5 |
5 files changed, 57 insertions, 0 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index d7ec86863f..e4d754c712 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -485,6 +485,10 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, } } + if (recomputeVisibleRegions == true) { + maybeDirtyInput(); + } + return true; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 64cfb3d699..3765d0d39d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -993,6 +993,9 @@ uint32_t Layer::doTransaction(uint32_t flags) { commitTransaction(c); mPendingStatesSnapshot = mPendingStates; mCurrentState.callbackHandles = {}; + + maybeDirtyInput(); + return flags; } @@ -2472,6 +2475,32 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp } } +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 20d72324c3..e21a866616 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -997,6 +997,10 @@ protected: // 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 e764d24eaa..ffb8ae925a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2779,6 +2779,19 @@ void SurfaceFlinger::updateInputFlinger() { 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 @@ void SurfaceFlinger::updateInputWindowInfo() { 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 e7f9930392..a157a06d34 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1235,6 +1235,11 @@ private: // 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 |