drm_hwcomposer: Implement getDisplayConfigurations
This deprecates calls like getDisplayConfigs and getDisplayAttribute.
Once HWC2 support has been removed from drm_hwcomposer, the legacy calls
could be implemented by calling getDisplayConfigurations.
The main different between the two is that in HWC3, the dpi is in
dots-per-inch and its unit is float. In HWC2, the dpi is in
dots-per-1000-inches and its unit is int32.
Change-Id: I9eed17d6f575bc05f1794dc0575f268fe1fc297d
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 789ac79..36333d2 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -347,8 +347,8 @@
return HWC2::Error::None;
}
-HWC2::Error HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
- hwc2_config_t *configs) {
+HWC2::Error HwcDisplay::LegacyGetDisplayConfigs(uint32_t *num_configs,
+ hwc2_config_t *configs) {
uint32_t idx = 0;
for (auto &hwc_config : configs_.hwc_configs) {
if (hwc_config.second.disabled) {
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 9fe555d..87d2da7 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -54,6 +54,10 @@
std::string Dump();
+ const HwcDisplayConfigs &GetDisplayConfigs() const {
+ return configs_;
+ }
+
// HWC Hooks
HWC2::Error AcceptDisplayChanges();
HWC2::Error CreateLayer(hwc2_layer_t *layer);
@@ -66,7 +70,8 @@
HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
int32_t *value);
- HWC2::Error GetDisplayConfigs(uint32_t *num_configs, hwc2_config_t *configs);
+ HWC2::Error LegacyGetDisplayConfigs(uint32_t *num_configs,
+ hwc2_config_t *configs);
HWC2::Error GetDisplayName(uint32_t *size, char *name);
HWC2::Error GetDisplayRequests(int32_t *display_requests,
uint32_t *num_elements, hwc2_layer_t *layers,
diff --git a/hwc2_device/hwc2_device.cpp b/hwc2_device/hwc2_device.cpp
index bd2ada5..28b6963 100644
--- a/hwc2_device/hwc2_device.cpp
+++ b/hwc2_device/hwc2_device.cpp
@@ -177,8 +177,8 @@
int32_t *>);
case HWC2::FunctionDescriptor::GetDisplayConfigs:
return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
- DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
- &HwcDisplay::GetDisplayConfigs, uint32_t *,
+ DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
+ &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
hwc2_config_t *>);
case HWC2::FunctionDescriptor::GetDisplayName:
return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index a3e5ebc..f353abb 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -42,11 +42,13 @@
#include "cutils/native_handle.h"
#include "hardware/hwcomposer_defs.h"
#include "hwc2_device/HwcDisplay.h"
+#include "hwc2_device/HwcDisplayConfigs.h"
#include "hwc2_device/HwcLayer.h"
#include "hwc3/DrmHwcThree.h"
#include "hwc3/Utils.h"
using ::android::HwcDisplay;
+using ::android::HwcDisplayConfigs;
#include "utils/log.h"
@@ -522,14 +524,14 @@
uint32_t num_configs = 0;
hwc3::Error error = Hwc2toHwc3Error(
- display->GetDisplayConfigs(&num_configs, nullptr));
+ display->LegacyGetDisplayConfigs(&num_configs, nullptr));
if (error != hwc3::Error::kNone) {
return ToBinderStatus(error);
}
std::vector<hwc2_config_t> out_configs(num_configs);
error = Hwc2toHwc3Error(
- display->GetDisplayConfigs(&num_configs, out_configs.data()));
+ display->LegacyGetDisplayConfigs(&num_configs, out_configs.data()));
if (error != hwc3::Error::kNone) {
return ToBinderStatus(error);
}
@@ -953,9 +955,41 @@
}
ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
- int64_t display, int32_t max_frame_interval_ns,
+ int64_t display_id, int32_t /*max_frame_interval_ns*/,
std::vector<DisplayConfiguration>* configurations) {
- return ToBinderStatus(hwc3::Error::kUnsupported);
+ DEBUG_FUNC();
+ const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+ HwcDisplay* display = GetDisplay(display_id);
+ if (display == nullptr) {
+ return ToBinderStatus(hwc3::Error::kBadDisplay);
+ }
+
+ const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
+ for (const auto& [id, config] : configs.hwc_configs) {
+ static const int kNanosecondsPerSecond = 1E9;
+ configurations->emplace_back(
+ DisplayConfiguration{.configId = static_cast<int32_t>(config.id),
+ .width = config.mode.GetRawMode().hdisplay,
+ .height = config.mode.GetRawMode().vdisplay,
+ .configGroup = static_cast<int32_t>(
+ config.group_id),
+ .vsyncPeriod = static_cast<int>(kNanosecondsPerSecond * double(
+ 1 / config.mode.GetVRefresh()))});
+
+ if (configs.mm_width != 0) {
+ // ideally this should be vdisplay/mm_heigth, however mm_height
+ // comes from edid parsing and is highly unreliable. Viewing the
+ // rarity of anisotropic displays, falling back to a single value
+ // for dpi yield more correct output.
+ static const float kMmPerInch = 25.4;
+ float dpi = float(config.mode.GetRawMode().hdisplay) * kMmPerInch /
+ float(configs.mm_width);
+ configurations->back().dpi = {.x = dpi, .y = dpi};
+ }
+
+ // TODO: Populate vrrConfig.
+ }
+ return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus ComposerClient::notifyExpectedPresent(