Add a vsync worker that calls back into the DrmDisplayCompositor, for now at every 60 vsyncs if the scene does not change we trigger the flattening of the scene using the writeback connector. Other, more complex and proper heuristics could be implemented later on. Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@xxxxxxx> --- drmdisplaycompositor.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++--- drmdisplaycompositor.h | 12 +++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 576539b..e535e8a 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -39,6 +39,20 @@ namespace android { +class CompositorVsyncCallback : public VsyncCallback { + public: + CompositorVsyncCallback(DrmDisplayCompositor *compositor) + : compositor_(compositor) { + } + + void Callback(int display, int64_t timestamp) { + compositor_->Vsync(display, timestamp); + } + + private: + DrmDisplayCompositor *compositor_; +}; + void SquashState::Init(DrmHwcLayer *layers, size_t num_layers) { generation_number_++; valid_history_ = 0; @@ -183,7 +197,8 @@ DrmDisplayCompositor::DrmDisplayCompositor() framebuffer_index_(0), squash_framebuffer_index_(0), dump_frames_composited_(0), - dump_last_timestamp_ns_(0) { + dump_last_timestamp_ns_(0), + flatten_countdown_(FLATTEN_COUNTDOWN_INIT) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) return; @@ -193,7 +208,7 @@ DrmDisplayCompositor::DrmDisplayCompositor() DrmDisplayCompositor::~DrmDisplayCompositor() { if (!initialized_) return; - + vsync_worker_.Exit(); int ret = pthread_mutex_lock(&lock_); if (ret) ALOGE("Failed to acquire compositor lock %d", ret); @@ -222,7 +237,9 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int display) { return ret; } planner_ = Planner::CreateInstance(drm); - + vsync_worker_.Init(drm_, display_); + auto callback = std::make_shared<CompositorVsyncCallback>(this); + vsync_worker_.RegisterCallback(callback); initialized_ = true; return 0; } @@ -896,6 +913,10 @@ int DrmDisplayCompositor::ApplyComposition( return ret; } +int DrmDisplayCompositor::FlattenScene() { + return -EINVAL; +} + int DrmDisplayCompositor::SquashAll() { AutoLock lock(&lock_, "compositor"); int ret = lock.Lock(); @@ -1044,6 +1065,24 @@ move_layers_back: return ret; } +bool DrmDisplayCompositor::CountdownExpired() const { + return flatten_countdown_ <= 0; +} + +void DrmDisplayCompositor::Vsync(int display, int64_t timestamp) { + AutoLock lock(&lock_, __FUNCTION__); + if (lock.Lock()) + return; + flatten_countdown_--; + if (CountdownExpired()) { + lock.Unlock(); + int ret = FlattenScene(); + ALOGI("scene flattening triggered for display %d at timestamp %" PRIu64 + " result = %d \n", + display, timestamp, ret); + } +} + void DrmDisplayCompositor::Dump(std::ostringstream *out) const { int ret = pthread_mutex_lock(&lock_); if (ret) diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h index b35ef70..26201b9 100644 --- a/drmdisplaycompositor.h +++ b/drmdisplaycompositor.h @@ -29,11 +29,16 @@ #include <hardware/hardware.h> #include <hardware/hwcomposer.h> +#include <vsyncworker.h> // One for the front, one for the back, and one for cases where we need to // squash a frame that the hw can't display with hw overlays. #define DRM_DISPLAY_BUFFERS 3 +// If a scene is still for this number of vblanks flatten it to reduce power +// consumption. +#define FLATTEN_COUNTDOWN_INIT 60 + namespace android { class GLWorkerCompositor; @@ -92,7 +97,7 @@ class DrmDisplayCompositor { int Composite(); int SquashAll(); void Dump(std::ostringstream *out) const; - + void Vsync(int display, int64_t timestamp); std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution(); SquashState *squash_state() { @@ -128,6 +133,9 @@ class DrmDisplayCompositor { void ClearDisplay(); void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition, int status, bool writeback = false); + int FlattenScene(); + + bool CountdownExpired() const; std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode); @@ -157,6 +165,8 @@ class DrmDisplayCompositor { // we need to reset them on every Dump() call. mutable uint64_t dump_frames_composited_; mutable uint64_t dump_last_timestamp_ns_; + VSyncWorker vsync_worker_; + int64_t flatten_countdown_; std::unique_ptr<Planner> planner_; }; } -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel