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 
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"
15 #include "impeller/core/formats.h"
23 
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 
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