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