[Impeller] tear down swapchain when backgrounding. (#165259)
When we return to the foreground the swapchain is reconstructed anyway. Eagerly tearing the old one down releases memory faster. Highlighted by a regression in a customer: money benchmark.
This commit is contained in:
@@ -206,6 +206,7 @@
|
||||
../../../flutter/impeller/renderer/backend/vulkan/render_pass_cache_unittests.cc
|
||||
../../../flutter/impeller/renderer/backend/vulkan/render_pass_vk_unittests.cc
|
||||
../../../flutter/impeller/renderer/backend/vulkan/resource_manager_vk_unittests.cc
|
||||
../../../flutter/impeller/renderer/backend/vulkan/surface_context_vk_unittests.cc
|
||||
../../../flutter/impeller/renderer/backend/vulkan/swapchain/README.md
|
||||
../../../flutter/impeller/renderer/backend/vulkan/swapchain/khr/README.md
|
||||
../../../flutter/impeller/renderer/backend/vulkan/test
|
||||
|
||||
@@ -22,6 +22,7 @@ impeller_component("vulkan_unittests") {
|
||||
"render_pass_cache_unittests.cc",
|
||||
"render_pass_vk_unittests.cc",
|
||||
"resource_manager_vk_unittests.cc",
|
||||
"surface_context_vk_unittests.cc",
|
||||
"test/gpu_tracer_unittests.cc",
|
||||
"test/mock_vulkan.cc",
|
||||
"test/mock_vulkan.h",
|
||||
|
||||
@@ -72,6 +72,13 @@ bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface,
|
||||
return SetSwapchain(SwapchainVK::Create(parent_, std::move(surface), size));
|
||||
}
|
||||
|
||||
void SurfaceContextVK::TeardownSwapchain() {
|
||||
// When background the application, tear down the swapchain to release memory
|
||||
// from the images. When returning to the foreground, SetWindowSurface will be
|
||||
// called which will re-create the swapchain.
|
||||
swapchain_.reset();
|
||||
}
|
||||
|
||||
bool SurfaceContextVK::SetSwapchain(std::shared_ptr<SwapchainVK> swapchain) {
|
||||
if (!swapchain || !swapchain->IsValid()) {
|
||||
VALIDATION_LOG << "Invalid swapchain.";
|
||||
|
||||
@@ -96,6 +96,9 @@ class SurfaceContextVK : public Context,
|
||||
/// recreated on the next frame.
|
||||
void UpdateSurfaceSize(const ISize& size) const;
|
||||
|
||||
/// @brief Can be called when the surface is destroyed to reduce memory usage.
|
||||
void TeardownSwapchain();
|
||||
|
||||
// |Context|
|
||||
void InitializeCommonlyUsedShadersIfNeeded() const override;
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "impeller/renderer/backend/vulkan/surface_context_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
|
||||
#include "impeller/renderer/surface.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
vk::UniqueSurfaceKHR CreateSurface(const ContextVK& context) {
|
||||
#if FML_OS_DARWIN
|
||||
impeller::vk::MetalSurfaceCreateInfoEXT createInfo = {};
|
||||
auto [result, surface] =
|
||||
context.GetInstance().createMetalSurfaceEXTUnique(createInfo);
|
||||
FML_DCHECK(result == vk::Result::eSuccess);
|
||||
return std::move(surface);
|
||||
#else
|
||||
return {};
|
||||
#endif // FML_OS_DARWIN
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(SurfaceContextVK, TearsDownSwapchain) {
|
||||
SetSwapchainImageSize({100, 100});
|
||||
std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
|
||||
|
||||
vk::UniqueSurfaceKHR surface = CreateSurface(*context);
|
||||
SurfaceContextVK surface_context(context);
|
||||
|
||||
EXPECT_TRUE(surface_context.SetWindowSurface(std::move(surface), {100, 100}));
|
||||
EXPECT_NE(surface_context.AcquireNextSurface(), nullptr);
|
||||
|
||||
surface_context.TeardownSwapchain();
|
||||
|
||||
EXPECT_EQ(surface_context.AcquireNextSurface(), nullptr);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
@@ -37,7 +37,7 @@ bool AndroidSurfaceVKImpeller::IsValid() const {
|
||||
}
|
||||
|
||||
void AndroidSurfaceVKImpeller::TeardownOnScreenContext() {
|
||||
// Nothing to do.
|
||||
surface_context_vk_->TeardownSwapchain();
|
||||
}
|
||||
|
||||
std::unique_ptr<Surface> AndroidSurfaceVKImpeller::CreateGPUSurface(
|
||||
|
||||
Reference in New Issue
Block a user