123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include "CVTextureCache.h"
- #include "DisplayManager.h"
- #include <OpenGLES/ES2/glext.h>
- #include <OpenGLES/ES3/gl.h>
- #include <OpenGLES/ES3/glext.h>
- #include <CoreVideo/CVOpenGLESTextureCache.h>
- #include "UnityMetalSupport.h"
- #if UNITY_CAN_USE_METAL
- #include <CoreVideo/CVMetalTextureCache.h>
- #else
- typedef void* CVMetalTextureCacheRef;
- typedef void* CVMetalTextureRef;
- const CFStringRef kCVPixelBufferMetalCompatibilityKey = CFSTR("MetalCompatibility");
- inline CVReturn CVMetalTextureCacheCreate(CFAllocatorRef, CFDictionaryRef, MTLDeviceRef, CFDictionaryRef, CVMetalTextureCacheRef*) { return 0; }
- inline CVReturn CVMetalTextureCacheCreateTextureFromImage(CFAllocatorRef, CVMetalTextureCacheRef, CVImageBufferRef, CFDictionaryRef, MTLPixelFormat, size_t, size_t, size_t, CVMetalTextureRef*) { return 0; }
- inline void CVMetalTextureCacheFlush(CVMetalTextureCacheRef, uint64_t options) {}
- inline MTLTextureRef CVMetalTextureGetTexture(CVMetalTextureRef) { return nil; }
- inline Boolean CVMetalTextureIsFlipped(CVMetalTextureRef) { return 0; }
- #endif
- void* CreateCVTextureCache()
- {
- void* ret = 0;
- CVReturn err = 0;
- if (UnitySelectedRenderingAPI() == apiMetal)
- err = CVMetalTextureCacheCreate(kCFAllocatorDefault, 0, UnityGetMetalDevice(), 0, (CVMetalTextureCacheRef*)&ret);
- else
- err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, 0, UnityGetMainScreenContextGLES(), 0, (CVOpenGLESTextureCacheRef*)&ret);
- if (err)
- {
- ::printf("Error at CVOpenGLESTextureCacheCreate: %d", err);
- ret = 0;
- }
- return ret;
- }
- void FlushCVTextureCache(void* cache)
- {
- if (UnitySelectedRenderingAPI() == apiMetal)
- CVMetalTextureCacheFlush((CVMetalTextureCacheRef)cache, 0);
- else
- CVOpenGLESTextureCacheFlush((CVOpenGLESTextureCacheRef)cache, 0);
- }
- void* CreateBGRA32TextureFromCVTextureCache(void* cache, void* image, size_t w, size_t h)
- {
- void* texture = 0;
- CVReturn err = 0;
- if (UnitySelectedRenderingAPI() == apiMetal)
- {
- err = CVMetalTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
- (MTLPixelFormat)((UnityDisplaySurfaceMTL*)GetMainDisplaySurface())->colorFormat, w, h, 0, (CVMetalTextureRef*)&texture
- );
- }
- else
- {
- err = CVOpenGLESTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, (CVOpenGLESTextureCacheRef)cache, (CVImageBufferRef)image, 0,
- GL_TEXTURE_2D, GL_RGBA, (GLsizei)w, (GLsizei)h, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
- 0, (CVOpenGLESTextureRef*)&texture
- );
- }
- if (err)
- {
- ::printf("Error at CVOpenGLESTextureCacheCreateTextureFromImage: %d\n", err);
- texture = 0;
- }
- return texture;
- }
- void* CreateHalfFloatTextureFromCVTextureCache(void* cache, void* image, size_t w, size_t h)
- {
- void* texture = 0;
- CVReturn err = 0;
- if (UnitySelectedRenderingAPI() == apiMetal)
- {
- err = CVMetalTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
- MTLPixelFormatR16Float, w, h, 0, (CVMetalTextureRef*)&texture
- );
- }
- else if (UnitySelectedRenderingAPI() == apiOpenGLES3)
- {
- err = CVOpenGLESTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, (CVOpenGLESTextureCacheRef)cache, (CVImageBufferRef)image, 0,
- GL_TEXTURE_2D, GL_R16F, (GLsizei)w, (GLsizei)h, GL_RED, GL_HALF_FLOAT,
- 0, (CVOpenGLESTextureRef*)&texture
- );
- }
- else // OpenGLES2
- {
- err = CVOpenGLESTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault, (CVOpenGLESTextureCacheRef)cache, (CVImageBufferRef)image, 0,
- GL_TEXTURE_2D, GL_RED_EXT, (GLsizei)w, (GLsizei)h, GL_RED_EXT, GL_HALF_FLOAT_OES,
- 0, (CVOpenGLESTextureRef*)&texture
- );
- }
- if (err)
- {
- ::printf("Error at CVOpenGLESTextureCacheCreateTextureFromImage: %d\n", err);
- texture = 0;
- }
- return texture;
- }
- unsigned GetGLTextureFromCVTextureCache(void* texture)
- {
- assert(UnitySelectedRenderingAPI() != apiMetal);
- return CVOpenGLESTextureGetName((CVOpenGLESTextureRef)texture);
- }
- id<MTLTexture> GetMetalTextureFromCVTextureCache(void* texture)
- {
- assert(UnitySelectedRenderingAPI() == apiMetal);
- return CVMetalTextureGetTexture((CVMetalTextureRef)texture);
- }
- uintptr_t GetTextureFromCVTextureCache(void* texture)
- {
- if (UnitySelectedRenderingAPI() == apiMetal)
- return (uintptr_t)(__bridge void*)GetMetalTextureFromCVTextureCache(texture);
- else
- return (uintptr_t)GetGLTextureFromCVTextureCache(texture);
- }
- void* CreatePixelBufferForCVTextureCache(size_t w, size_t h)
- {
- NSString* apiKey = UnitySelectedRenderingAPI() == apiMetal ? (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey
- : (__bridge NSString*)kCVPixelBufferOpenGLESCompatibilityKey;
- CVPixelBufferRef pb = 0;
- NSDictionary* options = @{ (__bridge NSString*)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
- (__bridge NSString*)kCVPixelBufferWidthKey: @(w),
- (__bridge NSString*)kCVPixelBufferHeightKey: @(h),
- apiKey: @(YES),
- (__bridge NSString*)kCVPixelBufferIOSurfacePropertiesKey: @{}};
- CVPixelBufferCreate(kCFAllocatorDefault, w, h, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef)options, &pb);
- return pb;
- }
- void* CreateReadableRTFromCVTextureCache(void* cache, size_t w, size_t h, void** pb)
- {
- *pb = CreatePixelBufferForCVTextureCache(w, h);
- return CreateBGRA32TextureFromCVTextureCache(cache, *pb, w, h);
- }
- int IsCVTextureFlipped(void* texture)
- {
- if (UnitySelectedRenderingAPI() == apiMetal)
- return CVMetalTextureIsFlipped((CVMetalTextureRef)texture);
- else
- return CVOpenGLESTextureIsFlipped((CVOpenGLESTextureRef)texture);
- }
|