UnityRendering.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #pragma once
  2. #include <stdint.h>
  3. #ifdef __OBJC__
  4. @class CAEAGLLayer;
  5. @class EAGLContext;
  6. #else
  7. typedef struct objc_object CAEAGLLayer;
  8. typedef struct objc_object EAGLContext;
  9. #endif
  10. #ifdef __OBJC__
  11. @class CAMetalLayer;
  12. @protocol CAMetalDrawable;
  13. @protocol MTLDrawable;
  14. @protocol MTLDevice;
  15. @protocol MTLTexture;
  16. @protocol MTLCommandBuffer;
  17. @protocol MTLCommandQueue;
  18. @protocol MTLCommandEncoder;
  19. typedef id<CAMetalDrawable> CAMetalDrawableRef;
  20. typedef id<MTLDevice> MTLDeviceRef;
  21. typedef id<MTLTexture> MTLTextureRef;
  22. typedef id<MTLCommandBuffer> MTLCommandBufferRef;
  23. typedef id<MTLCommandQueue> MTLCommandQueueRef;
  24. typedef id<MTLCommandEncoder> MTLCommandEncoderRef;
  25. #else
  26. typedef struct objc_object CAMetalLayer;
  27. typedef struct objc_object* CAMetalDrawableRef;
  28. typedef struct objc_object* MTLDeviceRef;
  29. typedef struct objc_object* MTLTextureRef;
  30. typedef struct objc_object* MTLCommandBufferRef;
  31. typedef struct objc_object* MTLCommandQueueRef;
  32. typedef struct objc_object* MTLCommandEncoderRef;
  33. #endif
  34. // unity internal native render buffer struct (the one you acquire in C# with RenderBuffer.GetNativeRenderBufferPtr())
  35. struct RenderSurfaceBase;
  36. typedef struct RenderSurfaceBase* UnityRenderBufferHandle;
  37. // be aware that this struct is shared with unity implementation so you should absolutely not change it
  38. typedef struct UnityRenderBufferDesc
  39. {
  40. unsigned width, height, depth;
  41. unsigned samples;
  42. int backbuffer;
  43. } UnityRenderBufferDesc;
  44. // trick to make structure inheritance work transparently between c/cpp
  45. // for c we use "anonymous struct"
  46. #ifdef __cplusplus
  47. #define START_STRUCT(T, Base) struct T : Base {
  48. #define END_STRUCT(T) };
  49. #else
  50. #define START_STRUCT(T, Base) typedef struct T { struct Base;
  51. #define END_STRUCT(T) } T;
  52. #endif
  53. // we will keep objc objects in struct, so we need to explicitely mark references as strong to not confuse ARC
  54. // please note that actual object lifetime is managed in objc++ code, so __unsafe_unretained is good enough for objc code
  55. // DO NOT assign objects to UnityDisplaySurface* members in objc code.
  56. // DO NOT store objects from UnityDisplaySurface* members in objc code, as this wont be caught by ARC
  57. #ifdef __OBJC__
  58. #ifdef __cplusplus
  59. #define OBJC_OBJECT_PTR __strong
  60. #else
  61. #define OBJC_OBJECT_PTR __unsafe_unretained
  62. #endif
  63. #else
  64. #define OBJC_OBJECT_PTR
  65. #endif
  66. // unity common rendering (display) surface
  67. typedef struct UnityDisplaySurfaceBase
  68. {
  69. UnityRenderBufferHandle unityColorBuffer;
  70. UnityRenderBufferHandle unityDepthBuffer;
  71. UnityRenderBufferHandle systemColorBuffer;
  72. UnityRenderBufferHandle systemDepthBuffer;
  73. void* cvTextureCache; // CVOpenGLESTextureCacheRef
  74. void* cvTextureCacheTexture; // CVOpenGLESTextureRef
  75. void* cvPixelBuffer; // CVPixelBufferRef
  76. unsigned targetW, targetH;
  77. unsigned systemW, systemH;
  78. int msaaSamples;
  79. int useCVTextureCache; // [bool]
  80. int srgb; // [bool]
  81. int wideColor; // [bool]
  82. int disableDepthAndStencil; // [bool]
  83. int allowScreenshot; // [bool] currently we allow screenshots (from script) only on main display
  84. int memorylessDepth; // [bool]
  85. int api; // [UnityRenderingAPI]
  86. } UnityDisplaySurfaceBase;
  87. // START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
  88. #pragma clang diagnostic push
  89. #pragma clang diagnostic ignored "-Wmissing-declarations"
  90. #define kUnityNumOffscreenSurfaces 2
  91. // GLES display surface
  92. START_STRUCT(UnityDisplaySurfaceGLES, UnityDisplaySurfaceBase)
  93. OBJC_OBJECT_PTR CAEAGLLayer * layer;
  94. OBJC_OBJECT_PTR EAGLContext* context;
  95. // system FB
  96. unsigned systemFB;
  97. unsigned systemColorRB;
  98. // target resolution FB/target RT to blit from
  99. unsigned targetFB;
  100. unsigned targetColorRT;
  101. // MSAA FB
  102. unsigned msaaFB;
  103. unsigned msaaColorRB;
  104. // when we enable AA for non-native resolution we need interim RT to resolve AA to (and then we will blit it to screen)
  105. UnityRenderBufferHandle resolvedColorBuffer;
  106. // will be "shared", only one depth buffer is needed
  107. unsigned depthRB;
  108. // render surface gl setup: formats and AA
  109. unsigned colorFormat;
  110. unsigned depthFormat;
  111. END_STRUCT(UnityDisplaySurfaceGLES)
  112. // Metal display surface
  113. START_STRUCT(UnityDisplaySurfaceMTL, UnityDisplaySurfaceBase)
  114. OBJC_OBJECT_PTR CAMetalLayer * layer;
  115. OBJC_OBJECT_PTR MTLDeviceRef device;
  116. OBJC_OBJECT_PTR MTLCommandQueueRef commandQueue;
  117. OBJC_OBJECT_PTR MTLCommandQueueRef drawableCommandQueue;
  118. OBJC_OBJECT_PTR MTLCommandBufferRef presentCB;
  119. OBJC_OBJECT_PTR CAMetalDrawableRef drawable;
  120. OBJC_OBJECT_PTR MTLTextureRef drawableProxyRT[kUnityNumOffscreenSurfaces];
  121. // These are used on a Mac with drawableProxyRT when off-screen rendering is used
  122. volatile int32_t bufferCompleted;
  123. volatile int32_t bufferSwap;
  124. OBJC_OBJECT_PTR MTLTextureRef systemColorRB;
  125. OBJC_OBJECT_PTR MTLTextureRef targetColorRT;
  126. OBJC_OBJECT_PTR MTLTextureRef targetAAColorRT;
  127. OBJC_OBJECT_PTR MTLTextureRef depthRB;
  128. OBJC_OBJECT_PTR MTLTextureRef stencilRB;
  129. unsigned colorFormat; // [MTLPixelFormat]
  130. unsigned depthFormat; // [MTLPixelFormat]
  131. int framebufferOnly;
  132. END_STRUCT(UnityDisplaySurfaceMTL)
  133. // START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
  134. #pragma clang diagnostic pop
  135. // be aware that this enum is shared with unity implementation so you should absolutely not change it
  136. typedef enum UnityRenderingAPI
  137. {
  138. apiOpenGLES2 = 2,
  139. apiOpenGLES3 = 3,
  140. apiMetal = 4,
  141. } UnityRenderingAPI;
  142. typedef struct
  143. RenderingSurfaceParams
  144. {
  145. // rendering setup
  146. int msaaSampleCount;
  147. int renderW;
  148. int renderH;
  149. int srgb;
  150. int wideColor;
  151. int metalFramebufferOnly;
  152. int metalMemorylessDepth;
  153. // unity setup
  154. int disableDepthAndStencil;
  155. int useCVTextureCache;
  156. }
  157. RenderingSurfaceParams;
  158. #ifdef __cplusplus
  159. extern "C" {
  160. #endif
  161. int UnitySelectedRenderingAPI();
  162. #ifdef __cplusplus
  163. } // extern "C"
  164. #endif
  165. // gles
  166. #ifdef __cplusplus
  167. extern "C" {
  168. #endif
  169. void InitRenderingGLES();
  170. void CreateSystemRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
  171. void DestroySystemRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
  172. void CreateRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
  173. void DestroyRenderingSurfaceGLES(UnityDisplaySurfaceGLES* surface);
  174. void CreateSharedDepthbufferGLES(UnityDisplaySurfaceGLES* surface);
  175. void DestroySharedDepthbufferGLES(UnityDisplaySurfaceGLES* surface);
  176. void CreateUnityRenderBuffersGLES(UnityDisplaySurfaceGLES* surface);
  177. void DestroyUnityRenderBuffersGLES(UnityDisplaySurfaceGLES* surface);
  178. void StartFrameRenderingGLES(UnityDisplaySurfaceGLES* surface);
  179. void EndFrameRenderingGLES(UnityDisplaySurfaceGLES* surface);
  180. void PreparePresentGLES(UnityDisplaySurfaceGLES* surface);
  181. void PresentGLES(UnityDisplaySurfaceGLES* surface);
  182. #ifdef __cplusplus
  183. } // extern "C"
  184. #endif
  185. // metal
  186. #ifdef __cplusplus
  187. extern "C" {
  188. #endif
  189. void InitRenderingMTL();
  190. void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  191. void DestroySystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  192. void CreateRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  193. void DestroyRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  194. void CreateSharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  195. void DestroySharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  196. void CreateUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  197. void DestroyUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  198. void StartFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  199. void EndFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  200. void PreparePresentMTL(UnityDisplaySurfaceMTL* surface);
  201. void PresentMTL(UnityDisplaySurfaceMTL* surface);
  202. // Acquires CAMetalDrawable resource for the surface and returns the drawable texture
  203. MTLTextureRef AcquireDrawableMTL(UnityDisplaySurfaceMTL* surface);
  204. // starting with ios11 apple insists on having just one presentDrawable per command buffer
  205. // hence we keep normal processing for main screen, but when airplay is used we will create extra command buffers
  206. void PreparePresentNonMainScreenMTL(UnityDisplaySurfaceMTL* surface);
  207. void SetDrawableSizeMTL(UnityDisplaySurfaceMTL* surface, int width, int height);
  208. #ifdef __cplusplus
  209. } // extern "C"
  210. #endif
  211. #ifdef __cplusplus
  212. extern "C" {
  213. #endif
  214. // for Create* functions if surf is null we will actuially create new one, otherwise we update the one provided
  215. // gles: one and only one of texid/rbid should be non-zero
  216. // metal: resolveTex should be non-nil only if tex have AA
  217. UnityRenderBufferHandle UnityCreateExternalSurfaceGLES(UnityRenderBufferHandle surf, int isColor, unsigned texid, unsigned rbid, unsigned glesFormat, const UnityRenderBufferDesc* desc);
  218. UnityRenderBufferHandle UnityCreateExternalSurfaceMTL(UnityRenderBufferHandle surf, int isColor, MTLTextureRef tex, const UnityRenderBufferDesc* desc);
  219. // Passing non-nil displaySurface will mark render surface as proxy and will do a delayed drawable acquisition when setting up framebuffer
  220. UnityRenderBufferHandle UnityCreateExternalColorSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef resolveTex, const UnityRenderBufferDesc* desc, UnityDisplaySurfaceMTL* displaySurface);
  221. UnityRenderBufferHandle UnityCreateExternalDepthSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef stencilTex, const UnityRenderBufferDesc* desc);
  222. // creates "dummy" surface - will indicate "missing" buffer (e.g. depth-only RT will have color as dummy)
  223. UnityRenderBufferHandle UnityCreateDummySurface(UnityRenderBufferHandle surf, int isColor, const UnityRenderBufferDesc* desc);
  224. // disable rendering to render buffers (all Cameras that were rendering to one of buffers would be reset to use backbuffer)
  225. void UnityDisableRenderBuffers(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  226. // destroys render buffer
  227. void UnityDestroyExternalSurface(UnityRenderBufferHandle surf);
  228. // sets current render target
  229. void UnitySetRenderTarget(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  230. // final blit to backbuffer
  231. void UnityBlitToBackbuffer(UnityRenderBufferHandle srcColor, UnityRenderBufferHandle dstColor, UnityRenderBufferHandle dstDepth);
  232. // get native renderbuffer from handle
  233. // sets vSync on OSX 10.13 and up
  234. #if PLATFORM_OSX
  235. void MetalUpdateDisplaySync();
  236. #endif
  237. UnityRenderBufferHandle UnityNativeRenderBufferFromHandle(void *rb);
  238. MTLCommandBufferRef UnityCurrentMTLCommandBuffer();
  239. void UnityUpdateDrawableSize(UnityDisplaySurfaceMTL* surface);
  240. #ifdef __cplusplus
  241. } // extern "C"
  242. #endif
  243. // metal/gles unification
  244. #define GLES_METAL_COMMON_IMPL_SURF(f) \
  245. inline void f(UnityDisplaySurfaceBase* surface) \
  246. { \
  247. if(surface->api == apiMetal) f ## MTL((UnityDisplaySurfaceMTL*)surface); \
  248. else f ## GLES((UnityDisplaySurfaceGLES*)surface);\
  249. } \
  250. #define GLES_METAL_COMMON_IMPL(f) \
  251. inline void f() \
  252. { \
  253. if(UnitySelectedRenderingAPI() == apiMetal) f ## MTL(); \
  254. else f ## GLES();\
  255. } \
  256. GLES_METAL_COMMON_IMPL(InitRendering);
  257. GLES_METAL_COMMON_IMPL_SURF(CreateSystemRenderingSurface);
  258. GLES_METAL_COMMON_IMPL_SURF(DestroySystemRenderingSurface);
  259. GLES_METAL_COMMON_IMPL_SURF(CreateRenderingSurface);
  260. GLES_METAL_COMMON_IMPL_SURF(DestroyRenderingSurface);
  261. GLES_METAL_COMMON_IMPL_SURF(CreateSharedDepthbuffer);
  262. GLES_METAL_COMMON_IMPL_SURF(DestroySharedDepthbuffer);
  263. GLES_METAL_COMMON_IMPL_SURF(CreateUnityRenderBuffers);
  264. GLES_METAL_COMMON_IMPL_SURF(DestroyUnityRenderBuffers);
  265. GLES_METAL_COMMON_IMPL_SURF(StartFrameRendering);
  266. GLES_METAL_COMMON_IMPL_SURF(EndFrameRendering);
  267. GLES_METAL_COMMON_IMPL_SURF(PreparePresent);
  268. GLES_METAL_COMMON_IMPL_SURF(Present);
  269. #undef GLES_METAL_COMMON_IMPL_SURF
  270. #undef GLES_METAL_COMMON_IMPL