OSDN Git Service

drm_hwcomposer: Disable planes on frame failure
authorSean Paul <seanpaul@chromium.org>
Tue, 13 Oct 2015 19:47:22 +0000 (15:47 -0400)
committerSean Paul <seanpaul@chromium.org>
Tue, 13 Oct 2015 19:55:04 +0000 (15:55 -0400)
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 <seanpaul@chromium.org>
drmdisplaycompositor.cpp
drmdisplaycompositor.h

index 3b3deef..20779dd 100644 (file)
@@ -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<DrmCompositionLayer> *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;
index 419960c..89d5b67 100644 (file)
@@ -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_;