diff options
author | Sean Paul <seanpaul@chromium.org> | 2016-06-22 22:48:22 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-06-22 23:59:10 -0400 |
commit | 137a6a8e9bea5c90a6832e9ed3e630f47041ab15 (patch) | |
tree | 4adc5fcac3e8bf96fb1508711fe7074ac5558ab8 | |
parent | aa18d918e24d63b650791fe021f41761d8a33d3b (diff) | |
download | drm_hwcomposer-137a6a8e9bea5c90a6832e9ed3e630f47041ab15.tar.gz drm_hwcomposer-137a6a8e9bea5c90a6832e9ed3e630f47041ab15.tar.xz |
drm_hwcomposer: On error, free active composition
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>
-rw-r--r-- | drmdisplaycompositor.cpp | 26 | ||||
-rw-r--r-- | drmdisplaycompositor.h | 1 |
2 files changed, 24 insertions, 3 deletions
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 0b2506f..279d5a6 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -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; } } diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h index e4c3b53..9487cac 100644 --- a/drmdisplaycompositor.h +++ b/drmdisplaycompositor.h @@ -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); |