Flutter Engine
 
Loading...
Searching...
No Matches
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
7#include <format>
8#include <memory>
9#include <utility>
10
13
14namespace impeller {
15
17
18BlitPass::~BlitPass() = default;
19
20void BlitPass::SetLabel(std::string_view label) {
21 if (label.empty()) {
22 return;
23 }
24 OnSetLabel(label);
25}
26
27bool 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
73 std::move(source), std::move(destination), source_region.value(),
74 destination_origin, label);
75}
76
77bool 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) {
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
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) {
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
165 const std::shared_ptr<Texture>& texture) {
166 return true;
167}
168
169bool 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
void SetLabel(std::string_view label)
Definition blit_pass.cc:20
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
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:169
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:164
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
FlTexture * texture
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition formats.h:466
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:357
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:337
constexpr T Area() const
Get the area of the rectangle, equivalent to |GetSize().Area()|.
Definition rect.h:376
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:333
constexpr auto GetRight() const
Definition rect.h:355
static constexpr 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