diff options
| -rw-r--r-- | services/surfaceflinger/Android.bp | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 30 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 9 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 37 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 4 |
5 files changed, 81 insertions, 1 deletions
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 088c2562b9..1007b3dc85 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -54,6 +54,7 @@ cc_defaults { "libsync", "libtimestats_proto", "libui", + "libinput", "libutils", ], static_libs: [ @@ -183,6 +184,7 @@ cc_defaults { "libdisplayservicehidl", "libhidlbase", "libhidltransport", + "libinput", "liblayers_proto", "liblog", "libsync", diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f3182be7cc..d9ec44a03e 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1057,6 +1057,11 @@ uint32_t Layer::doTransaction(uint32_t flags) { clearSyncPoints(); } + if (mCurrentState.inputInfoChanged) { + flags |= eInputInfoChanged; + mCurrentState.inputInfoChanged = false; + } + // Commit the transaction commitTransaction(c); mCurrentState.callbackHandles = {}; @@ -1928,6 +1933,13 @@ void Layer::commitChildList() { mDrawingParent = mCurrentParent; } +void Layer::setInputInfo(const InputWindowInfo& info) { + mCurrentState.inputInfo = info; + mCurrentState.modified = true; + mCurrentState.inputInfoChanged = true; + setTransactionFlags(eTransactionNeeded); +} + void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) { const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; @@ -2055,6 +2067,24 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromCurrentState; } +InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) { + InputWindowInfo info = mDrawingState.inputInfo; + info.frameLeft = screenBounds.left; + info.inputInfo.frameTop = screenBounds.top; + info.inputInfo.frameRight = screenBounds.right; + info.inputInfo.frameBottom = screenBounds.bottom; + + info.touchableRegion = mDrawingState.inputInfo.touchableRegion.translate( + screenBounds.left, + screenBounds.top); + info.visible = isVisible(); + return info; +} + +bool Layer::hasInput() const { + return mDrawingState.inputInfo.inputChannel != nullptr; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index ed51c61140..fe8d5a95c9 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -22,6 +22,7 @@ #include <gui/BufferQueue.h> #include <gui/ISurfaceComposerClient.h> #include <gui/LayerState.h> +#include <input/InputWindow.h> #include <layerproto/LayerProtoHeader.h> #include <math/vec4.h> #include <renderengine/Mesh.h> @@ -109,6 +110,7 @@ public: enum { // flags for doTransaction() eDontUpdateGeometryState = 0x00000001, eVisibleRegion = 0x00000002, + eInputInfoChanged = 0x00000004 }; struct Geometry { @@ -166,6 +168,9 @@ public: half4 color; + bool inputInfoChanged; + InputWindowInfo inputInfo; + // The fields below this point are only used by BufferStateLayer Geometry active; @@ -708,6 +713,10 @@ public: bool getPremultipledAlpha() const; bool mPendingHWCDestroy{false}; + void setInputInfo(const InputWindowInfo& info); + + InputWindowInfo fillInputInfo(const Rect& screenBounds); + bool hasInput() const; protected: // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index af7334615b..e9dd6bc003 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -37,6 +37,8 @@ #include <dvr/vr_flinger.h> +#include <input/IInputFlinger.h> + #include <ui/ColorSpace.h> #include <ui/DebugUtils.h> #include <ui/DisplayInfo.h> @@ -554,6 +556,13 @@ void SurfaceFlinger::bootFinished() if (window != 0) { window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); } + sp<IBinder> input(defaultServiceManager()->getService( + String16("inputflinger"))); + if (input == nullptr) { + ALOGE("Failed to link to input service"); + } else { + mInputFlinger = interface_cast<IInputFlinger>(input); + } if (mVrFlinger) { mVrFlinger->OnBootFinished(); @@ -2569,6 +2578,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) * (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); @@ -2577,6 +2587,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const uint32_t flags = layer->doTransaction(0); if (flags & Layer::eVisibleRegion) mVisibleRegionsDirty = true; + + if (flags & Layer::eInputInfoChanged) { + inputChanged = true; + } }); } @@ -2686,9 +2700,26 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) commitTransaction(); + if ((inputChanged || mVisibleRegionsDirty) && mInputFlinger) { + updateInputWindows(); + } + updateCursorAsync(); } +void SurfaceFlinger::updateInputWindows() { + ATRACE_CALL(); + + Vector<InputWindowInfo> inputHandles; + + mDrawingState.traverseInReverseZOrder([&](Layer* layer) { + if (layer->hasInput()) { + inputHandles.add(layer->fillInputInfo(layer->computeScreenBounds())); + } + }); + mInputFlinger->setInputWindows(inputHandles); +} + void SurfaceFlinger::updateCursorAsync() { for (const auto& [token, display] : mDisplays) { @@ -2796,6 +2827,7 @@ void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displa if (CC_LIKELY(layer->isVisible())) { const bool translucent = !layer->isOpaque(s); Rect bounds(layer->computeScreenBounds()); + visibleRegion.set(bounds); ui::Transform tr = layer->getTransform(); if (!visibleRegion.isEmpty()) { @@ -3611,7 +3643,10 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState if (what & layer_state_t::eSidebandStreamChanged) { if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded; } - + if (what & layer_state_t::eInputInfoChanged) { + layer->setInputInfo(s.inputInfo); + flags |= eTraversalNeeded; + } std::vector<sp<CallbackHandle>> callbackHandles; if ((what & layer_state_t::eListenerCallbacksChanged) && (!s.listenerCallbacks.empty())) { mTransactionCompletedThread.run(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f98dddfb34..4a14de7f73 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -98,6 +98,7 @@ class EventControlThread; class EventThread; class IGraphicBufferConsumer; class IGraphicBufferProducer; +class IInputFlinger; class InjectVSyncSource; class Layer; class Surface; @@ -531,6 +532,7 @@ private: void handleTransaction(uint32_t transactionFlags); void handleTransactionLocked(uint32_t transactionFlags); + void updateInputWindows(); void updateCursorAsync(); /* handlePageFlip - latch a new buffer if available and compute the dirty @@ -986,6 +988,8 @@ private: std::unique_ptr<Scheduler> mScheduler; sp<Scheduler::ConnectionHandle> mAppConnectionHandle; sp<Scheduler::ConnectionHandle> mSfConnectionHandle; + + sp<IInputFlinger> mInputFlinger; }; }; // namespace android |