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

Commit 5e91f68c authored by Alex Sakhartchouk's avatar Alex Sakhartchouk
Browse files

Properly recover vr_wm from surface vr_flinger crashes.

This is addressing a number of issues:

1) surface_flinger_view_ was incorrectly reset
on de-allocation, which renders vr_wm incapable of seeing
new frames after a crash.

2) dvrGraphicsWaitNextFrame will return -1 if vr_flinger
crashes, which means our graphics context is no longer valid.
We need to de-allocate resources and wait for SF to
reconnect.

3) Displays needed be be de-allocated on SF detach because
they will return incorrect fences on SF re-connect.

4) display_client_ needs to be allocated on demand instead
of at initialization time because vr_flinger crash
invalidates it.

Bug: 36589793
Test: Crash vr_flinger, observe vr_wm working after SF restarts.

Change-Id: I72a79690ee5224e3326c7c571ae4e23797103e6d
parent e153b292
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -174,7 +174,12 @@ void Application::DrawFrame() {
  // TODO(steventhomas): If we're not visible, block until we are. For now we
  // TODO(steventhomas): If we're not visible, block until we are. For now we
  // throttle by calling dvrGraphicsWaitNextFrame.
  // throttle by calling dvrGraphicsWaitNextFrame.
  DvrFrameSchedule schedule;
  DvrFrameSchedule schedule;
  dvrGraphicsWaitNextFrame(graphics_context_, 0, &schedule);
  int status = dvrGraphicsWaitNextFrame(graphics_context_, 0, &schedule);
  if (status < 0) {
    ALOGE("Context lost, deallocating graphics resources");
    SetVisibility(false);
    DeallocateResources();
  }


  OnDrawFrame();
  OnDrawFrame();


+22 −5
Original line number Original line Diff line number Diff line
@@ -126,10 +126,6 @@ int ShellView::Initialize() {
  if (!surface_flinger_view_->Initialize(this))
  if (!surface_flinger_view_->Initialize(this))
    return 1;
    return 1;


  // This is a temporary fix for now. These APIs will be changed when everything
  // is moved into vrcore.
  display_client_ = DisplayClient::Create();

  return 0;
  return 0;
}
}


@@ -164,7 +160,14 @@ int ShellView::AllocateResources() {
}
}


void ShellView::DeallocateResources() {
void ShellView::DeallocateResources() {
  surface_flinger_view_.reset();
  {
    std::unique_lock<std::mutex> l(display_frame_mutex_);
    removed_displays_.clear();
    new_displays_.clear();
    displays_.clear();
  }

  display_client_.reset();
  reticle_.reset();
  reticle_.reset();
  controller_mesh_.reset();
  controller_mesh_.reset();
  program_.reset(new ShaderProgram);
  program_.reset(new ShaderProgram);
@@ -283,6 +286,20 @@ base::unique_fd ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {


  bool showing = false;
  bool showing = false;


  // This is a temporary fix for now. These APIs will be changed when everything
  // is moved into vrcore.
  // Do this on demand in case vr_flinger crashed and we are reconnecting.
  if (!display_client_.get()) {
    int error = 0;
    display_client_ = DisplayClient::Create(&error);

    if (error) {
      ALOGE("Could not connect to display service : %s(%d)", strerror(error),
            error);
      return base::unique_fd();
    }
  }

  // TODO(achaulk): change when moved into vrcore.
  // TODO(achaulk): change when moved into vrcore.
  bool vr_running = display_client_->IsVrAppRunning();
  bool vr_running = display_client_->IsVrAppRunning();