SF: Move/Refactor updateCursorAsync to CompositionEngine
As part of this change, the existing LayerFE::latchCompositionState is
extended to allow for more state types to be fetched.
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I71e0f547440a64c1025f36741beb68e72c18e475
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index 9558266..8bc3a34 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -16,6 +16,7 @@
#include <compositionengine/CompositionRefreshArgs.h>
#include <compositionengine/LayerFE.h>
+#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/CompositionEngine.h>
#include <compositionengine/impl/Display.h>
#include <compositionengine/impl/Layer.h>
@@ -70,6 +71,22 @@
return mRefreshStartTime;
}
+void CompositionEngine::updateCursorAsync(CompositionRefreshArgs& args) {
+ std::unordered_map<compositionengine::LayerFE*, compositionengine::LayerFECompositionState*>
+ uniqueVisibleLayers;
+
+ for (const auto& output : args.outputs) {
+ for (auto& layer : output->getOutputLayersOrderedByZ()) {
+ if (layer->isHardwareCursor()) {
+ // Latch the cursor composition state from each front-end layer.
+ layer->getLayerFE().latchCursorCompositionState(
+ layer->getLayer().editState().frontEnd);
+ layer->writeCursorPositionToHWC();
+ }
+ }
+ }
+}
+
void CompositionEngine::preComposition(CompositionRefreshArgs& args) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index e721cf5..73bb03b 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -550,6 +550,27 @@
}
}
+void OutputLayer::writeCursorPositionToHWC() const {
+ // Skip doing this if there is no HWC interface
+ auto hwcLayer = getHwcLayer();
+ if (!hwcLayer) {
+ return;
+ }
+
+ const auto& layerFEState = mLayer->getState().frontEnd;
+ const auto& outputState = mOutput.getState();
+
+ Rect frame = layerFEState.cursorFrame;
+ frame.intersect(outputState.viewport, &frame);
+ Rect position = outputState.transform.transform(frame);
+
+ if (auto error = hwcLayer->setCursorPosition(position.left, position.top);
+ error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set cursor position to (%d, %d): %s (%d)", mLayerFE->getDebugName(),
+ position.left, position.top, to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+}
+
HWC2::Layer* OutputLayer::getHwcLayer() const {
return mState.hwc ? mState.hwc->hwcLayer.get() : nullptr;
}
@@ -559,6 +580,11 @@
mState.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CLIENT;
}
+bool OutputLayer::isHardwareCursor() const {
+ return mState.hwc &&
+ mState.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CURSOR;
+}
+
void OutputLayer::detectDisallowedCompositionTypeChange(
Hwc2::IComposerClient::Composition from, Hwc2::IComposerClient::Composition to) const {
bool result = false;