| Index: webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m
|
| diff --git a/webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m b/webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m
|
| index 537397f37866484a02d2af09a6083934353ca106..1fb03bc909e27305eee7eb41bd9f6066983f7e3e 100644
|
| --- a/webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m
|
| +++ b/webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m
|
| @@ -12,7 +12,8 @@
|
|
|
| #import <GLKit/GLKit.h>
|
|
|
| -#import "RTCOpenGLVideoRenderer.h"
|
| +#import "RTCShader+Private.h"
|
| +#import "WebRTC/RTCLogging.h"
|
| #import "WebRTC/RTCVideoFrame.h"
|
|
|
| // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen
|
| @@ -88,7 +89,6 @@
|
| // from the display link callback so atomicity is required.
|
| @property(atomic, strong) RTCVideoFrame *videoFrame;
|
| @property(nonatomic, readonly) GLKView *glkView;
|
| -@property(nonatomic, readonly) RTCOpenGLVideoRenderer *glRenderer;
|
| @end
|
|
|
| @implementation RTCEAGLVideoView {
|
| @@ -97,12 +97,14 @@
|
| // This flag should only be set and read on the main thread (e.g. by
|
| // setNeedsDisplay)
|
| BOOL _isDirty;
|
| + id<RTCShader> _i420Shader;
|
| + id<RTCShader> _nv12Shader;
|
| + RTCVideoFrame *_lastDrawnFrame;
|
| }
|
|
|
| @synthesize delegate = _delegate;
|
| @synthesize videoFrame = _videoFrame;
|
| @synthesize glkView = _glkView;
|
| -@synthesize glRenderer = _glRenderer;
|
|
|
| - (instancetype)initWithFrame:(CGRect)frame {
|
| if (self = [super initWithFrame:frame]) {
|
| @@ -125,7 +127,6 @@
|
| glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
| }
|
| _glContext = glContext;
|
| - _glRenderer = [[RTCOpenGLVideoRenderer alloc] initWithContext:_glContext];
|
|
|
| // GLKView manages a framebuffer for us.
|
| _glkView = [[GLKView alloc] initWithFrame:CGRectZero
|
| @@ -200,7 +201,29 @@
|
| - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
|
| // The renderer will draw the frame to the framebuffer corresponding to the
|
| // one used by |view|.
|
| - [_glRenderer drawFrame:self.videoFrame];
|
| + RTCVideoFrame *frame = self.videoFrame;
|
| + if (!frame || frame == _lastDrawnFrame) {
|
| + return;
|
| + }
|
| + [self ensureGLContext];
|
| + glClear(GL_COLOR_BUFFER_BIT);
|
| + id<RTCShader> shader = nil;
|
| + if (frame.nativeHandle) {
|
| + if (!_nv12Shader) {
|
| + _nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_glContext];
|
| + }
|
| + shader = _nv12Shader;
|
| + } else {
|
| + if (!_i420Shader) {
|
| + _i420Shader = [[RTCI420Shader alloc] initWithContext:_glContext];
|
| + }
|
| + shader = _i420Shader;
|
| + }
|
| + if (shader && [shader drawFrame:frame]) {
|
| + _lastDrawnFrame = frame;
|
| + } else {
|
| + RTCLog(@"Failed to draw frame.");
|
| + }
|
| }
|
|
|
| #pragma mark - RTCVideoRenderer
|
| @@ -223,7 +246,7 @@
|
| - (void)displayLinkTimerDidFire {
|
| // Don't render unless video frame have changed or the view content
|
| // has explicitly been marked dirty.
|
| - if (!_isDirty && _glRenderer.lastDrawnFrame == self.videoFrame) {
|
| + if (!_isDirty && _lastDrawnFrame == self.videoFrame) {
|
| return;
|
| }
|
|
|
| @@ -242,7 +265,8 @@
|
|
|
| - (void)setupGL {
|
| self.videoFrame = nil;
|
| - [_glRenderer setupGL];
|
| + [self ensureGLContext];
|
| + glDisable(GL_DITHER);
|
| _timer.isPaused = NO;
|
| }
|
|
|
| @@ -250,7 +274,9 @@
|
| self.videoFrame = nil;
|
| _timer.isPaused = YES;
|
| [_glkView deleteDrawable];
|
| - [_glRenderer teardownGL];
|
| + [self ensureGLContext];
|
| + _i420Shader = nil;
|
| + _nv12Shader = nil;
|
| }
|
|
|
| - (void)didBecomeActive {
|
| @@ -261,4 +287,11 @@
|
| [self teardownGL];
|
| }
|
|
|
| +- (void)ensureGLContext {
|
| + NSAssert(_glContext, @"context shouldn't be nil");
|
| + if ([EAGLContext currentContext] != _glContext) {
|
| + [EAGLContext setCurrentContext:_glContext];
|
| + }
|
| +}
|
| +
|
| @end
|
|
|