OSDN Git Service

drm_hwcomposer: On error, free active composition
authorSean Paul <seanpaul@chromium.org>
Thu, 23 Jun 2016 02:48:22 +0000 (22:48 -0400)
committerSean Paul <seanpaul@chromium.org>
Thu, 23 Jun 2016 03:59:10 +0000 (23:59 -0400)
If we drop a frame while compositing, free the active composition.

Assume a frame pipeline of A->B->A. If we drop frame B, it will become
the active composition, which means the fences for A will not be released,
causing us to block A on A --> DEADLOCK.

BUG=b/29122961
TEST=Tested on smaug, no longer hangs

Change-Id: I98817bb361f1d0669395ddac5d96cf4f19d4b26a
Signed-off-by: Sean Paul <seanpaul@chromium.org>
drmdisplaycompositor.cpp
drmdisplaycompositor.h

index 0b2506f..279d5a6 100644 (file)
@@ -864,6 +864,23 @@ std::tuple<int, uint32_t> DrmDisplayCompositor::CreateModeBlob(
   return std::make_tuple(ret, id);
 }
 
+void DrmDisplayCompositor::ClearDisplay() {
+  AutoLock lock(&lock_, "compositor");
+  int ret = lock.Lock();
+  if (ret)
+    return;
+
+  if (!active_composition_)
+    return;
+
+  if (DisablePlanes(active_composition_.get()))
+    return;
+
+  active_composition_->SignalCompositionDone();
+
+  active_composition_.reset(NULL);
+}
+
 void DrmDisplayCompositor::ApplyFrame(
     std::unique_ptr<DrmDisplayComposition> composition, int status) {
   int ret = status;
@@ -873,11 +890,10 @@ void DrmDisplayCompositor::ApplyFrame(
 
   if (ret) {
     ALOGE("Composite failed for display %d", display_);
-
     // Disable the hw used by the last active composition. This allows us to
     // signal the release fences from that composition to avoid hanging.
-    if (DisablePlanes(active_composition_.get()))
-      return;
+    ClearDisplay();
+    return;
   }
   ++dump_frames_composited_;
 
@@ -958,6 +974,10 @@ int DrmDisplayCompositor::Composite() {
           composition = std::move(squashed);
         } else {
           ALOGE("Failed to squash frame for display %d", display_);
+          // Disable the hw used by the last active composition. This allows us
+          // to signal the release fences from that composition to avoid
+          // hanging.
+          ClearDisplay();
           return ret;
         }
       }
index e4c3b53..9487cac 100644 (file)
@@ -149,6 +149,7 @@ class DrmDisplayCompositor {
   int ApplyDpms(DrmDisplayComposition *display_comp);
   int DisablePlanes(DrmDisplayComposition *display_comp);
 
+  void ClearDisplay();
   void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
                   int status);