Flutter Impeller
texture_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 <memory>
7 
11 
12 namespace impeller {
13 
14 std::shared_ptr<Texture> WrapperMTL(TextureDescriptor desc,
15  const void* mtl_texture,
16  std::function<void()> deletion_proc) {
17  return TextureMTL::Wrapper(desc, (__bridge id<MTLTexture>)mtl_texture,
18  std::move(deletion_proc));
19 }
20 
22  const AcquireTextureProc& aquire_proc,
23  bool wrapped,
24  bool drawable)
25  : Texture(p_desc), aquire_proc_(aquire_proc), is_drawable_(drawable) {
26  const auto& desc = GetTextureDescriptor();
27 
28  if (!desc.IsValid() || !aquire_proc) {
29  return;
30  }
31 
32  if (desc.size != GetSize()) {
33  VALIDATION_LOG << "The texture and its descriptor disagree about its size.";
34  return;
35  }
36 
37  is_wrapped_ = wrapped;
38  is_valid_ = true;
39 }
40 
41 std::shared_ptr<TextureMTL> TextureMTL::Wrapper(
42  TextureDescriptor desc,
43  id<MTLTexture> texture,
44  std::function<void()> deletion_proc) {
45  if (deletion_proc) {
46  return std::shared_ptr<TextureMTL>(
47  new TextureMTL(
48  desc, [texture]() { return texture; }, true),
49  [deletion_proc = std::move(deletion_proc)](TextureMTL* t) {
50  deletion_proc();
51  delete t;
52  });
53  }
54  return std::shared_ptr<TextureMTL>(
55  new TextureMTL(desc, [texture]() { return texture; }, true));
56 }
57 
58 std::shared_ptr<TextureMTL> TextureMTL::Create(TextureDescriptor desc,
59  id<MTLTexture> texture) {
60  return std::make_shared<TextureMTL>(desc, [texture]() { return texture; });
61 }
62 
64 #ifdef IMPELLER_DEBUG
65  if (debug_allocator_) {
66  auto desc = GetTextureDescriptor();
68  return;
69  }
70  debug_allocator_->Decrement(desc.GetByteSizeOfBaseMipLevel());
71  }
72 #endif // IMPELLER_DEBUG
73 }
74 
75 void TextureMTL::SetLabel(std::string_view label) {
76  if (is_drawable_) {
77  return;
78  }
79  [aquire_proc_() setLabel:@(label.data())];
80 }
81 
82 // |Texture|
83 bool TextureMTL::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
84  size_t slice) {
85  // Metal has no threading restrictions. So we can pass this data along to the
86  // client rendering API immediately.
87  return OnSetContents(mapping->GetMapping(), mapping->GetSize(), slice);
88 }
89 
90 #ifdef IMPELLER_DEBUG
91 void TextureMTL::SetDebugAllocator(
92  const std::shared_ptr<DebugAllocatorStats>& debug_allocator) {
93  debug_allocator_ = debug_allocator;
94 }
95 #endif // IMPELLER_DEBUG
96 
97 // |Texture|
98 bool TextureMTL::OnSetContents(const uint8_t* contents,
99  size_t length,
100  size_t slice) {
101  if (!IsValid() || !contents || is_wrapped_ || is_drawable_) {
102  return false;
103  }
104 
105  const auto& desc = GetTextureDescriptor();
106 
107  // Out of bounds access.
108  if (length != desc.GetByteSizeOfBaseMipLevel()) {
109  return false;
110  }
111 
112  const auto region =
113  MTLRegionMake2D(0u, 0u, desc.size.width, desc.size.height);
114  [aquire_proc_() replaceRegion:region //
115  mipmapLevel:0u //
116  slice:slice //
117  withBytes:contents //
118  bytesPerRow:desc.GetBytesPerRow() //
119  bytesPerImage:desc.GetByteSizeOfBaseMipLevel() //
120  ];
121 
122  return true;
123 }
124 
125 ISize TextureMTL::GetSize() const {
126  if (is_drawable_) {
127  return GetTextureDescriptor().size;
128  }
129  const auto& texture = aquire_proc_();
130  return {static_cast<ISize::Type>(texture.width),
131  static_cast<ISize::Type>(texture.height)};
132 }
133 
134 id<MTLTexture> TextureMTL::GetMTLTexture() const {
135  return aquire_proc_();
136 }
137 
138 bool TextureMTL::IsValid() const {
139  return is_valid_;
140 }
141 
142 bool TextureMTL::IsWrapped() const {
143  return is_wrapped_;
144 }
145 
147  return is_drawable_;
148 }
149 
150 bool TextureMTL::GenerateMipmap(id<MTLBlitCommandEncoder> encoder) {
151  if (is_drawable_) {
152  return false;
153  }
154 
155  auto texture = aquire_proc_();
156  if (!texture) {
157  return false;
158  }
159 
160  [encoder generateMipmapsForTexture:texture];
161  mipmap_generated_ = true;
162 
163  return true;
164 }
165 
166 } // namespace impeller
impeller::ISize
ISize64 ISize
Definition: size.h:140
impeller::TextureMTL::AcquireTextureProc
std::function< id< MTLTexture >()> AcquireTextureProc
This callback needs to always return the same texture when called multiple times.
Definition: texture_mtl.h:21
impeller::TextureMTL::IsDrawable
bool IsDrawable() const
Whether or not this texture is wrapping a Metal drawable.
Definition: texture_mtl.mm:146
impeller::TextureMTL::GenerateMipmap
bool GenerateMipmap(id< MTLBlitCommandEncoder > encoder)
Definition: texture_mtl.mm:150
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
texture_descriptor.h
formats.h
impeller::TextureMTL::GetMTLTexture
id< MTLTexture > GetMTLTexture() const
Definition: texture_mtl.mm:134
impeller::TextureMTL::TextureMTL
TextureMTL(TextureDescriptor desc, const AcquireTextureProc &aquire_proc, bool wrapped=false, bool drawable=false)
Definition: texture_mtl.mm:21
impeller::TextureMTL
Definition: texture_mtl.h:16
validation.h
impeller::TSize::Type
T Type
Definition: size.h:20
impeller::TextureDescriptor::IsValid
constexpr bool IsValid() const
Definition: texture_descriptor.h:98
impeller::Texture
Definition: texture.h:17
impeller::StorageMode::kDeviceTransient
@ kDeviceTransient
impeller::TextureMTL::IsValid
bool IsValid() const override
Definition: texture_mtl.mm:138
impeller::WrapperMTL
std::shared_ptr< Texture > WrapperMTL(TextureDescriptor desc, const void *mtl_texture, std::function< void()> deletion_proc)
Definition: texture_mtl.mm:14
impeller::TextureMTL::Create
static std::shared_ptr< TextureMTL > Create(TextureDescriptor desc, id< MTLTexture > texture)
Definition: texture_mtl.mm:58
impeller::Texture::mipmap_generated_
bool mipmap_generated_
Definition: texture.h:70
impeller::TextureMTL::Wrapper
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
Definition: texture_mtl.mm:41
impeller::TSize::width
Type width
Definition: size.h:22
impeller::TextureMTL::~TextureMTL
~TextureMTL() override
Definition: texture_mtl.mm:63
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
std
Definition: comparable.h:95
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:48
texture_mtl.h
impeller::TextureMTL::IsWrapped
bool IsWrapped() const
Definition: texture_mtl.mm:142
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TSize::height
Type height
Definition: size.h:23
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller
Definition: aiks_blend_unittests.cc:18