OSDN Git Service

drm_hwcomposer: Move client flattening closer to the frontend
authorRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Thu, 30 Sep 2021 07:09:31 +0000 (10:09 +0300)
committerRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Sat, 23 Oct 2021 01:47:33 +0000 (04:47 +0300)
Remove unnecessary code from DrmCompositor.
Drops ~100 LoC.

Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
DrmHwcTwo.cpp
DrmHwcTwo.h
backend/Backend.cpp
compositor/DrmDisplayCompositor.cpp
compositor/DrmDisplayCompositor.h

index 10177e9..6ec8b31 100644 (file)
@@ -140,9 +140,28 @@ std::string DrmHwcTwo::HwcDisplay::DumpDelta(
 }
 
 std::string DrmHwcTwo::HwcDisplay::Dump() {
+  std::string flattening_state_str;
+  switch (flattenning_state_) {
+    case ClientFlattenningState::Disabled:
+      flattening_state_str = "Disabled";
+      break;
+    case ClientFlattenningState::NotRequired:
+      flattening_state_str = "Not needed";
+      break;
+    case ClientFlattenningState::Flattened:
+      flattening_state_str = "Active";
+      break;
+    case ClientFlattenningState::ClientRefreshRequested:
+      flattening_state_str = "Refresh requested";
+      break;
+    default:
+      flattening_state_str = std::to_string(flattenning_state_) +
+                             " VSync remains";
+  }
+
   std::stringstream ss;
   ss << "- Display on: " << connector_->name() << "\n"
-     << "  Flattening state: " << compositor_.GetFlatteningState() << "\n"
+     << "  Flattening state: " << flattening_state_str << "\n"
      << "Statistics since system boot:\n"
      << DumpDelta(total_stats_) << "\n\n"
      << "Statistics since last dumpsys request:\n"
@@ -246,14 +265,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
   }
 
   int display = static_cast<int>(handle_);
-  int ret = compositor_.Init(resource_manager_, display, [this] {
-    /* refresh callback */
-    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
-    if (hwc2_->refresh_callback_.first != nullptr &&
-        hwc2_->refresh_callback_.second != nullptr) {
-      hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
-    }
-  });
+  int ret = compositor_.Init(resource_manager_, display);
   if (ret) {
     ALOGE("Failed display compositor init for display %d (%d)", display, ret);
     return HWC2::Error::NoResources;
@@ -307,6 +319,23 @@ HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
     return HWC2::Error::BadDisplay;
   }
 
+  ret = flattening_vsync_worker_.Init(drm_, display, [this](int64_t /*timestamp*/) {
+    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
+    /* Frontend flattening */
+    if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
+        --flattenning_state_ ==
+            ClientFlattenningState::ClientRefreshRequested &&
+        hwc2_->refresh_callback_.first != nullptr &&
+        hwc2_->refresh_callback_.second != nullptr) {
+      hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
+      flattening_vsync_worker_.VSyncControl(false);
+    }
+  });
+  if (ret) {
+    ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
+    return HWC2::Error::BadDisplay;
+  }
+
   ret = BackendManager::GetInstance().SetBackendForDisplay(this);
   if (ret) {
     ALOGE("Failed to set backend for d=%d %d\n", display, ret);
index 19355cd..0d213fd 100644 (file)
@@ -293,7 +293,40 @@ class DrmHwcTwo : public hwc2_device_t {
       return total_stats_;
     }
 
+    /* returns true if composition should be sent to client */
+    bool ProcessClientFlatteningState(bool skip) {
+      int flattenning_state = flattenning_state_;
+      if (flattenning_state == ClientFlattenningState::Disabled) {
+        return false;
+      }
+
+      if (skip) {
+        flattenning_state_ = ClientFlattenningState::NotRequired;
+        return false;
+      }
+
+      if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
+        flattenning_state_ = ClientFlattenningState::Flattened;
+        return true;
+      }
+
+      flattening_vsync_worker_.VSyncControl(true);
+      flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
+      return false;
+    }
+
    private:
+    enum ClientFlattenningState : int32_t {
+      Disabled = -3,
+      NotRequired = -2,
+      Flattened = -1,
+      ClientRefreshRequested = 0,
+      VsyncCountdownMax = 60, /* 1 sec @ 60FPS */
+    };
+
+    std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
+    VSyncWorker flattening_vsync_worker_;
+
     void AddFenceToPresentFence(UniqueFd fd);
 
     constexpr static size_t MATRIX_SIZE = 16;
index 312faed..d7eb240 100644 (file)
@@ -34,7 +34,8 @@ HWC2::Error Backend::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
   int client_start = -1;
   size_t client_size = 0;
 
