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 
10 
11 namespace impeller {
12 
13 std::shared_ptr<Texture> WrapperMTL(TextureDescriptor desc,
14  const void* mtl_texture,
15  std::function<void()> deletion_proc) {
16  return TextureMTL::Wrapper(desc, (__bridge id<MTLTexture>)mtl_texture,
17  std::move(deletion_proc));
18 }
19 
21  const AcquireTextureProc& aquire_proc,
22  bool wrapped,
23  bool drawable)
24  : Texture(p_desc), aquire_proc_(aquire_proc), is_drawable_(drawable) {
25  const auto& desc = GetTextureDescriptor();
26 
27  if (!desc.IsValid() || !aquire_proc) {
28  return;
29  }
30 
31  if (desc.size != GetSize()) {
32  VALIDATION_LOG << "The texture and its descriptor disagree about its size.";
33  return;
34  }
35 
36  is_wrapped_ = wrapped;
37  is_valid_ = true;
38 }
39 
40 std::shared_ptr<TextureMTL> TextureMTL::Wrapper(
41  TextureDescriptor desc,
42  id<MTLTexture> texture,
43  std::function<void()> deletion_proc) {
44  if (deletion_proc) {
45  return std::shared_ptr<TextureMTL>(
46  new TextureMTL(
47  desc, [texture]() { return texture; }, true),
48  [deletion_proc = std::move(deletion_proc)](TextureMTL* t) {
49  deletion_proc();
50  delete t;
51  });
52  }
53  return std::shared_ptr<TextureMTL>(
54  new TextureMTL(desc, [texture]() { return texture; }, true));
55 }
56 
57 std::shared_ptr<TextureMTL> TextureMTL::Create(TextureDescriptor desc,
58  id<MTLTexture> texture) {
59  return std::make_shared<TextureMTL>(desc, [texture]() { return texture; });
60 }
61 
62 TextureMTL::~TextureMTL() = default;
63 
64 void TextureMTL::SetLabel(std::string_view label) {
65  if (is_drawable_) {
66  return;
67  }
68  [aquire_proc_() setLabel:@(label.data())];
69 }
70 
71 // |Texture|
72 bool TextureMTL::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
73  size_t slice) {
74  // Metal has no threading restrictions. So we can pass this data along to the
75  // client rendering API immediately.
76  return OnSetContents(mapping->GetMapping(), mapping->GetSize(), slice);
77 }
78 
79 // |Texture|
80 bool TextureMTL::OnSetContents(const uint8_t* contents,
81  size_t length,
82  size_t slice) {
83  if (!IsValid() || !contents || is_wrapped_ || is_drawable_) {
84  return false;
85  }
86 
87  const auto& desc = GetTextureDescriptor();
88 
89  // Out of bounds access.
90  if (length != desc.GetByteSizeOfBaseMipLevel()) {
91  return false;
92  }
93 
94  const auto region =
95  MTLRegionMake2D(0u, 0u, desc.size.width, desc.size.height);
96  [aquire_proc_() replaceRegion:region //
97  mipmapLevel:0u //
98  slice:slice //
99  withBytes:contents //
100  bytesPerRow:desc.GetBytesPerRow() //
101  bytesPerImage:desc.GetByteSizeOfBaseMipLevel() //
102  ];
103 
104  return true;
105 }
106 
107 ISize TextureMTL::GetSize() const {
108  if (is_drawable_) {
109  return GetTextureDescriptor().size;
110  }
111  const auto& texture = aquire_proc_();
112  return {static_cast<ISize::Type>(texture.width),
113  static_cast<ISize::Type>(texture.height)};
114 }
115 
116 id<MTLTexture> TextureMTL::GetMTLTexture() const {
117  return aquire_proc_();
118 }
119 
120 bool TextureMTL::IsValid() const {
121  return is_valid_;
122 }
123 
124 bool TextureMTL::IsWrapped() const {
125  return is_wrapped_;
126 }
127 
129  return is_drawable_;
130 }
131 
132 bool TextureMTL::GenerateMipmap(id<MTLBlitCommandEncoder> encoder) {
133  if (is_drawable_) {
134  return false;
135  }
136 
137  auto texture = aquire_proc_();
138  if (!texture) {
139  return false;
140  }
141 
142  [encoder generateMipmapsForTexture:texture];
143  mipmap_generated_ = true;
144 
145  return true;
146 }
147 
148 } // namespace impeller
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:128
impeller::TextureMTL::GenerateMipmap
bool GenerateMipmap(id< MTLBlitCommandEncoder > encoder)
Definition: texture_mtl.mm:132
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
texture_descriptor.h
impeller::TextureMTL::GetMTLTexture
id< MTLTexture > GetMTLTexture() const
Definition: texture_mtl.mm:116
impeller::TextureMTL::TextureMTL
TextureMTL(TextureDescriptor desc, const AcquireTextureProc &aquire_proc, bool wrapped=false, bool drawable=false)
Definition: texture_mtl.mm:20
impeller::TextureMTL
Definition: texture_mtl.h:16
validation.h
impeller::TSize< int64_t >::Type
int64_t Type
Definition: size.h:20
impeller::TextureDescriptor::IsValid
constexpr bool IsValid() const
Definition: texture_descriptor.h:81
impeller::Texture
Definition: texture.h:17
impeller::TextureMTL::IsValid
bool IsValid() const override
Definition: texture_mtl.mm:120
impeller::WrapperMTL
std::shared_ptr< Texture > WrapperMTL(TextureDescriptor desc, const void *mtl_texture, std::function< void()> deletion_proc)
Definition: texture_mtl.mm:13
impeller::TextureMTL::Create
static std::shared_ptr< TextureMTL > Create(TextureDescriptor desc, id< MTLTexture > texture)
Definition: texture_mtl.mm:57
impeller::Texture::mipmap_generated_
bool mipmap_generated_
Definition: texture.h:64
impeller::TextureMTL::Wrapper
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
Definition: texture_mtl.mm:40
impeller::TSize::width
Type width
Definition: size.h:22
impeller::TextureMTL::~TextureMTL
~TextureMTL() override
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
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:47
texture_mtl.h
impeller::TextureMTL::IsWrapped
bool IsWrapped() const
Definition: texture_mtl.mm:124
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:37
impeller
Definition: aiks_blur_unittests.cc:20