• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #undef LOG_TAG
18 #define LOG_TAG "TexturePoolTest"
19 
20 #include <compositionengine/impl/planner/TexturePool.h>
21 #include <gtest/gtest.h>
22 #include <log/log.h>
23 #include <renderengine/mock/RenderEngine.h>
24 
25 namespace android::compositionengine::impl::planner {
26 namespace {
27 
28 const ui::Size kDisplaySize(1, 1);
29 const ui::Size kDisplaySizeTwo(2, 2);
30 
31 class TestableTexturePool : public TexturePool {
32 public:
TestableTexturePool(renderengine::RenderEngine & renderEngine)33     TestableTexturePool(renderengine::RenderEngine& renderEngine) : TexturePool(renderEngine) {}
34 
getMinPoolSize() const35     size_t getMinPoolSize() const { return kMinPoolSize; }
getMaxPoolSize() const36     size_t getMaxPoolSize() const { return kMaxPoolSize; }
getPoolSize() const37     size_t getPoolSize() const { return mPool.size(); }
38 };
39 
40 struct TexturePoolTest : public testing::Test {
TexturePoolTestandroid::compositionengine::impl::planner::__anon301f42410111::TexturePoolTest41     TexturePoolTest() {
42         const ::testing::TestInfo* const test_info =
43                 ::testing::UnitTest::GetInstance()->current_test_info();
44         ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
45         mTexturePool.setEnabled(true);
46         mTexturePool.setDisplaySize(kDisplaySize);
47     }
48 
~TexturePoolTestandroid::compositionengine::impl::planner::__anon301f42410111::TexturePoolTest49     ~TexturePoolTest() {
50         const ::testing::TestInfo* const test_info =
51                 ::testing::UnitTest::GetInstance()->current_test_info();
52         ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
53     }
54 
55     renderengine::mock::RenderEngine mRenderEngine;
56     TestableTexturePool mTexturePool = TestableTexturePool(mRenderEngine);
57 };
58 
TEST_F(TexturePoolTest,preallocatesMinPool)59 TEST_F(TexturePoolTest, preallocatesMinPool) {
60     EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
61 }
62 
TEST_F(TexturePoolTest,doesNotAllocateBeyondMinPool)63 TEST_F(TexturePoolTest, doesNotAllocateBeyondMinPool) {
64     for (size_t i = 0; i < mTexturePool.getMinPoolSize() + 1; i++) {
65         auto texture = mTexturePool.borrowTexture();
66     }
67 
68     EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
69 }
70 
TEST_F(TexturePoolTest,cyclesUpToMaxPoolSize)71 TEST_F(TexturePoolTest, cyclesUpToMaxPoolSize) {
72     std::unordered_set<uint64_t> bufferIds;
73     std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
74     for (size_t i = 0; i < mTexturePool.getMaxPoolSize(); i++) {
75         textures.emplace_back(mTexturePool.borrowTexture());
76         bufferIds.insert(textures.back()->get()->getBuffer()->getId());
77     }
78 
79     EXPECT_EQ(mTexturePool.getMaxPoolSize(), bufferIds.size());
80 
81     for (size_t i = 0; i < 3; i++) {
82         textures.pop_front();
83         textures.emplace_back(mTexturePool.borrowTexture());
84         bufferIds.insert(textures.back()->get()->getBuffer()->getId());
85     }
86 
87     EXPECT_EQ(mTexturePool.getMaxPoolSize(), bufferIds.size());
88 }
89 
TEST_F(TexturePoolTest,goesPastMaxSizeAndRebounds)90 TEST_F(TexturePoolTest, goesPastMaxSizeAndRebounds) {
91     std::unordered_set<uint64_t> bufferIds;
92     std::vector<std::shared_ptr<TexturePool::AutoTexture>> textures;
93     for (size_t i = 0; i < mTexturePool.getMaxPoolSize() + 2; i++) {
94         textures.emplace_back(mTexturePool.borrowTexture());
95         bufferIds.insert(textures.back()->get()->getBuffer()->getId());
96     }
97 
98     EXPECT_EQ(mTexturePool.getMaxPoolSize() + 2, bufferIds.size());
99 
100     // Return the textures to the pool.
101     // Now when we cycle through the pool it's again bounded by max textures.
102     textures.clear();
103 
104     std::unordered_set<uint64_t> newBufferIds;
105     for (size_t i = 0; i < 2 * mTexturePool.getMaxPoolSize(); i++) {
106         auto texture = mTexturePool.borrowTexture();
107         newBufferIds.insert(texture->get()->getBuffer()->getId());
108     }
109 
110     EXPECT_EQ(mTexturePool.getMaxPoolSize(), newBufferIds.size());
111 }
112 
TEST_F(TexturePoolTest,reallocatesWhenDisplaySizeChanges)113 TEST_F(TexturePoolTest, reallocatesWhenDisplaySizeChanges) {
114     auto texture = mTexturePool.borrowTexture();
115 
116     EXPECT_EQ(kDisplaySize.getWidth(),
117               static_cast<int32_t>(texture->get()->getBuffer()->getWidth()));
118     EXPECT_EQ(kDisplaySize.getHeight(),
119               static_cast<int32_t>(texture->get()->getBuffer()->getHeight()));
120     mTexturePool.setDisplaySize(kDisplaySizeTwo);
121 
122     EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
123     texture.reset();
124     // When the texture is returned to the pool, the pool now destroys it.
125     EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
126 
127     texture = mTexturePool.borrowTexture();
128     EXPECT_EQ(kDisplaySizeTwo.getWidth(),
129               static_cast<int32_t>(texture->get()->getBuffer()->getWidth()));
130     EXPECT_EQ(kDisplaySizeTwo.getHeight(),
131               static_cast<int32_t>(texture->get()->getBuffer()->getHeight()));
132 }
133 
TEST_F(TexturePoolTest,freesBuffersWhenDisabled)134 TEST_F(TexturePoolTest, freesBuffersWhenDisabled) {
135     EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
136 
137     std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
138     for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
139         textures.emplace_back(mTexturePool.borrowTexture());
140     }
141 
142     EXPECT_EQ(mTexturePool.getPoolSize(), 1u);
143     mTexturePool.setEnabled(false);
144     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
145 
146     textures.clear();
147     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
148 }
149 
TEST_F(TexturePoolTest,doesNotHoldBuffersWhenDisabled)150 TEST_F(TexturePoolTest, doesNotHoldBuffersWhenDisabled) {
151     EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
152     mTexturePool.setEnabled(false);
153     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
154 
155     std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
156     for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
157         textures.emplace_back(mTexturePool.borrowTexture());
158     }
159 
160     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
161     textures.clear();
162     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
163 }
164 
TEST_F(TexturePoolTest,reallocatesWhenReEnabled)165 TEST_F(TexturePoolTest, reallocatesWhenReEnabled) {
166     EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
167     mTexturePool.setEnabled(false);
168     EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
169     mTexturePool.setEnabled(true);
170     EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
171 }
172 
173 } // namespace
174 } // namespace android::compositionengine::impl::planner
175