Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
1 change: 1 addition & 0 deletions impeller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impeller_component("impeller_unittests") {
"core:allocator_unittests",
"display_list:skia_conversions_unittests",
"geometry:geometry_unittests",
"renderer/backend/metal:metal_unittests",
"runtime_stage:runtime_stage_unittests",
"scene/importer:importer_unittests",
"shader_archive:shader_archive_unittests",
Expand Down
16 changes: 16 additions & 0 deletions impeller/renderer/backend/metal/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,19 @@ impeller_component("metal") {

frameworks = [ "Metal.framework" ]
}

impeller_component("metal_unittests") {
testonly = true

sources = [ "texture_mtl_unittests.mm" ]

deps = [
":metal",
"//flutter/testing:testing_lib",
]

frameworks = [
"AppKit.framework",
"QuartzCore.framework",
]
}
2 changes: 1 addition & 1 deletion impeller/renderer/backend/metal/allocator_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static MTLStorageMode ToMTLStorageMode(StorageMode mode,
if (!texture) {
return nullptr;
}
return std::make_shared<TextureMTL>(desc, texture);
return TextureMTL::Create(desc, texture);
}

uint16_t AllocatorMTL::MinimumBytesPerRow(PixelFormat format) const {
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/metal/device_buffer_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
if (!texture) {
return nullptr;
}
return std::make_shared<TextureMTL>(descriptor, texture);
return TextureMTL::Create(descriptor, texture);
}

[[nodiscard]] bool DeviceBufferMTL::OnCopyHostBuffer(const uint8_t* source,
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/metal/surface_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
resolve_tex_desc.compression_type = CompressionType::kLossy;
resolve_tex = allocator.CreateTexture(resolve_tex_desc);
} else {
resolve_tex = std::make_shared<TextureMTL>(resolve_tex_desc, texture);
resolve_tex = TextureMTL::Create(resolve_tex_desc, texture);
}

if (!resolve_tex) {
Expand Down
64 changes: 31 additions & 33 deletions impeller/renderer/backend/metal/texture_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,53 @@
#include "impeller/base/backend_cast.h"
#include "impeller/core/texture.h"

@protocol CAMetalDrawable;
@class CAMetalLayer;

namespace impeller {

class TextureMTL final : public Texture,
public BackendCast<TextureMTL, Texture> {
class TextureMTL : public Texture, public BackendCast<TextureMTL, Texture> {
public:
TextureMTL(TextureDescriptor desc,
id<MTLTexture> texture,
bool wrapped = false);

static std::shared_ptr<TextureMTL> Wrapper(
TextureDescriptor desc,
id<MTLTexture> texture,
std::function<void()> deletion_proc = nullptr);

// |Texture|
~TextureMTL() override;

id<MTLTexture> GetMTLTexture() const;

bool IsWrapped() const;

bool GenerateMipmap(id<MTLBlitCommandEncoder> encoder);
/// @brief Create a new metal texture.
static std::shared_ptr<TextureMTL> Create(TextureDescriptor desc,
id<MTLTexture> texture);

private:
id<MTLTexture> texture_ = nullptr;
bool is_valid_ = false;
bool is_wrapped_ = false;
#pragma GCC diagnostic push
// Disable the diagnostic for iOS Simulators. Metal without emulation isn't
// available prior to iOS 13 and that's what the simulator headers say when
// support for CAMetalLayer begins. CAMetalLayer is available on iOS 8.0 and
// above which is well below Flutters support level.
#pragma GCC diagnostic ignored "-Wunguarded-availability-new"

// |Texture|
void SetLabel(std::string_view label) override;
/// @brief Create a new texture backed by a lazily acquired drawable
static std::shared_ptr<TextureMTL> WrapDrawable(TextureDescriptor desc,
CAMetalLayer* layer);
#pragma GCC diagnostic pop

// |Texture|
bool OnSetContents(const uint8_t* contents,
size_t length,
size_t slice) override;
virtual id<MTLTexture> GetMTLTexture() const = 0;

// |Texture|
bool OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
size_t slice) override;
/// @brief Return the backing Metal drawable (if it has been acquired) or
/// otherwise block on drawable aquisition.
///
/// This is only valud for textures that return true from
/// [IsDrawableBacked].
virtual id<CAMetalDrawable> WaitForNextDrawable() const = 0;

// |Texture|
bool IsValid() const override;
virtual bool IsWrapped() const = 0;

// |Texture|
ISize GetSize() const override;
/// @brief Whether or not this texture is backed by a CAMetalLayer and needs
/// to acquire a drawable before a texture can be returned.
virtual bool IsDrawableBacked() const = 0;

TextureMTL(const TextureMTL&) = delete;
virtual bool GenerateMipmap(id<MTLBlitCommandEncoder> encoder) = 0;

TextureMTL& operator=(const TextureMTL&) = delete;
protected:
explicit TextureMTL(const TextureDescriptor& desc);
};

} // namespace impeller
Loading