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

Commit 520fb0e2 authored by Albert Chaulk's avatar Albert Chaulk Committed by Alex Vakulenko
Browse files

Allow VRWM to show 2D apps

2D apps appear as a single app layer at the front of the stack. We can
distinguish them from VR apps as VR has two layers at the front.
When we detect a 2D app we don't skip the first layers for rendering

Test: launch VR app, launch calculator
Bug: None
Change-Id: Iea8420870852b84ab790b5185ac1a44103c2aae5
parent e7916f88
Loading
Loading
Loading
Loading
+30 −17
Original line number Diff line number Diff line
@@ -194,16 +194,22 @@ quat FromGvrQuatf(const gvr_quatf& quaternion) {
}

// Determine if ths frame should be shown or hidden.
bool CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
ViewMode CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
                                            uint32_t vr_app) {
  auto& layers = frame.layers();

  // We assume the first two layers are the VR app.
  if (layers.size() < kVRAppLayerCount)
    return false;
    return ViewMode::Hidden;

  if (vr_app != layers[0].appid || layers[0].appid == 0)
    return false;
  if (vr_app != layers[0].appid || layers[0].appid == 0 ||
      layers[1].appid != layers[0].appid) {
    if (layers[1].appid != layers[0].appid && layers[0].appid) {
      // This might be a 2D app.
      return ViewMode::App;
    }
    return ViewMode::Hidden;
  }

  // If a non-VR-app, non-skipped layer appears, show.
  size_t index = kVRAppLayerCount;
@@ -219,11 +225,12 @@ bool CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
  // If any non-skipped layers exist now then we show, otherwise hide.
  for (size_t i = index; i < layers.size(); i++) {
    if (!layers[i].should_skip_layer())
      return true;
      return ViewMode::VR;
  }
  return false;
  return ViewMode::Hidden;
}


}  // namespace

ShellView::ShellView() {
@@ -308,7 +315,7 @@ void ShellView::OnDrawFrame() {
    if (!pending_frames_.empty()) {
      // Check if we should advance the frame.
      auto& frame = pending_frames_.front();
      if (!frame.visibility ||
      if (frame.visibility == ViewMode::Hidden ||
          frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
        current_frame_ = std::move(frame);
        pending_frames_.pop_front();
@@ -316,17 +323,20 @@ void ShellView::OnDrawFrame() {
    }
  }

  if (!debug_mode_ && current_frame_.visibility != is_visible_) {
    SetVisibility(current_frame_.visibility);
  bool visible = current_frame_.visibility != ViewMode::Hidden;

  if (!debug_mode_ && visible != is_visible_) {
    SetVisibility(current_frame_.visibility != ViewMode::Hidden);
  }

  if (!current_frame_.visibility)
  if (!visible)
    return;

  ime_texture_ = TextureLayer();

  surface_flinger_view_->GetTextures(*current_frame_.frame.get(), &textures_,
                                     &ime_texture_, debug_mode_);
                                     &ime_texture_, debug_mode_,
                                     view_mode_ == ViewMode::VR);
  has_ime_ = ime_texture_.texture != nullptr;
}

@@ -373,14 +383,17 @@ void ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
  if (!frame || frame->layers().empty())
    return;

  bool visibility = debug_mode_ || CalculateVisibilityFromLayerConfig(
                                       *frame.get(), current_vr_app_);
  ViewMode visibility =
      CalculateVisibilityFromLayerConfig(*frame.get(), current_vr_app_);

  if (visibility == ViewMode::Hidden && debug_mode_)
    visibility = ViewMode::VR;
  current_vr_app_ = frame->layers().front().appid;

  // If we are not showing the frame there's no need to keep anything around.
  if (!visibility) {
  if (visibility == ViewMode::Hidden) {
    // Hidden, no change so drop it completely
    if (!current_frame_.visibility)
    if (current_frame_.visibility == ViewMode::Hidden)
      return;

    frame.reset(nullptr);
@@ -395,7 +408,7 @@ void ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {

  // If we are showing ourselves the main thread is not processing anything,
  // so give it a kick.
  if (visibility && !current_frame_.visibility) {
  if (visibility != ViewMode::Hidden && current_frame_.visibility == ViewMode::Hidden) {
    QueueTask(MainThreadTask::EnteringVrMode);
    QueueTask(MainThreadTask::Show);
  }
+10 −2
Original line number Diff line number Diff line
@@ -14,6 +14,12 @@
namespace android {
namespace dvr {

enum class ViewMode {
  Hidden,
  VR,
  App,
};

class ShellView : public Application, public HwcCallback::Client {
 public:
  ShellView();
@@ -64,6 +70,8 @@ class ShellView : public Application, public HwcCallback::Client {
  std::unique_ptr<ShaderProgram> overlay_program_;
  std::unique_ptr<ShaderProgram> controller_program_;

  ViewMode view_mode_ = ViewMode::Hidden;

  uint32_t current_vr_app_;

  // Used to center the scene when the shell becomes visible.
@@ -92,7 +100,7 @@ class ShellView : public Application, public HwcCallback::Client {

  struct PendingFrame {
    PendingFrame() = default;
    PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, bool visibility)
    PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, ViewMode visibility)
        : frame(std::move(frame)), visibility(visibility) {}
    PendingFrame(PendingFrame&& r)
        : frame(std::move(r.frame)), visibility(r.visibility) {}
@@ -103,7 +111,7 @@ class ShellView : public Application, public HwcCallback::Client {
    }

    std::unique_ptr<HwcCallback::Frame> frame;
    bool visibility = false;
    ViewMode visibility = ViewMode::Hidden;
  };
  std::deque<PendingFrame> pending_frames_;
  std::mutex pending_frame_mutex_;
+2 −2
Original line number Diff line number Diff line
@@ -38,13 +38,13 @@ bool SurfaceFlingerView::Initialize(HwcCallback::Client *client) {
bool SurfaceFlingerView::GetTextures(const HwcCallback::Frame& frame,
                                     std::vector<TextureLayer>* texture_layers,
                                     TextureLayer* ime_layer,
                                     bool debug) const {
                                     bool debug, bool skip_first_layer) const {
  auto& layers = frame.layers();
  texture_layers->clear();

  size_t start = 0;
  // Skip the second layer if it is from the VR app.
  if (!debug) {
  if (!debug && skip_first_layer) {
    start = 1;
    if (layers[0].appid && layers[0].appid == layers[1].appid)
      start = 2;
+2 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ class SurfaceFlingerView {

  bool GetTextures(const HwcCallback::Frame& layers,
                   std::vector<TextureLayer>* texture_layers,
                   TextureLayer* ime_layer, bool debug) const;
                   TextureLayer* ime_layer, bool debug,
                   bool skip_first_layer) const;

 private:
  sp<IVrComposerView> composer_service_;