6 #include <Metal/Metal.h>
7 #import <MetalPerformanceShaders/MetalPerformanceShaders.h>
12 #include "flutter/fml/closure.h"
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/trace_event.h"
29 BlitPassMTL::BlitPassMTL(id<MTLCommandBuffer> buffer, id<MTLDevice> device)
30 : buffer_(buffer), device_(device) {
34 encoder_ = [buffer_ blitCommandEncoder];
36 is_metal_trace_active_ =
37 [[MTLCaptureManager sharedCaptureManager] isCapturing];
38 #endif // IMPELLER_DEBUG
43 if (!did_finish_encoding_) {
44 [encoder_ endEncoding];
48 bool BlitPassMTL::IsValid()
const {
52 void BlitPassMTL::OnSetLabel(std::string label) {
56 [encoder_ setLabel:@(label.c_str())];
59 bool BlitPassMTL::EncodeCommands(
60 const std::shared_ptr<Allocator>& transients_allocator)
const {
61 [encoder_ endEncoding];
62 did_finish_encoding_ =
true;
67 bool BlitPassMTL::OnCopyTextureToTextureCommand(
68 std::shared_ptr<Texture> source,
69 std::shared_ptr<Texture> destination,
79 if (!destination_mtl) {
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);
91 if (is_metal_trace_active_) {
92 [encoder_ pushDebugGroup:@(label.c_str())];
94 #endif // IMPELLER_DEBUG
95 [encoder_ copyFromTexture:source_mtl
98 sourceOrigin:source_origin_mtl
99 sourceSize:source_size_mtl
100 toTexture:destination_mtl
103 destinationOrigin:destination_origin_mtl];
105 #ifdef IMPELLER_DEBUG
106 if (is_metal_trace_active_) {
107 [encoder_ popDebugGroup];
109 #endif // IMPELLER_DEBUG
114 bool BlitPassMTL::ResizeTexture(
const std::shared_ptr<Texture>& source,
115 const std::shared_ptr<Texture>& destination) {
122 if (!destination_mtl) {
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];
136 bool BlitPassMTL::OnCopyTextureToBufferCommand(
137 std::shared_ptr<Texture> source,
138 std::shared_ptr<DeviceBuffer> destination,
140 size_t destination_offset,
148 if (!destination_mtl) {
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);
157 auto destination_bytes_per_pixel =
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;
164 #ifdef IMPELLER_DEBUG
165 if (is_metal_trace_active_) {
166 [encoder_ pushDebugGroup:@(label.c_str())];
168 #endif // IMPELLER_DEBUG
169 [encoder_ copyFromTexture:source_mtl
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];
179 #ifdef IMPELLER_DEBUG
180 if (is_metal_trace_active_) {
181 [encoder_ popDebugGroup];
183 #endif // IMPELLER_DEBUG
187 bool BlitPassMTL::OnCopyBufferToTextureCommand(
189 std::shared_ptr<Texture> destination,
190 IRect destination_region,
193 bool convert_to_read) {
200 if (!destination_mtl) {
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);
209 auto destination_bytes_per_pixel =
211 auto source_bytes_per_row =
212 destination_region.GetWidth() * destination_bytes_per_pixel;
214 #ifdef IMPELLER_DEBUG
215 if (is_metal_trace_active_) {
216 [encoder_ pushDebugGroup:@(label.c_str())];
218 #endif // IMPELLER_DEBUG
220 copyFromBuffer:source_mtl
221 sourceOffset:source.range.offset
222 sourceBytesPerRow:source_bytes_per_row
226 sourceSize:source_size_mtl
227 toTexture:destination_mtl
228 destinationSlice:slice
230 destinationOrigin:destination_origin_mtl];
232 #ifdef IMPELLER_DEBUG
233 if (is_metal_trace_active_) {
234 [encoder_ popDebugGroup];
236 #endif // IMPELLER_DEBUG
241 bool BlitPassMTL::OnGenerateMipmapCommand(std::shared_ptr<Texture> texture,
243 #ifdef IMPELLER_DEBUG
244 if (is_metal_trace_active_) {
245 [encoder_ pushDebugGroup:@(label.c_str())];
247 #endif // IMPELLER_DEBUG
249 #ifdef IMPELLER_DEBUG
250 if (is_metal_trace_active_) {
251 [encoder_ popDebugGroup];
253 #endif // IMPELLER_DEBUG