Flutter Engine
 
Loading...
Searching...
No Matches
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
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"
26
28
29namespace impeller {
30
31BlitPassMTL::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
44BlitPassMTL::~BlitPassMTL() {
45 if (!did_finish_encoding_) {
46 [encoder_ endEncoding];
47 }
48}
49
50bool BlitPassMTL::IsValid() const {
51 return is_valid_;
52}
53
54void BlitPassMTL::OnSetLabel(std::string_view label) {
55 if (label.empty()) {
56 return;
57 }
58 [encoder_ setLabel:@(label.data())];
59}
60
61bool BlitPassMTL::EncodeCommands() const {
62 [encoder_ endEncoding];
63 did_finish_encoding_ = true;
64 return true;
65}
66
67// |BlitPass|
68bool 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|
115bool 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|
137bool 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
188bool 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|
243bool 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
VkDevice device
Definition main.cc:69
FlTexture * texture
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
Definition switch_defs.h:98
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition formats.h:466