Flutter Impeller
render_target_cache_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 <memory>
6 
7 #include "flutter/testing/testing.h"
10 #include "impeller/core/formats.h"
15 #include "impeller/renderer/testing/mocks.h"
16 
17 namespace impeller {
18 namespace testing {
19 
22 
23 class TestAllocator : public Allocator {
24  public:
25  TestAllocator() = default;
26 
27  ~TestAllocator() = default;
28 
29  ISize GetMaxTextureSizeSupported() const override {
30  return ISize(1024, 1024);
31  };
32 
33  std::shared_ptr<DeviceBuffer> OnCreateBuffer(
34  const DeviceBufferDescriptor& desc) override {
35  if (should_fail) {
36  return nullptr;
37  }
38  return std::make_shared<MockDeviceBuffer>(desc);
39  };
40 
41  virtual std::shared_ptr<Texture> OnCreateTexture(
42  const TextureDescriptor& desc) override {
43  if (should_fail) {
44  return nullptr;
45  }
46  return std::make_shared<MockTexture>(desc);
47  };
48 
49  bool should_fail = false;
50 };
51 
52 TEST_P(RenderTargetCacheTest, CachesUsedTexturesAcrossFrames) {
53  auto render_target_cache = RenderTargetCache(
54  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
55 
56  render_target_cache.Start();
57  // Create two render targets of the same exact size/shape. Both should be
58  // marked as used this frame, so the cached data set will contain two.
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
61 
62  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
63 
64  render_target_cache.End();
65  render_target_cache.Start();
66 
67  // Next frame, only create one texture. The set will still contain two,
68  // but one will be removed at the end of the frame.
69  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
70  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
71 
72  render_target_cache.End();
73  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
74 }
75 
76 TEST_P(RenderTargetCacheTest, CachesUsedTexturesAcrossFramesWithKeepAlive) {
77  auto render_target_cache = RenderTargetCache(
78  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/3);
79 
80  render_target_cache.Start();
81  // Create two render targets of the same exact size/shape. Both should be
82  // marked as used this frame, so the cached data set will contain two.
83  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
87 
88  render_target_cache.End();
89  render_target_cache.Start();
90 
91  // The unused texture is kept alive until the keep alive countdown
92  // reaches 0.
93  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
94 
95  for (auto i = 0; i < 3; i++) {
96  render_target_cache.Start();
97  render_target_cache.End();
98  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
99  }
100  // After the countdown has elapsed the texture is removed.
101  render_target_cache.Start();
102  render_target_cache.End();
103  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
104 }
105 
106 TEST_P(RenderTargetCacheTest, DoesNotPersistFailedAllocations) {
107  ScopedValidationDisable disable;
108  auto allocator = std::make_shared<TestAllocator>();
109  auto render_target_cache =
110  RenderTargetCache(allocator, /*keep_alive_frame_count=*/0);
111 
112  render_target_cache.Start();
113  allocator->should_fail = true;
114 
115  auto render_target =
116  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
117 
118  EXPECT_FALSE(render_target.IsValid());
119  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
120 }
121 
122 TEST_P(RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig) {
123  auto render_target_cache = RenderTargetCache(
124  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
125 
126  render_target_cache.Start();
127  RenderTarget::AttachmentConfig color_attachment_config =
129  RenderTarget target1 = render_target_cache.CreateOffscreen(
130  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
131  render_target_cache.End();
132 
133  render_target_cache.Start();
134  color_attachment_config.clear_color = Color::Red();
135  RenderTarget target2 = render_target_cache.CreateOffscreen(
136  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
137  render_target_cache.End();
138 
139  ColorAttachment color1 = target1.GetColorAttachment(0);
140  ColorAttachment color2 = target2.GetColorAttachment(0);
141  // The second color attachment should reuse the first attachment's texture
142  // but with attributes from the second AttachmentConfig.
143  EXPECT_EQ(color2.texture, color1.texture);
144  EXPECT_EQ(color2.clear_color, Color::Red());
145 }
146 
147 TEST_P(RenderTargetCacheTest, CreateWithEmptySize) {
148  auto render_target_cache = RenderTargetCache(
149  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
150 
151  render_target_cache.Start();
152  RenderTarget empty_target =
153  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
154  RenderTarget empty_target_msaa =
155  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
156  render_target_cache.End();
157 
158  {
159  ScopedValidationDisable disable_validation;
160  EXPECT_FALSE(empty_target.IsValid());
161  EXPECT_FALSE(empty_target_msaa.IsValid());
162  }
163 }
164 
165 } // namespace testing
166 } // namespace impeller
An object that allocates device memory.
Definition: allocator.h:24
An implementation of the [RenderTargetAllocator] that caches all allocated texture data for one frame...
ColorAttachment GetColorAttachment(size_t index) const
Get the color attachment at [index].
static constexpr AttachmentConfig kDefaultColorAttachmentConfig
Definition: render_target.h:55
std::shared_ptr< DeviceBuffer > OnCreateBuffer(const DeviceBufferDescriptor &desc) override
virtual std::shared_ptr< Texture > OnCreateTexture(const TextureDescriptor &desc) override
TEST_P(AiksTest, DrawAtlasNoColor)
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
ISize64 ISize
Definition: size.h:162
std::shared_ptr< Texture > texture
Definition: formats.h:657
static constexpr Color Red()
Definition: color.h:272
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...