| 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 #include <memory>
7 #include <utility>
8
9 #include "impeller/base/strings.h"
10 #include "impeller/base/validation.h"
11 #include "impeller/core/formats.h"
12
13 namespace impeller {
14
15 BlitPass::BlitPass() {}
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) {
42 VALIDATION_LOG << SPrintF(
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) {
51 VALIDATION_LOG << SPrintF(
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
71 return OnCopyTextureToTextureCommand(
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) {
99 VALIDATION_LOG
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
116 bool BlitPass::AddCopy(BufferView source,
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) {
143 VALIDATION_LOG
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
163 bool BlitPass::ConvertTextureToShaderRead(
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
blit_pass.h
impeller::BlitPass::SetLabel
void SetLabel(std::string_view label)
Definition: blit_pass.cc:19
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:26
impeller::BlitPass::BlitPass
BlitPass()
Definition: blit_pass.cc:15
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:168
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:163
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::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::PixelFormatToString
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
strings.h
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:361
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:341
impeller::TRect::Area
constexpr T Area() const
Get the area of the rectangle, equivalent to |GetSize().Area()|.
Definition: rect.h:380
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:337
impeller::TRect::GetRight
constexpr auto GetRight() const
Definition: rect.h:359
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