summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin DuBois <kevindubois@google.com>2019-03-01 09:39:11 -0800
committerKevin DuBois <kevindubois@google.com>2019-03-06 09:39:21 -0800
commit1284c3f5c329b2c6aa4057f172742aa724a84478 (patch)
tree1df56339f3fb618aecc167691dad9d7cc6cd1316
parentc67af46944a34bcdd8f5f4f39a4fb95c84b2d4f6 (diff)
downloadandroid_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.cpp57
-rw-r--r--libhistogram/ringbuffer.h4
-rw-r--r--libhistogram/ringbuffer_test.cpp250
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) {