blob: 6a2a82031c181ad27d7915f08138bb46bbdfaa09 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"
#import <AppKit/AppKit.h>
#import <CoreVideo/CoreVideo.h>
#import <OpenGL/gl.h>
static void OnCVOpenGLTextureRelease(CVOpenGLTextureRef cvOpenGLTexture) {
CVOpenGLTextureRelease(cvOpenGLTexture);
}
@implementation FlutterExternalTextureGL {
/**
* OpenGL texture cache.
*/
CVOpenGLTextureCacheRef _openGLTextureCache;
/**
* User side texture object, used to copy pixel buffer.
*/
id<FlutterTexture> _texture;
}
- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture {
self = [super init];
if (self) {
_texture = texture;
}
return self;
}
- (int64_t)textureID {
return reinterpret_cast<int64_t>(_texture);
}
- (BOOL)populateTexture:(FlutterOpenGLTexture*)openGLTexture {
// Copy the pixel buffer from the FlutterTexture instance implemented on the user side.
CVPixelBufferRef pixelBuffer = [_texture copyPixelBuffer];
if (!pixelBuffer) {
return NO;
}
// Create the opengl texture cache if necessary.
if (!_openGLTextureCache) {
CGLContextObj context = [NSOpenGLContext currentContext].CGLContextObj;
CGLPixelFormatObj format = CGLGetPixelFormat(context);
if (CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, context, format, NULL,
&_openGLTextureCache) != kCVReturnSuccess) {
NSLog(@"Could not create texture cache.");
CVPixelBufferRelease(pixelBuffer);
return NO;
}
}
// Try to clear the cache of OpenGL textures to save memory.
CVOpenGLTextureCacheFlush(_openGLTextureCache, 0);
CVOpenGLTextureRef cvOpenGLTexture = NULL;
if (CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _openGLTextureCache,
pixelBuffer, NULL,
&cvOpenGLTexture) != kCVReturnSuccess) {
CVPixelBufferRelease(pixelBuffer);
return NO;
}
openGLTexture->target = static_cast<uint32_t>(CVOpenGLTextureGetTarget(cvOpenGLTexture));
openGLTexture->name = static_cast<uint32_t>(CVOpenGLTextureGetName(cvOpenGLTexture));
openGLTexture->format = static_cast<uint32_t>(GL_RGBA8);
openGLTexture->destruction_callback = (VoidCallback)OnCVOpenGLTextureRelease;
openGLTexture->user_data = cvOpenGLTexture;
openGLTexture->width = CVPixelBufferGetWidth(pixelBuffer);
openGLTexture->height = CVPixelBufferGetHeight(pixelBuffer);
CVPixelBufferRelease(pixelBuffer);
return YES;
}
- (void)dealloc {
CVOpenGLTextureCacheRelease(_openGLTextureCache);
}
@end