summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp')
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
new file mode 100644
index 0000000000..e3772a22d2
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+
+#undef LOG_TAG
+#define LOG_TAG "Planner"
+
+#include <compositionengine/impl/planner/TexturePool.h>
+#include <utils/Log.h>
+
+namespace android::compositionengine::impl::planner {
+
+void TexturePool::setDisplaySize(ui::Size size) {
+ if (mSize == size) {
+ return;
+ }
+ mSize = size;
+ mPool.clear();
+ mPool.resize(kMinPoolSize);
+ std::generate_n(mPool.begin(), kMinPoolSize, [&]() { return Entry{genTexture(), nullptr}; });
+}
+
+std::shared_ptr<TexturePool::AutoTexture> TexturePool::borrowTexture() {
+ if (mPool.empty()) {
+ return std::make_shared<AutoTexture>(*this, genTexture(), nullptr);
+ }
+
+ const auto entry = mPool.front();
+ mPool.pop_front();
+ return std::make_shared<AutoTexture>(*this, entry.texture, entry.fence);
+}
+
+void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture,
+ const sp<Fence>& fence) {
+ // Drop 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()) {
+ ALOGV("Deallocating texture from Planner's pool - display size changed (previous: (%dx%d), "
+ "current: (%dx%d))",
+ texture->getBuffer()->getWidth(), texture->getBuffer()->getHeight(), mSize.getWidth(),
+ mSize.getHeight());
+ return;
+ }
+
+ // Also ensure the pool does not grow beyond a maximum size.
+ if (mPool.size() == kMaxPoolSize) {
+ ALOGD("Deallocating texture from Planner's pool - max size [%" PRIu64 "] reached",
+ static_cast<uint64_t>(kMaxPoolSize));
+ return;
+ }
+
+ mPool.push_back({std::move(texture), fence});
+}
+
+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::ExternalTexture>(sp<GraphicBuffer>::
+ make(mSize.getWidth(), mSize.getHeight(),
+ HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GraphicBuffer::USAGE_HW_RENDER |
+ GraphicBuffer::USAGE_HW_COMPOSER |
+ GraphicBuffer::USAGE_HW_TEXTURE,
+ "Planner"),
+ mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+}
+
+} // namespace android::compositionengine::impl::planner \ No newline at end of file