Flutter Impeller
render_target.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 
6 
7 #include <sstream>
8 
12 #include "impeller/core/formats.h"
13 #include "impeller/core/texture.h"
16 
17 namespace impeller {
18 
19 RenderTarget::RenderTarget() = default;
20 
21 RenderTarget::~RenderTarget() = default;
22 
23 bool RenderTarget::IsValid() const {
24  // Validate that there is a color attachment at zero index.
25  if (!HasColorAttachment(0u)) {
27  << "Render target does not have color attachment at index 0.";
28  return false;
29  }
30 
31  // Validate that all attachments are of the same size.
32  {
33  std::optional<ISize> size;
34  bool sizes_are_same = true;
35  auto iterator = [&](const Attachment& attachment) -> bool {
36  if (!size.has_value()) {
37  size = attachment.texture->GetSize();
38  }
39  if (size != attachment.texture->GetSize()) {
40  sizes_are_same = false;
41  return false;
42  }
43  return true;
44  };
45  IterateAllAttachments(iterator);
46  if (!sizes_are_same) {
48  << "Sizes of all render target attachments are not the same.";
49  return false;
50  }
51  }
52 
53  // Validate that all attachments are of the same type and sample counts.
54  {
55  std::optional<TextureType> texture_type;
56  std::optional<SampleCount> sample_count;
57  bool passes_type_validation = true;
58  auto iterator = [&](const Attachment& attachment) -> bool {
59  if (!texture_type.has_value() || !sample_count.has_value()) {
60  texture_type = attachment.texture->GetTextureDescriptor().type;
61  sample_count = attachment.texture->GetTextureDescriptor().sample_count;
62  }
63 
64  if (texture_type != attachment.texture->GetTextureDescriptor().type) {
65  passes_type_validation = false;
66  VALIDATION_LOG << "Render target has incompatible texture types: "
67  << TextureTypeToString(texture_type.value()) << " != "
69  attachment.texture->GetTextureDescriptor().type)
70  << " on target " << ToString();
71  return false;
72  }
73 
74  if (sample_count !=
75  attachment.texture->GetTextureDescriptor().sample_count) {
76  passes_type_validation = false;
77  VALIDATION_LOG << "Render target (" << ToString()
78  << ") has incompatible sample counts.";
79 
80  return false;
81  }
82 
83  return true;
84  };
85  IterateAllAttachments(iterator);
86  if (!passes_type_validation) {
87  return false;
88  }
89  }
90 
91  return true;
92 }
93 
95  const std::function<bool(const Attachment& attachment)>& iterator) const {
96  for (const auto& color : colors_) {
97  if (!iterator(color.second)) {
98  return;
99  }
100  }
101 
102  if (depth_.has_value()) {
103  if (!iterator(depth_.value())) {
104  return;
105  }
106  }
107 
108  if (stencil_.has_value()) {
109  if (!iterator(stencil_.value())) {
110  return;
111  }
112  }
113 }
114 
116  if (auto found = colors_.find(0u); found != colors_.end()) {
117  return found->second.texture->GetTextureDescriptor().sample_count;
118  }
119  return SampleCount::kCount1;
120 }
121 
122 bool RenderTarget::HasColorAttachment(size_t index) const {
123  if (auto found = colors_.find(index); found != colors_.end()) {
124  return true;
125  }
126  return false;
127 }
128 
129 std::optional<ISize> RenderTarget::GetColorAttachmentSize(size_t index) const {
130  auto found = colors_.find(index);
131 
132  if (found == colors_.end()) {
133  return std::nullopt;
134  }
135 
136  return found->second.texture->GetSize();
137 }
138 
140  auto size = GetColorAttachmentSize(0u);
141  return size.has_value() ? size.value() : ISize{};
142 }
143 
144 std::shared_ptr<Texture> RenderTarget::GetRenderTargetTexture() const {
145  auto found = colors_.find(0u);
146  if (found == colors_.end()) {
147  return nullptr;
148  }
149  return found->second.resolve_texture ? found->second.resolve_texture
150  : found->second.texture;
151 }
152 
154  if (auto texture = GetRenderTargetTexture(); texture != nullptr) {
155  return texture->GetTextureDescriptor().format;
156  }
157 
158  return PixelFormat::kUnknown;
159 }
160 
162  size_t max = 0;
163  for (const auto& color : colors_) {
164  max = std::max(color.first, max);
165  }
166  return max;
167 }
168 
170  const ColorAttachment& attachment,
171  size_t index) {
172  if (attachment.IsValid()) {
173  colors_[index] = attachment;
174  }
175  return *this;
176 }
177 
179  std::optional<DepthAttachment> attachment) {
180  if (!attachment.has_value()) {
181  depth_ = std::nullopt;
182  } else if (attachment->IsValid()) {
183  depth_ = std::move(attachment);
184  }
185  return *this;
186 }
187 
189  std::optional<StencilAttachment> attachment) {
190  if (!attachment.has_value()) {
191  stencil_ = std::nullopt;
192  } else if (attachment->IsValid()) {
193  stencil_ = std::move(attachment);
194  }
195  return *this;
196 }
197 
198 const std::map<size_t, ColorAttachment>& RenderTarget::GetColorAttachments()
199  const {
200  return colors_;
201 }
202 
203 const std::optional<DepthAttachment>& RenderTarget::GetDepthAttachment() const {
204  return depth_;
205 }
206 
207 const std::optional<StencilAttachment>& RenderTarget::GetStencilAttachment()
208  const {
209  return stencil_;
210 }
211 
213  size_t count = 0u;
214  for (const auto& [_, color] : colors_) {
215  if (color.texture) {
216  count++;
217  }
218  if (color.resolve_texture) {
219  count++;
220  }
221  }
222  if (depth_.has_value()) {
223  count++;
224  }
225  if (stencil_.has_value()) {
226  count++;
227  }
228  return count;
229 }
230 
231 std::string RenderTarget::ToString() const {
232  std::stringstream stream;
233 
234  for (const auto& [index, color] : colors_) {
235  stream << SPrintF("Color[%zu]=(%s)", index,
236  ColorAttachmentToString(color).c_str());
237  }
238  if (depth_) {
239  stream << ",";
240  stream << SPrintF("Depth=(%s)",
241  DepthAttachmentToString(depth_.value()).c_str());
242  }
243  if (stencil_) {
244  stream << ",";
245  stream << SPrintF("Stencil=(%s)",
246  StencilAttachmentToString(stencil_.value()).c_str());
247  }
248  return stream.str();
249 }
250 
252  std::shared_ptr<Allocator> allocator)
253  : allocator_(std::move(allocator)) {}
254 
256 
258 
260  const Context& context,
261  ISize size,
262  int mip_count,
263  const std::string& label,
264  RenderTarget::AttachmentConfig color_attachment_config,
265  std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
266  const std::shared_ptr<Texture>& existing_color_texture,
267  const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
268  if (size.IsEmpty()) {
269  return {};
270  }
271 
272  RenderTarget target;
273 
274  std::shared_ptr<Texture> color0_tex;
275  if (existing_color_texture) {
276  color0_tex = existing_color_texture;
277  } else {
278  PixelFormat pixel_format =
279  context.GetCapabilities()->GetDefaultColorFormat();
280  TextureDescriptor color0_tex_desc;
281  color0_tex_desc.storage_mode = color_attachment_config.storage_mode;
282  color0_tex_desc.format = pixel_format;
283  color0_tex_desc.size = size;
284  color0_tex_desc.mip_count = mip_count;
285  color0_tex_desc.usage =
287  color0_tex = allocator_->CreateTexture(color0_tex_desc);
288  if (!color0_tex) {
289  return {};
290  }
291  }
292  color0_tex->SetLabel(SPrintF("%s Color Texture", label.c_str()));
293 
294  ColorAttachment color0;
295  color0.clear_color = color_attachment_config.clear_color;
296  color0.load_action = color_attachment_config.load_action;
297  color0.store_action = color_attachment_config.store_action;
298  color0.texture = color0_tex;
299  target.SetColorAttachment(color0, 0u);
300 
301  if (stencil_attachment_config.has_value()) {
303  context, *allocator_, size, false, label,
304  stencil_attachment_config.value(), existing_depth_stencil_texture);
305  } else {
306  target.SetStencilAttachment(std::nullopt);
307  target.SetDepthAttachment(std::nullopt);
308  }
309 
310  return target;
311 }
312 
314  const Context& context,
315  ISize size,
316  int mip_count,
317  const std::string& label,
318  RenderTarget::AttachmentConfigMSAA color_attachment_config,
319  std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
320  const std::shared_ptr<Texture>& existing_color_msaa_texture,
321  const std::shared_ptr<Texture>& existing_color_resolve_texture,
322  const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
323  if (size.IsEmpty()) {
324  return {};
325  }
326 
327  RenderTarget target;
328  PixelFormat pixel_format = context.GetCapabilities()->GetDefaultColorFormat();
329 
330  // Create MSAA color texture.
331  std::shared_ptr<Texture> color0_msaa_tex;
332  if (existing_color_msaa_texture) {
333  color0_msaa_tex = existing_color_msaa_texture;
334  } else {
335  TextureDescriptor color0_tex_desc;
336  color0_tex_desc.storage_mode = color_attachment_config.storage_mode;
337  color0_tex_desc.type = TextureType::kTexture2DMultisample;
338  color0_tex_desc.sample_count = SampleCount::kCount4;
339  color0_tex_desc.format = pixel_format;
340  color0_tex_desc.size = size;
341  color0_tex_desc.usage = TextureUsage::kRenderTarget;
342  if (context.GetCapabilities()->SupportsImplicitResolvingMSAA()) {
343  // See below ("SupportsImplicitResolvingMSAA") for more details.
344  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
345  }
346  color0_msaa_tex = allocator_->CreateTexture(color0_tex_desc);
347  if (!color0_msaa_tex) {
348  VALIDATION_LOG << "Could not create multisample color texture.";
349  return {};
350  }
351  }
352  color0_msaa_tex->SetLabel(
353  SPrintF("%s Color Texture (Multisample)", label.c_str()));
354 
355  // Create color resolve texture.
356  std::shared_ptr<Texture> color0_resolve_tex;
357  if (existing_color_resolve_texture) {
358  color0_resolve_tex = existing_color_resolve_texture;
359  } else {
360  TextureDescriptor color0_resolve_tex_desc;
361  color0_resolve_tex_desc.storage_mode =
362  color_attachment_config.resolve_storage_mode;
363  color0_resolve_tex_desc.format = pixel_format;
364  color0_resolve_tex_desc.size = size;
365  color0_resolve_tex_desc.compression_type = CompressionType::kLossy;
366  color0_resolve_tex_desc.usage =
368  color0_resolve_tex_desc.mip_count = mip_count;
369  color0_resolve_tex = allocator_->CreateTexture(color0_resolve_tex_desc);
370  if (!color0_resolve_tex) {
371  VALIDATION_LOG << "Could not create color texture.";
372  return {};
373  }
374  }
375  color0_resolve_tex->SetLabel(SPrintF("%s Color Texture", label.c_str()));
376 
377  // Color attachment.
378 
379  ColorAttachment color0;
380  color0.clear_color = color_attachment_config.clear_color;
381  color0.load_action = color_attachment_config.load_action;
382  color0.store_action = color_attachment_config.store_action;
383  color0.texture = color0_msaa_tex;
384  color0.resolve_texture = color0_resolve_tex;
385 
386  if (context.GetCapabilities()->SupportsImplicitResolvingMSAA()) {
387  // If implicit MSAA is supported, then the resolve texture is not needed
388  // because the multisample texture is automatically resolved. We instead
389  // provide a view of the multisample texture as the resolve texture (because
390  // the HAL does expect a resolve texture).
391  //
392  // In practice, this is used for GLES 2.0 EXT_multisampled_render_to_texture
393  // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_multisampled_render_to_texture.txt
394  color0.resolve_texture = color0_msaa_tex;
395  }
396 
397  target.SetColorAttachment(color0, 0u);
398 
399  // Create MSAA stencil texture.
400 
401  if (stencil_attachment_config.has_value()) {
402  target.SetupDepthStencilAttachments(context, *allocator_, size, true, label,
403  stencil_attachment_config.value(),
404  existing_depth_stencil_texture);
405  } else {
406  target.SetDepthAttachment(std::nullopt);
407  target.SetStencilAttachment(std::nullopt);
408  }
409 
410  return target;
411 }
412 
414  const Context& context,
415  Allocator& allocator,
416  ISize size,
417  bool msaa,
418  const std::string& label,
419  RenderTarget::AttachmentConfig stencil_attachment_config,
420  const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
421  std::shared_ptr<Texture> depth_stencil_texture;
422  if (existing_depth_stencil_texture) {
423  depth_stencil_texture = existing_depth_stencil_texture;
424  } else {
425  TextureDescriptor depth_stencil_texture_desc;
426  depth_stencil_texture_desc.storage_mode =
427  stencil_attachment_config.storage_mode;
428  if (msaa) {
429  depth_stencil_texture_desc.type = TextureType::kTexture2DMultisample;
430  depth_stencil_texture_desc.sample_count = SampleCount::kCount4;
431  }
432  depth_stencil_texture_desc.format =
433  context.GetCapabilities()->GetDefaultDepthStencilFormat();
434  depth_stencil_texture_desc.size = size;
435  depth_stencil_texture_desc.usage = TextureUsage::kRenderTarget;
436  depth_stencil_texture = allocator.CreateTexture(depth_stencil_texture_desc);
437  if (!depth_stencil_texture) {
438  return; // Error messages are handled by `Allocator::CreateTexture`.
439  }
440  }
441 
442  DepthAttachment depth0;
443  depth0.load_action = stencil_attachment_config.load_action;
444  depth0.store_action = stencil_attachment_config.store_action;
445  depth0.clear_depth = 0u;
446  depth0.texture = depth_stencil_texture;
447 
448  StencilAttachment stencil0;
449  stencil0.load_action = stencil_attachment_config.load_action;
450  stencil0.store_action = stencil_attachment_config.store_action;
451  stencil0.clear_stencil = 0u;
452  stencil0.texture = std::move(depth_stencil_texture);
453 
454  stencil0.texture->SetLabel(
455  SPrintF("%s Depth+Stencil Texture", label.c_str()));
456  SetDepthAttachment(std::move(depth0));
457  SetStencilAttachment(std::move(stencil0));
458 }
459 
460 } // namespace impeller
impeller::RenderTarget::GetTotalAttachmentCount
size_t GetTotalAttachmentCount() const
Definition: render_target.cc:212
impeller::RenderTarget::AttachmentConfig::store_action
StoreAction store_action
Definition: render_target.h:43
impeller::RenderTargetAllocator::CreateOffscreen
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, const std::string &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)
Definition: render_target.cc:259
impeller::RenderTarget::AttachmentConfig::load_action
LoadAction load_action
Definition: render_target.h:42
impeller::Attachment::store_action
StoreAction store_action
Definition: formats.h:642
impeller::RenderTargetAllocator::Start
virtual void Start()
Mark the beginning of a frame workload.
Definition: render_target.cc:255
impeller::Context::GetCapabilities
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
impeller::ColorAttachment
Definition: formats.h:647
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::RenderTarget::SetColorAttachment
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
Definition: render_target.cc:169
texture_descriptor.h
formats.h
impeller::RenderTarget::AttachmentConfigMSAA::store_action
StoreAction store_action
Definition: render_target.h:51
impeller::TextureDescriptor::mip_count
size_t mip_count
Definition: texture_descriptor.h:42
impeller::RenderTarget::GetRenderTargetPixelFormat
PixelFormat GetRenderTargetPixelFormat() const
Definition: render_target.cc:153
impeller::RenderTarget::GetColorAttachmentSize
std::optional< ISize > GetColorAttachmentSize(size_t index) const
Definition: render_target.cc:129
impeller::RenderTargetAllocator::RenderTargetAllocator
RenderTargetAllocator(std::shared_ptr< Allocator > allocator)
Definition: render_target.cc:251
impeller::TextureUsage::kRenderTarget
@ kRenderTarget
impeller::Allocator::CreateTexture
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &desc)
Definition: allocator.cc:49
impeller::RenderTarget::GetColorAttachments
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
Definition: render_target.cc:198
impeller::TextureDescriptor::sample_count
SampleCount sample_count
Definition: texture_descriptor.h:44
impeller::RenderTarget::AttachmentConfigMSAA::load_action
LoadAction load_action
Definition: render_target.h:50
validation.h
impeller::TextureDescriptor::usage
TextureUsageMask usage
Definition: texture_descriptor.h:43
impeller::RenderTarget::AttachmentConfigMSAA::resolve_storage_mode
StorageMode resolve_storage_mode
Definition: render_target.h:49
impeller::RenderTarget::AttachmentConfigMSAA
Definition: render_target.h:47
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:100
impeller::RenderTarget::AttachmentConfig
Definition: render_target.h:40
impeller::TextureDescriptor::type
TextureType type
Definition: texture_descriptor.h:39
impeller::TextureType::kTexture2DMultisample
@ kTexture2DMultisample
impeller::StencilAttachment
Definition: formats.h:655
impeller::TSize< int64_t >
impeller::RenderTarget::GetDepthAttachment
const std::optional< DepthAttachment > & GetDepthAttachment() const
Definition: render_target.cc:203
impeller::ColorAttachment::clear_color
Color clear_color
Definition: formats.h:648
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:144
impeller::RenderTarget::IterateAllAttachments
void IterateAllAttachments(const std::function< bool(const Attachment &attachment)> &iterator) const
Definition: render_target.cc:94
impeller::RenderTarget::~RenderTarget
~RenderTarget()
impeller::Attachment::texture
std::shared_ptr< Texture > texture
Definition: formats.h:639
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::ColorAttachmentToString
std::string ColorAttachmentToString(const ColorAttachment &color)
Definition: formats.cc:123
impeller::Allocator
An object that allocates device memory.
Definition: allocator.h:22
impeller::RenderTarget::AttachmentConfig::storage_mode
StorageMode storage_mode
Definition: render_target.h:41
impeller::Attachment
Definition: formats.h:638
impeller::RenderTarget
Definition: render_target.h:38
impeller::StencilAttachment::clear_stencil
uint32_t clear_stencil
Definition: formats.h:656
impeller::CompressionType::kLossy
@ kLossy
strings.h
impeller::RenderTarget::IsValid
bool IsValid() const
Definition: render_target.cc:23
impeller::RenderTargetAllocator::CreateOffscreenMSAA
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, const std::string &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)
Definition: render_target.cc:313
impeller::PixelFormat::kUnknown
@ kUnknown
impeller::RenderTarget::AttachmentConfig::clear_color
Color clear_color
Definition: render_target.h:44
impeller::RenderTarget::GetRenderTargetSize
ISize GetRenderTargetSize() const
Definition: render_target.cc:139
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
allocator.h
impeller::TextureTypeToString
constexpr const char * TextureTypeToString(TextureType type)
Definition: formats.h:270
impeller::Attachment::resolve_texture
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:640
impeller::RenderTarget::AttachmentConfigMSAA::storage_mode
StorageMode storage_mode
Definition: render_target.h:48
impeller::RenderTarget::SetStencilAttachment
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
Definition: render_target.cc:188
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
std
Definition: comparable.h:95
impeller::DepthAttachmentToString
std::string DepthAttachmentToString(const DepthAttachment &depth)
Definition: formats.cc:130
impeller::RenderTargetAllocator::End
virtual void End()
Mark the end of a frame workload.
Definition: render_target.cc:257
impeller::SampleCount
SampleCount
Definition: formats.h:296
impeller::Attachment::load_action
LoadAction load_action
Definition: formats.h:641
impeller::TextureUsage::kShaderRead
@ kShaderRead
texture.h
impeller::Attachment::IsValid
bool IsValid() const
Definition: formats.cc:26
context.h
impeller::DepthAttachment::clear_depth
double clear_depth
Definition: formats.h:652
impeller::SampleCount::kCount1
@ kCount1
impeller::RenderTarget::GetMaxColorAttacmentBindIndex
size_t GetMaxColorAttacmentBindIndex() const
Definition: render_target.cc:161
impeller::SampleCount::kCount4
@ kCount4
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::DepthAttachment
Definition: formats.h:651
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:105
render_target.h
impeller::RenderTarget::GetStencilAttachment
const std::optional< StencilAttachment > & GetStencilAttachment() const
Definition: render_target.cc:207
impeller::RenderTarget::SetDepthAttachment
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
Definition: render_target.cc:178
impeller::RenderTarget::SetupDepthStencilAttachments
void SetupDepthStencilAttachments(const Context &context, Allocator &allocator, ISize size, bool msaa, const std::string &label="Offscreen", RenderTarget::AttachmentConfig stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &depth_stencil_texture=nullptr)
Definition: render_target.cc:413
impeller::RenderTarget::GetSampleCount
SampleCount GetSampleCount() const
Definition: render_target.cc:115
impeller::TextureDescriptor::compression_type
CompressionType compression_type
Definition: texture_descriptor.h:45
impeller::RenderTarget::HasColorAttachment
bool HasColorAttachment(size_t index) const
Definition: render_target.cc:122
impeller
Definition: aiks_blur_unittests.cc:20
impeller::StencilAttachmentToString
std::string StencilAttachmentToString(const StencilAttachment &stencil)
Definition: formats.cc:137
impeller::RenderTarget::ToString
std::string ToString() const
Definition: render_target.cc:231
impeller::RenderTarget::AttachmentConfigMSAA::clear_color
Color clear_color
Definition: render_target.h:52
impeller::RenderTarget::RenderTarget
RenderTarget()