[SF] Use HWC api getPhysicalDisplayOrientation
With HWC3.0 we have the getPhysicalDisplayOrientation
api that can replace the sysprop ro.surface_flinger.primary_display_orientation
BUG: 184085132
Test: atest libsurfaceflinger_unittest
Change-Id: Ie2b0f8e1a81219dc8231a56b9e6174d549a4cbd1
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 1f1dd1a..9b9b29d 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -134,7 +134,9 @@
std::optional<aidl::android::hardware::graphics::common::
DisplayDecorationSupport>* support));
MOCK_METHOD2(setIdleTimerEnabled, status_t(PhysicalDisplayId, std::chrono::milliseconds));
- MOCK_METHOD1(hasDisplayIdleTimerCapability, bool(PhysicalDisplayId displayId));
+ MOCK_METHOD(bool, hasDisplayIdleTimerCapability, (PhysicalDisplayId), (const, override));
+ MOCK_METHOD(Hwc2::AidlTransform, getPhysicalDisplayOrientation, (PhysicalDisplayId),
+ (const, override));
};
} // namespace mock
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 92592f7..8b376f1 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -249,6 +249,7 @@
case OptionalFeature::DisplayBrightnessCommand:
case OptionalFeature::BootDisplayConfig:
case OptionalFeature::KernelIdleTimer:
+ case OptionalFeature::PhysicalDisplayOrientation:
return true;
}
}
@@ -1126,5 +1127,17 @@
return Error::NONE;
}
+Error AidlComposer::getPhysicalDisplayOrientation(Display displayId,
+ AidlTransform* outDisplayOrientation) {
+ const auto status =
+ mAidlComposerClient->getDisplayPhysicalOrientation(translate<int64_t>(displayId),
+ outDisplayOrientation);
+ if (!status.isOk()) {
+ ALOGE("getPhysicalDisplayOrientation failed %s", status.getDescription().c_str());
+ return static_cast<Error>(status.getServiceSpecificError());
+ }
+ return Error::NONE;
+}
+
} // namespace Hwc2
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 6c0f636..28ff167 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -223,6 +223,9 @@
std::optional<DisplayDecorationSupport>* support) override;
Error setIdleTimerEnabled(Display displayId, std::chrono::milliseconds timeout) override;
+ Error getPhysicalDisplayOrientation(Display displayId,
+ AidlTransform* outDisplayOrientation) override;
+
private:
// Many public functions above simply write a command into the command
// queue to batch the calls. validateDisplay and presentDisplay will call
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 6abe7d1..7d9946d 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -38,6 +38,7 @@
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
+#include <aidl/android/hardware/graphics/common/Transform.h>
#include <optional>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -80,6 +81,7 @@
using PerFrameMetadata = IComposerClient::PerFrameMetadata;
using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;
using PerFrameMetadataBlob = IComposerClient::PerFrameMetadataBlob;
+using AidlTransform = ::aidl::android::hardware::graphics::common::Transform;
class Composer {
public:
@@ -94,6 +96,7 @@
DisplayBrightnessCommand,
BootDisplayConfig,
KernelIdleTimer,
+ PhysicalDisplayOrientation,
};
virtual bool isSupported(OptionalFeature) const = 0;
@@ -277,6 +280,8 @@
std::optional<::aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) = 0;
virtual Error setIdleTimerEnabled(Display displayId, std::chrono::milliseconds timeout) = 0;
+ virtual Error getPhysicalDisplayOrientation(Display displayId,
+ AidlTransform* outDisplayOrientation) = 0;
};
} // namespace Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 6501276..c0432bf 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -154,6 +154,11 @@
isCapabilitySupported;
}
+Error Display::getPhysicalDisplayOrientation(Hwc2::AidlTransform* outTransform) const {
+ auto error = mComposer.getPhysicalDisplayOrientation(mId, outTransform);
+ return static_cast<Error>(error);
+}
+
Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
std::vector<Hwc2::Layer> layerIds;
std::vector<Composition> types;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index c03cede..d78562d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -169,6 +169,8 @@
support) = 0;
[[clang::warn_unused_result]] virtual hal::Error setIdleTimerEnabled(
std::chrono::milliseconds timeout) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getPhysicalDisplayOrientation(
+ Hwc2::AidlTransform* outTransform) const = 0;
};
namespace impl {
@@ -256,6 +258,7 @@
bool isVsyncPeriodSwitchSupported() const override;
bool hasDisplayIdleTimerCapability() const override;
void onLayerDestroyed(hal::HWLayerId layerId) override;
+ hal::Error getPhysicalDisplayOrientation(Hwc2::AidlTransform* outTransform) const override;
private:
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 02b3772..d4574df 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -986,9 +986,19 @@
return NO_ERROR;
}
-bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) {
+bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
- return mDisplayData[displayId].hwcDisplay->hasDisplayIdleTimerCapability();
+ return mDisplayData.at(displayId).hwcDisplay->hasDisplayIdleTimerCapability();
+}
+
+Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
+ ATRACE_CALL();
+ RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
+ Hwc2::AidlTransform outTransform;
+ const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
+ const auto error = hwcDisplay->getPhysicalDisplayOrientation(&outTransform);
+ RETURN_IF_HWC_ERROR(error, displayId, Hwc2::AidlTransform::NONE);
+ return outTransform;
}
void HWComposer::loadLayerMetadataSupport() {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f9637f0..20b7f4e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -268,7 +268,8 @@
std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) = 0;
virtual status_t setIdleTimerEnabled(PhysicalDisplayId, std::chrono::milliseconds timeout) = 0;
- virtual bool hasDisplayIdleTimerCapability(PhysicalDisplayId) = 0;
+ virtual bool hasDisplayIdleTimerCapability(PhysicalDisplayId) const = 0;
+ virtual Hwc2::AidlTransform getPhysicalDisplayOrientation(PhysicalDisplayId) const = 0;
};
namespace impl {
@@ -405,7 +406,8 @@
std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) override;
status_t setIdleTimerEnabled(PhysicalDisplayId, std::chrono::milliseconds timeout) override;
- bool hasDisplayIdleTimerCapability(PhysicalDisplayId) override;
+ bool hasDisplayIdleTimerCapability(PhysicalDisplayId) const override;
+ Hwc2::AidlTransform getPhysicalDisplayOrientation(PhysicalDisplayId) const override;
// for debugging ----------------------------------------------------------
void dump(std::string& out) const override;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 33adceb..e8dc084 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -237,6 +237,7 @@
case OptionalFeature::DisplayBrightnessCommand:
case OptionalFeature::BootDisplayConfig:
case OptionalFeature::KernelIdleTimer:
+ case OptionalFeature::PhysicalDisplayOrientation:
return false;
}
}
@@ -1331,6 +1332,11 @@
"OptionalFeature::KernelIdleTimer is not supported on HIDL");
}
+Error HidlComposer::getPhysicalDisplayOrientation(Display, AidlTransform*) {
+ LOG_ALWAYS_FATAL("getPhysicalDisplayOrientation should have never been called on this as "
+ "OptionalFeature::PhysicalDisplayOrientation is not supported on HIDL");
+}
+
void HidlComposer::registerCallback(ComposerCallback& callback) {
const bool vsyncSwitchingSupported =
isSupported(Hwc2::Composer::OptionalFeature::RefreshRateSwitching);
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index a1ea4f2..5869ae5 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -334,6 +334,9 @@
support) override;
Error setIdleTimerEnabled(Display displayId, std::chrono::milliseconds timeout) override;
+ Error getPhysicalDisplayOrientation(Display displayId,
+ AidlTransform* outDisplayOrientation) override;
+
private:
class CommandWriter : public CommandWriterBase {
public:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 425b78b..6a06d95 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -324,7 +324,6 @@
uint32_t SurfaceFlinger::maxGraphicsWidth;
uint32_t SurfaceFlinger::maxGraphicsHeight;
bool SurfaceFlinger::hasWideColorDisplay;
-ui::Rotation SurfaceFlinger::internalDisplayOrientation = ui::ROTATION_0;
bool SurfaceFlinger::useContextPriority;
Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
@@ -416,22 +415,6 @@
useContextPriority = use_context_priority(true);
- using Values = SurfaceFlingerProperties::primary_display_orientation_values;
- switch (primary_display_orientation(Values::ORIENTATION_0)) {
- case Values::ORIENTATION_0:
- break;
- case Values::ORIENTATION_90:
- internalDisplayOrientation = ui::ROTATION_90;
- break;
- case Values::ORIENTATION_180:
- internalDisplayOrientation = ui::ROTATION_180;
- break;
- case Values::ORIENTATION_270:
- internalDisplayOrientation = ui::ROTATION_270;
- break;
- }
- ALOGV("Internal Display Orientation: %s", toCString(internalDisplayOrientation));
-
mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();
// debugging stuff...
@@ -1014,9 +997,7 @@
info->secure = display->isSecure();
info->deviceProductInfo = display->getDeviceProductInfo();
-
- // TODO: Scale this to multiple displays.
- info->installOrientation = display->isPrimary() ? internalDisplayOrientation : ui::ROTATION_0;
+ info->installOrientation = display->getPhysicalOrientation();
return NO_ERROR;
}
@@ -1054,9 +1035,8 @@
auto xDpi = mode->getDpiX();
auto yDpi = mode->getDpiY();
- if (display->isPrimary() &&
- (internalDisplayOrientation == ui::ROTATION_90 ||
- internalDisplayOrientation == ui::ROTATION_270)) {
+ if (const auto physicalOrientation = display->getPhysicalOrientation();
+ physicalOrientation == ui::ROTATION_90 || physicalOrientation == ui::ROTATION_270) {
std::swap(width, height);
std::swap(xDpi, yDpi);
}
@@ -2394,6 +2374,42 @@
return true;
}
+ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId,
+ bool isPrimary) const {
+ const auto id = PhysicalDisplayId::tryCast(displayId);
+ if (!id) {
+ return ui::ROTATION_0;
+ }
+ if (getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {
+ switch (getHwComposer().getPhysicalDisplayOrientation(*id)) {
+ case Hwc2::AidlTransform::ROT_90:
+ return ui::ROTATION_90;
+ case Hwc2::AidlTransform::ROT_180:
+ return ui::ROTATION_180;
+ case Hwc2::AidlTransform::ROT_270:
+ return ui::ROTATION_270;
+ default:
+ return ui::ROTATION_0;
+ }
+ }
+
+ if (isPrimary) {
+ using Values = SurfaceFlingerProperties::primary_display_orientation_values;
+ switch (primary_display_orientation(Values::ORIENTATION_0)) {
+ case Values::ORIENTATION_90:
+ return ui::ROTATION_90;
+ case Values::ORIENTATION_180:
+ return ui::ROTATION_180;
+ case Values::ORIENTATION_270:
+ return ui::ROTATION_270;
+ default:
+ break;
+ }
+ }
+ return ui::ROTATION_0;
+}
+
void SurfaceFlinger::postComposition() {
ATRACE_CALL();
ALOGV("postComposition");
@@ -2873,7 +2889,8 @@
}
creationArgs.physicalOrientation =
- creationArgs.isPrimary ? internalDisplayOrientation : ui::ROTATION_0;
+ getPhysicalDisplayOrientation(compositionDisplay->getId(), creationArgs.isPrimary);
+ ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
// virtual displays are always considered enabled
creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index fa65803..3369a86 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -256,8 +256,6 @@
// found on devices with wide color gamut (e.g. Display-P3) display.
static bool hasWideColorDisplay;
- static ui::Rotation internalDisplayOrientation;
-
// Indicate if device wants color management on its display.
static const constexpr bool useColorManagement = true;
@@ -1145,6 +1143,9 @@
bool isHdrLayer(Layer* layer) const;
+ ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const
+ REQUIRES(mStateLock);
+
sp<StartPropertySetThread> mStartPropertySetThread;
surfaceflinger::Factory& mFactory;
pid_t mPid;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
index afc1abd..a5a716d 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
@@ -29,9 +29,6 @@
LatchUnsignaledConfig::Disabled,
};
-static constexpr ui::Rotation kRotations[] = {ui::Rotation::Rotation0, ui::Rotation::Rotation90,
- ui::Rotation::Rotation180, ui::Rotation::Rotation270};
-
static constexpr BnSurfaceComposer::ISurfaceComposerTag kSurfaceComposerTags[]{
BnSurfaceComposer::BOOT_FINISHED,
BnSurfaceComposer::CREATE_CONNECTION,
@@ -134,7 +131,6 @@
mFlinger->maxGraphicsWidth = mFdp.ConsumeIntegral<uint32_t>();
mFlinger->maxGraphicsHeight = mFdp.ConsumeIntegral<uint32_t>();
mFlinger->hasWideColorDisplay = mFdp.ConsumeBool();
- mFlinger->internalDisplayOrientation = mFdp.PickValueInArray(kRotations);
mFlinger->useContextPriority = mFdp.ConsumeBool();
mFlinger->defaultCompositionDataspace = mFdp.PickValueInArray(kDataspaces);
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 996f835..c1d41bb 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -160,6 +160,7 @@
Error(Display, std::optional<DisplayDecorationSupport>*));
MOCK_METHOD2(setIdleTimerEnabled, Error(Display, std::chrono::milliseconds));
MOCK_METHOD2(hasDisplayIdleTimerCapability, Error(Display, bool*));
+ MOCK_METHOD2(getPhysicalDisplayOrientation, Error(Display, AidlTransform*));
};
} // namespace Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index d9faa06..ac2ab199c 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -101,6 +101,8 @@
(override));
MOCK_METHOD(hal::Error, setIdleTimerEnabled, (std::chrono::milliseconds), (override));
MOCK_METHOD(bool, hasDisplayIdleTimerCapability, (), (const override));
+ MOCK_METHOD(hal::Error, getPhysicalDisplayOrientation, (Hwc2::AidlTransform *),
+ (const override));
};
class Layer : public HWC2::Layer {