/* * Copyright (c) 2024, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #import namespace Gfx { class MetalTextureImpl final : public MetalTexture { public: MetalTextureImpl(id texture) : m_texture(texture) { } void const* texture() const override { return m_texture; } size_t width() const override { return m_texture.width; } size_t height() const override { return m_texture.height; } virtual ~MetalTextureImpl() { [m_texture release]; } private: id m_texture; }; class MetalContextImpl final : public MetalContext { public: MetalContextImpl(id device, id queue) : m_device(device) , m_queue(queue) { } void const* device() const override { return m_device; } void const* queue() const override { return m_queue; } OwnPtr create_texture_from_iosurface(Core::IOSurfaceHandle const& iosurface) override { auto* const descriptor = [[MTLTextureDescriptor alloc] init]; descriptor.pixelFormat = MTLPixelFormatBGRA8Unorm; descriptor.width = iosurface.width(); descriptor.height = iosurface.height(); descriptor.storageMode = MTLStorageModeShared; descriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; id texture = [m_device newTextureWithDescriptor:descriptor iosurface:(IOSurfaceRef)iosurface.core_foundation_pointer() plane:0]; [descriptor release]; return make(texture); } virtual ~MetalContextImpl() override { [m_queue release]; [m_device release]; } private: id m_device; id m_queue; }; OwnPtr get_metal_context() { auto device = MTLCreateSystemDefaultDevice(); if (!device) { dbgln("Failed to create Metal device"); return {}; } auto queue = [device newCommandQueue]; if (!queue) { dbgln("Failed to create Metal command queue"); [device release]; return {}; } return make(device, queue); } }