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