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

Commit 436ddb14 authored by Steven Thomas's avatar Steven Thomas Committed by android-build-merger
Browse files

Merge "Support external display rendering in vr flinger" into pi-dev

am: 5f643f8f

Change-Id: I293f1615c1d9729b7f4b0c3e24a3273d574b1fe8
parents 8e272aac 5f643f8f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ cc_library_static {
    srcs: sourceFiles,
    export_include_dirs: includeFiles,

    clang: true,
    cflags: [
        "-DLOG_TAG=\"vr_flinger\"",
        "-DTRACE=0",
@@ -83,6 +84,9 @@ cc_library_static {
        "-Wno-error=sign-compare", // to fix later
        "-Wno-unused-variable",
    ],
    cppflags: [
        "-std=c++1z"
    ],
    shared_libs: sharedLibraries,
    whole_static_libs: staticLibraries,
    header_libs: headerLibraries,
+6 −6
Original line number Diff line number Diff line
@@ -177,12 +177,12 @@ Status<void> DisplayService::HandleMessage(pdx::Message& message) {

Status<display::Metrics> DisplayService::OnGetMetrics(
    pdx::Message& /*message*/) {
  return {{static_cast<uint32_t>(GetDisplayMetrics().width),
           static_cast<uint32_t>(GetDisplayMetrics().height),
           static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
           static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
           static_cast<uint32_t>(
               hardware_composer_.native_display_metrics().vsync_period_ns),
  const auto& params = hardware_composer_.GetPrimaryDisplayParams();
  return {{static_cast<uint32_t>(params.width),
           static_cast<uint32_t>(params.height),
           static_cast<uint32_t>(params.dpi.x),
           static_cast<uint32_t>(params.dpi.y),
           static_cast<uint32_t>(params.vsync_period_ns),
           0,
           0,
           0,
+0 −4
Original line number Diff line number Diff line
@@ -65,10 +65,6 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
    hardware_composer_.SetVSyncCallback(callback);
  }

  HWCDisplayMetrics GetDisplayMetrics() {
    return hardware_composer_.display_metrics();
  }

  void GrantDisplayOwnership() { hardware_composer_.Enable(); }
  void SeizeDisplayOwnership() { hardware_composer_.Disable(); }
  void OnBootFinished() { hardware_composer_.OnBootFinished(); }
+387 −224

File changed.

Preview size limit exceeded, changes collapsed.

+93 −85
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <condition_variable>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <tuple>
#include <vector>
@@ -35,16 +36,19 @@
namespace android {
namespace dvr {

// Basic display metrics for physical displays. Dimensions and densities are
// relative to the physical display orientation, which may be different from the
// logical display orientation exposed to applications.
struct HWCDisplayMetrics {
// Basic display metrics for physical displays.
struct DisplayParams {
  hwc2_display_t id;
  bool is_primary;

  int width;
  int height;

  struct {
    int x;
    int y;
  } dpi;

  int vsync_period_ns;
};

@@ -58,26 +62,29 @@ class Layer {
  // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
  // every frame.
  //
  // |composer| The composer instance.
  // |display_params| Info about the display to use.
  // |blending| receives HWC_BLENDING_* values.
  // |transform| receives HWC_TRANSFORM_* values.
  // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
  // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
  // |index| is the index of this surface in the DirectDisplaySurface array.
  Layer(const std::shared_ptr<DirectDisplaySurface>& surface,
        HWC::BlendMode blending, HWC::Transform transform,
        HWC::Composition composition_type, size_t z_roder);
  Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
        const std::shared_ptr<DirectDisplaySurface>& surface,
        HWC::BlendMode blending, HWC::Composition composition_type,
        size_t z_order);

  // Sets up the layer to use a direct buffer as its content source. No special
  // handling of the buffer is performed; responsibility for updating or
  // changing the buffer each frame is on the caller.
  //
  // |composer| The composer instance.
  // |display_params| Info about the display to use.
  // |blending| receives HWC_BLENDING_* values.
  // |transform| receives HWC_TRANSFORM_* values.
  // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
  // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
  Layer(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
        HWC::Transform transform, HWC::Composition composition_type,
        size_t z_order);
  Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
        const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
        HWC::Composition composition_type, size_t z_order);

  Layer(Layer&&);
  Layer& operator=(Layer&&);
@@ -144,17 +151,8 @@ class Layer {
  }
  bool operator<(int surface_id) const { return GetSurfaceId() < surface_id; }

  // Sets the composer instance used by all Layer instances.
  static void SetComposer(Hwc2::Composer* composer) { composer_ = composer; }

  // Sets the display metrics used by all Layer instances.
  static void SetDisplayMetrics(HWCDisplayMetrics display_metrics) {
    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;
  void IgnoreBadDisplayErrorsOnDestroy(bool ignore) {
    ignore_bad_display_errors_on_destroy_ = ignore;
  }

 private:
@@ -174,21 +172,11 @@ class Layer {
  // associated and always returns false.
  bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id);

  // Composer instance shared by all instances of Layer. This must be set
  // whenever a new instance of the Composer is created. This may be set to
  // nullptr as long as there are no instances of Layer that might need to use
  // it.
  static Hwc2::Composer* composer_;

  // Display metrics shared by all instances of Layer. This must be set at least
  // once during VrFlinger initialization and is expected to remain constant
  // thereafter.
  static HWCDisplayMetrics display_metrics_;
  // Composer instance.
  Hwc2::Composer* composer_ = nullptr;

  // 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_;
  // Parameters of the display to use for this layer.
  DisplayParams display_params_;

  // The hardware composer layer and metrics to use during the prepare cycle.
  hwc2_layer_t hardware_composer_layer_ = 0;
@@ -197,7 +185,6 @@ class Layer {
  // Prepare phase.
  size_t z_order_ = 0;
  HWC::BlendMode blending_ = HWC::BlendMode::None;
  HWC::Transform transform_ = HWC::Transform::None;
  HWC::Composition composition_type_ = HWC::Composition::Invalid;
  HWC::Composition target_composition_type_ = HWC::Composition::Device;

@@ -293,6 +280,12 @@ class Layer {
  // importing a buffer HWC already knows about.
  std::map<std::size_t, int> cached_buffer_map_;

  // When calling destroyLayer() on an external display that's been removed we
  // typically get HWC2_ERROR_BAD_DISPLAY errors. If
  // ignore_bad_display_errors_on_destroy_ is true, don't log the bad display
  // errors, since they're expected.
  bool ignore_bad_display_errors_on_destroy_ = false;

  Layer(const Layer&) = delete;
  void operator=(const Layer&) = delete;
};
@@ -330,22 +323,12 @@ class HardwareComposer {
  // Called on a binder thread.
  void OnBootFinished();

  // Get the HMD display metrics for the current display.
  display::Metrics GetHmdDisplayMetrics() const;

  std::string Dump();

  void SetVSyncCallback(VSyncCallback callback);

  // Metrics of the logical display, which is always landscape.
  int DisplayWidth() const { return display_metrics_.width; }
  int DisplayHeight() const { return display_metrics_.height; }
  HWCDisplayMetrics display_metrics() const { return display_metrics_; }

  // Metrics of the native display, which depends on the specific hardware
  // implementation of the display.
  HWCDisplayMetrics native_display_metrics() const {
    return native_display_metrics_;
  const DisplayParams& GetPrimaryDisplayParams() const {
    return primary_display_;
  }

  // Sets the display surfaces to compose the hardware layer stack.
@@ -356,16 +339,16 @@ class HardwareComposer {
  void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);

 private:
  HWC::Error GetDisplayAttribute(Hwc2::Composer* composer,
                                 hwc2_display_t display, hwc2_config_t config,
                                 hwc2_attribute_t attributes,
                                 int32_t* out_value) const;
  HWC::Error GetDisplayMetrics(Hwc2::Composer* composer, hwc2_display_t display,
                               hwc2_config_t config,
                               HWCDisplayMetrics* out_metrics) const;
  DisplayParams GetDisplayParams(Hwc2::Composer* composer,
      hwc2_display_t display, bool is_primary);

  HWC::Error EnableVsync(bool enabled);
  HWC::Error SetPowerMode(bool active);
  // Turn display vsync on/off. Returns true on success, false on failure.
  bool EnableVsync(const DisplayParams& display, bool enabled);
  // Turn display power on/off. Returns true on success, false on failure.
  bool SetPowerMode(const DisplayParams& display, bool active);
  // Convenience function to turn a display on/off. Turns both power and vsync
  // on/off. Returns true on success, false on failure.
  bool EnableDisplay(const DisplayParams& display, bool enabled);

  class ComposerCallback : public Hwc2::IComposerCallback {
   public:
@@ -376,22 +359,38 @@ class HardwareComposer {
    hardware::Return<void> onVsync(Hwc2::Display display,
                                   int64_t timestamp) override;

    bool HasDisplayId() { return has_display_id_; }
    hwc2_display_t GetDisplayId() { return display_id_; }
    pdx::Status<int64_t> GetVsyncTime();
    bool GotFirstHotplug() { return got_first_hotplug_; }

    struct Displays {
      hwc2_display_t primary_display = 0;
      std::optional<hwc2_display_t> external_display;
      bool external_display_was_hotplugged = false;
    };

    Displays GetDisplays();
    pdx::Status<int64_t> GetVsyncTime(hwc2_display_t display);

   private:
    std::mutex vsync_mutex_;
    bool has_display_id_ = false;
    hwc2_display_t display_id_;
    pdx::LocalHandle driver_vsync_event_fd_;
    int64_t callback_vsync_timestamp_{0};
    struct DisplayInfo {
      hwc2_display_t id = 0;
      pdx::LocalHandle driver_vsync_event_fd;
      int64_t callback_vsync_timestamp{0};
    };

    DisplayInfo* GetDisplayInfo(hwc2_display_t display);

    std::mutex mutex_;

    bool got_first_hotplug_ = false;
    DisplayInfo primary_display_;
    std::optional<DisplayInfo> external_display_;
    bool external_display_was_hotplugged_ = false;
  };

  HWC::Error Validate(hwc2_display_t display);
  HWC::Error Present(hwc2_display_t display);

  void PostLayers();
  void PostLayers(hwc2_display_t display);
  void PostThread();

  // The post thread has two controlling states:
@@ -419,16 +418,24 @@ class HardwareComposer {
  int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
                                  int requested_events, int timeout_ms);

  // WaitForVSync and SleepUntil are blocking calls made on the post thread that
  // can be interrupted by a control thread. If interrupted, these calls return
  // kPostThreadInterrupted.
  // WaitForPredictedVSync and SleepUntil are blocking calls made on the post
  // thread that can be interrupted by a control thread. If interrupted, these
  // calls return kPostThreadInterrupted.
  int ReadWaitPPState();
  pdx::Status<int64_t> WaitForVSync();
  pdx::Status<int64_t> WaitForPredictedVSync();
  int SleepUntil(int64_t wakeup_timestamp);

  // Initialize any newly connected displays, and set target_display_ to the
  // display we should render to. Returns true if target_display_
  // changed. Called only from the post thread.
  bool UpdateTargetDisplay();

  // Reconfigures the layer stack if the display surfaces changed since the last
  // frame. Called only from the post thread.
  bool UpdateLayerConfig();
  void UpdateLayerConfig();

  // Called on the post thread to create the Composer instance.
  void CreateComposer();

  // Called on the post thread when the post thread is resumed.
  void OnPostThreadResumed();
@@ -459,18 +466,19 @@ class HardwareComposer {
  sp<ComposerCallback> composer_callback_;
  RequestDisplayCallback request_display_callback_;

  // Display metrics of the physical display.
  HWCDisplayMetrics native_display_metrics_;
  // Display metrics of the logical display, adjusted so that orientation is
  // landscape.
  HWCDisplayMetrics display_metrics_;
  // Transform required to get from native to logical display orientation.
  HWC::Transform display_transform_ = HWC::Transform::None;

  // Pending surface list. Set by the display service when DirectSurfaces are
  // added, removed, or change visibility. Written by the message dispatch
  // thread and read by the post thread.
  std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
  DisplayParams primary_display_;
  std::optional<DisplayParams> external_display_;
  DisplayParams* target_display_ = &primary_display_;

  // The list of surfaces we should draw. Set by the display service when
  // DirectSurfaces are added, removed, or change visibility. Written by the
  // message dispatch thread and read by the post thread.
  std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces_;
  // Set to true by the dispatch thread whenever surfaces_ changes. Set to false
  // by the post thread when the new list of surfaces is processed.
  bool surfaces_changed_ = false;

  std::vector<std::shared_ptr<DirectDisplaySurface>> current_surfaces_;

  // Layer set for handling buffer flow into hardware composer layers. This
  // vector must be sorted by surface_id in ascending order.