diff options
Diffstat (limited to 'intern/ghost/intern/GHOST_ContextCGL.h')
-rw-r--r-- | intern/ghost/intern/GHOST_ContextCGL.h | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index badc3241107..130b926f25c 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -9,8 +9,13 @@ #include "GHOST_Context.h" +#include <Cocoa/Cocoa.h> +#include <Metal/Metal.h> +#include <QuartzCore/QuartzCore.h> + @class CAMetalLayer; @class MTLCommandQueue; +@class MTLDevice; @class MTLRenderPipelineState; @class MTLTexture; @class NSOpenGLContext; @@ -36,62 +41,89 @@ class GHOST_ContextCGL : public GHOST_Context { * Swaps front and back buffers of a window. * \return A boolean success indicator. */ - GHOST_TSuccess swapBuffers(); + GHOST_TSuccess swapBuffers() override; /** * Activates the drawing context of this window. * \return A boolean success indicator. */ - GHOST_TSuccess activateDrawingContext(); + GHOST_TSuccess activateDrawingContext() override; /** * Release the drawing context of the calling thread. * \return A boolean success indicator. */ - GHOST_TSuccess releaseDrawingContext(); + GHOST_TSuccess releaseDrawingContext() override; - unsigned int getDefaultFramebuffer(); + unsigned int getDefaultFramebuffer() override; /** * Call immediately after new to initialize. If this fails then immediately delete the object. * \return Indication as to whether initialization has succeeded. */ - GHOST_TSuccess initializeDrawingContext(); + GHOST_TSuccess initializeDrawingContext() override; /** * Removes references to native handles from this context and then returns * \return GHOST_kSuccess if it is OK for the parent to release the handles and * GHOST_kFailure if releasing the handles will interfere with sharing */ - GHOST_TSuccess releaseNativeHandles(); + GHOST_TSuccess releaseNativeHandles() override; /** * Sets the swap interval for #swapBuffers. * \param interval: The swap interval to use. * \return A boolean success indicator. */ - GHOST_TSuccess setSwapInterval(int interval); + GHOST_TSuccess setSwapInterval(int interval) override; /** * Gets the current swap interval for #swapBuffers. * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ - GHOST_TSuccess getSwapInterval(int &); + GHOST_TSuccess getSwapInterval(int &) override; /** * Updates the drawing context of this window. * Needed whenever the window is changed. * \return Indication of success. */ - GHOST_TSuccess updateDrawingContext(); + GHOST_TSuccess updateDrawingContext() override; + + /** + * Returns a texture that Metal code can use as a render target. The current + * contents of this texture will be composited on top of the frame-buffer + * each time `swapBuffers` is called. + */ + id<MTLTexture> metalOverlayTexture(); + + /** + * Return a pointer to the Metal command queue used by this context. + */ + MTLCommandQueue *metalCommandQueue(); + + /** + * Return a pointer to the Metal device associated with this context. + */ + MTLDevice *metalDevice(); + + /** + * Register present callback + */ + void metalRegisterPresentCallback(void (*callback)( + MTLRenderPassDescriptor *, id<MTLRenderPipelineState>, id<MTLTexture>, id<CAMetalDrawable>)); private: /** Metal state */ + /* Set this flag to `true` when rendering with Metal API for Viewport. + * TODO(Metal): This should be assigned to externally. */ + bool m_useMetalForRendering = false; NSView *m_metalView; CAMetalLayer *m_metalLayer; MTLCommandQueue *m_metalCmdQueue; MTLRenderPipelineState *m_metalRenderPipeline; + bool m_ownsMetalDevice; /** OpenGL state, for GPUs that don't support Metal */ NSOpenGLView *m_openGLView; @@ -103,10 +135,30 @@ class GHOST_ContextCGL : public GHOST_Context { unsigned int m_defaultFramebuffer; /** The virtualized default frame-buffer's texture. */ - MTLTexture *m_defaultFramebufferMetalTexture; - - bool m_coreProfile; - + /** + * Texture that you can render into with Metal. The texture will be + * composited on top of `m_defaultFramebufferMetalTexture` whenever + * `swapBuffers` is called. + */ + static const int METAL_SWAPCHAIN_SIZE = 3; + struct MTLSwapchainTexture { + id<MTLTexture> texture; + unsigned int index; + }; + MTLSwapchainTexture m_defaultFramebufferMetalTexture[METAL_SWAPCHAIN_SIZE]; + unsigned int current_swapchain_index = 0; + + /* Present callback. + * We use this such that presentation can be controlled from within the Metal + * Context. This is required for optimal performance and clean control flow. + * Also helps ensure flickering does not occur by present being dependent + * on existing submissions. */ + void (*contextPresentCallback)(MTLRenderPassDescriptor *, + id<MTLRenderPipelineState>, + id<MTLTexture>, + id<CAMetalDrawable>); + + int mtl_SwapInterval; const bool m_debug; /** The first created OpenGL context (for sharing display lists) */ @@ -119,4 +171,5 @@ class GHOST_ContextCGL : public GHOST_Context { void metalInitFramebuffer(); void metalUpdateFramebuffer(); void metalSwapBuffers(); + void initClear(); }; |