CVTextureCache.mm 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "CVTextureCache.h"
  2. #include "DisplayManager.h"
  3. #include <OpenGLES/ES2/gl.h>
  4. #include <OpenGLES/ES2/glext.h>
  5. #include <CoreVideo/CVOpenGLESTextureCache.h>
  6. #include "UnityMetalSupport.h"
  7. #if UNITY_CAN_USE_METAL
  8. #include <CoreVideo/CVMetalTextureCache.h>
  9. #else
  10. typedef void* CVMetalTextureCacheRef;
  11. typedef void* CVMetalTextureRef;
  12. const CFStringRef kCVPixelBufferMetalCompatibilityKey = CFSTR("MetalCompatibility");
  13. inline CVReturn CVMetalTextureCacheCreate(CFAllocatorRef, CFDictionaryRef, MTLDeviceRef, CFDictionaryRef, CVMetalTextureCacheRef*) { return 0; }
  14. inline CVReturn CVMetalTextureCacheCreateTextureFromImage(CFAllocatorRef, CVMetalTextureCacheRef, CVImageBufferRef, CFDictionaryRef, MTLPixelFormat, size_t, size_t, size_t, CVMetalTextureRef*) { return 0; }
  15. inline void CVMetalTextureCacheFlush(CVMetalTextureCacheRef, uint64_t options) {}
  16. inline MTLTextureRef CVMetalTextureGetTexture(CVMetalTextureRef) { return nil; }
  17. inline Boolean CVMetalTextureIsFlipped(CVMetalTextureRef) { return 0; }
  18. #endif
  19. void* CreateCVTextureCache()
  20. {
  21. void* ret = 0;
  22. CVReturn err = 0;
  23. if (UnitySelectedRenderingAPI() == apiMetal)
  24. err = CVMetalTextureCacheCreate(kCFAllocatorDefault, 0, UnityGetMetalDevice(), 0, (CVMetalTextureCacheRef*)&ret);
  25. else
  26. err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, 0, UnityGetMainScreenContextGLES(), 0, (CVOpenGLESTextureCacheRef*)&ret);
  27. if (err)
  28. {
  29. ::printf("Error at CVOpenGLESTextureCacheCreate: %d", err);
  30. ret = 0;
  31. }
  32. return ret;
  33. }
  34. void FlushCVTextureCache(void* cache)
  35. {
  36. if (UnitySelectedRenderingAPI() == apiMetal)
  37. CVMetalTextureCacheFlush((CVMetalTextureCacheRef)cache, 0);
  38. else
  39. CVOpenGLESTextureCacheFlush((CVOpenGLESTextureCacheRef)cache, 0);
  40. }
  41. void* CreateTextureFromCVTextureCache(void* cache, void* image, size_t w, size_t h)
  42. {
  43. void* texture = 0;
  44. CVReturn err = 0;
  45. if (UnitySelectedRenderingAPI() == apiMetal)
  46. {
  47. err = CVMetalTextureCacheCreateTextureFromImage(
  48. kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
  49. MTLPixelFormatBGRA8Unorm, w, h, 0, (CVMetalTextureRef*)&texture
  50. );
  51. }
  52. else
  53. {
  54. err = CVOpenGLESTextureCacheCreateTextureFromImage(
  55. kCFAllocatorDefault, (CVOpenGLESTextureCacheRef)cache, (CVImageBufferRef)image, 0,
  56. GL_TEXTURE_2D, GL_RGBA, (GLsizei)w, (GLsizei)h, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
  57. 0, (CVOpenGLESTextureRef*)&texture
  58. );
  59. }
  60. if (err)
  61. {
  62. ::printf("Error at CVOpenGLESTextureCacheCreateTextureFromImage: %d", err);
  63. texture = 0;
  64. }
  65. return texture;
  66. }
  67. unsigned GetGLTextureFromCVTextureCache(void* texture)
  68. {
  69. assert(UnitySelectedRenderingAPI() != apiMetal);
  70. return CVOpenGLESTextureGetName((CVOpenGLESTextureRef)texture);
  71. }
  72. id<MTLTexture> GetMetalTextureFromCVTextureCache(void* texture)
  73. {
  74. assert(UnitySelectedRenderingAPI() == apiMetal);
  75. return CVMetalTextureGetTexture((CVMetalTextureRef)texture);
  76. }
  77. uintptr_t GetTextureFromCVTextureCache(void* texture)
  78. {
  79. if (UnitySelectedRenderingAPI() == apiMetal)
  80. return (uintptr_t)(__bridge void*)GetMetalTextureFromCVTextureCache(texture);
  81. else
  82. return (uintptr_t)GetGLTextureFromCVTextureCache(texture);
  83. }
  84. void* CreatePixelBufferForCVTextureCache(size_t w, size_t h)
  85. {
  86. NSString* apiKey = UnitySelectedRenderingAPI() == apiMetal ? (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey
  87. : (__bridge NSString*)kCVPixelBufferOpenGLESCompatibilityKey;
  88. CVPixelBufferRef pb = 0;
  89. NSDictionary* options = @{ (__bridge NSString*)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
  90. (__bridge NSString*)kCVPixelBufferWidthKey: @(w),
  91. (__bridge NSString*)kCVPixelBufferHeightKey: @(h),
  92. apiKey: @(YES),
  93. (__bridge NSString*)kCVPixelBufferIOSurfacePropertiesKey: @{}};
  94. CVPixelBufferCreate(kCFAllocatorDefault, w, h, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef)options, &pb);
  95. return pb;
  96. }
  97. void* CreateReadableRTFromCVTextureCache(void* cache, size_t w, size_t h, void** pb)
  98. {
  99. *pb = CreatePixelBufferForCVTextureCache(w, h);
  100. return CreateTextureFromCVTextureCache(cache, *pb, w, h);
  101. }
  102. int IsCVTextureFlipped(void* texture)
  103. {
  104. if (UnitySelectedRenderingAPI() == apiMetal)
  105. return CVMetalTextureIsFlipped((CVMetalTextureRef)texture);
  106. else
  107. return CVOpenGLESTextureIsFlipped((CVOpenGLESTextureRef)texture);
  108. }