Flutter Impeller
device_buffer_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 "flutter/fml/logging.h"
11 
12 namespace impeller {
13 
14 DeviceBufferMTL::DeviceBufferMTL(DeviceBufferDescriptor desc,
15  id<MTLBuffer> buffer,
16  MTLStorageMode storage_mode)
17  : DeviceBuffer(desc), buffer_(buffer), storage_mode_(storage_mode) {}
18 
19 DeviceBufferMTL::~DeviceBufferMTL() = default;
20 
21 id<MTLBuffer> DeviceBufferMTL::GetMTLBuffer() const {
22  return buffer_;
23 }
24 
25 uint8_t* DeviceBufferMTL::OnGetContents() const {
26 #if !FML_OS_IOS
27  if (storage_mode_ != MTLStorageModeShared &&
28  storage_mode_ != MTLStorageModeManaged) {
29  return nullptr;
30  }
31 #else
32  if (storage_mode_ != MTLStorageModeShared) {
33  return nullptr;
34  }
35 #endif // !FML_OS_IOS
36 
37  return reinterpret_cast<uint8_t*>(buffer_.contents);
38 }
39 
40 [[nodiscard]] bool DeviceBufferMTL::OnCopyHostBuffer(const uint8_t* source,
41  Range source_range,
42  size_t offset) {
43  auto dest = static_cast<uint8_t*>(buffer_.contents);
44 
45  if (!dest) {
46  return false;
47  }
48 
49  if (source) {
50  ::memmove(dest + offset, source + source_range.offset, source_range.length);
51  }
52 
53 // MTLStorageModeManaged is never present on always returns false on iOS. But
54 // the compiler is mad that `didModifyRange:` appears in a TU meant for iOS. So,
55 // just compile it away.
56 #if !FML_OS_IOS
57  if (storage_mode_ == MTLStorageModeManaged) {
58  [buffer_ didModifyRange:NSMakeRange(offset, source_range.length)];
59  }
60 #endif
61 
62  return true;
63 }
64 
65 void DeviceBufferMTL::Flush(std::optional<Range> range) const {
66 #if !FML_OS_IOS
67  auto flush_range = range.value_or(Range{0, GetDeviceBufferDescriptor().size});
68  if (storage_mode_ == MTLStorageModeManaged) {
69  [buffer_
70  didModifyRange:NSMakeRange(flush_range.offset, flush_range.length)];
71  }
72 #endif
73 }
74 
75 bool DeviceBufferMTL::SetLabel(std::string_view label) {
76 #ifdef IMPELLER_DEBUG
77  if (label.empty()) {
78  return false;
79  }
80  [buffer_ setLabel:@(label.data())];
81 #endif // IMPELLER_DEBUG
82  return true;
83 }
84 
85 bool DeviceBufferMTL::SetLabel(std::string_view label, Range range) {
86 #ifdef IMPELLER_DEBUG
87  if (label.empty()) {
88  return false;
89  }
90  [buffer_ addDebugMarker:@(label.data())
91  range:NSMakeRange(range.offset, range.length)];
92 #endif // IMPELLER_DEBUG
93  return true;
94 }
95 
96 } // namespace impeller