| Flutter Impeller |

blit_pass_mtl.mm
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/backend/metal/blit_pass_mtl.h"
6
7 #include <Metal/Metal.h>
8 #import <MetalPerformanceShaders/MetalPerformanceShaders.h>
9 #include <cstdint>
10 #include <memory>
11 #include <utility>
12 #include <variant>
13
14 #include "flutter/fml/closure.h"
15 #include "flutter/fml/logging.h"
16 #include "flutter/fml/trace_event.h"
17 #include "impeller/base/backend_cast.h"
18 #include "impeller/core/formats.h"
19 #include "impeller/core/host_buffer.h"
20 #include "impeller/core/shader_types.h"
21 #include "impeller/renderer/backend/metal/device_buffer_mtl.h"
22 #include "impeller/renderer/backend/metal/formats_mtl.h"
23 #include "impeller/renderer/backend/metal/pipeline_mtl.h"
24 #include "impeller/renderer/backend/metal/sampler_mtl.h"
25 #include "impeller/renderer/backend/metal/texture_mtl.h"
26
27 #include "impeller/renderer/blit_command.h"
28
29 namespace impeller {
30
31 BlitPassMTL::BlitPassMTL(id<MTLCommandBuffer> buffer, id<MTLDevice> device)
32 : buffer_(buffer), device_(device) {
33 if (!buffer_) {
34 return;
35 }
36 encoder_ = [buffer_ blitCommandEncoder];
37 #ifdef IMPELLER_DEBUG
38 is_metal_trace_active_ =
39 [[MTLCaptureManager sharedCaptureManager] isCapturing];
40 #endif // IMPELLER_DEBUG
41 is_valid_ = true;
42 }
43
44 BlitPassMTL::~BlitPassMTL() {
45 if (!did_finish_encoding_) {
46 [encoder_ endEncoding];
47 }
48 }
49
50 bool BlitPassMTL::IsValid() const {
51 return is_valid_;
52 }
53
54 void BlitPassMTL::OnSetLabel(std::string_view label) {
55 if (label.empty()) {
56 return;
57 }
58 [encoder_ setLabel:@(label.data())];
59 }
60
61 bool BlitPassMTL::EncodeCommands() const {
62 [encoder_ endEncoding];
63 did_finish_encoding_ = true;
64 return true;
65 }
66
67 // |BlitPass|
68 bool BlitPassMTL::OnCopyTextureToTextureCommand(
69 std::shared_ptr<Texture> source,
70 std::shared_ptr<Texture> destination,
71 IRect source_region,
72 IPoint destination_origin,
73 std::string_view label) {
74 auto source_mtl = TextureMTL::Cast(*source).GetMTLTexture();
75 if (!source_mtl) {
76 return false;
77 }
78
79 auto destination_mtl = TextureMTL::Cast(*destination).GetMTLTexture();
80 if (!destination_mtl) {
81 return false;
82 }
83
84 auto source_origin_mtl =
85 MTLOriginMake(source_region.GetX(), source_region.GetY(), 0);
86 auto source_size_mtl =
87 MTLSizeMake(source_region.GetWidth(), source_region.GetHeight(), 1);
88 auto destination_origin_mtl =
89 MTLOriginMake(destination_origin.x, destination_origin.y, 0);
90
91 #ifdef IMPELLER_DEBUG
92 if (is_metal_trace_active_) {
93 [encoder_ pushDebugGroup:@(label.data())];
94 }
95 #endif // IMPELLER_DEBUG
96 [encoder_ copyFromTexture:source_mtl
97 sourceSlice:0
98 sourceLevel:0
99 sourceOrigin:source_origin_mtl
100 sourceSize:source_size_mtl
101 toTexture:destination_mtl
102 destinationSlice:0
103 destinationLevel:0
104 destinationOrigin:destination_origin_mtl];
105
106 #ifdef IMPELLER_DEBUG
107 if (is_metal_trace_active_) {
108 [encoder_ popDebugGroup];
109 }
110 #endif // IMPELLER_DEBUG
111 return true;
112 }
113
114 // |BlitPass|
115 bool BlitPassMTL::ResizeTexture(const std::shared_ptr<Texture>& source,
116 const std::shared_ptr<Texture>& destination) {
117 auto source_mtl = TextureMTL::Cast(*source).GetMTLTexture();
118 if (!source_mtl) {
119 return false;
120 }
121
122 auto destination_mtl = TextureMTL::Cast(*destination).GetMTLTexture();
123 if (!destination_mtl) {
124 return false;
125 }
126
127 [encoder_ endEncoding];
128 auto filter = [[MPSImageBilinearScale alloc] initWithDevice:device_];
129 [filter encodeToCommandBuffer:buffer_
130 sourceTexture:source_mtl
131 destinationTexture:destination_mtl];
132 encoder_ = [buffer_ blitCommandEncoder];
133 return true;
134 }
135
136 // |BlitPass|
137 bool BlitPassMTL::OnCopyTextureToBufferCommand(
138 std::shared_ptr<Texture> source,
139 std::shared_ptr<DeviceBuffer> destination,
140 IRect source_region,
141 size_t destination_offset,
142 std::string_view label) {
143 auto source_mtl = TextureMTL::Cast(*source).GetMTLTexture();
144 if (!source_mtl) {
145 return false;
146 }
147
148 auto destination_mtl = DeviceBufferMTL::Cast(*destination).GetMTLBuffer();
149 if (!destination_mtl) {
150 return false;
151 }
152
153 auto source_origin_mtl =
154 MTLOriginMake(source_region.GetX(), source_region.GetY(), 0);
155 auto source_size_mtl =
156 MTLSizeMake(source_region.GetWidth(), source_region.GetHeight(), 1);
157
158 auto destination_bytes_per_pixel =
159 BytesPerPixelForPixelFormat(source->GetTextureDescriptor().format);
160 auto destination_bytes_per_row =
161 source_size_mtl.width * destination_bytes_per_pixel;
162 auto destination_bytes_per_image =
163 source_size_mtl.height * destination_bytes_per_row;
164
165 #ifdef IMPELLER_DEBUG
166 if (is_metal_trace_active_) {
167 [encoder_ pushDebugGroup:@(label.data())];
168 }
169 #endif // IMPELLER_DEBUG
170 [encoder_ copyFromTexture:source_mtl
171 sourceSlice:0
172 sourceLevel:0
173 sourceOrigin:source_origin_mtl
174 sourceSize:source_size_mtl
175 toBuffer:destination_mtl
176 destinationOffset:destination_offset
177 destinationBytesPerRow:destination_bytes_per_row
178 destinationBytesPerImage:destination_bytes_per_image];
179
180 #ifdef IMPELLER_DEBUG
181 if (is_metal_trace_active_) {
182 [encoder_ popDebugGroup];
183 }
184 #endif // IMPELLER_DEBUG
185 return true;
186 }
187
188 bool BlitPassMTL::OnCopyBufferToTextureCommand(
189 BufferView source,
190 std::shared_ptr<Texture> destination,
191 IRect destination_region,
192 std::string_view label,
193 uint32_t mip_level,
194 uint32_t slice,
195 bool convert_to_read) {
196 auto source_mtl = DeviceBufferMTL::Cast(*source.GetBuffer()).GetMTLBuffer();
197 if (!source_mtl) {
198 return false;
199 }
200
201 auto destination_mtl = TextureMTL::Cast(*destination).GetMTLTexture();
202 if (!destination_mtl) {
203 return false;
204 }
205
206 auto destination_origin_mtl =
207 MTLOriginMake(destination_region.GetX(), destination_region.GetY(), 0);
208 auto source_size_mtl = MTLSizeMake(destination_region.GetWidth(),
209 destination_region.GetHeight(), 1);
210
211 auto destination_bytes_per_pixel =
212 BytesPerPixelForPixelFormat(destination->GetTextureDescriptor().format);
213 auto source_bytes_per_row =
214 destination_region.GetWidth() * destination_bytes_per_pixel;
215
216 #ifdef IMPELLER_DEBUG
217 if (is_metal_trace_active_) {
218 [encoder_ pushDebugGroup:@(label.data())];
219 }
220 #endif // IMPELLER_DEBUG
221 [encoder_
222 copyFromBuffer:source_mtl
223 sourceOffset:source.GetRange().offset
224 sourceBytesPerRow:source_bytes_per_row
225 sourceBytesPerImage:
226 0 // 0 for 2D textures according to
227 // https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400752-copyfrombuffer
228 sourceSize:source_size_mtl
229 toTexture:destination_mtl
230 destinationSlice:slice
231 destinationLevel:mip_level
232 destinationOrigin:destination_origin_mtl];
233
234 #ifdef IMPELLER_DEBUG
235 if (is_metal_trace_active_) {
236 [encoder_ popDebugGroup];
237 }
238 #endif // IMPELLER_DEBUG
239 return true;
240 }
241
242 // |BlitPass|
243 bool BlitPassMTL::OnGenerateMipmapCommand(std::shared_ptr<Texture> texture,
244 std::string_view label) {
245 #ifdef IMPELLER_DEBUG
246 if (is_metal_trace_active_) {
247 [encoder_ pushDebugGroup:@(label.data())];
248 }
249 #endif // IMPELLER_DEBUG
250 auto result = TextureMTL::Cast(*texture).GenerateMipmap(encoder_);
251 #ifdef IMPELLER_DEBUG
252 if (is_metal_trace_active_) {
253 [encoder_ popDebugGroup];
254 }
255 #endif // IMPELLER_DEBUG
256 return result;
257 }
258
259 } // namespace impeller
backend_cast.h
blit_command.h
blit_pass_mtl.h
formats.h
device_buffer_mtl.h
formats_mtl.h
host_buffer.h
impeller
Definition: allocation.cc:12
impeller::BytesPerPixelForPixelFormat
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:469
impeller::IRect
IRect64 IRect
Definition: rect.h:791
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:426
pipeline_mtl.h
sampler_mtl.h
shader_types.h
texture_mtl.h