blob: aaf7e7129627d82819b7012ed115aebc99db008f [file] [log] [blame]
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import "RTCOpenGLVideoRenderer.h"
#import "RTCShader+Private.h"
#import "WebRTC/RTCVideoFrame.h"
@implementation RTCOpenGLVideoRenderer {
GlContextType *_context;
BOOL _isInitialized;
id<RTCShader> _i420Shader;
id<RTCShader> _nv12Shader;
}
@synthesize lastDrawnFrame = _lastDrawnFrame;
+ (void)initialize {
// Disable dithering for performance.
glDisable(GL_DITHER);
}
- (instancetype)initWithContext:(GlContextType *)context {
NSAssert(context != nil, @"context cannot be nil");
if (self = [super init]) {
_context = context;
}
return self;
}
- (BOOL)drawFrame:(RTCVideoFrame *)frame {
if (!_isInitialized || !frame || frame == _lastDrawnFrame) {
return NO;
}
[self ensureGLContext];
glClear(GL_COLOR_BUFFER_BIT);
id<RTCShader> shader = nil;
#if TARGET_OS_IPHONE
if (frame.nativeHandle) {
if (!_nv12Shader) {
_nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_context];
}
shader = _nv12Shader;
#else
// Rendering native CVPixelBuffer is not supported on OS X.
if (false) {
#endif
} else {
if (!_i420Shader) {
_i420Shader = [[RTCI420Shader alloc] initWithContext:_context];
}
shader = _i420Shader;
}
if (!shader || ![shader drawFrame:frame]) {
return NO;
}
#if !TARGET_OS_IPHONE
[_context flushBuffer];
#endif
_lastDrawnFrame = frame;
return YES;
}
- (void)setupGL {
if (_isInitialized) {
return;
}
[self ensureGLContext];
_isInitialized = YES;
}
- (void)teardownGL {
if (!_isInitialized) {
return;
}
[self ensureGLContext];
_i420Shader = nil;
_nv12Shader = nil;
_isInitialized = NO;
}
#pragma mark - Private
- (void)ensureGLContext {
NSAssert(_context, @"context shouldn't be nil");
#if TARGET_OS_IPHONE
if ([EAGLContext currentContext] != _context) {
[EAGLContext setCurrentContext:_context];
}
#else
if ([NSOpenGLContext currentContext] != _context) {
[_context makeCurrentContext];
}
#endif
}
@end