summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kovalivskyi <roman.kovalivskyi@globallogic.com>2020-02-03 18:13:57 +0200
committerRoman Kovalivskyi <roman.kovalivskyi@globallogic.com>2020-02-19 17:13:43 +0200
commit9170b3105e9c6decd3e15a693584f410a0188234 (patch)
tree87e2f61bcd726d64fc504217cf78445c4c920d63
parent8fae156cf9127c61fc3ba998e71de85b737ac3e8 (diff)
drm_hwcomposer: Add statistics on flattening to dump message
We need some way to verify that current composition is not failed to compose, but instead sent to flatten on GPU. Dump message shows current flattening state. It also displays how often do compositor switches into flattening. Signed-off-by: Roman Kovalivskyi <roman.kovalivskyi@globallogic.com>
-rw-r--r--compositor/drmdisplaycompositor.cpp50
-rw-r--r--drmhwctwo.cpp4
-rw-r--r--include/drmdisplaycompositor.h5
-rw-r--r--include/drmhwctwo.h7
4 files changed, 55 insertions, 11 deletions
diff --git a/compositor/drmdisplaycompositor.cpp b/compositor/drmdisplaycompositor.cpp
index 401af48..1519736 100644
--- a/compositor/drmdisplaycompositor.cpp
+++ b/compositor/drmdisplaycompositor.cpp
@@ -23,6 +23,7 @@
#include <sched.h>
#include <stdlib.h>
#include <time.h>
+#include <array>
#include <sstream>
#include <vector>
@@ -40,6 +41,15 @@ static const uint32_t kWaitWritebackFence = 100; // ms
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)];
+}
+
class CompositorVsyncCallback : public VsyncCallback {
public:
CompositorVsyncCallback(DrmDisplayCompositor *compositor)
@@ -64,7 +74,8 @@ DrmDisplayCompositor::DrmDisplayCompositor()
dump_last_timestamp_ns_(0),
flatten_countdown_(FLATTEN_COUNTDOWN_INIT),
writeback_fence_(-1),
- flattening_state_(FlatteningState::kNone) {
+ flattening_state_(FlatteningState::kNone),
+ frames_flattened_(0) {
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts))
return;
@@ -148,6 +159,10 @@ 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;
@@ -616,9 +631,9 @@ void DrmDisplayCompositor::ApplyFrame(
flatten_countdown_ = FLATTEN_COUNTDOWN_INIT;
if (flattening_state_ != FlatteningState::kClientRequested) {
- flattening_state_ = FlatteningState::kNone;
+ SetFlattening(FlatteningState::kNone);
} else {
- flattening_state_ = FlatteningState::kClientDone;
+ SetFlattening(FlatteningState::kClientDone);
}
vsync_worker_.VSyncControl(!writeback);
}
@@ -776,6 +791,23 @@ int DrmDisplayCompositor::FlattenOnDisplay(
return 0;
}
+void DrmDisplayCompositor::SetFlattening(FlatteningState new_state) {
+ if (flattening_state_ != new_state) {
+ switch (flattening_state_) {
+ case FlatteningState::kClientDone:
+ case FlatteningState::kConcurrent:
+ case FlatteningState::kSerial:
+ ++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;
}
@@ -787,7 +819,7 @@ int DrmDisplayCompositor::FlattenOnClient() {
if (!IsFlatteningNeeded()) {
if (flattening_state_ != FlatteningState::kClientDone) {
ALOGV("Flattening is not needed");
- flattening_state_ = FlatteningState::kNotNeeded;
+ SetFlattening(FlatteningState::kNotNeeded);
}
return -EALREADY;
}
@@ -796,7 +828,7 @@ int DrmDisplayCompositor::FlattenOnClient() {
ALOGV(
"No writeback connector available, "
"falling back to client composition");
- flattening_state_ = FlatteningState::kClientRequested;
+ SetFlattening(FlatteningState::kClientRequested);
refresh_display_cb_(display_);
return 0;
} else {
@@ -822,7 +854,7 @@ int DrmDisplayCompositor::FlattenSerial(DrmConnector *writeback_conn) {
return ret;
if (!IsFlatteningNeeded()) {
ALOGV("Flattening is not needed");
- flattening_state_ = FlatteningState::kNotNeeded;
+ SetFlattening(FlatteningState::kNotNeeded);
return -EALREADY;
}
@@ -931,7 +963,7 @@ int DrmDisplayCompositor::FlattenConcurrent(DrmConnector *writeback_conn) {
return ret;
if (!IsFlatteningNeeded()) {
ALOGV("Flattening is not needed");
- flattening_state_ = FlatteningState::kNotNeeded;
+ SetFlattening(FlatteningState::kNotNeeded);
return -EALREADY;
}
DrmCrtc *crtc = active_composition_->crtc();
@@ -1007,10 +1039,10 @@ int DrmDisplayCompositor::FlattenActiveComposition() {
}
if (writeback_conn->display() != display_) {
- flattening_state_ = FlatteningState::kConcurrent;
+ SetFlattening(FlatteningState::kConcurrent);
return FlattenConcurrent(writeback_conn);
} else {
- flattening_state_ = FlatteningState::kSerial;
+ SetFlattening(FlatteningState::kSerial);
return FlattenSerial(writeback_conn);
}
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index a4a8187..605406b 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -142,6 +142,7 @@ std::string DrmHwcTwo::HwcDisplay::DumpDelta(
<< ((delta.failed_kms_present_ > 0)
? " !!! Internal failure, FIX it please\n"
: "")
+ << " Flattened frames: " << delta.frames_flattened_ << "\n"
<< " Pixel operations (free units)"
<< " : [TOTAL: " << delta.total_pixops_
<< " / GPU: " << delta.gpu_pixops_ << "]\n"
@@ -152,6 +153,8 @@ std::string DrmHwcTwo::HwcDisplay::DumpDelta(
std::string DrmHwcTwo::HwcDisplay::Dump() {
auto out = (std::stringstream()
<< "- Display on: " << connector_->name() << "\n"
+ << " Flattening state: " << compositor_.GetFlatteningState()
+ << "\n"
<< "Statistics since system boot:\n"
<< DumpDelta(total_stats_) << "\n\n"
<< "Statistics since last dumpsys request:\n"
@@ -970,6 +973,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
*num_types = client_size;
+ total_stats_.frames_flattened_ = compositor_.GetFlattenedFramesCount();
total_stats_.gpu_pixops_ += gpu_pixops;
total_stats_.total_pixops_ += total_pixops;
diff --git a/include/drmdisplaycompositor.h b/include/drmdisplaycompositor.h
index cfd8f4a..26e2572 100644
--- a/include/drmdisplaycompositor.h
+++ b/include/drmdisplaycompositor.h
@@ -50,6 +50,8 @@ enum class FlatteningState {
kConcurrent
};
+std::ostream &operator<<(std::ostream &str, FlatteningState state);
+
class DrmDisplayCompositor {
public:
DrmDisplayCompositor();
@@ -77,6 +79,7 @@ class DrmDisplayCompositor {
}
FlatteningState GetFlatteningState() const;
+ uint32_t GetFlattenedFramesCount() const;
bool ShouldFlattenOnClient() const;
std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
@@ -108,6 +111,7 @@ class DrmDisplayCompositor {
void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
int status, bool writeback = false);
+ void SetFlattening(FlatteningState new_state);
bool IsFlatteningNeeded() const;
int FlattenActiveComposition();
int FlattenOnClient();
@@ -148,6 +152,7 @@ class DrmDisplayCompositor {
int writeback_fence_;
FlatteningState flattening_state_;
+ uint32_t frames_flattened_;
std::function<void(int)> refresh_display_cb_;
};
diff --git a/include/drmhwctwo.h b/include/drmhwctwo.h
index 43f1fce..2bbe334 100644
--- a/include/drmhwctwo.h
+++ b/include/drmhwctwo.h
@@ -260,9 +260,11 @@ class DrmHwcTwo : public hwc2_device_t {
struct Stats {
Stats minus(Stats b) {
return {total_frames_ - b.total_frames_,
- total_pixops_ - b.total_pixops_, gpu_pixops_ - b.gpu_pixops_,
+ total_pixops_ - b.total_pixops_,
+ gpu_pixops_ - b.gpu_pixops_,
failed_kms_validate_ - b.failed_kms_validate_,
- failed_kms_present_ - b.failed_kms_present_};
+ failed_kms_present_ - b.failed_kms_present_,
+ frames_flattened_ - b.frames_flattened_};
}
uint32_t total_frames_ = 0;
@@ -270,6 +272,7 @@ class DrmHwcTwo : public hwc2_device_t {
uint64_t gpu_pixops_ = 0;
uint32_t failed_kms_validate_ = 0;
uint32_t failed_kms_present_ = 0;
+ uint32_t frames_flattened_ = 0;
} total_stats_, prev_stats_;
std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta);
};