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

Commit 2b3b666c authored by Albert Chaulk's avatar Albert Chaulk
Browse files

vrwm: Add support for multiple independent displays

This doesn't change much, just splits ShellView and shuffles code
around.

Display-related things go into DisplayView - everything related to
processing and drawing buffers, hit detection, visibility.

ShellView retains overall state management, touchpad, controller and
is the initial recipient of all incoming frames

The composer library is modified to accept and pass multiple displays

Bug: 35996499
Test: Works for the existing single-display output
Change-Id: Ied5061b4dad9e7d68bb187bf86c3d0f2f3b7a55e
parent fcf7e25f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ LOCAL_PATH := $(call my-dir)
native_src := \
  application.cpp \
  controller_mesh.cpp \
  display_view.cpp \
  elbow_model.cpp \
  hwc_callback.cpp \
  reticle.cpp \
+2 −0
Original line number Diff line number Diff line
@@ -224,6 +224,8 @@ void Application::DrawFrame() {
    DrawEye(kRightEye, fov_[kRightEye].GetProjectionMatrix(0.1f, 500.0f),
            eye_from_head_[kRightEye], head_matrix);

    OnEndFrame();

    dvrPresent(graphics_context_);
  }
}
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ class Application {
  virtual void OnDrawFrame() = 0;
  virtual void DrawEye(EyeType eye, const mat4& perspective,
                       const mat4& eye_matrix, const mat4& head_matrix) = 0;
  virtual void OnEndFrame() = 0;

  void SetVisibility(bool visible);
  virtual void OnVisibilityChanged(bool visible);
+159 −90
Original line number Diff line number Diff line
@@ -102,7 +102,8 @@ HwcLayer* HwcDisplay::CreateLayer() {

HwcLayer* HwcDisplay::GetLayer(Layer id) {
  for (size_t i = 0; i < layers_.size(); ++i)
    if (layers_[i].info.id == id) return &layers_[i];
    if (layers_[i].info.id == id)
      return &layers_[i];

  return nullptr;
}
@@ -219,7 +220,7 @@ std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
////////////////////////////////////////////////////////////////////////////////
// VrHwcClient

VrHwc::VrHwc() {}
VrHwc::VrHwc() { displays_[kDefaultDisplayId].reset(new HwcDisplay()); }

VrHwc::~VrHwc() {}

@@ -231,7 +232,6 @@ void VrHwc::removeClient() {
}

void VrHwc::enableCallback(bool enable) {
  std::lock_guard<std::mutex> guard(mutex_);
  if (enable && client_ != nullptr) {
    client_.promote()->onHotplug(kDefaultDisplayId,
                                 IComposerCallback::Connection::CONNECTED);
@@ -247,31 +247,43 @@ Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
  return Error::NONE;
}

Error VrHwc::destroyVirtualDisplay(Display display) { return Error::NONE; }

Error VrHwc::createLayer(Display display, Layer* outLayer) {
  if (display != kDefaultDisplayId) {
Error VrHwc::destroyVirtualDisplay(Display display) {
  std::lock_guard<std::mutex> guard(mutex_);
  if (display == kDefaultDisplayId || displays_.erase(display) == 0)
    return Error::BAD_DISPLAY;
  ComposerView::Frame frame;
  frame.display_id = display;
  frame.removed = true;
  if (observer_)
    observer_->OnNewFrame(frame);
  return Error::NONE;
}

Error VrHwc::createLayer(Display display, Layer* outLayer) {
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* layer = display_.CreateLayer();
  HwcLayer* layer = display_ptr->CreateLayer();
  *outLayer = layer->info.id;
  return Error::NONE;
}

Error VrHwc::destroyLayer(Display display, Layer layer) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr) {
    return Error::BAD_DISPLAY;
  }

  return display_.DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
  return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
}

Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  *outConfig = kDefaultConfigId;
  return Error::NONE;
}
@@ -291,10 +303,9 @@ Error VrHwc::getColorModes(Display display, hidl_vec<ColorMode>* outModes) {
Error VrHwc::getDisplayAttribute(Display display, Config config,
                                 IComposerClient::Attribute attribute,
                                 int32_t* outValue) {
  if (display != kDefaultDisplayId) {
  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  }

  if (config != kDefaultConfigId) {
    return Error::BAD_CONFIG;
  }
@@ -321,10 +332,9 @@ Error VrHwc::getDisplayAttribute(Display display, Config config,
}

Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
  if (display != kDefaultDisplayId) {
  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  }

  std::vector<Config> configs(1, kDefaultConfigId);
  *outConfigs = hidl_vec<Config>(configs);
  return Error::NONE;
@@ -337,7 +347,9 @@ Error VrHwc::getDisplayName(Display display, hidl_string* outName) {

Error VrHwc::getDisplayType(Display display,
                            IComposerClient::DisplayType* outType) {
  if (display != kDefaultDisplayId) {
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr) {
    *outType = IComposerClient::DisplayType::INVALID;
    return Error::BAD_DISPLAY;
  }
@@ -348,10 +360,10 @@ Error VrHwc::getDisplayType(Display display,

Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
  *outSupport = false;
  if (display == kDefaultDisplayId)
    return Error::NONE;
  else
  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
@@ -365,35 +377,41 @@ Error VrHwc::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
}

Error VrHwc::setActiveConfig(Display display, Config config) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  if (config != kDefaultConfigId) return Error::BAD_CONFIG;
  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  if (config != kDefaultConfigId)
    return Error::BAD_CONFIG;

  return Error::NONE;
}

Error VrHwc::setColorMode(Display display, ColorMode mode) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setColorTransform(Display display, const float* matrix,
                               int32_t hint) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

@@ -401,13 +419,15 @@ Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
                             int32_t acquireFence, int32_t dataspace,
                             const std::vector<hwc_rect_t>& damage) {
  base::unique_fd fence(acquireFence);
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  if (target == nullptr) return Error::NONE;

  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  if (target == nullptr)
    return Error::NONE;

  if (!display_.SetClientTarget(target, std::move(fence)))
  if (!display_ptr->SetClientTarget(target, std::move(fence)))
    return Error::BAD_PARAMETER;

  return Error::NONE;
@@ -416,7 +436,10 @@ Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
Error VrHwc::setOutputBuffer(Display display, buffer_handle_t buffer,
                             int32_t releaseFence) {
  base::unique_fd fence(releaseFence);
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  ALOGE("Virtual display support not implemented");
  return Error::UNSUPPORTED;
@@ -427,13 +450,13 @@ Error VrHwc::validateDisplay(
    std::vector<IComposerClient::Composition>* outCompositionTypes,
    uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
    std::vector<uint32_t>* outRequestMasks) {
  if (display != kDefaultDisplayId) {
    return Error::BAD_DISPLAY;
  }

  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  display_.GetChangedCompositionTypes(outChangedLayers, outCompositionTypes);
  display_ptr->GetChangedCompositionTypes(outChangedLayers,
                                          outCompositionTypes);
  return Error::NONE;
}

@@ -446,18 +469,20 @@ Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
  outLayers->clear();
  outReleaseFences->clear();

  if (display != kDefaultDisplayId) {
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);

  if (!display_ptr)
    return Error::BAD_DISPLAY;
  }

  std::vector<ComposerView::ComposerLayer> frame;
  ComposerView::Frame frame;
  std::vector<Layer> last_frame_layers;
  std::lock_guard<std::mutex> guard(mutex_);
  Error status = display_.GetFrame(&frame);
  Error status = display_ptr->GetFrame(&frame.layers);
  frame.display_id = display;
  if (status != Error::NONE)
    return status;

  last_frame_layers = display_.UpdateLastFrameAndGetLastFrameLayers();
  last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers();

  base::unique_fd fence;
  if (observer_)
@@ -476,18 +501,23 @@ Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,

Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
                                    int32_t y) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerBuffer(Display display, Layer layer,
                            buffer_handle_t buffer, int32_t acquireFence) {
  base::unique_fd fence(acquireFence);
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.buffer = GetBufferFromHandle(buffer);
  hwc_layer->info.fence = new Fence(fence.release());
@@ -497,16 +527,21 @@ Error VrHwc::setLayerBuffer(Display display, Layer layer,

Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
                                   const std::vector<hwc_rect_t>& damage) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.blend_mode =
      static_cast<ComposerView::ComposerLayer::BlendMode>(mode);
@@ -516,17 +551,22 @@ Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {

Error VrHwc::setLayerColor(Display display, Layer layer,
                           IComposerClient::Color color) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerCompositionType(Display display, Layer layer,
                                     int32_t type) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->composition_type = static_cast<HwcLayer::Composition>(type);

@@ -535,17 +575,22 @@ Error VrHwc::setLayerCompositionType(Display display, Layer layer,

Error VrHwc::setLayerDataspace(Display display, Layer layer,
                               int32_t dataspace) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
                                  const hwc_rect_t& frame) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.display_frame =
      {frame.left, frame.top, frame.right, frame.bottom};
@@ -554,10 +599,14 @@ Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
}

Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.alpha = alpha;

@@ -566,17 +615,22 @@ Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {

Error VrHwc::setLayerSidebandStream(Display display, Layer layer,
                                    buffer_handle_t stream) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
                                const hwc_frect_t& crop) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.crop = {crop.left, crop.top, crop.right, crop.bottom};

@@ -585,23 +639,29 @@ Error VrHwc::setLayerSourceCrop(Display display, Layer layer,

Error VrHwc::setLayerTransform(Display display, Layer layer,
                               int32_t transform) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
                                   const std::vector<hwc_rect_t>& visible) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;

  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
    return Error::BAD_DISPLAY;
  return Error::NONE;
}

Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->z_order = z;

@@ -610,10 +670,14 @@ Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {

Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
                          uint32_t appId) {
  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
  std::lock_guard<std::mutex> guard(mutex_);
  auto display_ptr = FindDisplay(display);
  if (!display_ptr)
    return Error::BAD_DISPLAY;

  HwcLayer* hwc_layer = display_.GetLayer(layer);
  if (!hwc_layer) return Error::BAD_LAYER;
  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
  if (!hwc_layer)
    return Error::BAD_LAYER;

  hwc_layer->info.type = type;
  hwc_layer->info.app_id = appId;
@@ -665,6 +729,11 @@ void VrHwc::UnregisterObserver(Observer* observer) {
    observer_ = nullptr;
}

HwcDisplay* VrHwc::FindDisplay(Display display) {
  auto iter = displays_.find(display);
  return iter == displays_.end() ? nullptr : iter->second.get();
}

ComposerView* GetComposerViewFromIComposer(
    hardware::graphics::composer::V2_1::IComposer* composer) {
  return static_cast<VrHwc*>(composer);
+12 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <utils/StrongPointer.h>

#include <mutex>
#include <unordered_map>

using namespace android::hardware::graphics::common::V1_0;
using namespace android::hardware::graphics::composer::V2_1;
@@ -67,7 +68,14 @@ class ComposerView {
    uint32_t app_id;
  };

  using Frame = std::vector<ComposerLayer>;
  struct Frame {
    Display display_id;
    // This is set to true to notify the upper layer that the display is
    // being removed, or left false in the case of a normal frame. The upper
    // layer tracks display IDs and will handle new ones showing up.
    bool removed = false;
    std::vector<ComposerLayer> layers;
  };

  class Observer {
   public:
@@ -231,13 +239,15 @@ class VrHwc : public IComposer, public ComposerBase, public ComposerView {
  void UnregisterObserver(Observer* observer) override;

 private:
  HwcDisplay* FindDisplay(Display display);

  wp<VrComposerClient> client_;
  sp<IComposerCallback> callbacks_;

  // Guard access to internal state from binder threads.
  std::mutex mutex_;

  HwcDisplay display_;
  std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_;

  Observer* observer_ = nullptr;

Loading