2022-12-26 05:03:28 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Darling.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2022 Darling developers
|
|
|
|
*
|
|
|
|
* Darling is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Darling is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Darling. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#import <QuartzCore/CAMetalDrawable.h>
|
|
|
|
#import <Metal/MTLDrawableInternal.h>
|
|
|
|
#import <Metal/MTLTextureInternal.h>
|
|
|
|
#import <OpenGL/gl.h>
|
|
|
|
#import <OpenGL/OpenGL.h>
|
|
|
|
|
2022-12-31 18:16:50 +00:00
|
|
|
#if DARLING_METAL_ENABLED
|
|
|
|
|
2022-12-26 05:03:28 +00:00
|
|
|
#include <indium/indium.private.hpp>
|
|
|
|
|
|
|
|
@class CAMetalLayerInternal;
|
|
|
|
|
|
|
|
class CAMetalDrawableTexture: public Indium::PrivateTexture {
|
|
|
|
CGSize _size;
|
|
|
|
VkImage _image = VK_NULL_HANDLE;
|
|
|
|
VkDeviceMemory _memory = VK_NULL_HANDLE;
|
|
|
|
VkImageView _imageView = VK_NULL_HANDLE;
|
|
|
|
GLuint _textureID = 0;
|
|
|
|
GLuint _memoryObject = 0;
|
|
|
|
Indium::PixelFormat _pixelFormat;
|
|
|
|
VkImage _internalImage = VK_NULL_HANDLE;
|
|
|
|
VkDeviceMemory _internalMemory = VK_NULL_HANDLE;
|
2023-04-11 12:16:16 +00:00
|
|
|
bool _framebufferOnly = false;
|
2022-12-26 05:03:28 +00:00
|
|
|
|
|
|
|
public:
|
2023-04-11 12:16:16 +00:00
|
|
|
CAMetalDrawableTexture(CGSize size, Indium::PixelFormat pixelFormat, bool framebufferOnly, std::shared_ptr<Indium::PrivateDevice> privateDevice);
|
2022-12-26 05:03:28 +00:00
|
|
|
virtual ~CAMetalDrawableTexture();
|
|
|
|
|
|
|
|
GLuint glTexture() const;
|
|
|
|
|
|
|
|
virtual VkImageView imageView() override;
|
|
|
|
virtual VkImage image() override;
|
|
|
|
virtual VkImageLayout imageLayout() override;
|
|
|
|
virtual Indium::TextureType textureType() const override;
|
|
|
|
virtual Indium::PixelFormat pixelFormat() const override;
|
|
|
|
virtual size_t width() const override;
|
|
|
|
virtual size_t height() const override;
|
|
|
|
virtual size_t depth() const override;
|
|
|
|
virtual size_t mipmapLevelCount() const override;
|
|
|
|
virtual size_t arrayLength() const override;
|
|
|
|
virtual size_t sampleCount() const override;
|
|
|
|
virtual bool framebufferOnly() const override;
|
|
|
|
virtual bool allowGPUOptimizedContents() const override;
|
|
|
|
virtual bool shareable() const override;
|
|
|
|
virtual Indium::TextureSwizzleChannels swizzle() const override;
|
|
|
|
virtual void replaceRegion(Indium::Region region, size_t mipmapLevel, const void* bytes, size_t bytesPerRow) override;
|
|
|
|
virtual void replaceRegion(Indium::Region region, size_t mipmapLevel, size_t slice, const void* bytes, size_t bytesPerRow, size_t bytesPerImage) override;
|
|
|
|
|
|
|
|
virtual void precommit(std::shared_ptr<Indium::PrivateCommandBuffer> cmdbuf) override;
|
|
|
|
virtual bool needsExportablePresentationSemaphore() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CAMetalDrawableActual: public Indium::Drawable {
|
|
|
|
private:
|
|
|
|
std::shared_ptr<CAMetalDrawableTexture> _texture = nullptr;
|
|
|
|
CAMetalLayerInternal* _layer = nil;
|
|
|
|
std::shared_ptr<Indium::BinarySemaphore> _semaphore = nullptr;
|
|
|
|
GLuint _glSemaphore = 0;
|
2022-12-28 02:02:08 +00:00
|
|
|
std::function<void()> _wantsToPresentCallback = nullptr;
|
|
|
|
std::function<void()> _didPresentCallback = nullptr;
|
2022-12-26 05:03:28 +00:00
|
|
|
NSUInteger _drawableID = NSUIntegerMax;
|
|
|
|
CFTimeInterval _presentedTime = 0;
|
|
|
|
bool _queued = false;
|
|
|
|
CGLContextObj _glContext = nullptr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CAMetalDrawableActual(CAMetalLayerInternal* layer, CGSize size, NSUInteger drawableID, Indium::PixelFormat pixelFormat, std::shared_ptr<Indium::Device> device, CGLContextObj _glContext);
|
|
|
|
virtual ~CAMetalDrawableActual();
|
|
|
|
|
|
|
|
virtual void present() override;
|
|
|
|
|
|
|
|
std::shared_ptr<CAMetalDrawableTexture> texture();
|
|
|
|
NSUInteger drawableID() const;
|
|
|
|
CFTimeInterval presentedTime() const;
|
|
|
|
|
2022-12-28 02:02:08 +00:00
|
|
|
void setWantsToPresentCallback(std::function<void()> wantsToPresentCallback);
|
|
|
|
void setDidPresentCallback(std::function<void()> didPresentCallback);
|
2022-12-26 05:03:28 +00:00
|
|
|
|
|
|
|
void disown();
|
|
|
|
|
|
|
|
void synchronizeRender();
|
|
|
|
|
|
|
|
void didPresent();
|
|
|
|
void didDrop();
|
|
|
|
// this has nothing to do with memory management; this indicates that the drawable is no longer in use and can be recycled
|
|
|
|
void release();
|
|
|
|
void reset();
|
|
|
|
};
|
2022-12-31 18:16:50 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
@interface CAMetalDrawableInternal : NSObject <CAMetalDrawable, MTLDrawableInternal>
|
2022-12-26 05:03:28 +00:00
|
|
|
|
2022-12-31 18:16:50 +00:00
|
|
|
#if DARLING_METAL_ENABLED
|
|
|
|
{
|
2022-12-26 05:03:28 +00:00
|
|
|
NSUInteger _drawableID;
|
|
|
|
CFTimeInterval _presentedTime;
|
|
|
|
std::shared_ptr<CAMetalDrawableActual> _drawable;
|
|
|
|
MTLTextureInternal* _texture;
|
|
|
|
CAMetalLayer* _layer;
|
|
|
|
NSMutableArray<MTLDrawablePresentedHandler>* _presentedHandlers;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)initWithLayer: (CAMetalLayer*)layer
|
|
|
|
drawable: (std::shared_ptr<CAMetalDrawableActual>)drawable;
|
2022-12-31 18:16:50 +00:00
|
|
|
#endif
|
2022-12-26 05:03:28 +00:00
|
|
|
|
|
|
|
@end
|