| 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
5 #include "impeller/entity/render_target_cache.h"
6 #include "impeller/core/formats.h"
7 #include "impeller/renderer/render_target.h"
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
16 void RenderTargetCache::Start() {
17 cache_disabled_count_ = 0;
18 for (auto& td : render_target_data_) {
19 td.used_this_frame = false;
20 }
21 }
22
23 void RenderTargetCache::End() {
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
38 void RenderTargetCache::DisableCache() {
39 cache_disabled_count_++;
40 }
41
42 bool RenderTargetCache::CacheEnabled() const {
43 return cache_disabled_count_ == 0;
44 }
45
46 void RenderTargetCache::EnableCache() {
47 FML_DCHECK(cache_disabled_count_ > 0);
48 if (cache_disabled_count_ == 0) {
49 return;
50 }
51 cache_disabled_count_--;
52 }
53
54 RenderTarget RenderTargetCache::CreateOffscreen(
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 std::optional<PixelFormat> target_pixel_format) {
64 if (size.IsEmpty()) {
65 return {};
66 }
67
68 FML_DCHECK(existing_color_texture == nullptr &&
69 existing_depth_stencil_texture == nullptr);
70 auto config = RenderTargetConfig{
71 .size = size,
72 .mip_count = static_cast<size_t>(mip_count),
73 .has_msaa = false,
74 .has_depth_stencil = stencil_attachment_config.has_value(),
75 };
76
77 if (CacheEnabled()) {
78 for (RenderTargetData& render_target_data : render_target_data_) {
79 const RenderTargetConfig other_config = render_target_data.config;
80 if (!render_target_data.used_this_frame && other_config == config) {
81 render_target_data.used_this_frame = true;
82 render_target_data.keep_alive_frame_count = keep_alive_frame_count_;
83 ColorAttachment color0 =
84 render_target_data.render_target.GetColorAttachment(0);
85 std::optional<DepthAttachment> depth =
86 render_target_data.render_target.GetDepthAttachment();
87 std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
88 return RenderTargetAllocator::CreateOffscreen(
89 context, size, mip_count, label, color_attachment_config,
90 stencil_attachment_config, color0.texture, depth_tex,
91 target_pixel_format);
92 }
93 }
94 }
95 RenderTarget created_target = RenderTargetAllocator::CreateOffscreen(
96 context, size, mip_count, label, color_attachment_config,
97 stencil_attachment_config, nullptr, nullptr, target_pixel_format);
98 if (!created_target.IsValid()) {
99 return created_target;
100 }
101 if (CacheEnabled()) {
102 render_target_data_.push_back(RenderTargetData{
103 .used_this_frame = true, //
104 .keep_alive_frame_count = keep_alive_frame_count_, //
105 .config = config, //
106 .render_target = created_target //
107 });
108 }
109 return created_target;
110 }
111
112 RenderTarget RenderTargetCache::CreateOffscreenMSAA(
113 const Context& context,
114 ISize size,
115 int mip_count,
116 std::string_view label,
117 RenderTarget::AttachmentConfigMSAA color_attachment_config,
118 std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
119 const std::shared_ptr<Texture>& existing_color_msaa_texture,
120 const std::shared_ptr<Texture>& existing_color_resolve_texture,
121 const std::shared_ptr<Texture>& existing_depth_stencil_texture,
122 std::optional<PixelFormat> target_pixel_format) {
123 if (size.IsEmpty()) {
124 return {};
125 }
126
127 FML_DCHECK(existing_color_msaa_texture == nullptr &&
128 existing_color_resolve_texture == nullptr &&
129 existing_depth_stencil_texture == nullptr);
130 auto config = RenderTargetConfig{
131 .size = size,
132 .mip_count = static_cast<size_t>(mip_count),
133 .has_msaa = true,
134 .has_depth_stencil = stencil_attachment_config.has_value(),
135 };
136 if (CacheEnabled()) {
137 for (RenderTargetData& render_target_data : render_target_data_) {
138 const RenderTargetConfig other_config = render_target_data.config;
139 if (!render_target_data.used_this_frame && other_config == config) {
140 render_target_data.used_this_frame = true;
141 render_target_data.keep_alive_frame_count = keep_alive_frame_count_;
142 ColorAttachment color0 =
143 render_target_data.render_target.GetColorAttachment(0);
144 std::optional<DepthAttachment> depth =
145 render_target_data.render_target.GetDepthAttachment();
146 std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
147 return RenderTargetAllocator::CreateOffscreenMSAA(
148 context, size, mip_count, label, color_attachment_config,
149 stencil_attachment_config, color0.texture, color0.resolve_texture,
150 depth_tex, target_pixel_format);
151 }
152 }
153 }
154 RenderTarget created_target = RenderTargetAllocator::CreateOffscreenMSAA(
155 context, size, mip_count, label, color_attachment_config,
156 stencil_attachment_config, nullptr, nullptr, nullptr,
157 target_pixel_format);
158 if (!created_target.IsValid()) {
159 return created_target;
160 }
161 if (CacheEnabled()) {
162 render_target_data_.push_back(RenderTargetData{
163 .used_this_frame = true, //
164 .keep_alive_frame_count = keep_alive_frame_count_, //
165 .config = config, //
166 .render_target = created_target //
167 });
168 }
169 return created_target;
170 }
171
172 size_t RenderTargetCache::CachedTextureCount() const {
173 return render_target_data_.size();
174 }
175
176 } // namespace impeller
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:65
impeller::RenderTargetAllocator
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
Definition: render_target.h:149
impeller::RenderTargetAllocator::CreateOffscreenMSAA
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, std::optional< PixelFormat > target_pixel_format=std::nullopt)
Definition: render_target.cc:378
impeller::RenderTargetAllocator::CreateOffscreen
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, std::optional< PixelFormat > target_pixel_format=std::nullopt)
Definition: render_target.cc:322
impeller::RenderTargetCache::CreateOffscreen
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, std::optional< PixelFormat > target_pixel_format=std::nullopt) override
Definition: render_target_cache.cc:54
impeller::RenderTargetCache::CachedTextureCount
size_t CachedTextureCount() const
Definition: render_target_cache.cc:172
impeller::RenderTargetCache::DisableCache
void DisableCache() override
Disable any caching until the next call to EnabledCache.
Definition: render_target_cache.cc:38
impeller::RenderTargetCache::EnableCache
void EnableCache() override
Re-enable any caching if disabled.
Definition: render_target_cache.cc:46
impeller::RenderTargetCache::CreateOffscreenMSAA
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, std::optional< PixelFormat > target_pixel_format=std::nullopt) override
Definition: render_target_cache.cc:112
impeller::RenderTargetCache::RenderTargetCache
RenderTargetCache(std::shared_ptr< Allocator > allocator, uint32_t keep_alive_frame_count=4)
Definition: render_target_cache.cc:11
impeller::RenderTargetCache::End
void End() override
Mark the end of a frame workload.
Definition: render_target_cache.cc:23
impeller::RenderTargetCache::Start
void Start() override
Mark the beginning of a frame workload.
Definition: render_target_cache.cc:16
impeller::RenderTarget
Definition: render_target.h:38
impeller::RenderTarget::IsValid
bool IsValid() const
Definition: render_target.cc:23
formats.h
impeller
Definition: allocation.cc:12
std
Definition: comparable.h:95
render_target.h
render_target_cache.h
impeller::Attachment::resolve_texture
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:662
impeller::Attachment::texture
std::shared_ptr< Texture > texture
Definition: formats.h:661
impeller::ColorAttachment
Definition: formats.h:669
impeller::RenderTarget::AttachmentConfig
Definition: render_target.h:40
impeller::RenderTarget::AttachmentConfigMSAA
Definition: render_target.h:47
impeller::RenderTargetConfig
Definition: render_target.h:21
impeller::RenderTargetConfig::size
ISize size
Definition: render_target.h:22
impeller::TSize
Definition: size.h:25
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:123