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