Skip to content

Commit 9dfcfef

Browse files
AMouriAndroid (Google) Code Review
authored andcommitted
Merge "Move RingBuffer from SF utils into libui" into main
2 parents 1bd65bd + 78b8252 commit 9dfcfef

7 files changed

Lines changed: 98 additions & 37 deletions

File tree

services/surfaceflinger/Utils/RingBuffer.h renamed to libs/ui/include/ui/RingBuffer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <stddef.h>
2020
#include <array>
2121

22-
namespace android::utils {
22+
namespace android::ui {
2323

2424
template <class T, size_t SIZE>
2525
class RingBuffer {
@@ -31,8 +31,8 @@ class RingBuffer {
3131
~RingBuffer() = default;
3232

3333
constexpr size_t capacity() const { return SIZE; }
34-
3534
size_t size() const { return mCount; }
35+
bool isFull() const { return size() == capacity(); }
3636

3737
T& next() {
3838
mHead = static_cast<size_t>(mHead + 1) % SIZE;
@@ -67,4 +67,4 @@ class RingBuffer {
6767
size_t mCount = 0;
6868
};
6969

70-
} // namespace android::utils
70+
} // namespace android::ui

libs/ui/tests/Android.bp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ cc_test {
143143
],
144144
}
145145

146+
cc_test {
147+
name: "RingBuffer_test",
148+
test_suites: ["device-tests"],
149+
shared_libs: ["libui"],
150+
srcs: ["RingBuffer_test.cpp"],
151+
cflags: [
152+
"-Wall",
153+
"-Werror",
154+
],
155+
}
156+
146157
cc_test {
147158
name: "Size_test",
148159
test_suites: ["device-tests"],

libs/ui/tests/RingBuffer_test.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <gtest/gtest.h>
18+
#include <ui/RingBuffer.h>
19+
20+
namespace android::ui {
21+
22+
TEST(RingBuffer, basic) {
23+
RingBuffer<int, 5> rb;
24+
25+
rb.next() = 1;
26+
ASSERT_EQ(1, rb.size());
27+
ASSERT_EQ(1, rb.back());
28+
ASSERT_EQ(1, rb.front());
29+
30+
rb.next() = 2;
31+
ASSERT_EQ(2, rb.size());
32+
ASSERT_EQ(2, rb.back());
33+
ASSERT_EQ(1, rb.front());
34+
ASSERT_EQ(1, rb[-1]);
35+
36+
rb.next() = 3;
37+
ASSERT_EQ(3, rb.size());
38+
ASSERT_EQ(3, rb.back());
39+
ASSERT_EQ(1, rb.front());
40+
ASSERT_EQ(2, rb[-1]);
41+
ASSERT_EQ(1, rb[-2]);
42+
43+
rb.next() = 4;
44+
ASSERT_EQ(4, rb.size());
45+
ASSERT_EQ(4, rb.back());
46+
ASSERT_EQ(1, rb.front());
47+
ASSERT_EQ(3, rb[-1]);
48+
ASSERT_EQ(2, rb[-2]);
49+
ASSERT_EQ(1, rb[-3]);
50+
51+
rb.next() = 5;
52+
ASSERT_EQ(5, rb.size());
53+
ASSERT_EQ(5, rb.back());
54+
ASSERT_EQ(1, rb.front());
55+
ASSERT_EQ(4, rb[-1]);
56+
ASSERT_EQ(3, rb[-2]);
57+
ASSERT_EQ(2, rb[-3]);
58+
ASSERT_EQ(1, rb[-4]);
59+
60+
rb.next() = 6;
61+
ASSERT_EQ(5, rb.size());
62+
ASSERT_EQ(6, rb.back());
63+
ASSERT_EQ(2, rb.front());
64+
ASSERT_EQ(5, rb[-1]);
65+
ASSERT_EQ(4, rb[-2]);
66+
ASSERT_EQ(3, rb[-3]);
67+
ASSERT_EQ(2, rb[-4]);
68+
}
69+
70+
} // namespace android::ui

services/surfaceflinger/HdrLayerInfoReporter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
#include <android-base/thread_annotations.h>
2020
#include <android/gui/IHdrLayerInfoListener.h>
2121
#include <binder/IBinder.h>
22+
#include <ui/RingBuffer.h>
2223
#include <utils/Timers.h>
2324

2425
#include <unordered_map>
2526

26-
#include "Utils/RingBuffer.h"
2727
#include "WpHash.h"
2828

2929
namespace android {
@@ -102,7 +102,7 @@ class HdrLayerInfoReporter final : public IBinder::DeathRecipient {
102102
EventHistoryEntry(const HdrLayerInfo& info) : info(info) { timestamp = systemTime(); }
103103
};
104104

105-
utils::RingBuffer<EventHistoryEntry, 32> mHdrInfoHistory;
105+
ui::RingBuffer<EventHistoryEntry, 32> mHdrInfoHistory;
106106
};
107107

108108
} // namespace android

services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ void PowerAdvisor::setRequiresRenderEngine(DisplayId displayId, bool requiresRen
515515
}
516516

517517
void PowerAdvisor::setExpectedPresentTime(TimePoint expectedPresentTime) {
518-
mExpectedPresentTimes.append(expectedPresentTime);
518+
mExpectedPresentTimes.next() = expectedPresentTime;
519519
}
520520

521521
void PowerAdvisor::setSfPresentTiming(TimePoint presentFenceTime, TimePoint presentEndTime) {
@@ -532,7 +532,7 @@ void PowerAdvisor::setHwcPresentDelayedTime(DisplayId displayId, TimePoint earli
532532
}
533533

534534
void PowerAdvisor::setCommitStart(TimePoint commitStartTime) {
535-
mCommitStartTimes.append(commitStartTime);
535+
mCommitStartTimes.next() = commitStartTime;
536536
}
537537

538538
void PowerAdvisor::setCompositeEnd(TimePoint compositeEndTime) {
@@ -579,7 +579,7 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() {
579579
}
580580

581581
// Tracks when we finish presenting to hwc
582-
TimePoint estimatedHwcEndTime = mCommitStartTimes[0];
582+
TimePoint estimatedHwcEndTime = mCommitStartTimes.back();
583583

584584
// How long we spent this frame not doing anything, waiting for fences or vsync
585585
Duration idleDuration = 0ns;
@@ -643,13 +643,13 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() {
643643
// Also add the frame delay duration since the target did not move while we were delayed
644644
Duration totalDuration = mFrameDelayDuration +
645645
std::max(estimatedHwcEndTime, estimatedGpuEndTime.value_or(TimePoint{0ns})) -
646-
mCommitStartTimes[0];
646+
mCommitStartTimes.back();
647647
Duration totalDurationWithoutGpu =
648-
mFrameDelayDuration + estimatedHwcEndTime - mCommitStartTimes[0];
648+
mFrameDelayDuration + estimatedHwcEndTime - mCommitStartTimes.back();
649649

650650
// We finish SurfaceFlinger when post-composition finishes, so add that in here
651651
Duration flingerDuration =
652-
estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes[0];
652+
estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes.back();
653653
Duration estimatedGpuDuration = firstGpuTimeline.has_value()
654654
? estimatedGpuEndTime.value_or(TimePoint{0ns}) - firstGpuTimeline->startTime
655655
: Duration::fromNs(0);
@@ -661,7 +661,7 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() {
661661
hal::WorkDuration duration{
662662
.timeStampNanos = TimePoint::now().ns(),
663663
.durationNanos = combinedDuration.ns(),
664-
.workPeriodStartTimestampNanos = mCommitStartTimes[0].ns(),
664+
.workPeriodStartTimestampNanos = mCommitStartTimes.back().ns(),
665665
.cpuDurationNanos = supportsGpuReporting() ? cpuDuration.ns() : 0,
666666
.gpuDurationNanos = supportsGpuReporting() ? estimatedGpuDuration.ns() : 0,
667667
};

services/surfaceflinger/PowerAdvisor/PowerAdvisor.h

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <ui/DisplayId.h>
2525
#include <ui/FenceTime.h>
26+
#include <ui/RingBuffer.h>
2627
#include <utils/Mutex.h>
2728

2829
// FMQ library in IPower does questionable conversions
@@ -247,27 +248,6 @@ class PowerAdvisor final : public adpf::PowerAdvisor {
247248
std::optional<GpuTimeline> estimateGpuTiming(std::optional<TimePoint> previousEndTime);
248249
};
249250

250-
template <class T, size_t N>
251-
class RingBuffer {
252-
std::array<T, N> elements = {};
253-
size_t mIndex = 0;
254-
size_t numElements = 0;
255-
256-
public:
257-
void append(T item) {
258-
mIndex = (mIndex + 1) % N;
259-
numElements = std::min(N, numElements + 1);
260-
elements[mIndex] = item;
261-
}
262-
bool isFull() const { return numElements == N; }
263-
// Allows access like [0] == current, [-1] = previous, etc..
264-
T& operator[](int offset) {
265-
size_t positiveOffset =
266-
static_cast<size_t>((offset % static_cast<int>(N)) + static_cast<int>(N));
267-
return elements[(mIndex + positiveOffset) % N];
268-
}
269-
};
270-
271251
// Filter and sort the display ids by a given property
272252
std::vector<DisplayId> getOrderedDisplayIds(
273253
std::optional<TimePoint> DisplayTimingData::*sortBy);
@@ -287,9 +267,9 @@ class PowerAdvisor final : public adpf::PowerAdvisor {
287267
// Last frame's post-composition duration
288268
Duration mLastPostcompDuration{0ns};
289269
// Buffer of recent commit start times
290-
RingBuffer<TimePoint, 2> mCommitStartTimes;
270+
ui::RingBuffer<TimePoint, 2> mCommitStartTimes;
291271
// Buffer of recent expected present times
292-
RingBuffer<TimePoint, 2> mExpectedPresentTimes;
272+
ui::RingBuffer<TimePoint, 2> mExpectedPresentTimes;
293273
// Most recent present fence time, provided by SF after composition engine finishes presenting
294274
TimePoint mLastPresentFenceTime;
295275
// Most recent composition engine present end time, returned with the present fence from SF

services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <ui/DisplayId.h>
2525
#include <ui/Fence.h>
2626
#include <ui/FenceTime.h>
27+
#include <ui/RingBuffer.h>
2728

2829
#include <scheduler/Features.h>
2930
#include <scheduler/FrameTime.h>
@@ -34,7 +35,6 @@
3435
// TODO(b/185536303): Pull to FTL.
3536
#include "../../../TracedOrdinal.h"
3637
#include "../../../Utils/Dumper.h"
37-
#include "../../../Utils/RingBuffer.h"
3838

3939
namespace android::scheduler {
4040

@@ -108,7 +108,7 @@ class FrameTarget {
108108
std::pair<bool /* wouldBackpressure */, PresentFence> expectedSignaledPresentFence(
109109
Period vsyncPeriod, Period minFramePeriod) const;
110110
std::array<PresentFence, 2> mPresentFencesLegacy;
111-
utils::RingBuffer<PresentFence, 5> mPresentFences;
111+
ui::RingBuffer<PresentFence, 5> mPresentFences;
112112

113113
FrameTime mLastSignaledFrameTime;
114114

0 commit comments

Comments
 (0)