Merge "Revert "Generate texture pool asynchronously"" into udc-qpr-dev
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
index 9f6141a..d607c75 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h
@@ -66,7 +66,7 @@
TexturePool(renderengine::RenderEngine& renderEngine)
: mRenderEngine(renderEngine), mEnabled(false) {}
- virtual ~TexturePool();
+ virtual ~TexturePool() = default;
// Sets the display size for the texture pool.
// This will trigger a reallocation for all remaining textures in the pool.
@@ -83,10 +83,11 @@
// be held by the pool. This is useful when the active display changes.
void setEnabled(bool enable);
- void dump(std::string& out) const EXCLUDES(mMutex);
+ void dump(std::string& out) const;
protected:
// Proteted visibility so that they can be used for testing
+ const static constexpr size_t kMinPoolSize = 3;
const static constexpr size_t kMaxPoolSize = 4;
struct Entry {
@@ -95,20 +96,16 @@
};
std::deque<Entry> mPool;
- std::future<std::shared_ptr<renderengine::ExternalTexture>> mGenTextureFuture;
private:
- std::shared_ptr<renderengine::ExternalTexture> genTexture(ui::Size size);
+ std::shared_ptr<renderengine::ExternalTexture> genTexture();
// Returns a previously borrowed texture to the pool.
void returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture,
const sp<Fence>& fence);
- void genTextureAsyncIfNeeded() REQUIRES(mMutex);
- void resetPool() REQUIRES(mMutex);
- renderengine::RenderEngine& mRenderEngine GUARDED_BY(mRenderEngineMutex);
- ui::Size mSize GUARDED_BY(mMutex);
+ void allocatePool();
+ renderengine::RenderEngine& mRenderEngine;
+ ui::Size mSize;
bool mEnabled;
- mutable std::mutex mMutex;
- mutable std::mutex mRenderEngineMutex;
};
} // namespace android::compositionengine::impl::planner
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
index 10f58ce..54ecb56 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
@@ -25,61 +25,31 @@
namespace android::compositionengine::impl::planner {
-TexturePool::~TexturePool() {
- if (mGenTextureFuture.valid()) {
- mGenTextureFuture.get();
- }
-}
-
-void TexturePool::resetPool() {
- if (mGenTextureFuture.valid()) {
- mGenTextureFuture.get();
- }
+void TexturePool::allocatePool() {
mPool.clear();
- genTextureAsyncIfNeeded();
-}
-
-// Generate a new texture asynchronously so it will not require allocation on the main
-// thread.
-void TexturePool::genTextureAsyncIfNeeded() {
- if (mEnabled && mSize.isValid() && !mGenTextureFuture.valid()) {
- mGenTextureFuture = std::async(
- std::launch::async, [&](ui::Size size) { return genTexture(size); }, mSize);
+ if (mEnabled && mSize.isValid()) {
+ mPool.resize(kMinPoolSize);
+ std::generate_n(mPool.begin(), kMinPoolSize, [&]() {
+ return Entry{genTexture(), nullptr};
+ });
}
}
void TexturePool::setDisplaySize(ui::Size size) {
- std::lock_guard lock(mMutex);
if (mSize == size) {
return;
}
mSize = size;
- resetPool();
+ allocatePool();
}
std::shared_ptr<TexturePool::AutoTexture> TexturePool::borrowTexture() {
if (mPool.empty()) {
- std::lock_guard lock(mMutex);
- std::shared_ptr<TexturePool::AutoTexture> tex;
- if (mGenTextureFuture.valid()) {
- tex = std::make_shared<AutoTexture>(*this, mGenTextureFuture.get(), nullptr);
- } else {
- tex = std::make_shared<AutoTexture>(*this, genTexture(mSize), nullptr);
- }
- // Speculatively generate a new texture, so that the next call does not need
- // to wait for allocation.
- genTextureAsyncIfNeeded();
- return tex;
+ return std::make_shared<AutoTexture>(*this, genTexture(), nullptr);
}
const auto entry = mPool.front();
mPool.pop_front();
- if (mPool.empty()) {
- std::lock_guard lock(mMutex);
- // Similiarly generate a new texture when lending out the last entry, so that
- // the next call does not need to wait for allocation.
- genTextureAsyncIfNeeded();
- }
return std::make_shared<AutoTexture>(*this, entry.texture, entry.fence);
}
@@ -90,8 +60,6 @@
return;
}
- std::lock_guard lock(mMutex);
-
// Or the texture on the floor if the pool is no longer tracking textures of the same size.
if (static_cast<int32_t>(texture->getBuffer()->getWidth()) != mSize.getWidth() ||
static_cast<int32_t>(texture->getBuffer()->getHeight()) != mSize.getHeight()) {
@@ -112,14 +80,13 @@
mPool.push_back({std::move(texture), fence});
}
-std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture(ui::Size size) {
- std::lock_guard lock(mRenderEngineMutex);
- LOG_ALWAYS_FATAL_IF(!size.isValid(), "Attempted to generate texture with invalid size");
+std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture() {
+ LOG_ALWAYS_FATAL_IF(!mSize.isValid(), "Attempted to generate texture with invalid size");
return std::make_shared<
renderengine::impl::
ExternalTexture>(sp<GraphicBuffer>::
- make(static_cast<uint32_t>(size.getWidth()),
- static_cast<uint32_t>(size.getHeight()),
+ make(static_cast<uint32_t>(mSize.getWidth()),
+ static_cast<uint32_t>(mSize.getHeight()),
HAL_PIXEL_FORMAT_RGBA_8888, 1U,
static_cast<uint64_t>(
GraphicBuffer::USAGE_HW_RENDER |
@@ -133,16 +100,13 @@
void TexturePool::setEnabled(bool enabled) {
mEnabled = enabled;
-
- std::lock_guard lock(mMutex);
- resetPool();
+ allocatePool();
}
void TexturePool::dump(std::string& out) const {
- std::lock_guard lock(mMutex);
base::StringAppendF(&out,
"TexturePool (%s) has %zu buffers of size [%" PRId32 ", %" PRId32 "]\n",
mEnabled ? "enabled" : "disabled", mPool.size(), mSize.width, mSize.height);
}
-} // namespace android::compositionengine::impl::planner
+} // namespace android::compositionengine::impl::planner
\ No newline at end of file
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
index 494a9f4..6fc90fe 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/TexturePoolTest.cpp
@@ -32,9 +32,9 @@
public:
TestableTexturePool(renderengine::RenderEngine& renderEngine) : TexturePool(renderEngine) {}
+ size_t getMinPoolSize() const { return kMinPoolSize; }
size_t getMaxPoolSize() const { return kMaxPoolSize; }
size_t getPoolSize() const { return mPool.size(); }
- size_t isGenTextureFutureValid() const { return mGenTextureFuture.valid(); }
};
struct TexturePoolTest : public testing::Test {
@@ -56,8 +56,16 @@
TestableTexturePool mTexturePool = TestableTexturePool(mRenderEngine);
};
-TEST_F(TexturePoolTest, preallocatesZeroSizePool) {
- EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+TEST_F(TexturePoolTest, preallocatesMinPool) {
+ EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
+}
+
+TEST_F(TexturePoolTest, doesNotAllocateBeyondMinPool) {
+ for (size_t i = 0; i < mTexturePool.getMinPoolSize() + 1; i++) {
+ auto texture = mTexturePool.borrowTexture();
+ }
+
+ EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
}
TEST_F(TexturePoolTest, cyclesUpToMaxPoolSize) {
@@ -111,10 +119,10 @@
static_cast<int32_t>(texture->get()->getBuffer()->getHeight()));
mTexturePool.setDisplaySize(kDisplaySizeTwo);
- EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+ EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
texture.reset();
// When the texture is returned to the pool, the pool now destroys it.
- EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
+ EXPECT_EQ(mTexturePool.getMinPoolSize(), mTexturePool.getPoolSize());
texture = mTexturePool.borrowTexture();
EXPECT_EQ(kDisplaySizeTwo.getWidth(),
@@ -124,11 +132,14 @@
}
TEST_F(TexturePoolTest, freesBuffersWhenDisabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
+
std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
- for (size_t i = 0; i < 2; i++) {
+ for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
textures.emplace_back(mTexturePool.borrowTexture());
}
+ EXPECT_EQ(mTexturePool.getPoolSize(), 1u);
mTexturePool.setEnabled(false);
EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
@@ -137,11 +148,12 @@
}
TEST_F(TexturePoolTest, doesNotHoldBuffersWhenDisabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
mTexturePool.setEnabled(false);
EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
std::deque<std::shared_ptr<TexturePool::AutoTexture>> textures;
- for (size_t i = 0; i < 2; i++) {
+ for (size_t i = 0; i < mTexturePool.getMinPoolSize() - 1; i++) {
textures.emplace_back(mTexturePool.borrowTexture());
}
@@ -150,13 +162,12 @@
EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
}
-TEST_F(TexturePoolTest, genFutureWhenReEnabled) {
+TEST_F(TexturePoolTest, reallocatesWhenReEnabled) {
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
mTexturePool.setEnabled(false);
EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
- EXPECT_FALSE(mTexturePool.isGenTextureFutureValid());
mTexturePool.setEnabled(true);
- EXPECT_EQ(mTexturePool.getPoolSize(), 0u);
- EXPECT_TRUE(mTexturePool.isGenTextureFutureValid());
+ EXPECT_EQ(mTexturePool.getPoolSize(), mTexturePool.getMinPoolSize());
}
} // namespace