-  if (display->compositor().ShouldFlattenOnClient()) {
+  if (display->ProcessClientFlatteningState(layers.size() <= 1)) {
+    display->total_stats().frames_flattened_++;
     client_start = 0;
     client_size = layers.size();
     MarkValidated(layers, client_start, client_size);
@@ -56,8 +57,6 @@ HWC2::Error Backend::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
 
   *num_types = client_size;
 
-  display->total_stats().frames_flattened_ = display->compositor()
-                                                 .GetFlattenedFramesCount();
   display->total_stats().gpu_pixops_ += CalcPixOps(layers, client_start,
                                                    client_size);
   display->total_stats().total_pixops_ += CalcPixOps(layers, 0, layers.size());
index 5ad2de2..5b16cad 100644 (file)
 
 namespace android {
 
-std::ostream &operator<<(std::ostream &str, FlatteningState state) {
-  std::array<const char *, 6> flattenting_state_str = {
-      "None",   "Not needed", "SF Requested", "Squashed by GPU",
-      "Serial", "Concurrent",
-  };
-
-  return str << flattenting_state_str[static_cast<int>(state)];
-}
-
 DrmDisplayCompositor::DrmDisplayCompositor()
     : resource_manager_(nullptr),
       display_(-1),
@@ -56,10 +47,7 @@ DrmDisplayCompositor::DrmDisplayCompositor()
       active_(false),
       use_hw_overlays_(true),
       dump_frames_composited_(0),
-      dump_last_timestamp_ns_(0),
-      flatten_countdown_(FLATTEN_COUNTDOWN_INIT),
-      flattening_state_(FlatteningState::kNone),
-      frames_flattened_(0) {
+      dump_last_timestamp_ns_(0) {
   struct timespec ts {};
   if (clock_gettime(CLOCK_MONOTONIC, &ts))
     return;
@@ -69,11 +57,6 @@ 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);
   DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
   if (mode_.blob_id)
     drm->DestroyPropertyBlob(mode_.blob_id);
@@ -81,18 +64,10 @@ DrmDisplayCompositor::~DrmDisplayCompositor() {
     drm->DestroyPropertyBlob(mode_.old_blob_id);
 
   active_composition_.reset();
-
-  ret = pthread_mutex_unlock(&lock_);
-  if (ret)
-    ALOGE("Failed to acquire compositor lock %d", ret);
-
-  pthread_mutex_destroy(&lock_);
 }
 
-auto DrmDisplayCompositor::Init(ResourceManager *resource_manager, int display,
-                                std::function<void()> client_refresh_callback)
+auto DrmDisplayCompositor::Init(ResourceManager *resource_manager, int display)
     -> int {
-  client_refresh_callback_ = std::move(client_refresh_callback);
   resource_manager_ = resource_manager;
   display_ = display;
   DrmDevice *drm = resource_manager_->GetDrmDevice(display);
@@ -100,27 +75,8 @@ auto DrmDisplayCompositor::Init(ResourceManager *resource_manager, int display,
     ALOGE("Could not find drmdevice for display");
     return -EINVAL;
   }
-  int ret = pthread_mutex_init(&lock_, nullptr);
-  if (ret) {
-    ALOGE("Failed to initialize drm compositor lock %d\n", ret);
-    return ret;
-  }
   planner_ = Planner::CreateInstance(drm);
 
-  vsync_worker_.Init(drm, display_, [this](int64_t timestamp) {
-    AutoLock lock(&lock_, "DrmDisplayCompositor::Init()");
-    if (lock.Lock())
-      return;
-    flatten_countdown_--;
-    if (!CountdownExpired())
-      return;
-    lock.Unlock();
-    int ret = FlattenActiveComposition();
-    ALOGV("scene flattening triggered for display %d at timestamp %" PRIu64
-          " result = %d \n",
-          display_, timestamp, ret);
-  });
-
   initialized_ = true;
   return 0;
 }
@@ -137,19 +93,6 @@ DrmDisplayCompositor::CreateInitializedComposition() const {
   return std::make_unique<DrmDisplayComposition>(crtc, planner_.get());
 }
 
-FlatteningState DrmDisplayCompositor::GetFlatteningState() const {
-  return flattening_state_;
-}
-
-uint32_t DrmDisplayCompositor::GetFlattenedFramesCount() const {
-  return frames_flattened_;
-}
-
-bool DrmDisplayCompositor::ShouldFlattenOnClient() const {
-  return flattening_state_ == FlatteningState::kClientRequested ||
-         flattening_state_ == FlatteningState::kClientDone;
-}
-
 std::tuple<uint32_t, uint32_t, int>
 DrmDisplayCompositor::GetActiveModeResolution() {
   DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
@@ -348,9 +291,6 @@ void DrmDisplayCompositor::ClearDisplay() {
 
 void DrmDisplayCompositor::ApplyFrame(
     std::unique_ptr<DrmDisplayComposition> composition, int status) {
-  AutoLock lock(&lock_, __func__);
-  if (lock.Lock())
-    return;
   int ret = status;
 
   if (!ret) {
@@ -367,14 +307,6 @@ void DrmDisplayCompositor::ApplyFrame(
   ++dump_frames_composited_;
 
   active_composition_.swap(composition);
-
-  flatten_countdown_ = FLATTEN_COUNTDOWN_INIT;
-  if (flattening_state_ != FlatteningState::kClientRequested) {
-    SetFlattening(FlatteningState::kNone);
-  } else {
-    SetFlattening(FlatteningState::kClientDone);
-  }
-  vsync_worker_.VSyncControl(true);
 }
 
 int DrmDisplayCompositor::ApplyComposition(
@@ -424,70 +356,13 @@ int DrmDisplayCompositor::TestComposition(DrmDisplayComposition *composition) {
   return CommitFrame(composition, true);
 }
 
-void DrmDisplayCompositor::SetFlattening(FlatteningState new_state) {
-  if (flattening_state_ != new_state) {
-    switch (flattening_state_) {
-      case FlatteningState::kClientDone:
-        ++frames_flattened_;
-        break;
-      case FlatteningState::kClientRequested:
-      case FlatteningState::kNone:
-      case FlatteningState::kNotNeeded:
-        break;
-    }
-  }
-  flattening_state_ = new_state;
-}
-
-bool DrmDisplayCompositor::IsFlatteningNeeded() const {
-  return CountdownExpired() && active_composition_->layers().size() >= 2;
-}
-
-int DrmDisplayCompositor::FlattenOnClient() {
-  if (client_refresh_callback_) {
-    {
-      AutoLock lock(&lock_, __func__);
-      if (!IsFlatteningNeeded()) {
-        if (flattening_state_ != FlatteningState::kClientDone) {
-          ALOGV("Flattening is not needed");
-          SetFlattening(FlatteningState::kNotNeeded);
-        }
-        return -EALREADY;
-      }
-    }
-
-    ALOGV(
-        "No writeback connector available, "
-        "falling back to client composition");
-    SetFlattening(FlatteningState::kClientRequested);
-    client_refresh_callback_();
-    return 0;
-  }
-
-  ALOGV("No writeback connector available");
-  return -EINVAL;
-}
-
-int DrmDisplayCompositor::FlattenActiveComposition() {
-  return FlattenOnClient();
-}
-
-bool DrmDisplayCompositor::CountdownExpired() const {
-  return flatten_countdown_ <= 0;
-}
-
 void DrmDisplayCompositor::Dump(std::ostringstream *out) const {
-  int ret = pthread_mutex_lock(&lock_);
-  if (ret)
-    return;
-
   uint64_t num_frames = dump_frames_composited_;
   dump_frames_composited_ = 0;
 
   struct timespec ts {};
-  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+  int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
   if (ret) {
-    pthread_mutex_unlock(&lock_);
     return;
   }
 
@@ -502,7 +377,5 @@ void DrmDisplayCompositor::Dump(std::ostringstream *out) const {
        << " fps=" << fps << "\n";
 
   dump_last_timestamp_ns_ = cur_ts;
-
-  pthread_mutex_unlock(&lock_);
 }
 }  // namespace android
index afdb79e..04c0bae 100644 (file)
 #include "drm/VSyncWorker.h"
 #include "drmhwcomposer.h"
 
-// If a scene is still for this number of vblanks flatten it to reduce power
-// consumption.
-#define FLATTEN_COUNTDOWN_INIT 60
-
 namespace android {
 
-enum class FlatteningState {
-  kNone,
-  kNotNeeded,
-  kClientRequested,
-  kClientDone,
-};
-
-std::ostream &operator<<(std::ostream &str, FlatteningState state);
-
 class DrmDisplayCompositor {
  public:
   DrmDisplayCompositor();
   ~DrmDisplayCompositor();
 
-  auto Init(ResourceManager *resource_manager, int display,
-            std::function<void()> client_refresh_callback) -> int;
+  auto Init(ResourceManager *resource_manager, int display) -> int;
 
   std::unique_ptr<DrmDisplayComposition> CreateInitializedComposition() const;
   int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
@@ -68,14 +54,9 @@ class DrmDisplayCompositor {
     return std::move(active_composition_->out_fence_);
   }
 
-  FlatteningState GetFlatteningState() const;
-  uint32_t GetFlattenedFramesCount() const;
-  bool ShouldFlattenOnClient() const;
-
   std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
 
  private:
-  std::function<void()> client_refresh_callback_;
   struct ModeState {
     bool needs_modeset = false;
     DrmMode mode;
@@ -97,13 +78,6 @@ class DrmDisplayCompositor {
   void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
                   int status);
 
-  void SetFlattening(FlatteningState new_state);
-  bool IsFlatteningNeeded() const;
-  int FlattenActiveComposition();
-  int FlattenOnClient();
-
-  bool CountdownExpired() const;
-
   std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
 
   ResourceManager *resource_manager_;
@@ -117,21 +91,11 @@ class DrmDisplayCompositor {
 
   ModeState mode_;
 
-  // mutable since we need to acquire in Dump()
-  mutable pthread_mutex_t lock_{};
-
   // State tracking progress since our last Dump(). These are mutable since
   // 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_;
-
-  FlatteningState flattening_state_;
-  uint32_t frames_flattened_;
-
-  std::function<void(int)> refresh_display_cb_;
 };
 }  // namespace android