Flutter Impeller
blit_pass.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 #include <memory>
7 #include <utility>
8 
11 #include "impeller/core/formats.h"
12 
13 namespace impeller {
14 
16 
17 BlitPass::~BlitPass() = default;
18 
19 void BlitPass::SetLabel(std::string_view label) {
20  if (label.empty()) {
21  return;
22  }
23  OnSetLabel(label);
24 }
25 
26 bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
27  std::shared_ptr<Texture> destination,
28  std::optional<IRect> source_region,
29  IPoint destination_origin,
30  std::string_view label) {
31  if (!source) {
32  VALIDATION_LOG << "Attempted to add a texture blit with no source.";
33  return false;
34  }
35  if (!destination) {
36  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
37  return false;
38  }
39 
40  if (source->GetTextureDescriptor().sample_count !=
41  destination->GetTextureDescriptor().sample_count) {
43  "The source sample count (%d) must match the destination sample count "
44  "(%d) for blits.",
45  static_cast<int>(source->GetTextureDescriptor().sample_count),
46  static_cast<int>(destination->GetTextureDescriptor().sample_count));
47  return false;
48  }
49  if (source->GetTextureDescriptor().format !=
50  destination->GetTextureDescriptor().format) {
52  "The source pixel format (%s) must match the destination pixel format "
53  "(%s) "
54  "for blits.",
55  PixelFormatToString(source->GetTextureDescriptor().format),
56  PixelFormatToString(destination->GetTextureDescriptor().format));
57  return false;
58  }
59 
60  if (!source_region.has_value()) {
61  source_region = IRect::MakeSize(source->GetSize());
62  }
63 
64  // Clip the source image.
65  source_region =
66  source_region->Intersection(IRect::MakeSize(source->GetSize()));
67  if (!source_region.has_value()) {
68  return true; // Nothing to blit.
69  }
70 
72  std::move(source), std::move(destination), source_region.value(),
73  destination_origin, label);
74 }
75 
76 bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
77  std::shared_ptr<DeviceBuffer> destination,
78  std::optional<IRect> source_region,
79  size_t destination_offset,
80  std::string_view label) {
81  if (!source) {
82  VALIDATION_LOG << "Attempted to add a texture blit with no source.";
83  return false;
84  }
85  if (!destination) {
86  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
87  return false;
88  }
89 
90  if (!source_region.has_value()) {
91  source_region = IRect::MakeSize(source->GetSize());
92  }
93 
94  auto bytes_per_pixel =
95  BytesPerPixelForPixelFormat(source->GetTextureDescriptor().format);
96  auto bytes_per_image = source_region->Area() * bytes_per_pixel;
97  if (destination_offset + bytes_per_image >
98  destination->GetDeviceBufferDescriptor().size) {
100  << "Attempted to add a texture blit with out of bounds access.";
101  return false;
102  }
103 
104  // Clip the source image.
105  source_region =
106  source_region->Intersection(IRect::MakeSize(source->GetSize()));
107  if (!source_region.has_value()) {
108  return true; // Nothing to blit.
109  }
110 
111  return OnCopyTextureToBufferCommand(std::move(source), std::move(destination),
112  source_region.value(), destination_offset,
113  label);
114 }
115 
117  std::shared_ptr<Texture> destination,
118  std::optional<IRect> destination_region,
119  std::string_view label,
120  uint32_t mip_level,
121  uint32_t slice,
122  bool convert_to_read) {
123  if (!destination) {
124  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
125  return false;
126  }
127  ISize destination_size = destination->GetSize();
128  IRect destination_region_value =
129  destination_region.value_or(IRect::MakeSize(destination_size));
130  if (destination_region_value.GetX() < 0 ||
131  destination_region_value.GetY() < 0 ||
132  destination_region_value.GetRight() > destination_size.width ||
133  destination_region_value.GetBottom() > destination_size.height) {
134  VALIDATION_LOG << "Blit region cannot be larger than destination texture.";
135  return false;
136  }
137 
138  auto bytes_per_pixel =
139  BytesPerPixelForPixelFormat(destination->GetTextureDescriptor().format);
140  auto bytes_per_region = destination_region_value.Area() * bytes_per_pixel;
141 
142  if (source.GetRange().length != bytes_per_region) {
144  << "Attempted to add a texture blit with out of bounds access.";
145  return false;
146  }
147  if (mip_level >= destination->GetMipCount()) {
148  VALIDATION_LOG << "Invalid value for mip_level: " << mip_level << ". "
149  << "The destination texture has "
150  << destination->GetMipCount() << " mip levels.";
151  return false;
152  }
153  if (slice > 5) {
154  VALIDATION_LOG << "Invalid value for slice: " << slice;
155  return false;
156  }
157 
158  return OnCopyBufferToTextureCommand(std::move(source), std::move(destination),
159  destination_region_value, label,
160  mip_level, slice, convert_to_read);
161 }
162 
164  const std::shared_ptr<Texture>& texture) {
165  return true;
166 }
167 
168 bool BlitPass::GenerateMipmap(std::shared_ptr<Texture> texture,
169  std::string_view label) {
170  if (!texture) {
171  VALIDATION_LOG << "Attempted to add an invalid mipmap generation command "
172  "with no texture.";
173  return false;
174  }
175 
176  return OnGenerateMipmapCommand(std::move(texture), label);
177 }
178 
179 } // namespace impeller
void SetLabel(std::string_view label)
Definition: blit_pass.cc:19
bool AddCopy(std::shared_ptr< Texture > source, std::shared_ptr< Texture > destination, std::optional< IRect > source_region=std::nullopt, IPoint destination_origin={}, std::string_view label="")
Record a command to copy the contents of one texture to another texture. The blit area is limited by ...
Definition: blit_pass.cc:26
virtual bool OnCopyTextureToTextureCommand(std::shared_ptr< Texture > source, std::shared_ptr< Texture > destination, IRect source_region, IPoint destination_origin, std::string_view label)=0
bool GenerateMipmap(std::shared_ptr< Texture > texture, std::string_view label="")
Record a command to generate all mip levels for a texture.
Definition: blit_pass.cc:168
virtual bool OnGenerateMipmapCommand(std::shared_ptr< Texture > texture, std::string_view label)=0
virtual bool ConvertTextureToShaderRead(const std::shared_ptr< Texture > &texture)
If the texture is not already in a shader read internal state, then convert it to that state.
Definition: blit_pass.cc:163
virtual bool OnCopyBufferToTextureCommand(BufferView source, std::shared_ptr< Texture > destination, IRect destination_region, std::string_view label, uint32_t mip_level, uint32_t slice, bool convert_to_read)=0
virtual bool OnCopyTextureToBufferCommand(std::shared_ptr< Texture > source, std::shared_ptr< DeviceBuffer > destination, IRect source_region, size_t destination_offset, std::string_view label)=0
virtual void OnSetLabel(std::string_view label)=0
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:466
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
Range GetRange() const
Definition: buffer_view.h:27
size_t length
Definition: range.h:15
constexpr auto GetBottom() const
Definition: rect.h:361
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:341
constexpr T Area() const
Get the area of the rectangle, equivalent to |GetSize().Area()|.
Definition: rect.h:380
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:337
constexpr auto GetRight() const
Definition: rect.h:359
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
Type height
Definition: size.h:29
Type width
Definition: size.h:28
#define VALIDATION_LOG
Definition: validation.h:91