diff options
author | Kevin DuBois <kevindubois@google.com> | 2019-03-01 09:39:11 -0800 |
---|---|---|
committer | Kevin DuBois <kevindubois@google.com> | 2019-03-06 09:39:21 -0800 |
commit | 1284c3f5c329b2c6aa4057f172742aa724a84478 (patch) | |
tree | 1df56339f3fb618aecc167691dad9d7cc6cd1316 | |
parent | c67af46944a34bcdd8f5f4f39a4fb95c84b2d4f6 (diff) | |
download | android_hardware_qcom_sdm845_display-1284c3f5c329b2c6aa4057f172742aa724a84478.tar.gz android_hardware_qcom_sdm845_display-1284c3f5c329b2c6aa4057f172742aa724a84478.tar.bz2 android_hardware_qcom_sdm845_display-1284c3f5c329b2c6aa4057f172742aa724a84478.zip |
histogram: time-weight sampled color content values
Time weight sampled values so they are more representative of the
time that a given color was on screen. Units in the histogram
change from (NumberOfPixels) to (NumberOfPixels * milliseconds).
Fixes: 123692142
Test: boot
Test: PtsComposerTestCases
Test: ./color_sampling_test #(new tests)
Change-Id: If080635087bc4d76be3208a3ccf257561c923ec0
-rw-r--r-- | libhistogram/ringbuffer.cpp | 57 | ||||
-rw-r--r-- | libhistogram/ringbuffer.h | 4 | ||||
-rw-r--r-- | libhistogram/ringbuffer_test.cpp | 250 |
3 files changed, 218 insertions, 93 deletions
diff --git a/libhistogram/ringbuffer.cpp b/libhistogram/ringbuffer.cpp index 5b4c2fe2..43d8c3f8 100644 --- a/libhistogram/ringbuffer.cpp +++ b/libhistogram/ringbuffer.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include <cutils/compiler.h> #include <algorithm> #include "ringbuffer.h" @@ -28,22 +29,44 @@ histogram::Ringbuffer::Ringbuffer(size_t ringbuffer_size, std::unique_ptr<histog cumulative_bins.fill(0); } -std::unique_ptr<histogram::Ringbuffer> histogram::Ringbuffer::create(size_t ringbuffer_size, std::unique_ptr<histogram::TimeKeeper> tk) { +std::unique_ptr<histogram::Ringbuffer> histogram::Ringbuffer::create( + size_t ringbuffer_size, std::unique_ptr<histogram::TimeKeeper> tk) { if ((ringbuffer_size == 0) || !tk) return nullptr; return std::unique_ptr<histogram::Ringbuffer>(new histogram::Ringbuffer(ringbuffer_size, std::move(tk))); } +void histogram::Ringbuffer::update_cumulative(nsecs_t now, + uint64_t& count, std::array<uint64_t, HIST_V_SIZE>& bins) const { + + if (ringbuffer.empty()) + return; + + count++; + + const auto delta = std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::nanoseconds(now - ringbuffer.front().start_timestamp)); + + for (auto i = 0u; i < bins.size(); i++) { + auto const increment = ringbuffer.front().histogram.data[i] * delta.count(); + if (CC_UNLIKELY((bins[i] + increment < bins[i]) || (increment < ringbuffer.front().histogram.data[i]))) { + bins[i] = std::numeric_limits<uint64_t>::max(); + } else { + bins[i] += increment; + } + } +} + void histogram::Ringbuffer::insert(drm_msm_hist const& frame) { std::unique_lock<decltype(mutex)> lk(mutex); + auto now = timekeeper->current_time(); + update_cumulative(now, cumulative_frame_count, cumulative_bins); if (ringbuffer.size() == rb_max_size) ringbuffer.pop_back(); - ringbuffer.push_front({frame, timekeeper->current_time()}); - - cumulative_frame_count++; - for (auto i = 0u; i < cumulative_bins.size(); i++) - cumulative_bins[i] += frame.data[i]; + if (!ringbuffer.empty()) + ringbuffer.front().end_timestamp = now; + ringbuffer.push_front({frame, now, 0}); } bool histogram::Ringbuffer::resize(size_t ringbuffer_size) { @@ -58,7 +81,9 @@ bool histogram::Ringbuffer::resize(size_t ringbuffer_size) { histogram::Ringbuffer::Sample histogram::Ringbuffer::collect_cumulative() const { std::unique_lock<decltype(mutex)> lk(mutex); - return {cumulative_frame_count, cumulative_bins}; + histogram::Ringbuffer::Sample sample { cumulative_frame_count, cumulative_bins }; + update_cumulative(timekeeper->current_time(), std::get<0>(sample), std::get<1>(sample)); + return sample; } histogram::Ringbuffer::Sample histogram::Ringbuffer::collect_ringbuffer_all() const { @@ -91,8 +116,14 @@ histogram::Ringbuffer::Sample histogram::Ringbuffer::collect_max( std::array<uint64_t, HIST_V_SIZE> bins; bins.fill(0); for (auto it = ringbuffer.begin(); it != ringbuffer.begin() + collect_first; it++) { + nsecs_t end_timestamp = it->end_timestamp; + if (it == ringbuffer.begin() ) { + end_timestamp = timekeeper->current_time(); + } + const auto time_displayed = std::chrono::nanoseconds(end_timestamp - it->start_timestamp); + const auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(time_displayed); for (auto i = 0u; i < HIST_V_SIZE; i++) { - bins[i] += it->histogram.data[i]; + bins[i] += it->histogram.data[i] * delta.count(); } } return { collect_first, bins }; @@ -100,11 +131,11 @@ histogram::Ringbuffer::Sample histogram::Ringbuffer::collect_max( histogram::Ringbuffer::Sample histogram::Ringbuffer::collect_max_after( nsecs_t timestamp, uint32_t max_frames, std::unique_lock<std::mutex> const& lk) const { - auto ts_filter_begin = std::lower_bound(ringbuffer.begin(), ringbuffer.end(), - HistogramEntry{ {}, timestamp}, - [](auto const& a, auto const& b) { return a.timestamp >= b.timestamp; }); + auto ts_filter_begin = std::lower_bound( + ringbuffer.begin(), ringbuffer.end(), HistogramEntry{{}, timestamp, 0}, + [](auto const &a, auto const &b) { return a.start_timestamp >= b.start_timestamp; }); - auto collect_last = std::min( - std::distance(ringbuffer.begin(), ts_filter_begin), static_cast<std::ptrdiff_t>(max_frames)); + auto collect_last = std::min(std::distance(ringbuffer.begin(), ts_filter_begin), + static_cast<std::ptrdiff_t>(max_frames)); return collect_max(collect_last, lk); } diff --git a/libhistogram/ringbuffer.h b/libhistogram/ringbuffer.h index 424fc5c9..a1165537 100644 --- a/libhistogram/ringbuffer.h +++ b/libhistogram/ringbuffer.h @@ -66,11 +66,13 @@ private: Sample collect_max(uint32_t max_frames, std::unique_lock<std::mutex> const&) const; Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames, std::unique_lock<std::mutex> const&) const; + void update_cumulative(nsecs_t now, uint64_t& count, std::array<uint64_t, HIST_V_SIZE>& bins) const; std::mutex mutable mutex; struct HistogramEntry { drm_msm_hist histogram; - nsecs_t timestamp; + nsecs_t start_timestamp; + nsecs_t end_timestamp; }; std::deque<HistogramEntry> ringbuffer; size_t rb_max_size; diff --git a/libhistogram/ringbuffer_test.cpp b/libhistogram/ringbuffer_test.cpp index 6c272e2d..8e01aad0 100644 --- a/libhistogram/ringbuffer_test.cpp +++ b/libhistogram/ringbuffer_test.cpp @@ -14,31 +14,48 @@ * limitations under the License. */ +#include <chrono> #include <numeric> #include <gtest/gtest.h> #include <gmock/gmock.h> #include "ringbuffer.h" using namespace testing; +using namespace std::chrono_literals; -struct StubTimeKeeper : histogram::TimeKeeper { - StubTimeKeeper() {} - StubTimeKeeper(std::vector<nsecs_t> const& sequence) : time_sequence(sequence) {} - - nsecs_t current_time() const final { - if (time_sequence.empty()) - return fake_time++; - if (last_returned_in_sequence == time_sequence.size()) { - return time_sequence.back() + ++fake_time; - } else { - return time_sequence[last_returned_in_sequence++]; - } - } - std::vector<nsecs_t> time_sequence = {}; - int mutable fake_time = 0; - int mutable last_returned_in_sequence = 0; +template <typename Rep, typename Per> +nsecs_t toNsecs(std::chrono::duration<Rep, Per> time) { + return std::chrono::duration_cast<std::chrono::nanoseconds>(time).count(); +} + +template <typename Rep, typename Per> +uint64_t toMs(std::chrono::duration<Rep, Per> time) { + return std::chrono::duration_cast<std::chrono::milliseconds>(time).count(); +} + +struct TimeKeeperWrapper : histogram::TimeKeeper { + TimeKeeperWrapper(std::shared_ptr<histogram::TimeKeeper> const &tk) : tk(tk) {} + nsecs_t current_time() const final { return tk->current_time(); } + std::shared_ptr<histogram::TimeKeeper> const tk; }; +struct TickingTimeKeeper : histogram::TimeKeeper { + void tick() { fake_time = fake_time + toNsecs(1ms); } + + void increment_by(std::chrono::nanoseconds inc) { fake_time = fake_time + inc.count(); } + + nsecs_t current_time() const final { return fake_time; } + +private: + nsecs_t mutable fake_time = 0; +}; + +void insertFrameIncrementTimeline(histogram::Ringbuffer &rb, TickingTimeKeeper &tk, + drm_msm_hist &frame) { + rb.insert(frame); + tk.tick(); +} + class RingbufferTestCases : public ::testing::Test { void SetUp() { for (auto i = 0u; i < HIST_V_SIZE; i++) { @@ -47,37 +64,40 @@ class RingbufferTestCases : public ::testing::Test { frame2.data[i] = fill_frame2; frame3.data[i] = fill_frame3; frame4.data[i] = fill_frame4; + frame_saturate.data[i] = std::numeric_limits<uint32_t>::max(); } } protected: - std::unique_ptr<histogram::Ringbuffer> createFilledRingbuffer() { - auto rb = histogram::Ringbuffer::create(fake_timestamps.size(), std::make_unique<StubTimeKeeper>(fake_timestamps)); - rb->insert(frame0); - rb->insert(frame1); - rb->insert(frame2); - rb->insert(frame3); + std::unique_ptr<histogram::Ringbuffer> createFilledRingbuffer( + std::shared_ptr<TickingTimeKeeper> const &tk) { + auto rb = histogram::Ringbuffer::create(4, std::make_unique<TimeKeeperWrapper>(tk)); + insertFrameIncrementTimeline(*rb, *tk, frame0); + insertFrameIncrementTimeline(*rb, *tk, frame1); + insertFrameIncrementTimeline(*rb, *tk, frame2); + insertFrameIncrementTimeline(*rb, *tk, frame3); return rb; } - int fill_frame0 = 9; - int fill_frame1 = 11; - int fill_frame2 = 303; - int fill_frame3 = 1030; - int fill_frame4 = 112200; + uint64_t fill_frame0 = 9; + uint64_t fill_frame1 = 11; + uint64_t fill_frame2 = 303; + uint64_t fill_frame3 = 1030; + uint64_t fill_frame4 = 112200; drm_msm_hist frame0; drm_msm_hist frame1; drm_msm_hist frame2; drm_msm_hist frame3; drm_msm_hist frame4; - std::vector<nsecs_t> fake_timestamps { 1, 3, 5, 7 }; + drm_msm_hist frame_saturate; int numFrames = 0; std::array<uint64_t, HIST_V_SIZE> bins; }; TEST_F(RingbufferTestCases, ZeroSizedRingbufferReturnsNull) { - EXPECT_THAT(histogram::Ringbuffer::create(0, std::make_unique<StubTimeKeeper>()), Eq(nullptr)); + EXPECT_THAT(histogram::Ringbuffer::create(0, std::make_unique<TickingTimeKeeper>()), + Eq(nullptr)); } TEST_F(RingbufferTestCases, NullTimekeeperReturnsNull) { @@ -85,7 +105,7 @@ TEST_F(RingbufferTestCases, NullTimekeeperReturnsNull) { } TEST_F(RingbufferTestCases, CollectionWithNoFrames) { - auto rb = histogram::Ringbuffer::create(1, std::make_unique<StubTimeKeeper>()); + auto rb = histogram::Ringbuffer::create(1, std::make_unique<TickingTimeKeeper>()); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(0)); @@ -94,22 +114,23 @@ TEST_F(RingbufferTestCases, CollectionWithNoFrames) { TEST_F(RingbufferTestCases, SimpleTest) { static constexpr int numInsertions = 3u; - auto rb = histogram::Ringbuffer::create(numInsertions, std::make_unique<StubTimeKeeper>()); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(numInsertions, std::make_unique<TimeKeeperWrapper>(tk)); drm_msm_hist frame; for (auto i = 0u; i < HIST_V_SIZE; i++) { frame.data[i] = i; } - rb->insert(frame); - rb->insert(frame); - rb->insert(frame); + insertFrameIncrementTimeline(*rb, *tk, frame); + insertFrameIncrementTimeline(*rb, *tk, frame); + insertFrameIncrementTimeline(*rb, *tk, frame); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); ASSERT_THAT(bins.size(), Eq(HIST_V_SIZE)); for (auto i = 0u; i < bins.size(); i++) { - EXPECT_THAT(bins[i], Eq(numInsertions * i)); + EXPECT_THAT(bins[i], Eq(toMs(3ms) * i)); } } @@ -123,52 +144,52 @@ TEST_F(RingbufferTestCases, TestEvictionSingle) { frame1.data[i] = fill_frame1; } - auto rb = histogram::Ringbuffer::create(1, std::make_unique<StubTimeKeeper>()); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(1, std::make_unique<TimeKeeperWrapper>(tk)); - rb->insert(frame0); + insertFrameIncrementTimeline(*rb, *tk, frame0); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame0)); - rb->insert(frame1); + insertFrameIncrementTimeline(*rb, *tk, frame1); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame1)); } TEST_F(RingbufferTestCases, TestEvictionMultiple) { - auto rb = histogram::Ringbuffer::create(3, std::make_unique<StubTimeKeeper>()); - rb->insert(frame0); - rb->insert(frame1); - rb->insert(frame2); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(3, std::make_unique<TimeKeeperWrapper>(tk)); + + insertFrameIncrementTimeline(*rb, *tk, frame0); + insertFrameIncrementTimeline(*rb, *tk, frame1); + insertFrameIncrementTimeline(*rb, *tk, frame2); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + fill_frame2)); - rb->insert(frame3); + insertFrameIncrementTimeline(*rb, *tk, frame3); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame1 + fill_frame2 + fill_frame3)); - rb->insert(frame0); + insertFrameIncrementTimeline(*rb, *tk, frame0); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame2 + fill_frame3 + fill_frame0)); } TEST_F(RingbufferTestCases, TestResizeToZero) { - auto rb = histogram::Ringbuffer::create(4, std::make_unique<StubTimeKeeper>()); + auto rb = histogram::Ringbuffer::create(4, std::make_unique<TickingTimeKeeper>()); EXPECT_FALSE(rb->resize(0)); } TEST_F(RingbufferTestCases, TestResizeDown) { - auto rb = histogram::Ringbuffer::create(4, std::make_unique<StubTimeKeeper>()); - rb->insert(frame0); - rb->insert(frame1); - rb->insert(frame2); - rb->insert(frame3); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = createFilledRingbuffer(tk); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(4)); @@ -180,16 +201,18 @@ TEST_F(RingbufferTestCases, TestResizeDown) { EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame2 + fill_frame3)); - rb->insert(frame0); + insertFrameIncrementTimeline(*rb, *tk, frame0); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame3)); } TEST_F(RingbufferTestCases, TestResizeUp) { - auto rb = histogram::Ringbuffer::create(2, std::make_unique<StubTimeKeeper>()); - rb->insert(frame0); - rb->insert(frame1); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(2, std::make_unique<TimeKeeperWrapper>(tk)); + + insertFrameIncrementTimeline(*rb, *tk, frame0); + insertFrameIncrementTimeline(*rb, *tk, frame1); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(2)); @@ -201,43 +224,49 @@ TEST_F(RingbufferTestCases, TestResizeUp) { EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1)); - rb->insert(frame2); + insertFrameIncrementTimeline(*rb, *tk, frame2); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + fill_frame2)); - rb->insert(frame3); + insertFrameIncrementTimeline(*rb, *tk, frame3); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame1 + fill_frame2 + fill_frame3)); } TEST_F(RingbufferTestCases, TestTimestampFiltering) { - auto rb = createFilledRingbuffer(); + auto rb = createFilledRingbuffer(std::make_shared<TickingTimeKeeper>()); - std::tie(numFrames, bins) = rb->collect_after(4); + std::tie(numFrames, bins) = rb->collect_after(toNsecs(1500us)); EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame2 + fill_frame3)); - std::tie(numFrames, bins) = rb->collect_after(fake_timestamps.back() + 1); + std::tie(numFrames, bins) = rb->collect_after(toNsecs(45000us)); EXPECT_THAT(numFrames, Eq(0)); - std::tie(numFrames, bins) = rb->collect_after(fake_timestamps.front() - 1); + std::tie(numFrames, bins) = rb->collect_after(0); EXPECT_THAT(numFrames, Eq(4)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + fill_frame2 + fill_frame3)); } TEST_F(RingbufferTestCases, TestTimestampFilteringSameTimestamp) { - auto rb = createFilledRingbuffer(); - auto ts = fake_timestamps.back(); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(4, std::make_unique<TimeKeeperWrapper>(tk)); + insertFrameIncrementTimeline(*rb, *tk, frame0); + insertFrameIncrementTimeline(*rb, *tk, frame1); + insertFrameIncrementTimeline(*rb, *tk, frame2); + rb->insert(frame3); rb->insert(frame4); - std::tie(numFrames, bins) = rb->collect_after(ts); + tk->tick(); + + std::tie(numFrames, bins) = rb->collect_after(toNsecs(3ms)); EXPECT_THAT(numFrames, Eq(2)); - EXPECT_THAT(bins, Each(fill_frame3 + fill_frame4)); + EXPECT_THAT(bins, Each(fill_frame4)); } TEST_F(RingbufferTestCases, TestFrameFiltering) { - auto rb = createFilledRingbuffer(); + auto rb = createFilledRingbuffer(std::make_shared<TickingTimeKeeper>()); std::tie(numFrames, bins) = rb->collect_max(2); EXPECT_THAT(numFrames, Eq(2)); @@ -251,58 +280,58 @@ TEST_F(RingbufferTestCases, TestFrameFiltering) { EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame1 + fill_frame2 + fill_frame3)); - std::tie(numFrames, bins) = rb->collect_max( 2 * fake_timestamps.size()); + std::tie(numFrames, bins) = rb->collect_max(8); EXPECT_THAT(numFrames, Eq(4)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + fill_frame2 + fill_frame3)); } TEST_F(RingbufferTestCases, TestTimestampAndFrameFiltering) { - auto rb = createFilledRingbuffer(); + auto rb = createFilledRingbuffer(std::make_shared<TickingTimeKeeper>()); - std::tie(numFrames, bins) = rb->collect_max_after(2, 1); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(1500us), 1); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame3)); - std::tie(numFrames, bins) = rb->collect_max_after(4, 0); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(2500us), 0); EXPECT_THAT(numFrames, Eq(0)); EXPECT_THAT(bins, Each(0)); - std::tie(numFrames, bins) = rb->collect_max_after(10, 100); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(10ms), 100); EXPECT_THAT(numFrames, Eq(0)); EXPECT_THAT(bins, Each(0)); - std::tie(numFrames, bins) = rb->collect_max_after(0, 10); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(0ns), 10); EXPECT_THAT(numFrames, Eq(4)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + fill_frame2 + fill_frame3)); } TEST_F(RingbufferTestCases, TestTimestampAndFrameFilteringAndResize) { - auto rb = createFilledRingbuffer(); + auto rb = createFilledRingbuffer(std::make_shared<TickingTimeKeeper>()); - std::tie(numFrames, bins) = rb->collect_max_after(2, 1); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(500us), 1); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame3)); - std::tie(numFrames, bins) = rb->collect_max_after(2, 10); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(500us), 10); EXPECT_THAT(numFrames, Eq(3)); EXPECT_THAT(bins, Each(fill_frame1 + fill_frame2 + fill_frame3)); rb->resize(2); - std::tie(numFrames, bins) = rb->collect_max_after(2, 10); + std::tie(numFrames, bins) = rb->collect_max_after(toNsecs(500us), 10); EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame2 + fill_frame3)); } TEST_F(RingbufferTestCases, TestCumulativeCounts) { - auto rb = histogram::Ringbuffer::create(1, std::make_unique<StubTimeKeeper>()); - - rb->insert(frame0); + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(1, std::make_unique<TimeKeeperWrapper>(tk)); + insertFrameIncrementTimeline(*rb, *tk, frame0); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame0)); - rb->insert(frame1); + insertFrameIncrementTimeline(*rb, *tk, frame1); std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); EXPECT_THAT(numFrames, Eq(1)); EXPECT_THAT(bins, Each(fill_frame1)); @@ -310,6 +339,69 @@ TEST_F(RingbufferTestCases, TestCumulativeCounts) { std::tie(numFrames, bins) = rb->collect_cumulative(); EXPECT_THAT(numFrames, Eq(2)); EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1)); + rb->insert(frame2); + auto weight0 = std::chrono::duration_cast<std::chrono::nanoseconds>(1h); + tk->increment_by(weight0); + + std::tie(numFrames, bins) = rb->collect_cumulative(); + EXPECT_THAT(numFrames, Eq(3)); + EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + (fill_frame2 * + std::chrono::duration_cast<std::chrono::milliseconds>(weight0).count()))); + + auto weight1 = std::chrono::duration_cast<std::chrono::nanoseconds>(2min); + tk->increment_by(weight1); + std::tie(numFrames, bins) = rb->collect_cumulative(); + EXPECT_THAT(numFrames, Eq(3)); + EXPECT_THAT(bins, Each(fill_frame0 + fill_frame1 + (fill_frame2 * + std::chrono::duration_cast<std::chrono::milliseconds>(weight0 + weight1).count()))); +} + +TEST_F(RingbufferTestCases, TestCumulativeCountsEmpty) { + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(1, std::make_unique<TimeKeeperWrapper>(tk)); + std::tie(numFrames, bins) = rb->collect_cumulative(); + EXPECT_THAT(numFrames, Eq(0)); +} + +TEST_F(RingbufferTestCases, TestCumulativeCountsSaturate) { + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(1, std::make_unique<TimeKeeperWrapper>(tk)); + insertFrameIncrementTimeline(*rb, *tk, frame_saturate); + auto eon = std::chrono::nanoseconds(std::numeric_limits<uint64_t>::max()); + tk->increment_by(eon); + std::tie(numFrames, bins) = rb->collect_cumulative(); + EXPECT_THAT(numFrames, Eq(1)); + EXPECT_THAT(bins, Each(std::numeric_limits<uint64_t>::max())); +} + +TEST_F(RingbufferTestCases, TimeWeightingTest) { + static constexpr int numInsertions = 4u; + auto tk = std::make_shared<TickingTimeKeeper>(); + auto rb = histogram::Ringbuffer::create(numInsertions, std::make_unique<TimeKeeperWrapper>(tk)); + + auto weight0 = std::chrono::duration_cast<std::chrono::nanoseconds>(1ms); + auto weight1 = std::chrono::duration_cast<std::chrono::nanoseconds>(1h); + auto weight2 = std::chrono::duration_cast<std::chrono::nanoseconds>(1s); + using gigasecond = std::chrono::duration<uint64_t, std::giga>; + auto weight3 = std::chrono::duration_cast<std::chrono::nanoseconds>(gigasecond(4)); + + rb->insert(frame0); + tk->increment_by(weight0); + rb->insert(frame1); + tk->increment_by(weight1); + rb->insert(frame2); + tk->increment_by(weight2); + rb->insert(frame3); + tk->increment_by(weight3); + + std::tie(numFrames, bins) = rb->collect_ringbuffer_all(); + + ASSERT_THAT(bins.size(), Eq(HIST_V_SIZE)); + uint64_t expected_weight = fill_frame0 * toMs(weight0) + fill_frame1 * toMs(weight1) + + fill_frame2 * toMs(weight2) + fill_frame3 * toMs(weight3); + for (auto i = 0u; i < bins.size(); i++) { + EXPECT_THAT(bins[i], Eq(expected_weight)); + } } int main(int argc, char** argv) { |