Loading services/surfaceflinger/Layer.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "Layer.h" #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android/native_window.h> #include <binder/IPCThreadState.h> Loading Loading @@ -2481,7 +2482,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet if (traceFlags & SurfaceTracing::TRACE_INPUT) { InputWindowInfo info; if (useDrawing) { info = fillInputInfo(); info = fillInputInfo({nullptr}); } else { info = state.inputInfo; } Loading @@ -2502,7 +2503,7 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromCurrentState; } void Layer::fillInputFrameInfo(InputWindowInfo& info) { void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay) { // Transform layer size to screen space and inset it by surface insets. // If this is a portal window, set the touchableRegion to the layerBounds. Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE Loading @@ -2522,9 +2523,13 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { return; } ui::Transform t = getTransform(); ui::Transform layerToDisplay = getTransform(); // Transform that takes window coordinates to unrotated display coordinates ui::Transform t = toPhysicalDisplay * layerToDisplay; int32_t xSurfaceInset = info.surfaceInset; int32_t ySurfaceInset = info.surfaceInset; // Bring screenBounds into unrotated space Rect screenBounds = toPhysicalDisplay.transform(Rect{mScreenBounds}); const float xScale = t.getScaleX(); const float yScale = t.getScaleY(); Loading Loading @@ -2582,7 +2587,6 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { // We need to send the layer bounds cropped to the screenbounds since the layer can be cropped. // The frame should be the area the user sees on screen since it's used for occlusion // detection. Rect screenBounds = Rect{mScreenBounds}; transformedLayerBounds.intersect(screenBounds, &transformedLayerBounds); info.frameLeft = transformedLayerBounds.left; info.frameTop = transformedLayerBounds.top; Loading @@ -2594,7 +2598,7 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { info.touchableRegion = inputTransform.transform(info.touchableRegion); } InputWindowInfo Layer::fillInputInfo() { InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) { if (!hasInputInfo()) { mDrawingState.inputInfo.name = getName(); mDrawingState.inputInfo.ownerUid = mOwnerUid; Loading @@ -2611,7 +2615,13 @@ InputWindowInfo Layer::fillInputInfo() { info.displayId = getLayerStack(); } fillInputFrameInfo(info); // Transform that goes from "logical(rotated)" display to physical/unrotated display. // This is for when inputflinger operates in physical display-space. ui::Transform toPhysicalDisplay; if (display) { toPhysicalDisplay = display->getTransform(); } fillInputFrameInfo(info, toPhysicalDisplay); // For compatibility reasons we let layers which can receive input // receive input before they have actually submitted a buffer. Because Loading @@ -2627,12 +2637,14 @@ InputWindowInfo Layer::fillInputInfo() { auto cropLayer = mDrawingState.touchableRegionCrop.promote(); if (info.replaceTouchableRegionWithCrop) { if (cropLayer == nullptr) { info.touchableRegion = Region(Rect{mScreenBounds}); info.touchableRegion = Region(toPhysicalDisplay.transform(Rect{mScreenBounds})); } else { info.touchableRegion = Region(Rect{cropLayer->mScreenBounds}); info.touchableRegion = Region(toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds})); } } else if (cropLayer != nullptr) { info.touchableRegion = info.touchableRegion.intersect(Rect{cropLayer->mScreenBounds}); info.touchableRegion = info.touchableRegion.intersect( toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds})); } // If the layer is a clone, we need to crop the input region to cloned root to prevent Loading @@ -2640,7 +2652,7 @@ InputWindowInfo Layer::fillInputInfo() { if (isClone()) { sp<Layer> clonedRoot = getClonedRoot(); if (clonedRoot != nullptr) { Rect rect(clonedRoot->mScreenBounds); Rect rect = toPhysicalDisplay.transform(Rect{clonedRoot->mScreenBounds}); info.touchableRegion = info.touchableRegion.intersect(rect); } } Loading services/surfaceflinger/Layer.h +2 −2 Original line number Diff line number Diff line Loading @@ -913,7 +913,7 @@ public: bool getPremultipledAlpha() const; void setInputInfo(const InputWindowInfo& info); InputWindowInfo fillInputInfo(); InputWindowInfo fillInputInfo(const sp<DisplayDevice>& display); /** * Returns whether this layer has an explicitly set input-info. */ Loading Loading @@ -1193,7 +1193,7 @@ private: sp<Layer> getRootLayer(); // Fills in the frame and transform info for the InputWindowInfo void fillInputFrameInfo(InputWindowInfo& info); void fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay); // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling, which is Loading services/surfaceflinger/SurfaceFlinger.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -2906,15 +2906,32 @@ void SurfaceFlinger::updateInputFlinger() { mInputWindowCommands.clear(); } bool enablePerWindowInputRotation() { static bool value = android::base::GetBoolProperty("persist.debug.per_window_input_rotation", false); return value; } void SurfaceFlinger::updateInputWindowInfo() { std::vector<InputWindowInfo> inputInfos; mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (layer->needsInputInfo()) { if (!layer->needsInputInfo()) return; sp<DisplayDevice> display; if (enablePerWindowInputRotation()) { for (const auto& pair : ON_MAIN_THREAD(mDisplays)) { const auto& displayDevice = pair.second; if (!displayDevice->getCompositionDisplay() ->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { continue; } display = displayDevice; } } // When calculating the screen bounds we ignore the transparent region since it may // result in an unwanted offset. inputInfos.push_back(layer->fillInputInfo()); } inputInfos.push_back(layer->fillInputInfo(display)); }); mInputFlinger->setInputWindows(inputInfos, Loading Loading
services/surfaceflinger/Layer.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "Layer.h" #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android/native_window.h> #include <binder/IPCThreadState.h> Loading Loading @@ -2481,7 +2482,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet if (traceFlags & SurfaceTracing::TRACE_INPUT) { InputWindowInfo info; if (useDrawing) { info = fillInputInfo(); info = fillInputInfo({nullptr}); } else { info = state.inputInfo; } Loading @@ -2502,7 +2503,7 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromCurrentState; } void Layer::fillInputFrameInfo(InputWindowInfo& info) { void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay) { // Transform layer size to screen space and inset it by surface insets. // If this is a portal window, set the touchableRegion to the layerBounds. Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE Loading @@ -2522,9 +2523,13 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { return; } ui::Transform t = getTransform(); ui::Transform layerToDisplay = getTransform(); // Transform that takes window coordinates to unrotated display coordinates ui::Transform t = toPhysicalDisplay * layerToDisplay; int32_t xSurfaceInset = info.surfaceInset; int32_t ySurfaceInset = info.surfaceInset; // Bring screenBounds into unrotated space Rect screenBounds = toPhysicalDisplay.transform(Rect{mScreenBounds}); const float xScale = t.getScaleX(); const float yScale = t.getScaleY(); Loading Loading @@ -2582,7 +2587,6 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { // We need to send the layer bounds cropped to the screenbounds since the layer can be cropped. // The frame should be the area the user sees on screen since it's used for occlusion // detection. Rect screenBounds = Rect{mScreenBounds}; transformedLayerBounds.intersect(screenBounds, &transformedLayerBounds); info.frameLeft = transformedLayerBounds.left; info.frameTop = transformedLayerBounds.top; Loading @@ -2594,7 +2598,7 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info) { info.touchableRegion = inputTransform.transform(info.touchableRegion); } InputWindowInfo Layer::fillInputInfo() { InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) { if (!hasInputInfo()) { mDrawingState.inputInfo.name = getName(); mDrawingState.inputInfo.ownerUid = mOwnerUid; Loading @@ -2611,7 +2615,13 @@ InputWindowInfo Layer::fillInputInfo() { info.displayId = getLayerStack(); } fillInputFrameInfo(info); // Transform that goes from "logical(rotated)" display to physical/unrotated display. // This is for when inputflinger operates in physical display-space. ui::Transform toPhysicalDisplay; if (display) { toPhysicalDisplay = display->getTransform(); } fillInputFrameInfo(info, toPhysicalDisplay); // For compatibility reasons we let layers which can receive input // receive input before they have actually submitted a buffer. Because Loading @@ -2627,12 +2637,14 @@ InputWindowInfo Layer::fillInputInfo() { auto cropLayer = mDrawingState.touchableRegionCrop.promote(); if (info.replaceTouchableRegionWithCrop) { if (cropLayer == nullptr) { info.touchableRegion = Region(Rect{mScreenBounds}); info.touchableRegion = Region(toPhysicalDisplay.transform(Rect{mScreenBounds})); } else { info.touchableRegion = Region(Rect{cropLayer->mScreenBounds}); info.touchableRegion = Region(toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds})); } } else if (cropLayer != nullptr) { info.touchableRegion = info.touchableRegion.intersect(Rect{cropLayer->mScreenBounds}); info.touchableRegion = info.touchableRegion.intersect( toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds})); } // If the layer is a clone, we need to crop the input region to cloned root to prevent Loading @@ -2640,7 +2652,7 @@ InputWindowInfo Layer::fillInputInfo() { if (isClone()) { sp<Layer> clonedRoot = getClonedRoot(); if (clonedRoot != nullptr) { Rect rect(clonedRoot->mScreenBounds); Rect rect = toPhysicalDisplay.transform(Rect{clonedRoot->mScreenBounds}); info.touchableRegion = info.touchableRegion.intersect(rect); } } Loading
services/surfaceflinger/Layer.h +2 −2 Original line number Diff line number Diff line Loading @@ -913,7 +913,7 @@ public: bool getPremultipledAlpha() const; void setInputInfo(const InputWindowInfo& info); InputWindowInfo fillInputInfo(); InputWindowInfo fillInputInfo(const sp<DisplayDevice>& display); /** * Returns whether this layer has an explicitly set input-info. */ Loading Loading @@ -1193,7 +1193,7 @@ private: sp<Layer> getRootLayer(); // Fills in the frame and transform info for the InputWindowInfo void fillInputFrameInfo(InputWindowInfo& info); void fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay); // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling, which is Loading
services/surfaceflinger/SurfaceFlinger.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -2906,15 +2906,32 @@ void SurfaceFlinger::updateInputFlinger() { mInputWindowCommands.clear(); } bool enablePerWindowInputRotation() { static bool value = android::base::GetBoolProperty("persist.debug.per_window_input_rotation", false); return value; } void SurfaceFlinger::updateInputWindowInfo() { std::vector<InputWindowInfo> inputInfos; mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (layer->needsInputInfo()) { if (!layer->needsInputInfo()) return; sp<DisplayDevice> display; if (enablePerWindowInputRotation()) { for (const auto& pair : ON_MAIN_THREAD(mDisplays)) { const auto& displayDevice = pair.second; if (!displayDevice->getCompositionDisplay() ->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { continue; } display = displayDevice; } } // When calculating the screen bounds we ignore the transparent region since it may // result in an unwanted offset. inputInfos.push_back(layer->fillInputInfo()); } inputInfos.push_back(layer->fillInputInfo(display)); }); mInputFlinger->setInputWindows(inputInfos, Loading