blob: aaf7e7129627d82819b7012ed115aebc99db008f [file] [log] [blame]
Jon Hjellee799bad2016-01-11 13:47:11 -08001/*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "RTCOpenGLVideoRenderer.h"
12
tkchin04dbb342016-08-08 03:10:07 -070013#import "RTCShader+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070014#import "WebRTC/RTCVideoFrame.h"
15
Jon Hjellee799bad2016-01-11 13:47:11 -080016@implementation RTCOpenGLVideoRenderer {
tkchin04dbb342016-08-08 03:10:07 -070017 GlContextType *_context;
Jon Hjellee799bad2016-01-11 13:47:11 -080018 BOOL _isInitialized;
tkchin04dbb342016-08-08 03:10:07 -070019 id<RTCShader> _i420Shader;
20 id<RTCShader> _nv12Shader;
Jon Hjellee799bad2016-01-11 13:47:11 -080021}
22
23@synthesize lastDrawnFrame = _lastDrawnFrame;
24
25+ (void)initialize {
26 // Disable dithering for performance.
27 glDisable(GL_DITHER);
28}
29
tkchin04dbb342016-08-08 03:10:07 -070030- (instancetype)initWithContext:(GlContextType *)context {
Jon Hjellee799bad2016-01-11 13:47:11 -080031 NSAssert(context != nil, @"context cannot be nil");
32 if (self = [super init]) {
33 _context = context;
34 }
35 return self;
36}
37
38- (BOOL)drawFrame:(RTCVideoFrame *)frame {
tkchin04dbb342016-08-08 03:10:07 -070039 if (!_isInitialized || !frame || frame == _lastDrawnFrame) {
Jon Hjellee799bad2016-01-11 13:47:11 -080040 return NO;
41 }
42 [self ensureGLContext];
43 glClear(GL_COLOR_BUFFER_BIT);
tkchin04dbb342016-08-08 03:10:07 -070044 id<RTCShader> shader = nil;
45#if TARGET_OS_IPHONE
46 if (frame.nativeHandle) {
47 if (!_nv12Shader) {
48 _nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_context];
Jon Hjellee799bad2016-01-11 13:47:11 -080049 }
tkchin04dbb342016-08-08 03:10:07 -070050 shader = _nv12Shader;
51#else
52 // Rendering native CVPixelBuffer is not supported on OS X.
53 if (false) {
Jon Hjellee799bad2016-01-11 13:47:11 -080054#endif
tkchin04dbb342016-08-08 03:10:07 -070055 } else {
56 if (!_i420Shader) {
57 _i420Shader = [[RTCI420Shader alloc] initWithContext:_context];
58 }
59 shader = _i420Shader;
Jon Hjellee799bad2016-01-11 13:47:11 -080060 }
tkchin04dbb342016-08-08 03:10:07 -070061 if (!shader || ![shader drawFrame:frame]) {
62 return NO;
63 }
64
Jon Hjellee799bad2016-01-11 13:47:11 -080065#if !TARGET_OS_IPHONE
66 [_context flushBuffer];
67#endif
68 _lastDrawnFrame = frame;
tkchin04dbb342016-08-08 03:10:07 -070069
Jon Hjellee799bad2016-01-11 13:47:11 -080070 return YES;
71}
72
73- (void)setupGL {
74 if (_isInitialized) {
75 return;
76 }
77 [self ensureGLContext];
Jon Hjellee799bad2016-01-11 13:47:11 -080078 _isInitialized = YES;
79}
80
81- (void)teardownGL {
82 if (!_isInitialized) {
83 return;
84 }
85 [self ensureGLContext];
tkchin04dbb342016-08-08 03:10:07 -070086 _i420Shader = nil;
87 _nv12Shader = nil;
Jon Hjellee799bad2016-01-11 13:47:11 -080088 _isInitialized = NO;
89}
90
91#pragma mark - Private
92
93- (void)ensureGLContext {
94 NSAssert(_context, @"context shouldn't be nil");
95#if TARGET_OS_IPHONE
96 if ([EAGLContext currentContext] != _context) {
97 [EAGLContext setCurrentContext:_context];
98 }
99#else
100 if ([NSOpenGLContext currentContext] != _context) {
101 [_context makeCurrentContext];
102 }
103#endif
104}
105
Jon Hjellee799bad2016-01-11 13:47:11 -0800106@end