Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
swapchain_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/testing/testing.h" // IWYU pragma: keep
6#include "gtest/gtest.h"
10#include "vulkan/vulkan_enums.hpp"
11#include "vulkan/vulkan_handles.hpp"
12
13namespace impeller {
14namespace testing {
15
16vk::UniqueSurfaceKHR CreateSurface(const ContextVK& context) {
17#if FML_OS_DARWIN
18 impeller::vk::MetalSurfaceCreateInfoEXT createInfo = {};
19 auto [result, surface] =
20 context.GetInstance().createMetalSurfaceEXTUnique(createInfo);
21 FML_DCHECK(result == vk::Result::eSuccess);
22 return std::move(surface);
23#else
24 return {};
25#endif // FML_OS_DARWIN
26}
27
28TEST(SwapchainTest, CanCreateSwapchain) {
29 auto const context = MockVulkanContextBuilder().Build();
30
31 auto surface = CreateSurface(*context);
32 auto swapchain =
33 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1});
34
35 EXPECT_TRUE(swapchain->IsValid());
36}
37
38TEST(SwapchainTest, RecreateSwapchainWhenSizeChanges) {
39 auto const context = MockVulkanContextBuilder().Build();
40
41 auto surface = CreateSurface(*context);
43 auto swapchain =
44 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1},
45 /*enable_msaa=*/false);
46 auto image = swapchain->AcquireNextDrawable();
47 auto expected_size = ISize{1, 1};
48 EXPECT_EQ(image->GetSize(), expected_size);
49
51 swapchain->UpdateSurfaceSize(ISize{100, 100});
52
53 auto image_b = swapchain->AcquireNextDrawable();
54 expected_size = ISize{100, 100};
55 EXPECT_EQ(image_b->GetSize(), expected_size);
56}
57
58TEST(SwapchainTest, CachesRenderPassOnSwapchainImage) {
59 auto const context = MockVulkanContextBuilder().Build();
60
61 auto surface = CreateSurface(*context);
62 auto swapchain =
63 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1});
64
65 EXPECT_TRUE(swapchain->IsValid());
66
67 // The mock swapchain will always create 3 images, verify each one starts
68 // out with the same MSAA and depth+stencil texture, and no cached
69 // framebuffer.
70 std::vector<std::shared_ptr<Texture>> msaa_textures;
71 std::vector<std::shared_ptr<Texture>> depth_stencil_textures;
72 for (auto i = 0u; i < 3u; i++) {
73 auto drawable = swapchain->AcquireNextDrawable();
74 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
75
76 auto texture = render_target.GetRenderTargetTexture();
77 auto& texture_vk = TextureVK::Cast(*texture);
78 EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
79 EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
80
81 auto command_buffer = context->CreateCommandBuffer();
82 auto render_pass = command_buffer->CreateRenderPass(render_target);
83 render_pass->EncodeCommands();
84
85 auto& depth = render_target.GetDepthAttachment();
86 depth_stencil_textures.push_back(depth.has_value() ? depth->texture
87 : nullptr);
88 msaa_textures.push_back(
89 render_target.GetColorAttachments().find(0u)->second.texture);
90 }
91
92 for (auto i = 1; i < 3; i++) {
93 EXPECT_EQ(msaa_textures[i - 1], msaa_textures[i]);
94 EXPECT_EQ(depth_stencil_textures[i - 1], depth_stencil_textures[i]);
95 }
96
97 // After each images has been acquired once and the render pass presented,
98 // each should have a cached framebuffer and render pass.
99
100 std::vector<SharedHandleVK<vk::Framebuffer>> framebuffers;
101 std::vector<SharedHandleVK<vk::RenderPass>> render_passes;
102 for (auto i = 0u; i < 3u; i++) {
103 auto drawable = swapchain->AcquireNextDrawable();
104 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
105
106 auto texture = render_target.GetRenderTargetTexture();
107 auto& texture_vk = TextureVK::Cast(*texture);
108
109 EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
110 EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
111 framebuffers.push_back(texture_vk.GetCachedFramebuffer());
112 render_passes.push_back(texture_vk.GetCachedRenderPass());
113 }
114
115 // Iterate through once more to verify render passes and framebuffers are
116 // unchanged.
117 for (auto i = 0u; i < 3u; i++) {
118 auto drawable = swapchain->AcquireNextDrawable();
119 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
120
121 auto texture = render_target.GetRenderTargetTexture();
122 auto& texture_vk = TextureVK::Cast(*texture);
123
124 EXPECT_EQ(texture_vk.GetCachedFramebuffer(), framebuffers[i]);
125 EXPECT_EQ(texture_vk.GetCachedRenderPass(), render_passes[i]);
126 }
127}
128
129} // namespace testing
130} // namespace impeller
#define TEST(S, s, D, expected)
static TextureVK & Cast(Texture &base)
vk::Instance GetInstance() const
std::shared_ptr< Texture > GetRenderTargetTexture() const
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
const std::optional< DepthAttachment > & GetDepthAttachment() const
static std::shared_ptr< SwapchainVK > Create(const std::shared_ptr< Context > &context, vk::UniqueSurfaceKHR surface, const ISize &size, bool enable_msaa=true)
std::shared_ptr< ContextVK > Build()
Create a Vulkan context with Vulkan functions mocked. The caller is given a chance to tinker on the s...
VkSwapchainKHR swapchain
Definition main.cc:64
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
GAsyncResult * result
#define FML_DCHECK(condition)
Definition logging.h:103
FlTexture * texture
vk::UniqueSurfaceKHR CreateSurface(const ContextVK &context)
void SetSwapchainImageSize(ISize size)
Override the image size returned by all swapchain images.
#define EXPECT_TRUE(handle)
Definition unit_test.h:685