Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m

Issue 2812613003: ObjC: Remove RTCOpenGLVideoRenderer (Closed)
Patch Set: Fix pointer typo and add include. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/BUILD.gn ('k') | webrtc/sdk/objc/Framework/Classes/RTCI420Shader.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #import "WebRTC/RTCEAGLVideoView.h" 11 #import "WebRTC/RTCEAGLVideoView.h"
12 12
13 #import <GLKit/GLKit.h> 13 #import <GLKit/GLKit.h>
14 14
15 #import "RTCOpenGLVideoRenderer.h" 15 #import "RTCShader+Private.h"
16 #import "WebRTC/RTCLogging.h"
16 #import "WebRTC/RTCVideoFrame.h" 17 #import "WebRTC/RTCVideoFrame.h"
17 18
18 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen 19 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen
19 // refreshes, which should be 30fps. We wrap the display link in order to avoid 20 // refreshes, which should be 30fps. We wrap the display link in order to avoid
20 // a retain cycle since CADisplayLink takes a strong reference onto its target. 21 // a retain cycle since CADisplayLink takes a strong reference onto its target.
21 // The timer is paused by default. 22 // The timer is paused by default.
22 @interface RTCDisplayLinkTimer : NSObject 23 @interface RTCDisplayLinkTimer : NSObject
23 24
24 @property(nonatomic) BOOL isPaused; 25 @property(nonatomic) BOOL isPaused;
25 26
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 // the method that will trigger the binding of the render 82 // the method that will trigger the binding of the render
82 // buffer. Because the standard behaviour of -[UIView setNeedsDisplay] 83 // buffer. Because the standard behaviour of -[UIView setNeedsDisplay]
83 // is disabled for the reasons above, the RTCEAGLVideoView maintains 84 // is disabled for the reasons above, the RTCEAGLVideoView maintains
84 // its own |isDirty| flag. 85 // its own |isDirty| flag.
85 86
86 @interface RTCEAGLVideoView () <GLKViewDelegate> 87 @interface RTCEAGLVideoView () <GLKViewDelegate>
87 // |videoFrame| is set when we receive a frame from a worker thread and is read 88 // |videoFrame| is set when we receive a frame from a worker thread and is read
88 // from the display link callback so atomicity is required. 89 // from the display link callback so atomicity is required.
89 @property(atomic, strong) RTCVideoFrame *videoFrame; 90 @property(atomic, strong) RTCVideoFrame *videoFrame;
90 @property(nonatomic, readonly) GLKView *glkView; 91 @property(nonatomic, readonly) GLKView *glkView;
91 @property(nonatomic, readonly) RTCOpenGLVideoRenderer *glRenderer;
92 @end 92 @end
93 93
94 @implementation RTCEAGLVideoView { 94 @implementation RTCEAGLVideoView {
95 RTCDisplayLinkTimer *_timer; 95 RTCDisplayLinkTimer *_timer;
96 EAGLContext *_glContext; 96 EAGLContext *_glContext;
97 // This flag should only be set and read on the main thread (e.g. by 97 // This flag should only be set and read on the main thread (e.g. by
98 // setNeedsDisplay) 98 // setNeedsDisplay)
99 BOOL _isDirty; 99 BOOL _isDirty;
100 id<RTCShader> _i420Shader;
101 id<RTCShader> _nv12Shader;
102 RTCVideoFrame *_lastDrawnFrame;
100 } 103 }
101 104
102 @synthesize delegate = _delegate; 105 @synthesize delegate = _delegate;
103 @synthesize videoFrame = _videoFrame; 106 @synthesize videoFrame = _videoFrame;
104 @synthesize glkView = _glkView; 107 @synthesize glkView = _glkView;
105 @synthesize glRenderer = _glRenderer;
106 108
107 - (instancetype)initWithFrame:(CGRect)frame { 109 - (instancetype)initWithFrame:(CGRect)frame {
108 if (self = [super initWithFrame:frame]) { 110 if (self = [super initWithFrame:frame]) {
109 [self configure]; 111 [self configure];
110 } 112 }
111 return self; 113 return self;
112 } 114 }
113 115
114 - (instancetype)initWithCoder:(NSCoder *)aDecoder { 116 - (instancetype)initWithCoder:(NSCoder *)aDecoder {
115 if (self = [super initWithCoder:aDecoder]) { 117 if (self = [super initWithCoder:aDecoder]) {
116 [self configure]; 118 [self configure];
117 } 119 }
118 return self; 120 return self;
119 } 121 }
120 122
121 - (void)configure { 123 - (void)configure {
122 EAGLContext *glContext = 124 EAGLContext *glContext =
123 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; 125 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
124 if (!glContext) { 126 if (!glContext) {
125 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 127 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
126 } 128 }
127 _glContext = glContext; 129 _glContext = glContext;
128 _glRenderer = [[RTCOpenGLVideoRenderer alloc] initWithContext:_glContext];
129 130
130 // GLKView manages a framebuffer for us. 131 // GLKView manages a framebuffer for us.
131 _glkView = [[GLKView alloc] initWithFrame:CGRectZero 132 _glkView = [[GLKView alloc] initWithFrame:CGRectZero
132 context:_glContext]; 133 context:_glContext];
133 _glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 134 _glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
134 _glkView.drawableDepthFormat = GLKViewDrawableDepthFormatNone; 135 _glkView.drawableDepthFormat = GLKViewDrawableDepthFormatNone;
135 _glkView.drawableStencilFormat = GLKViewDrawableStencilFormatNone; 136 _glkView.drawableStencilFormat = GLKViewDrawableStencilFormatNone;
136 _glkView.drawableMultisample = GLKViewDrawableMultisampleNone; 137 _glkView.drawableMultisample = GLKViewDrawableMultisampleNone;
137 _glkView.delegate = self; 138 _glkView.delegate = self;
138 _glkView.layer.masksToBounds = YES; 139 _glkView.layer.masksToBounds = YES;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 _glkView.frame = self.bounds; 194 _glkView.frame = self.bounds;
194 } 195 }
195 196
196 #pragma mark - GLKViewDelegate 197 #pragma mark - GLKViewDelegate
197 198
198 // This method is called when the GLKView's content is dirty and needs to be 199 // This method is called when the GLKView's content is dirty and needs to be
199 // redrawn. This occurs on main thread. 200 // redrawn. This occurs on main thread.
200 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 201 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
201 // The renderer will draw the frame to the framebuffer corresponding to the 202 // The renderer will draw the frame to the framebuffer corresponding to the
202 // one used by |view|. 203 // one used by |view|.
203 [_glRenderer drawFrame:self.videoFrame]; 204 RTCVideoFrame *frame = self.videoFrame;
205 if (!frame || frame == _lastDrawnFrame) {
206 return;
207 }
208 [self ensureGLContext];
209 glClear(GL_COLOR_BUFFER_BIT);
210 id<RTCShader> shader = nil;
211 if (frame.nativeHandle) {
212 if (!_nv12Shader) {
213 _nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_glContext];
214 }
215 shader = _nv12Shader;
216 } else {
217 if (!_i420Shader) {
218 _i420Shader = [[RTCI420Shader alloc] initWithContext:_glContext];
219 }
220 shader = _i420Shader;
221 }
222 if (shader && [shader drawFrame:frame]) {
223 _lastDrawnFrame = frame;
224 } else {
225 RTCLog(@"Failed to draw frame.");
226 }
204 } 227 }
205 228
206 #pragma mark - RTCVideoRenderer 229 #pragma mark - RTCVideoRenderer
207 230
208 // These methods may be called on non-main thread. 231 // These methods may be called on non-main thread.
209 - (void)setSize:(CGSize)size { 232 - (void)setSize:(CGSize)size {
210 __weak RTCEAGLVideoView *weakSelf = self; 233 __weak RTCEAGLVideoView *weakSelf = self;
211 dispatch_async(dispatch_get_main_queue(), ^{ 234 dispatch_async(dispatch_get_main_queue(), ^{
212 RTCEAGLVideoView *strongSelf = weakSelf; 235 RTCEAGLVideoView *strongSelf = weakSelf;
213 [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size]; 236 [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size];
214 }); 237 });
215 } 238 }
216 239
217 - (void)renderFrame:(RTCVideoFrame *)frame { 240 - (void)renderFrame:(RTCVideoFrame *)frame {
218 self.videoFrame = frame; 241 self.videoFrame = frame;
219 } 242 }
220 243
221 #pragma mark - Private 244 #pragma mark - Private
222 245
223 - (void)displayLinkTimerDidFire { 246 - (void)displayLinkTimerDidFire {
224 // Don't render unless video frame have changed or the view content 247 // Don't render unless video frame have changed or the view content
225 // has explicitly been marked dirty. 248 // has explicitly been marked dirty.
226 if (!_isDirty && _glRenderer.lastDrawnFrame == self.videoFrame) { 249 if (!_isDirty && _lastDrawnFrame == self.videoFrame) {
227 return; 250 return;
228 } 251 }
229 252
230 // Always reset isDirty at this point, even if -[GLKView display] 253 // Always reset isDirty at this point, even if -[GLKView display]
231 // won't be called in the case the drawable size is empty. 254 // won't be called in the case the drawable size is empty.
232 _isDirty = NO; 255 _isDirty = NO;
233 256
234 // Only call -[GLKView display] if the drawable size is 257 // Only call -[GLKView display] if the drawable size is
235 // non-empty. Calling display will make the GLKView setup its 258 // non-empty. Calling display will make the GLKView setup its
236 // render buffer if necessary, but that will fail with error 259 // render buffer if necessary, but that will fail with error
237 // GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT if size is empty. 260 // GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT if size is empty.
238 if (self.bounds.size.width > 0 && self.bounds.size.height > 0) { 261 if (self.bounds.size.width > 0 && self.bounds.size.height > 0) {
239 [_glkView display]; 262 [_glkView display];
240 } 263 }
241 } 264 }
242 265
243 - (void)setupGL { 266 - (void)setupGL {
244 self.videoFrame = nil; 267 self.videoFrame = nil;
245 [_glRenderer setupGL]; 268 [self ensureGLContext];
269 glDisable(GL_DITHER);
246 _timer.isPaused = NO; 270 _timer.isPaused = NO;
247 } 271 }
248 272
249 - (void)teardownGL { 273 - (void)teardownGL {
250 self.videoFrame = nil; 274 self.videoFrame = nil;
251 _timer.isPaused = YES; 275 _timer.isPaused = YES;
252 [_glkView deleteDrawable]; 276 [_glkView deleteDrawable];
253 [_glRenderer teardownGL]; 277 [self ensureGLContext];
278 _i420Shader = nil;
279 _nv12Shader = nil;
254 } 280 }
255 281
256 - (void)didBecomeActive { 282 - (void)didBecomeActive {
257 [self setupGL]; 283 [self setupGL];
258 } 284 }
259 285
260 - (void)willResignActive { 286 - (void)willResignActive {
261 [self teardownGL]; 287 [self teardownGL];
262 } 288 }
263 289
290 - (void)ensureGLContext {
291 NSAssert(_glContext, @"context shouldn't be nil");
292 if ([EAGLContext currentContext] != _glContext) {
293 [EAGLContext setCurrentContext:_glContext];
294 }
295 }
296
264 @end 297 @end
OLDNEW
« no previous file with comments | « webrtc/sdk/BUILD.gn ('k') | webrtc/sdk/objc/Framework/Classes/RTCI420Shader.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698