ObjC: Remove RTCOpenGLVideoRenderer

RTCOpenGLVideoRenderer is currently shared between RTCEAGLVideoView and
RTCNSGLVideoView, and contains some iOS specific code and some Mac
specific code. We plan on adding an interface for injectable OpenGL ES
shaders to RTCEAGLVideoView, and it's easier if RTCEAGLVideoView and
RTCNSGLVideoView have separate code paths. This CL removes
RTCOpenGLVideoRenderer and inlines the necessary code in
RTCEAGLVideoView and RTCNSGLVideoView.

BUG=webrtc:7473

Review-Url: https://codereview.webrtc.org/2812613003
Cr-Commit-Position: refs/heads/master@{#17693}
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m b/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m
index 18dc4d1..530d9a7 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m
+++ b/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m
@@ -14,17 +14,20 @@
 
 #import "WebRTC/RTCNSGLVideoView.h"
 
+#import <AppKit/NSOpenGL.h>
 #import <CoreVideo/CVDisplayLink.h>
 #import <OpenGL/gl3.h>
 
-#import "RTCOpenGLVideoRenderer.h"
+#import "RTCShader+Private.h"
+#import "WebRTC/RTCLogging.h"
 #import "WebRTC/RTCVideoFrame.h"
 
 @interface RTCNSGLVideoView ()
 // |videoFrame| is set when we receive a frame from a worker thread and is read
 // from the display link callback so atomicity is required.
 @property(atomic, strong) RTCVideoFrame *videoFrame;
-@property(atomic, strong) RTCOpenGLVideoRenderer *glRenderer;
+@property(atomic, strong) id<RTCShader> i420Shader;
+
 - (void)drawFrame;
 @end
 
@@ -41,11 +44,12 @@
 
 @implementation RTCNSGLVideoView {
   CVDisplayLinkRef _displayLink;
+  RTCVideoFrame *_lastDrawnFrame;
 }
 
 @synthesize delegate = _delegate;
 @synthesize videoFrame = _videoFrame;
-@synthesize glRenderer = _glRenderer;
+@synthesize i420Shader = _i420Shader;
 
 - (void)dealloc {
   [self teardownDisplayLink];
@@ -74,17 +78,14 @@
 
 - (void)prepareOpenGL {
   [super prepareOpenGL];
-  if (!self.glRenderer) {
-    self.glRenderer =
-        [[RTCOpenGLVideoRenderer alloc] initWithContext:[self openGLContext]];
-  }
-  [self.glRenderer setupGL];
+  [self ensureGLContext];
+  glDisable(GL_DITHER);
   [self setupDisplayLink];
 }
 
 - (void)clearGLContext {
-  [self.glRenderer teardownGL];
-  self.glRenderer = nil;
+  [self ensureGLContext];
+  self.i420Shader = nil;
   [super clearGLContext];
 }
 
@@ -104,14 +105,30 @@
 #pragma mark - Private
 
 - (void)drawFrame {
-  RTCVideoFrame *videoFrame = self.videoFrame;
-  if (self.glRenderer.lastDrawnFrame != videoFrame) {
-    // This method may be called from CVDisplayLink callback which isn't on the
-    // main thread so we have to lock the GL context before drawing.
-    CGLLockContext([[self openGLContext] CGLContextObj]);
-    [self.glRenderer drawFrame:videoFrame];
-    CGLUnlockContext([[self openGLContext] CGLContextObj]);
+  RTCVideoFrame *frame = self.videoFrame;
+  if (!frame || frame == _lastDrawnFrame) {
+    return;
   }
+  // This method may be called from CVDisplayLink callback which isn't on the
+  // main thread so we have to lock the GL context before drawing.
+  NSOpenGLContext *context = [self openGLContext];
+  CGLLockContext([context CGLContextObj]);
+
+  [self ensureGLContext];
+  glClear(GL_COLOR_BUFFER_BIT);
+
+  // Rendering native CVPixelBuffer is not supported on OS X.
+  frame = [frame newI420VideoFrame];
+  if (!self.i420Shader) {
+    self.i420Shader = [[RTCI420Shader alloc] initWithContext:context];
+  }
+  if (self.i420Shader && [self.i420Shader drawFrame:frame]) {
+    [context flushBuffer];
+    _lastDrawnFrame = frame;
+  } else {
+    RTCLog(@"Failed to draw frame.");
+  }
+  CGLUnlockContext([context CGLContextObj]);
 }
 
 - (void)setupDisplayLink {
@@ -143,6 +160,14 @@
   _displayLink = NULL;
 }
 
+- (void)ensureGLContext {
+  NSOpenGLContext* context = [self openGLContext];
+  NSAssert(context, @"context shouldn't be nil");
+  if ([NSOpenGLContext currentContext] != context) {
+    [context makeCurrentContext];
+  }
+}
+
 @end
 
 #endif  // !TARGET_OS_IPHONE