blob: cf72e8f8dec1d52425307fef8b40595423c2368a [file] [log] [blame]
Lloyd Pique76ed7032018-12-04 17:24:28 -08001/*
2 * Copyright 2019 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 <compositionengine/impl/HwcBufferCache.h>
18#include <gtest/gtest.h>
19#include <gui/BufferQueue.h>
20#include <ui/GraphicBuffer.h>
21
22namespace android::compositionengine {
23namespace {
24
Brian Lindahl439afad2022-11-14 11:16:55 -070025using impl::HwcBufferCache;
26using impl::HwcSlotAndBuffer;
Valerie Hau6f89c372019-03-02 00:13:33 +000027
Lloyd Pique76ed7032018-12-04 17:24:28 -080028class HwcBufferCacheTest : public testing::Test {
29public:
30 ~HwcBufferCacheTest() override = default;
31
Ady Abrahamd11bade2022-08-01 16:18:03 -070032 sp<GraphicBuffer> mBuffer1 =
33 sp<GraphicBuffer>::make(1u, 1u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, 0u);
34 sp<GraphicBuffer> mBuffer2 =
35 sp<GraphicBuffer>::make(1u, 1u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, 0u);
Lloyd Pique76ed7032018-12-04 17:24:28 -080036};
37
Brian Lindahl439afad2022-11-14 11:16:55 -070038TEST_F(HwcBufferCacheTest, getHwcSlotAndBuffer_returnsUniqueSlotNumberForEachBuffer) {
39 HwcBufferCache cache;
40 sp<GraphicBuffer> outBuffer;
41
42 HwcSlotAndBuffer slotAndBufferFor1 = cache.getHwcSlotAndBuffer(mBuffer1);
43 EXPECT_NE(slotAndBufferFor1.slot, UINT32_MAX);
44 EXPECT_EQ(slotAndBufferFor1.buffer, mBuffer1);
45
46 HwcSlotAndBuffer slotAndBufferFor2 = cache.getHwcSlotAndBuffer(mBuffer2);
47 EXPECT_NE(slotAndBufferFor2.slot, slotAndBufferFor1.slot);
48 EXPECT_NE(slotAndBufferFor2.slot, UINT32_MAX);
49 EXPECT_EQ(slotAndBufferFor2.buffer, mBuffer2);
Valerie Hau13f0d1a2019-03-22 10:35:42 -070050}
51
Brian Lindahl439afad2022-11-14 11:16:55 -070052TEST_F(HwcBufferCacheTest, getHwcSlotAndBuffer_whenCached_returnsSameSlotNumberAndNullBuffer) {
53 HwcBufferCache cache;
54 sp<GraphicBuffer> outBuffer;
55
56 HwcSlotAndBuffer originalSlotAndBuffer = cache.getHwcSlotAndBuffer(mBuffer1);
57 EXPECT_NE(originalSlotAndBuffer.slot, UINT32_MAX);
58 EXPECT_EQ(originalSlotAndBuffer.buffer, mBuffer1);
59
60 HwcSlotAndBuffer finalSlotAndBuffer = cache.getHwcSlotAndBuffer(mBuffer1);
61 EXPECT_EQ(finalSlotAndBuffer.slot, originalSlotAndBuffer.slot);
62 EXPECT_EQ(finalSlotAndBuffer.buffer, nullptr);
Valerie Hau13f0d1a2019-03-22 10:35:42 -070063}
64
Brian Lindahl439afad2022-11-14 11:16:55 -070065TEST_F(HwcBufferCacheTest, getHwcSlotAndBuffer_whenSlotsFull_evictsOldestCachedBuffer) {
66 HwcBufferCache cache;
67 sp<GraphicBuffer> outBuffer;
68
69 sp<GraphicBuffer> graphicBuffers[100];
70 HwcSlotAndBuffer slotsAndBuffers[100];
71 int finalCachedBufferIndex = 0;
72 for (int i = 0; i < 100; ++i) {
73 graphicBuffers[i] = sp<GraphicBuffer>::make(1u, 1u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, 0u);
74 slotsAndBuffers[i] = cache.getHwcSlotAndBuffer(graphicBuffers[i]);
75 // we fill up the cache when the slot number for the first buffer is reused
76 if (i > 0 && slotsAndBuffers[i].slot == slotsAndBuffers[0].slot) {
77 finalCachedBufferIndex = i;
78 break;
79 }
80 }
81 ASSERT_GT(finalCachedBufferIndex, 1);
82 // the final cached buffer has the same slot value as the oldest buffer
83 EXPECT_EQ(slotsAndBuffers[finalCachedBufferIndex].slot, slotsAndBuffers[0].slot);
84 // the oldest buffer is no longer in the cache because it was evicted
85 EXPECT_EQ(cache.uncache(graphicBuffers[0]->getId()), UINT32_MAX);
86}
87
88TEST_F(HwcBufferCacheTest, uncache_whenCached_returnsSlotNumber) {
89 HwcBufferCache cache;
90 sp<GraphicBuffer> outBuffer;
91
92 HwcSlotAndBuffer slotAndBufferFor1 = cache.getHwcSlotAndBuffer(mBuffer1);
93 ASSERT_NE(slotAndBufferFor1.slot, UINT32_MAX);
94
95 HwcSlotAndBuffer slotAndBufferFor2 = cache.getHwcSlotAndBuffer(mBuffer2);
96 ASSERT_NE(slotAndBufferFor2.slot, UINT32_MAX);
97
98 // the 1st buffer should be found in the cache with a slot number
99 EXPECT_EQ(cache.uncache(mBuffer1->getId()), slotAndBufferFor1.slot);
100 // since the 1st buffer has been previously uncached, we should no longer receive a slot number
101 EXPECT_EQ(cache.uncache(mBuffer1->getId()), UINT32_MAX);
102 // the 2nd buffer should be still found in the cache with a slot number
103 EXPECT_EQ(cache.uncache(mBuffer2->getId()), slotAndBufferFor2.slot);
104 // since the 2nd buffer has been previously uncached, we should no longer receive a slot number
105 EXPECT_EQ(cache.uncache(mBuffer2->getId()), UINT32_MAX);
106}
107
108TEST_F(HwcBufferCacheTest, uncache_whenUncached_returnsInvalidSlotNumber) {
109 HwcBufferCache cache;
110 sp<GraphicBuffer> outBuffer;
111
112 HwcSlotAndBuffer slotAndBufferFor1 = cache.getHwcSlotAndBuffer(mBuffer1);
113 ASSERT_NE(slotAndBufferFor1.slot, UINT32_MAX);
114
115 EXPECT_EQ(cache.uncache(mBuffer2->getId()), UINT32_MAX);
116}
117
118TEST_F(HwcBufferCacheTest, getHwcSlotAndBufferForOverride_whenCached_returnsSameSlotAndNullBuffer) {
119 HwcBufferCache cache;
120 sp<GraphicBuffer> outBuffer;
121
122 HwcSlotAndBuffer originalSlotAndBuffer = cache.getHwcSlotAndBufferForOverride(mBuffer1);
123 EXPECT_NE(originalSlotAndBuffer.slot, UINT32_MAX);
124 EXPECT_EQ(originalSlotAndBuffer.buffer, mBuffer1);
125
126 HwcSlotAndBuffer finalSlotAndBuffer = cache.getHwcSlotAndBufferForOverride(mBuffer1);
127 EXPECT_EQ(finalSlotAndBuffer.slot, originalSlotAndBuffer.slot);
128 EXPECT_EQ(finalSlotAndBuffer.buffer, nullptr);
129}
130
131TEST_F(HwcBufferCacheTest, getHwcSlotAndBufferForOverride_whenSlotsFull_returnsIndependentSlot) {
132 HwcBufferCache cache;
133 sp<GraphicBuffer> outBuffer;
134
135 sp<GraphicBuffer> graphicBuffers[100];
136 HwcSlotAndBuffer slotsAndBuffers[100];
137 int finalCachedBufferIndex = -1;
138 for (int i = 0; i < 100; ++i) {
139 graphicBuffers[i] = sp<GraphicBuffer>::make(1u, 1u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, 0u);
140 slotsAndBuffers[i] = cache.getHwcSlotAndBuffer(graphicBuffers[i]);
141 // we fill up the cache when the slot number for the first buffer is reused
142 if (i > 0 && slotsAndBuffers[i].slot == slotsAndBuffers[0].slot) {
143 finalCachedBufferIndex = i;
144 break;
145 }
146 }
147 // expect to have cached at least a few buffers before evicting
148 ASSERT_GT(finalCachedBufferIndex, 1);
149
150 sp<GraphicBuffer> overrideBuffer =
151 sp<GraphicBuffer>::make(1u, 1u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, 0u);
152 HwcSlotAndBuffer overrideSlotAndBuffer = cache.getHwcSlotAndBufferForOverride(overrideBuffer);
153 // expect us to have a slot number
154 EXPECT_NE(overrideSlotAndBuffer.slot, UINT32_MAX);
155 // expect this to be the first time we cached the buffer
156 EXPECT_NE(overrideSlotAndBuffer.buffer, nullptr);
157
158 // expect the slot number to not equal any other slot number, even after the slots have been
159 // exhausted, indicating that the override buffer slot is independent from the slots for
160 // non-override buffers
161 for (int i = 0; i < finalCachedBufferIndex; ++i) {
162 EXPECT_NE(overrideSlotAndBuffer.slot, slotsAndBuffers[i].slot);
163 }
164 // the override buffer is independently uncached from the oldest cached buffer
165 // expect to find the override buffer still in the override buffer slot
166 EXPECT_EQ(cache.uncache(overrideBuffer->getId()), overrideSlotAndBuffer.slot);
167 // expect that the first buffer was not evicted from the cache when the override buffer was
168 // cached
169 EXPECT_EQ(cache.uncache(graphicBuffers[1]->getId()), slotsAndBuffers[1].slot);
170}
171
172TEST_F(HwcBufferCacheTest, uncache_whenOverrideCached_returnsSlotNumber) {
173 HwcBufferCache cache;
174 sp<GraphicBuffer> outBuffer;
175
176 HwcSlotAndBuffer hwcSlotAndBuffer = cache.getHwcSlotAndBufferForOverride(mBuffer1);
177 ASSERT_NE(hwcSlotAndBuffer.slot, UINT32_MAX);
178
179 EXPECT_EQ(cache.uncache(mBuffer1->getId()), hwcSlotAndBuffer.slot);
180 EXPECT_EQ(cache.uncache(mBuffer1->getId()), UINT32_MAX);
181}
182
183TEST_F(HwcBufferCacheTest, uncache_whenOverrideUncached_returnsInvalidSlotNumber) {
184 HwcBufferCache cache;
185 sp<GraphicBuffer> outBuffer;
186
187 HwcSlotAndBuffer hwcSlotAndBuffer = cache.getHwcSlotAndBufferForOverride(mBuffer1);
188 ASSERT_NE(hwcSlotAndBuffer.slot, UINT32_MAX);
189
190 EXPECT_EQ(cache.uncache(mBuffer2->getId()), UINT32_MAX);
Valerie Hau13f0d1a2019-03-22 10:35:42 -0700191}
192
Lloyd Pique76ed7032018-12-04 17:24:28 -0800193} // namespace
194} // namespace android::compositionengine