drm_hwcomposer: composite down to a primary plane after a timeout
DrmDisplayCompositor::SquashAll is triggered after a constant timeout in
DrmCompositorWorker::Routine. It will not be triggered more than one time
between genuine hwc_set calls. SquashAll has no effect if there are protected
layers, only one layer, or any errors. On success, SquashAll produces a new
DrmDisplayComposition that owns the layers in the planes of the active
composition and makes that the new active composition. SquashAll has no effect
on SquashState.
Change-Id: I975edb21847dcf2d93245f92a6e53a4e366c6a3b
diff --git a/drmcompositorworker.cpp b/drmcompositorworker.cpp
index c8eae5f..9804322 100644
--- a/drmcompositorworker.cpp
+++ b/drmcompositorworker.cpp
@@ -27,6 +27,8 @@
namespace android {
+static const int64_t kSquashWait = 500000000LL;
+
DrmCompositorWorker::DrmCompositorWorker(DrmDisplayCompositor *compositor)
: Worker("drm-compositor", HAL_PRIORITY_URGENT_DISPLAY),
compositor_(compositor) {
@@ -48,7 +50,11 @@
return;
}
- int wait_ret = WaitForSignalOrExitLocked();
+ // Only use a timeout if we didn't do a SquashAll last time. This will
+ // prevent wait_ret == -ETIMEDOUT which would trigger a SquashAll and be a
+ // pointless drain on resources.
+ int wait_ret = did_squash_all_ ? WaitForSignalOrExitLocked()
+ : WaitForSignalOrExitLocked(kSquashWait);
ret = Unlock();
if (ret) {
@@ -56,16 +62,26 @@
return;
}
- if (wait_ret == -EINTR) {
- return;
- } else if (wait_ret) {
- ALOGE("Failed to wait for signal, %d", wait_ret);
- return;
+ switch (wait_ret) {
+ case 0:
+ break;
+ case -EINTR:
+ return;
+ case -ETIMEDOUT:
+ ret = compositor_->SquashAll();
+ if (ret)
+ ALOGE("Failed to squash all %d", ret);
+ did_squash_all_ = true;
+ return;
+ default:
+ ALOGE("Failed to wait for signal, %d", wait_ret);
+ return;
}
}
ret = compositor_->Composite();
if (ret)
ALOGE("Failed to composite! %d", ret);
+ did_squash_all_ = false;
}
}