Index: webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m |
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m b/webrtc/sdk/objc/Framework/Classes/RTCNSGLVideoView.m |
index 18dc4d1315aad0c9906dddfefe55c8c948b8cc02..530d9a7e6a195e1d00afc10428f9e9a88b093d47 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 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, |
@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 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, |
- (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 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, |
#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 @@ static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink, |
_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 |