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

Commit c5de5b39 authored by Steven Thomas's avatar Steven Thomas Committed by Android (Google) Code Review
Browse files

Merge "Fix usage of HWC_DISPLAY_PRIMARY in vr flinger"

parents ebd62af1 6e8f706c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -38,10 +38,12 @@ namespace android {
namespace dvr {

DisplayService::DisplayService(Hwc2::Composer* hidl,
                               hwc2_display_t primary_display_id,
                               RequestDisplayCallback request_display_callback)
    : BASE("DisplayService",
           Endpoint::Create(display::DisplayProtocol::kClientPath)) {
  hardware_composer_.Initialize(hidl, request_display_callback);
    hardware_composer_.Initialize(
        hidl, primary_display_id, request_display_callback);
}

bool DisplayService::IsInitialized() const {
+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
  using RequestDisplayCallback = std::function<void(bool)>;

  DisplayService(android::Hwc2::Composer* hidl,
                 hwc2_display_t primary_display_id,
                 RequestDisplayCallback request_display_callback);

  pdx::Status<BorrowedNativeBufferHandle> OnGetGlobalBuffer(
+54 −64
Original line number Diff line number Diff line
@@ -121,7 +121,8 @@ HardwareComposer::~HardwareComposer(void) {
}

bool HardwareComposer::Initialize(
    Hwc2::Composer* composer, RequestDisplayCallback request_display_callback) {
    Hwc2::Composer* composer, hwc2_display_t primary_display_id,
    RequestDisplayCallback request_display_callback) {
  if (initialized_) {
    ALOGE("HardwareComposer::Initialize: already initialized.");
    return false;
@@ -134,7 +135,7 @@ bool HardwareComposer::Initialize(
  HWC::Error error = HWC::Error::None;

  Hwc2::Config config;
  error = composer->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
  error = composer->getActiveConfig(primary_display_id, &config);

  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer: Failed to get current display config : %d",
@@ -142,7 +143,7 @@ bool HardwareComposer::Initialize(
    return false;
  }

  error = GetDisplayMetrics(composer, HWC_DISPLAY_PRIMARY, config,
  error = GetDisplayMetrics(composer, primary_display_id, config,
                            &native_display_metrics_);

  if (error != HWC::Error::None) {
@@ -233,7 +234,10 @@ void HardwareComposer::OnPostThreadResumed() {
    composer_.reset(new Hwc2::Composer("default"));
    composer_callback_ = new ComposerCallback;
    composer_->registerCallback(composer_callback_);
    LOG_ALWAYS_FATAL_IF(!composer_callback_->HasDisplayId(),
        "Registered composer callback but didn't get primary display");
    Layer::SetComposer(composer_.get());
    Layer::SetDisplayId(composer_callback_->GetDisplayId());
  } else {
    SetPowerMode(true);
  }
@@ -263,6 +267,7 @@ void HardwareComposer::OnPostThreadPaused() {
    composer_callback_ = nullptr;
    composer_.reset(nullptr);
    Layer::SetComposer(nullptr);
    Layer::SetDisplayId(0);
  } else {
    SetPowerMode(false);
  }
@@ -290,7 +295,7 @@ HWC::Error HardwareComposer::Validate(hwc2_display_t display) {

HWC::Error HardwareComposer::EnableVsync(bool enabled) {
  return composer_->setVsyncEnabled(
      HWC_DISPLAY_PRIMARY,
      composer_callback_->GetDisplayId(),
      (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
                                             : HWC2_VSYNC_DISABLE));
}
@@ -298,7 +303,8 @@ HWC::Error HardwareComposer::EnableVsync(bool enabled) {
HWC::Error HardwareComposer::SetPowerMode(bool active) {
  HWC::PowerMode power_mode = active ? HWC::PowerMode::On : HWC::PowerMode::Off;
  return composer_->setPowerMode(
      HWC_DISPLAY_PRIMARY, power_mode.cast<Hwc2::IComposerClient::PowerMode>());
      composer_callback_->GetDisplayId(),
      power_mode.cast<Hwc2::IComposerClient::PowerMode>());
}

HWC::Error HardwareComposer::Present(hwc2_display_t display) {
@@ -419,7 +425,7 @@ void HardwareComposer::PostLayers() {
    layer.Prepare();
  }

  HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
  HWC::Error error = Validate(composer_callback_->GetDisplayId());
  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
          error.to_string().c_str());
@@ -466,7 +472,7 @@ void HardwareComposer::PostLayers() {
  }
#endif

  error = Present(HWC_DISPLAY_PRIMARY);
  error = Present(composer_callback_->GetDisplayId());
  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer::PostLayers: Present failed: %s",
          error.to_string().c_str());
@@ -475,8 +481,8 @@ void HardwareComposer::PostLayers() {

  std::vector<Hwc2::Layer> out_layers;
  std::vector<int> out_fences;
  error = composer_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
                                      &out_fences);
  error = composer_->getReleaseFences(composer_callback_->GetDisplayId(),
                                      &out_layers, &out_fences);
  ALOGE_IF(error != HWC::Error::None,
           "HardwareComposer::PostLayers: Failed to get release fences: %s",
           error.to_string().c_str());
@@ -615,14 +621,6 @@ int HardwareComposer::PostThreadPollInterruptible(
  }
}

Status<int64_t> HardwareComposer::GetVSyncTime() {
  auto status = composer_callback_->GetVsyncTime(HWC_DISPLAY_PRIMARY);
  ALOGE_IF(!status,
           "HardwareComposer::GetVSyncTime: Failed to get vsync timestamp: %s",
           status.GetErrorMessage().c_str());
  return status;
}

// Waits for the next vsync and returns the timestamp of the vsync event. If
// vsync already passed since the last call, returns the latest vsync timestamp
// instead of blocking.
@@ -795,8 +793,7 @@ void HardwareComposer::PostThread() {
    // Signal all of the vsync clients. Because absolute time is used for the
    // wakeup time below, this can take a little time if necessary.
    if (vsync_callback_)
      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp,
                      /*frame_time_estimate*/ 0, vsync_count_);
      vsync_callback_(vsync_timestamp, /*frame_time_estimate*/ 0, vsync_count_);

    {
      // Sleep until shortly before vsync.
@@ -819,7 +816,7 @@ void HardwareComposer::PostThread() {
            // If the layer config changed we need to validateDisplay() even if
            // we're going to drop the frame, to flush the Composer object's
            // internal command buffer and apply our layer changes.
            Validate(HWC_DISPLAY_PRIMARY);
            Validate(composer_callback_->GetDisplayId());
          }
          continue;
        }
@@ -827,7 +824,7 @@ void HardwareComposer::PostThread() {
    }

    {
      auto status = GetVSyncTime();
      auto status = composer_callback_->GetVsyncTime();
      if (!status) {
        ALOGE("HardwareComposer::PostThread: Failed to get VSYNC time: %s",
              status.GetErrorMessage().c_str());
@@ -946,10 +943,17 @@ void HardwareComposer::SetBacklightBrightness(int brightness) {
}

Return<void> HardwareComposer::ComposerCallback::onHotplug(
    Hwc2::Display display, IComposerCallback::Connection /*conn*/) {
  // See if the driver supports the vsync_event node in sysfs.
  if (display < HWC_NUM_PHYSICAL_DISPLAY_TYPES &&
      !displays_[display].driver_vsync_event_fd) {
    Hwc2::Display display, IComposerCallback::Connection conn) {
  // Our first onHotplug callback is always for the primary display.
  //
  // Ignore any other hotplug callbacks since the primary display is never
  // disconnected and we don't care about other displays.
  if (!has_display_id_) {
    LOG_ALWAYS_FATAL_IF(conn != IComposerCallback::Connection::CONNECTED,
        "Initial onHotplug callback should be primary display connected");
    has_display_id_ = true;
    display_id_ = display;

    std::array<char, 1024> buffer;
    snprintf(buffer.data(), buffer.size(),
             "/sys/class/graphics/fb%" PRIu64 "/vsync_event", display);
@@ -958,7 +962,7 @@ Return<void> HardwareComposer::ComposerCallback::onHotplug(
          "HardwareComposer::ComposerCallback::onHotplug: Driver supports "
          "vsync_event node for display %" PRIu64,
          display);
      displays_[display].driver_vsync_event_fd = std::move(handle);
      driver_vsync_event_fd_ = std::move(handle);
    } else {
      ALOGI(
          "HardwareComposer::ComposerCallback::onHotplug: Driver does not "
@@ -977,36 +981,23 @@ Return<void> HardwareComposer::ComposerCallback::onRefresh(

Return<void> HardwareComposer::ComposerCallback::onVsync(Hwc2::Display display,
                                                         int64_t timestamp) {
  // Ignore any onVsync callbacks for the non-primary display.
  if (has_display_id_ && display == display_id_) {
    TRACE_FORMAT("vsync_callback|display=%" PRIu64 ";timestamp=%" PRId64 "|",
                 display, timestamp);
  if (display < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
    displays_[display].callback_vsync_timestamp = timestamp;
  } else {
    ALOGW(
        "HardwareComposer::ComposerCallback::onVsync: Received vsync on "
        "non-physical display: display=%" PRId64,
        display);
    callback_vsync_timestamp_ = timestamp;
  }
  return Void();
}

Status<int64_t> HardwareComposer::ComposerCallback::GetVsyncTime(
    Hwc2::Display display) {
  if (display >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
    ALOGE(
        "HardwareComposer::ComposerCallback::GetVsyncTime: Invalid physical "
        "display requested: display=%" PRIu64,
        display);
    return ErrorStatus(EINVAL);
  }

Status<int64_t> HardwareComposer::ComposerCallback::GetVsyncTime() {
  // See if the driver supports direct vsync events.
  LocalHandle& event_fd = displays_[display].driver_vsync_event_fd;
  LocalHandle& event_fd = driver_vsync_event_fd_;
  if (!event_fd) {
    // Fall back to returning the last timestamp returned by the vsync
    // callback.
    std::lock_guard<std::mutex> autolock(vsync_mutex_);
    return displays_[display].callback_vsync_timestamp;
    return callback_vsync_timestamp_;
  }

  // When the driver supports the vsync_event sysfs node we can use it to
@@ -1056,10 +1047,11 @@ Status<int64_t> HardwareComposer::ComposerCallback::GetVsyncTime(

Hwc2::Composer* Layer::composer_{nullptr};
HWCDisplayMetrics Layer::display_metrics_{0, 0, {0, 0}, 0};
hwc2_display_t Layer::display_id_{0};

void Layer::Reset() {
  if (hardware_composer_layer_) {
    composer_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
    composer_->destroyLayer(display_id_, hardware_composer_layer_);
    hardware_composer_layer_ = 0;
  }

@@ -1154,17 +1146,16 @@ void Layer::UpdateVisibilitySettings() {
    pending_visibility_settings_ = false;

    HWC::Error error;
    hwc2_display_t display = HWC_DISPLAY_PRIMARY;

    error = composer_->setLayerBlendMode(
        display, hardware_composer_layer_,
        display_id_, hardware_composer_layer_,
        blending_.cast<Hwc2::IComposerClient::BlendMode>());
    ALOGE_IF(error != HWC::Error::None,
             "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
             error.to_string().c_str());

    error =
        composer_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
    error = composer_->setLayerZOrder(display_id_, hardware_composer_layer_,
                                      z_order_);
    ALOGE_IF(error != HWC::Error::None,
             "Layer::UpdateLayerSettings: Error setting z_ order: %s",
             error.to_string().c_str());
@@ -1173,36 +1164,35 @@ void Layer::UpdateVisibilitySettings() {

void Layer::UpdateLayerSettings() {
  HWC::Error error;
  hwc2_display_t display = HWC_DISPLAY_PRIMARY;

  UpdateVisibilitySettings();

  // TODO(eieio): Use surface attributes or some other mechanism to control
  // the layer display frame.
  error = composer_->setLayerDisplayFrame(
      display, hardware_composer_layer_,
      display_id_, hardware_composer_layer_,
      {0, 0, display_metrics_.width, display_metrics_.height});
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
           error.to_string().c_str());

  error = composer_->setLayerVisibleRegion(
      display, hardware_composer_layer_,
      display_id_, hardware_composer_layer_,
      {{0, 0, display_metrics_.width, display_metrics_.height}});
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
           error.to_string().c_str());

  error =
      composer_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
  error = composer_->setLayerPlaneAlpha(display_id_, hardware_composer_layer_,
                                        1.0f);
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
           error.to_string().c_str());
}

void Layer::CommonLayerSetup() {
  HWC::Error error =
      composer_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
  HWC::Error error = composer_->createLayer(display_id_,
                                            &hardware_composer_layer_);
  ALOGE_IF(error != HWC::Error::None,
           "Layer::CommonLayerSetup: Failed to create layer on primary "
           "display: %s",
@@ -1246,10 +1236,10 @@ void Layer::Prepare() {
    if (composition_type_ == HWC::Composition::Invalid) {
      composition_type_ = HWC::Composition::SolidColor;
      composer_->setLayerCompositionType(
          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
          display_id_, hardware_composer_layer_,
          composition_type_.cast<Hwc2::IComposerClient::Composition>());
      Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
      composer_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
      composer_->setLayerColor(display_id_, hardware_composer_layer_,
                               layer_color);
    } else {
      // The composition type is already set. Nothing else to do until a
@@ -1259,7 +1249,7 @@ void Layer::Prepare() {
    if (composition_type_ != target_composition_type_) {
      composition_type_ = target_composition_type_;
      composer_->setLayerCompositionType(
          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
          display_id_, hardware_composer_layer_,
          composition_type_.cast<Hwc2::IComposerClient::Composition>());
    }

@@ -1270,7 +1260,7 @@ void Layer::Prepare() {

    HWC::Error error{HWC::Error::None};
    error =
        composer_->setLayerBuffer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
        composer_->setLayerBuffer(display_id_, hardware_composer_layer_,
                                  slot, handle, acquire_fence_.Get());

    ALOGE_IF(error != HWC::Error::None,
@@ -1280,7 +1270,7 @@ void Layer::Prepare() {
    if (!surface_rect_functions_applied_) {
      const float float_right = right;
      const float float_bottom = bottom;
      error = composer_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
      error = composer_->setLayerSourceCrop(display_id_,
                                            hardware_composer_layer_,
                                            {0, 0, float_right, float_bottom});

+19 −9
Original line number Diff line number Diff line
@@ -152,6 +152,11 @@ class Layer {
    display_metrics_ = display_metrics;
  }

  // Sets the display id used by all Layer instances.
  static void SetDisplayId(hwc2_display_t display_id) {
    display_id_ = display_id;
  }

 private:
  void CommonLayerSetup();

@@ -180,6 +185,11 @@ class Layer {
  // thereafter.
  static HWCDisplayMetrics display_metrics_;

  // Id of the primary display. Shared by all instances of Layer. This must be
  // set whenever the primary display id changes. This can be left unset as long
  // as there are no instances of Layer that might need to use it.
  static hwc2_display_t display_id_;

  // The hardware composer layer and metrics to use during the prepare cycle.
  hwc2_layer_t hardware_composer_layer_ = 0;

@@ -298,13 +308,14 @@ class Layer {
class HardwareComposer {
 public:
  // Type for vsync callback.
  using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
  using VSyncCallback = std::function<void(int64_t, int64_t, uint32_t)>;
  using RequestDisplayCallback = std::function<void(bool)>;

  HardwareComposer();
  ~HardwareComposer();

  bool Initialize(Hwc2::Composer* composer,
                  hwc2_display_t primary_display_id,
                  RequestDisplayCallback request_display_callback);

  bool IsInitialized() const { return initialized_; }
@@ -362,16 +373,16 @@ class HardwareComposer {
    hardware::Return<void> onVsync(Hwc2::Display display,
                                   int64_t timestamp) override;

    pdx::Status<int64_t> GetVsyncTime(Hwc2::Display display);
    bool HasDisplayId() { return has_display_id_; }
    hwc2_display_t GetDisplayId() { return display_id_; }
    pdx::Status<int64_t> GetVsyncTime();

   private:
    std::mutex vsync_mutex_;

    struct Display {
      pdx::LocalHandle driver_vsync_event_fd;
      int64_t callback_vsync_timestamp{0};
    };
    std::array<Display, HWC_NUM_PHYSICAL_DISPLAY_TYPES> displays_;
    bool has_display_id_ = false;
    hwc2_display_t display_id_;
    pdx::LocalHandle driver_vsync_event_fd_;
    int64_t callback_vsync_timestamp_{0};
  };

  HWC::Error Validate(hwc2_display_t display);
@@ -412,7 +423,6 @@ class HardwareComposer {
  // kPostThreadInterrupted.
  int ReadWaitPPState();
  pdx::Status<int64_t> WaitForVSync();
  pdx::Status<int64_t> GetVSyncTime();
  int SleepUntil(int64_t wakeup_timestamp);

  // Reconfigures the layer stack if the display surfaces changed since the last
+10 −1
Original line number Diff line number Diff line
@@ -4,6 +4,12 @@
#include <thread>
#include <memory>

#define HWC2_INCLUDE_STRINGIFICATION
#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11

#include <pdx/service_dispatcher.h>
#include <vr/vr_manager/vr_manager.h>

@@ -21,7 +27,9 @@ class VrFlinger {
 public:
  using RequestDisplayCallback = std::function<void(bool)>;
  static std::unique_ptr<VrFlinger> Create(
      Hwc2::Composer* hidl, RequestDisplayCallback request_display_callback);
      Hwc2::Composer* hidl,
      hwc2_display_t primary_display_id,
      RequestDisplayCallback request_display_callback);
  ~VrFlinger();

  // These functions are all called on surface flinger's main thread.
@@ -35,6 +43,7 @@ class VrFlinger {
 private:
  VrFlinger();
  bool Init(Hwc2::Composer* hidl,
            hwc2_display_t primary_display_id,
            RequestDisplayCallback request_display_callback);

  // Needs to be a separate class for binder's ref counting
Loading