/* * 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 _i420Shader; id _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 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