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,
43  bool threadsafe) override {
44  if (should_fail) {
45  return nullptr;
46  }
47  return std::make_shared<MockTexture>(desc);
48  };
49 
50  bool should_fail = false;
51 };
52 
53 TEST_P(RenderTargetCacheTest, CachesUsedTexturesAcrossFrames) {
54  auto render_target_cache = RenderTargetCache(
55  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
56 
57  render_target_cache.Start();
58  // Create two render targets of the same exact size/shape. Both should be
59  // marked as used this frame, so the cached data set will contain two.
60  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
61  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
62 
63  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
64 
65  render_target_cache.End();
66  render_target_cache.Start();
67 
68  // Next frame, only create one texture. The set will still contain two,
69  // but one will be removed at the end of the frame.
70  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
71  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
72 
73  render_target_cache.End();
74  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
75 }
76 
77 TEST_P(RenderTargetCacheTest, CachesUsedTexturesAcrossFramesWithKeepAlive) {
78  auto render_target_cache = RenderTargetCache(
79  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/3);
80 
81  render_target_cache.Start();
82  // Create two render targets of the same exact size/shape. Both should be
83  // marked as used this frame, so the cached data set will contain two.
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
86 
87  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
88 
89  render_target_cache.End();
90  render_target_cache.Start();
91 
92  // The unused texture is kept alive until the keep alive countdown
93  // reaches 0.
94  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
95 
96  for (auto i = 0; i < 3; i++) {
97  render_target_cache.Start();
98  render_target_cache.End();
99  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
100  }
101  // After the countdown has elapsed the texture is removed.
102  render_target_cache.Start();
103  render_target_cache.End();
104  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
105 }
106 
107 TEST_P(RenderTargetCacheTest, DoesNotPersistFailedAllocations) {
108  ScopedValidationDisable disable;
109  auto allocator = std::make_shared<TestAllocator>();
110  auto render_target_cache =
111  RenderTargetCache(allocator, /*keep_alive_frame_count=*/0);
112 
113  render_target_cache.Start();
114  allocator->should_fail = true;
115 
116  auto render_target =
117  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
118 
119  EXPECT_FALSE(render_target.IsValid());
120  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
121 }
122 
123 TEST_P(RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig) {
124  auto render_target_cache = RenderTargetCache(
125  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
126 
127  render_target_cache.Start();
128  RenderTarget::AttachmentConfig color_attachment_config =
130  RenderTarget target1 = render_target_cache.CreateOffscreen(
131  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
132  render_target_cache.End();
133 
134  render_target_cache.Start();
135  color_attachment_config.clear_color = Color::Red();
136  RenderTarget target2 = render_target_cache.CreateOffscreen(
137  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
138  render_target_cache.End();
139 
140  ColorAttachment color1 = target1.GetColorAttachment(0);
141  ColorAttachment color2 = target2.GetColorAttachment(0);
142  // The second color attachment should reuse the first attachment's texture
143  // but with attributes from the second AttachmentConfig.
144  EXPECT_EQ(color2.texture, color1.texture);
145  EXPECT_EQ(color2.clear_color, Color::Red());
146 }
147 
148 TEST_P(RenderTargetCacheTest, CreateWithEmptySize) {
149  auto render_target_cache = RenderTargetCache(
150  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
151 
152  render_target_cache.Start();
153  RenderTarget empty_target =
154  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
155  RenderTarget empty_target_msaa =
156  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
157  render_target_cache.End();
158 
159  {
160  ScopedValidationDisable disable_validation;
161  EXPECT_FALSE(empty_target.IsValid());
162  EXPECT_FALSE(empty_target_msaa.IsValid());
163  }
164 }
165 
166 } // namespace testing
167 } // 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
virtual std::shared_ptr< Texture > OnCreateTexture(const TextureDescriptor &desc, bool threadsafe) override
std::shared_ptr< DeviceBuffer > OnCreateBuffer(const DeviceBufferDescriptor &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...