#pragma once
|
|
#ifdef __OBJC__
|
@class CAEAGLLayer;
|
@class EAGLContext;
|
#else
|
typedef struct objc_object CAEAGLLayer;
|
typedef struct objc_object EAGLContext;
|
#endif
|
|
#ifdef __OBJC__
|
@class CAMetalLayer;
|
@protocol CAMetalDrawable;
|
@protocol MTLDrawable;
|
@protocol MTLDevice;
|
@protocol MTLTexture;
|
@protocol MTLCommandBuffer;
|
@protocol MTLCommandQueue;
|
@protocol MTLCommandEncoder;
|
|
typedef id<CAMetalDrawable> CAMetalDrawableRef;
|
typedef id<MTLDevice> MTLDeviceRef;
|
typedef id<MTLTexture> MTLTextureRef;
|
typedef id<MTLCommandBuffer> MTLCommandBufferRef;
|
typedef id<MTLCommandQueue> MTLCommandQueueRef;
|
typedef id<MTLCommandEncoder> MTLCommandEncoderRef;
|
#else
|
typedef struct objc_object CAMetalLayer;
|
typedef struct objc_object* CAMetalDrawableRef;
|
typedef struct objc_object* MTLDeviceRef;
|
typedef struct objc_object* MTLTextureRef;
|
typedef struct objc_object* MTLCommandBufferRef;
|
typedef struct objc_object* MTLCommandQueueRef;
|
typedef struct objc_object* MTLCommandEncoderRef;
|
#endif
|
|
// unity internal native render buffer struct (the one you acquire in C# with RenderBuffer.GetNativeRenderBufferPtr())
|
struct RenderSurfaceBase;
|
typedef struct RenderSurfaceBase* UnityRenderBufferHandle;
|
|
// be aware that this struct is shared with unity implementation so you should absolutely not change it
|
typedef struct
|
UnityRenderBufferDesc
|
{
|
unsigned width, height, depth;
|
unsigned samples;
|
|
int backbuffer;
|
}
|
UnityRenderBufferDesc;
|
|
// trick to make structure inheritance work transparently between c/cpp
|
// for c we use "anonymous struct"
|
#ifdef __cplusplus
|
#define START_STRUCT(T, Base) struct T : Base {
|
#define END_STRUCT(T) };
|
#else
|
#define START_STRUCT(T, Base) typedef struct T { struct Base;
|
#define END_STRUCT(T) } T;
|
#endif
|
|
// we will keep objc objects in struct, so we need to explicitely mark references as strong to not confuse ARC
|
// please note that actual object lifetime is managed in objc++ code, so __unsafe_unretained is good enough for objc code
|
// DO NOT assign objects to UnityDisplaySurface* members in objc code.
|
// DO NOT store objects from UnityDisplaySurface* members in objc code, as this wont be caught by ARC
|
#ifdef __OBJC__
|
#ifdef __cplusplus
|
#define OBJC_OBJECT_PTR __strong
|
#else
|
#define OBJC_OBJECT_PTR __unsafe_unretained
|
#endif
|
#else
|
#define OBJC_OBJECT_PTR
|
#endif
|
|
// unity common rendering (display) surface
|
typedef struct
|
UnityDisplaySurfaceBase
|
{
|
UnityRenderBufferHandle unityColorBuffer;
|
UnityRenderBufferHandle unityDepthBuffer;
|
|
UnityRenderBufferHandle systemColorBuffer;
|
UnityRenderBufferHandle systemDepthBuffer;
|
|
void* cvTextureCache; // CVOpenGLESTextureCacheRef
|
void* cvTextureCacheTexture; // CVOpenGLESTextureRef
|
void* cvPixelBuffer; // CVPixelBufferRef
|
|
unsigned targetW, targetH;
|
unsigned systemW, systemH;
|
|
int msaaSamples;
|
int useCVTextureCache; // [bool]
|
int srgb; // [bool]
|
int disableDepthAndStencil; // [bool]
|
int allowScreenshot; // [bool] currently we allow screenshots (from script) only on main display
|
|
int api; // [UnityRenderingAPI]
|
}
|
UnityDisplaySurfaceBase;
|
|
|
// START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
|
#pragma clang diagnostic push
|
#pragma clang diagnostic ignored "-Wmissing-declarations"
|
|
// GLES display surface
|
START_STRUCT(UnityDisplaySurfaceGLES, UnityDisplaySurfaceBase)
|
OBJC_OBJECT_PTR CAEAGLLayer * layer;
|
OBJC_OBJECT_PTR EAGLContext* context;
|
|
// system FB
|
unsigned systemFB;
|
unsigned systemColorRB;
|
|
// target resolution FB/target RT to blit from
|
unsigned targetFB;
|
unsigned targetColorRT;
|
|
// MSAA FB
|
unsigned msaaFB;
|
unsigned msaaColorRB;
|
|
// when we enable AA for non-native resolution we need interim RT to resolve AA to (and then we will blit it to screen)
|
UnityRenderBufferHandle resolvedColorBuffer;
|
|
// will be "shared", only one depth buffer is needed
|
unsigned depthRB;
|
|
// render surface gl setup: formats and AA
|
unsigned colorFormat;
|
unsigned depthFormat;
|
END_STRUCT(UnityDisplaySurfaceGLES)
|
|
// Metal display surface
|
START_STRUCT(UnityDisplaySurfaceMTL, UnityDisplaySurfaceBase)
|
OBJC_OBJECT_PTR CAMetalLayer * layer;
|
OBJC_OBJECT_PTR MTLDeviceRef device;
|
|
OBJC_OBJECT_PTR MTLCommandQueueRef commandQueue;
|
OBJC_OBJECT_PTR CAMetalDrawableRef drawable;
|
|
OBJC_OBJECT_PTR MTLTextureRef systemColorRB;
|
OBJC_OBJECT_PTR MTLTextureRef targetColorRT;
|
OBJC_OBJECT_PTR MTLTextureRef targetAAColorRT;
|
|
OBJC_OBJECT_PTR MTLTextureRef depthRB;
|
OBJC_OBJECT_PTR MTLTextureRef stencilRB;
|
|
unsigned colorFormat; // [MTLPixelFormat]
|
unsigned depthFormat; // [MTLPixelFormat]
|
END_STRUCT(UnityDisplaySurfaceMTL)
|
|
// START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
|
#pragma clang diagnostic pop
|
|
// be aware that this enum is shared with unity implementation so you should absolutely not change it
|
typedef enum
|
UnityRenderingAPI
|
{
|
apiOpenGLES2 = 2,
|
apiOpenGLES3 = 3,
|
apiMetal = 4,
|
}
|
UnityRenderingAPI;
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
int UnitySelectedRenderingAPI();
|
#ifdef __cplusplus
|
} // extern "C"
|
#endif
|
|
// gles
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
void InitRenderingGLES();
|
|
void CreateSystemRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
|
void DestroySystemRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
|
void CreateRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
|
void DestroyRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
|
void CreateSharedDepthbufferGLES(UnityDisplaySurfaceGLES* surface);
|
void DestroySharedDepthbufferGLES(UnityDisplaySurfaceGLES* surface);
|
void CreateUnityRenderBuffersGLES(UnityDisplaySurfaceGLES* surface);
|
void DestroyUnityRenderBuffersGLES(UnityDisplaySurfaceGLES* surface);
|
void StartFrameRenderingGLES(UnityDisplaySurfaceGLES* surface);
|
void EndFrameRenderingGLES(UnityDisplaySurfaceGLES* surface);
|
void PreparePresentGLES(UnityDisplaySurfaceGLES* surface);
|
void PresentGLES(UnityDisplaySurfaceGLES* surface);
|
|
#ifdef __cplusplus
|
} // extern "C"
|
#endif
|
|
// metal
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
void InitRenderingMTL();
|
|
void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
|
void DestroySystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
|
void CreateRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
|
void DestroyRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
|
void CreateSharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
|
void DestroySharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
|
void CreateUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
|
void DestroyUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
|
void StartFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
|
void EndFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
|
void PreparePresentMTL(UnityDisplaySurfaceMTL* surface);
|
void PresentMTL(UnityDisplaySurfaceMTL* surface);
|
|
#ifdef __cplusplus
|
} // extern "C"
|
#endif
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
// for Create* functions if surf is null we will actuially create new one, otherwise we update the one provided
|
// gles: one and only one of texid/rbid should be non-zero
|
// metal: resolveTex should be non-nil only if tex have AA
|
UnityRenderBufferHandle UnityCreateExternalSurfaceGLES(UnityRenderBufferHandle surf, int isColor, unsigned texid, unsigned rbid, unsigned glesFormat, const UnityRenderBufferDesc* desc);
|
UnityRenderBufferHandle UnityCreateExternalSurfaceMTL(UnityRenderBufferHandle surf, int isColor, MTLTextureRef tex, const UnityRenderBufferDesc* desc);
|
UnityRenderBufferHandle UnityCreateExternalColorSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef resolveTex, const UnityRenderBufferDesc* desc);
|
UnityRenderBufferHandle UnityCreateExternalDepthSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef stencilTex, const UnityRenderBufferDesc* desc);
|
// creates "dummy" surface - will indicate "missing" buffer (e.g. depth-only RT will have color as dummy)
|
UnityRenderBufferHandle UnityCreateDummySurface(UnityRenderBufferHandle surf, int isColor, const UnityRenderBufferDesc* desc);
|
|
// disable rendering to render buffers (all Cameras that were rendering to one of buffers would be reset to use backbuffer)
|
void UnityDisableRenderBuffers(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
|
// destroys render buffer
|
void UnityDestroyExternalSurface(UnityRenderBufferHandle surf);
|
// sets current render target
|
void UnitySetRenderTarget(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
|
// final blit to backbuffer
|
void UnityBlitToBackbuffer(UnityRenderBufferHandle srcColor, UnityRenderBufferHandle dstColor, UnityRenderBufferHandle dstDepth);
|
// get native renderbuffer from handle
|
UnityRenderBufferHandle UnityNativeRenderBufferFromHandle(void *rb);
|
|
MTLCommandBufferRef UnityCurrentMTLCommandBuffer();
|
|
// sets vSync on OSX 10.13 and up
|
#if PLATFORM_OSX
|
void MetalUpdateDisplaySync();
|
#endif
|
|
#ifdef __cplusplus
|
} // extern "C"
|
#endif
|
|
// metal/gles unification
|
|
#define GLES_METAL_COMMON_IMPL_SURF(f) \
|
inline void f(UnityDisplaySurfaceBase* surface) \
|
{ \
|
if(surface->api == apiMetal) f ## MTL((UnityDisplaySurfaceMTL*)surface); \
|
else f ## GLES((UnityDisplaySurfaceGLES*)surface);\
|
} \
|
|
#define GLES_METAL_COMMON_IMPL(f) \
|
inline void f() \
|
{ \
|
if(UnitySelectedRenderingAPI() == apiMetal) f ## MTL(); \
|
else f ## GLES();\
|
} \
|
|
|
GLES_METAL_COMMON_IMPL(InitRendering);
|
|
GLES_METAL_COMMON_IMPL_SURF(CreateSystemRenderingSurface);
|
GLES_METAL_COMMON_IMPL_SURF(DestroySystemRenderingSurface);
|
GLES_METAL_COMMON_IMPL_SURF(CreateRenderingSurface);
|
GLES_METAL_COMMON_IMPL_SURF(DestroyRenderingSurface);
|
GLES_METAL_COMMON_IMPL_SURF(CreateSharedDepthbuffer);
|
GLES_METAL_COMMON_IMPL_SURF(DestroySharedDepthbuffer);
|
GLES_METAL_COMMON_IMPL_SURF(CreateUnityRenderBuffers);
|
GLES_METAL_COMMON_IMPL_SURF(DestroyUnityRenderBuffers);
|
GLES_METAL_COMMON_IMPL_SURF(StartFrameRendering);
|
GLES_METAL_COMMON_IMPL_SURF(EndFrameRendering);
|
GLES_METAL_COMMON_IMPL_SURF(PreparePresent);
|
GLES_METAL_COMMON_IMPL_SURF(Present);
|
|
#undef GLES_METAL_COMMON_IMPL_SURF
|
#undef GLES_METAL_COMMON_IMPL
|