Call releaseFrame on the IVrComposerView interface

Bug: None
Test: None
Change-Id: I800e6050efc4d5aa4fe79fc62464c9f221a5dc18
diff --git a/services/vr/vr_window_manager/hwc_callback.cpp b/services/vr/vr_window_manager/hwc_callback.cpp
index b2edc20..5045790 100644
--- a/services/vr/vr_window_manager/hwc_callback.cpp
+++ b/services/vr/vr_window_manager/hwc_callback.cpp
@@ -79,8 +79,7 @@
   }
 
   std::lock_guard<std::mutex> guard(mutex_);
-  if (client_)
-    client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
+  client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
 
   return Void();
 }
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 5290199..109aecd 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -311,21 +311,29 @@
                  : MainThreadTask::ExitingVrMode);
 }
 
+void ShellView::AdvanceFrame() {
+  if (!pending_frames_.empty()) {
+    // Check if we should advance the frame.
+    auto& frame = pending_frames_.front();
+    if (frame.visibility == ViewMode::Hidden ||
+        frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
+      current_frame_ = std::move(frame);
+      pending_frames_.pop_front();
+
+      for(int i = 0; i < skipped_frame_count_ + 1; i++)
+        surface_flinger_view_->ReleaseFrame();
+      skipped_frame_count_ = 0;
+    }
+  }
+}
+
 void ShellView::OnDrawFrame() {
   textures_.clear();
   has_ime_ = false;
 
   {
     std::unique_lock<std::mutex> l(pending_frame_mutex_);
-    if (!pending_frames_.empty()) {
-      // Check if we should advance the frame.
-      auto& frame = pending_frames_.front();
-      if (frame.visibility == ViewMode::Hidden ||
-          frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
-        current_frame_ = std::move(frame);
-        pending_frames_.pop_front();
-      }
-    }
+    AdvanceFrame();
   }
 
   bool visible = current_frame_.visibility != ViewMode::Hidden;
@@ -334,7 +342,7 @@
     SetVisibility(current_frame_.visibility != ViewMode::Hidden);
   }
 
-  if (!visible)
+  if (!debug_mode_ && !visible)
     return;
 
   ime_texture_ = TextureLayer();
@@ -385,9 +393,6 @@
 }
 
 void ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
-  if (!frame || frame->layers().empty())
-    return;
-
   ViewMode visibility =
       CalculateVisibilityFromLayerConfig(*frame.get(), current_vr_app_);
 
@@ -395,21 +400,21 @@
     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 == ViewMode::Hidden) {
-    // Hidden, no change so drop it completely
-    if (current_frame_.visibility == ViewMode::Hidden)
-      return;
-
-    frame.reset(nullptr);
-  }
-
   std::unique_lock<std::mutex> l(pending_frame_mutex_);
 
   pending_frames_.emplace_back(std::move(frame), visibility);
 
-  if (pending_frames_.size() > kMaximumPendingFrames)
+  if (pending_frames_.size() > kMaximumPendingFrames) {
+    skipped_frame_count_++;
     pending_frames_.pop_front();
+  }
+
+  if (visibility == ViewMode::Hidden &&
+      current_frame_.visibility == ViewMode::Hidden) {
+    // Consume all frames while hidden.
+    while (!pending_frames_.empty())
+      AdvanceFrame();
+  }
 
   // If we are showing ourselves the main thread is not processing anything,
   // so give it a kick.
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index e19a71d..a70b7ad 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -63,6 +63,8 @@
 
   bool OnClick(bool down);
 
+  void AdvanceFrame();
+
   // HwcCallback::Client:
   void OnFrame(std::unique_ptr<HwcCallback::Frame> frame) override;
 
@@ -71,6 +73,8 @@
   std::unique_ptr<ShaderProgram> controller_program_;
 
   ViewMode view_mode_ = ViewMode::Hidden;
+  // This starts at -1 so we don't call ReleaseFrame for the first frame.
+  int skipped_frame_count_ = -1;
 
   uint32_t current_vr_app_;
 
diff --git a/services/vr/vr_window_manager/surface_flinger_view.cpp b/services/vr/vr_window_manager/surface_flinger_view.cpp
index 6cc654a..b15d262 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.cpp
+++ b/services/vr/vr_window_manager/surface_flinger_view.cpp
@@ -75,5 +75,9 @@
   return true;
 }
 
+void SurfaceFlingerView::ReleaseFrame() {
+  composer_service_->releaseFrame();
+}
+
 }  // namespace dvr
 }  // namespace android
diff --git a/services/vr/vr_window_manager/surface_flinger_view.h b/services/vr/vr_window_manager/surface_flinger_view.h
index c39ab41..2e36ec1 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.h
+++ b/services/vr/vr_window_manager/surface_flinger_view.h
@@ -36,6 +36,8 @@
                    TextureLayer* ime_layer, bool debug,
                    bool skip_first_layer) const;
 
+  void ReleaseFrame();
+
  private:
   sp<IVrComposerView> composer_service_;
   std::unique_ptr<HwcCallback> composer_observer_;