Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 016e5e3c authored by Stephen Kiazyk's avatar Stephen Kiazyk
Browse files

Ensure display metrics on display service creation

This fixes a potential race condition where a VR app could request the
display metrics from the VR display service before it actually queries
them from the HWC.

Bug: None
Test: Compiled and ran Vr app.
Change-Id: Ie95b7f5a8ef2e286c7b2994ca94fd87214567e24
parent ae39f8cf
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -25,7 +25,13 @@ DisplayService::DisplayService() : DisplayService(nullptr) {}

DisplayService::DisplayService(Hwc2::Composer* hidl)
    : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
      hardware_composer_(hidl) {}
      hardware_composer_(hidl) {
  hardware_composer_.Initialize();
}

bool DisplayService::IsInitialized() const {
  return BASE::IsInitialized() && hardware_composer_.IsInitialized();
}

std::string DisplayService::DumpState(size_t max_length) {
  std::vector<char> buffer(max_length);
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ namespace dvr {
// DisplayService implements the displayd display service over ServiceFS.
class DisplayService : public pdx::ServiceBase<DisplayService> {
 public:
  bool IsInitialized() const override;
  std::string DumpState(size_t max_length) override;

  void OnChannelClose(pdx::Message& message,
+35 −45
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ HardwareComposer::HardwareComposer()
}

HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
    : hwc2_hidl_(hwc2_hidl),
    : initialized_(false),
      hwc2_hidl_(hwc2_hidl),
      display_transform_(HWC_TRANSFORM_NONE),
      display_surfaces_updated_(false),
      hardware_layers_need_update_(false),
@@ -126,65 +127,34 @@ HardwareComposer::~HardwareComposer(void) {
  Suspend();
}

bool HardwareComposer::Resume() {
  std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
  if (post_thread_state_ == PostThreadState::kRunning) {
bool HardwareComposer::Initialize() {
  if (initialized_) {
    ALOGE("HardwareComposer::Initialize: already initialized.");
    return false;
  }

  std::lock_guard<std::mutex> layer_lock(layer_mutex_);

  int32_t ret = HWC2_ERROR_NONE;

  static const uint32_t attributes[] = {
      HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_VSYNC_PERIOD,
      HWC_DISPLAY_DPI_X, HWC_DISPLAY_DPI_Y,  HWC_DISPLAY_NO_ATTRIBUTE,
  };

  std::vector<Hwc2::Config> configs;
  ret = (int32_t)hwc2_hidl_->getDisplayConfigs(HWC_DISPLAY_PRIMARY, &configs);
  Hwc2::Config config;
  ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);

  if (ret != HWC2_ERROR_NONE) {
    ALOGE("HardwareComposer: Failed to get display configs");
    ALOGE("HardwareComposer: Failed to get current display config : %d",
          config);
    return false;
  }

  uint32_t num_configs = configs.size();

  for (size_t i = 0; i < num_configs; i++) {
    ALOGI("HardwareComposer: cfg[%zd/%zd] = 0x%08x", i, num_configs,
          configs[i]);

    ret = GetDisplayMetrics(HWC_DISPLAY_PRIMARY, configs[i],
                            &native_display_metrics_);

    if (ret != HWC2_ERROR_NONE) {
      ALOGE("HardwareComposer: Failed to get display attributes %d", ret);
      continue;
    } else {
  ret =
          (int32_t)hwc2_hidl_->setActiveConfig(HWC_DISPLAY_PRIMARY, configs[i]);
      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);

  if (ret != HWC2_ERROR_NONE) {
        ALOGE("HardwareComposer: Failed to set display configuration; ret=%d",
    ALOGE(
        "HardwareComposer: Failed to get display attributes for current "
        "configuration : %d",
        ret);
        continue;
      }

      break;
    }
  }

  if (ret != HWC2_ERROR_NONE) {
    ALOGE("HardwareComposer: Could not set a valid display configuration.");
    return false;
  }

  // Set the display metrics but never use rotation to avoid the long latency of
  // rotation processing in hwc.
  display_transform_ = HWC_TRANSFORM_NONE;
  display_metrics_ = native_display_metrics_;

  ALOGI(
      "HardwareComposer: primary display attributes: width=%d height=%d "
      "vsync_period_ns=%d DPI=%dx%d",
@@ -192,6 +162,26 @@ bool HardwareComposer::Resume() {
      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
      native_display_metrics_.dpi.y);

  // Set the display metrics but never use rotation to avoid the long latency of
  // rotation processing in hwc.
  display_transform_ = HWC_TRANSFORM_NONE;
  display_metrics_ = native_display_metrics_;

  initialized_ = true;

  return initialized_;
}

bool HardwareComposer::Resume() {
  std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
  if (post_thread_state_ == PostThreadState::kRunning) {
    return false;
  }

  std::lock_guard<std::mutex> layer_lock(layer_mutex_);

  int32_t ret = HWC2_ERROR_NONE;

  // Always turn off vsync when we start.
  EnableVsync(false);

+6 −0
Original line number Diff line number Diff line
@@ -189,6 +189,10 @@ class HardwareComposer {
  HardwareComposer(Hwc2::Composer* hidl);
  ~HardwareComposer();

  bool Initialize();

  bool IsInitialized() const { return initialized_; }

  bool Suspend();
  bool Resume();

@@ -303,6 +307,8 @@ class HardwareComposer {

  void HandlePendingScreenshots();

  bool initialized_;

  // Hardware composer HAL device.
  std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
  sp<ComposerCallback> callbacks_;