blob: bfd6eebe7ebe70077d92dfe23f2111a1346aa021 [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;
tkchin04dbb342016-08-08 03:10:07 -070051 } else {
52 if (!_i420Shader) {
53 _i420Shader = [[RTCI420Shader alloc] initWithContext:_context];
54 }
55 shader = _i420Shader;
Jon Hjellee799bad2016-01-11 13:47:11 -080056 }
magjed7ee51252017-02-21 04:19:46 -080057#else
58 // Rendering native CVPixelBuffer is not supported on OS X.
59 frame = [frame newI420VideoFrame];
60 if (!_i420Shader) {
61 _i420Shader = [[RTCI420Shader alloc] initWithContext:_context];
62 }
63 shader = _i420Shader;
64#endif
tkchin04dbb342016-08-08 03:10:07 -070065 if (!shader || ![shader drawFrame:frame]) {
66 return NO;
67 }
68
Jon Hjellee799bad2016-01-11 13:47:11 -080069#if !TARGET_OS_IPHONE
70 [_context flushBuffer];
71#endif
72 _lastDrawnFrame = frame;
tkchin04dbb342016-08-08 03:10:07 -070073
Jon Hjellee799bad2016-01-11 13:47:11 -080074 return YES;
75}
76
77- (void)setupGL {
78 if (_isInitialized) {
79 return;
80 }
81 [self ensureGLContext];
Jon Hjellee799bad2016-01-11 13:47:11 -080082 _isInitialized = YES;
83}
84
85- (void)teardownGL {
86 if (!_isInitialized) {
87 return;
88 }
89 [self ensureGLContext];
tkchin04dbb342016-08-08 03:10:07 -070090 _i420Shader = nil;
91 _nv12Shader = nil;
Jon Hjellee799bad2016-01-11 13:47:11 -080092 _isInitialized = NO;
93}
94
95#pragma mark - Private
96
97- (void)ensureGLContext {
98 NSAssert(_context, @"context shouldn't be nil");
99#if TARGET_OS_IPHONE
100 if ([EAGLContext currentContext] != _context) {
101 [EAGLContext setCurrentContext:_context];
102 }
103#else
104 if ([NSOpenGLContext currentContext] != _context) {
105 [_context makeCurrentContext];
106 }
107#endif
108}
109
Jon Hjellee799bad2016-01-11 13:47:11 -0800110@end