From 7b1e4bc9186b3920cf67bab4f84af59b93118319 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 13 Oct 2015 15:47:22 -0400 Subject: [PATCH] drm_hwcomposer: Disable planes on frame failure When a frame fails, disable all active planes for the display and signal the release fences. This avoids the situation where we might end up frozen b/c someone is waiting for the active fences to signal. BUG=chrome-os-partner:46301 TEST=Tested on smaug with a kernel that fails every 1000 frames Change-Id: I3cd4ad4f22801068465b2c6278e96027b5a7e3c5 Signed-off-by: Sean Paul --- drmdisplaycompositor.cpp | 40 +++++++++++++++++++++++++++++++++++++++- drmdisplaycompositor.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 3b3deef..20779dd 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -227,6 +227,40 @@ int DrmDisplayCompositor::ApplyPreComposite( return ret; } +int DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) { + drmModePropertySetPtr pset = drmModePropertySetAlloc(); + if (!pset) { + ALOGE("Failed to allocate property set"); + return -ENOMEM; + } + + int ret; + std::vector *layers = + display_comp->GetCompositionLayers(); + for (DrmCompositionLayer &layer : *layers) { + DrmPlane *plane = layer.plane; + ret = drmModePropertySetAdd(pset, plane->id(), + plane->crtc_property().id(), 0) || + drmModePropertySetAdd(pset, plane->id(), plane->fb_property().id(), + 0); + if (ret) { + ALOGE("Failed to add plane %d disable to pset", plane->id()); + drmModePropertySetFree(pset); + return ret; + } + } + + ret = drmModePropertySetCommit(drm_->fd(), 0, drm_, pset); + if (ret) { + ALOGE("Failed to commit pset ret=%d\n", ret); + drmModePropertySetFree(pset); + return ret; + } + + drmModePropertySetFree(pset); + return 0; +} + int DrmDisplayCompositor::ApplyFrame(DrmDisplayComposition *display_comp) { int ret = 0; @@ -505,7 +539,11 @@ int DrmDisplayCompositor::Composite() { ret = ApplyFrame(composition.get()); if (ret) { ALOGE("Composite failed for display %d", display_); - return ret; + + // 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 ret; } ++dump_frames_composited_; break; diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h index 419960c..89d5b67 100644 --- a/drmdisplaycompositor.h +++ b/drmdisplaycompositor.h @@ -59,6 +59,7 @@ class DrmDisplayCompositor { int ApplyPreComposite(DrmDisplayComposition *display_comp); int ApplyFrame(DrmDisplayComposition *display_comp); int ApplyDpms(DrmDisplayComposition *display_comp); + int DisablePlanes(DrmDisplayComposition *display_comp); DrmResources *drm_; int display_; -- 2.11.0