Flutter Impeller
render_target_cache.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 
8 
9 namespace impeller {
10 
11 RenderTargetCache::RenderTargetCache(std::shared_ptr<Allocator> allocator,
12  uint32_t keep_alive_frame_count)
13  : RenderTargetAllocator(std::move(allocator)),
14  keep_alive_frame_count_(keep_alive_frame_count) {}
15 
17  cache_disabled_count_ = 0;
18  for (auto& td : render_target_data_) {
19  td.used_this_frame = false;
20  }
21 }
22 
24  cache_disabled_count_ = 0;
25  std::vector<RenderTargetData> retain;
26 
27  for (RenderTargetData& td : render_target_data_) {
28  if (td.used_this_frame) {
29  retain.push_back(td);
30  } else if (td.keep_alive_frame_count > 0) {
31  td.keep_alive_frame_count--;
32  retain.push_back(td);
33  }
34  }
35  render_target_data_.swap(retain);
36 }
37 
39  cache_disabled_count_++;
40 }
41 
42 bool RenderTargetCache::CacheEnabled() const {
43  return cache_disabled_count_ == 0;
44 }
45 
47  FML_DCHECK(cache_disabled_count_ > 0);
48  if (cache_disabled_count_ == 0) {
49  return;
50  }
51  cache_disabled_count_--;
52 }
53 
55  const Context& context,
56  ISize size,
57  int mip_count,
58  std::string_view label,
59  RenderTarget::AttachmentConfig color_attachment_config,
60  std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
61  const std::shared_ptr<Texture>& existing_color_texture,
62  const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
63  if (size.IsEmpty()) {
64  return {};
65  }
66 
67  FML_DCHECK(existing_color_texture == nullptr &&
68  existing_depth_stencil_texture == nullptr);
69  auto config = RenderTargetConfig{
70  .size = size,
71  .mip_count = static_cast<size_t>(mip_count),
72  .has_msaa = false,
73  .has_depth_stencil = stencil_attachment_config.has_value(),
74  };
75 
76  if (CacheEnabled()) {
77  for (RenderTargetData& render_target_data : render_target_data_) {
78  const RenderTargetConfig other_config = render_target_data.config;
79  if (!render_target_data.used_this_frame && other_config == config) {
80  render_target_data.used_this_frame = true;
81  render_target_data.keep_alive_frame_count = keep_alive_frame_count_;
82  ColorAttachment color0 =
83  render_target_data.render_target.GetColorAttachment(0);
84  std::optional<DepthAttachment> depth =
85  render_target_data.render_target.GetDepthAttachment();
86  std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
88  context, size, mip_count, label, color_attachment_config,
89  stencil_attachment_config, color0.texture, depth_tex);
90  }
91  }
92  }
94  context, size, mip_count, label, color_attachment_config,
95  stencil_attachment_config);
96  if (!created_target.IsValid()) {
97  return created_target;
98  }
99  render_target_data_.push_back(RenderTargetData{
100  .used_this_frame = true, //
101  .keep_alive_frame_count = keep_alive_frame_count_, //
102  .config = config, //
103  .render_target = created_target //
104  });
105  return created_target;
106 }
107 
109  const Context& context,
110  ISize size,
111  int mip_count,
112  std::string_view label,
113  RenderTarget::AttachmentConfigMSAA color_attachment_config,
114  std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
115  const std::shared_ptr<Texture>& existing_color_msaa_texture,
116  const std::shared_ptr<Texture>& existing_color_resolve_texture,
117  const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
118  if (size.IsEmpty()) {
119  return {};
120  }
121 
122  FML_DCHECK(existing_color_msaa_texture == nullptr &&
123  existing_color_resolve_texture == nullptr &&
124  existing_depth_stencil_texture == nullptr);
125  auto config = RenderTargetConfig{
126  .size = size,
127  .mip_count = static_cast<size_t>(mip_count),
128  .has_msaa = true,
129  .has_depth_stencil = stencil_attachment_config.has_value(),
130  };
131  if (CacheEnabled()) {
132  for (RenderTargetData& render_target_data : render_target_data_) {
133  const RenderTargetConfig other_config = render_target_data.config;
134  if (!render_target_data.used_this_frame && other_config == config) {
135  render_target_data.used_this_frame = true;
136  render_target_data.keep_alive_frame_count = keep_alive_frame_count_;
137  ColorAttachment color0 =
138  render_target_data.render_target.GetColorAttachment(0);
139  std::optional<DepthAttachment> depth =
140  render_target_data.render_target.GetDepthAttachment();
141  std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
143  context, size, mip_count, label, color_attachment_config,
144  stencil_attachment_config, color0.texture, color0.resolve_texture,
145  depth_tex);
146  }
147  }
148  }
150  context, size, mip_count, label, color_attachment_config,
151  stencil_attachment_config);
152  if (!created_target.IsValid()) {
153  return created_target;
154  }
155  render_target_data_.push_back(RenderTargetData{
156  .used_this_frame = true, //
157  .keep_alive_frame_count = keep_alive_frame_count_, //
158  .config = config, //
159  .render_target = created_target //
160  });
161  return created_target;
162 }
163 
165  return render_target_data_.size();
166 }
167 
168 } // namespace impeller
To do anything rendering related with Impeller, you need a context.
Definition: context.h:65
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config=RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_msaa_texture=nullptr, const std::shared_ptr< Texture > &existing_color_resolve_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen", RenderTarget::AttachmentConfig color_attachment_config=RenderTarget::kDefaultColorAttachmentConfig, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen", RenderTarget::AttachmentConfig color_attachment_config=RenderTarget::kDefaultColorAttachmentConfig, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr) override
void DisableCache() override
Disable any caching until the next call to EnabledCache.
void EnableCache() override
Re-enable any caching if disabled.
RenderTargetCache(std::shared_ptr< Allocator > allocator, uint32_t keep_alive_frame_count=4)
void End() override
Mark the end of a frame workload.
void Start() override
Mark the beginning of a frame workload.
RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config=RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_msaa_texture=nullptr, const std::shared_ptr< Texture > &existing_color_resolve_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr) override
Definition: comparable.h:95
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:658
std::shared_ptr< Texture > texture
Definition: formats.h:657
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:123