[vlc-devel] [PATCH v3 10/10] VLCOpenGLES2VideoView: handle UIView resize

Alexandre Janniaux ajanni at videolabs.io
Tue Feb 16 15:25:50 UTC 2021


The UIView resize was previously handled using mostly UIView framework.
This is now forwarded by the vout_window through the vout_window_Report*
mechanism, under display_lock, mimicking the behaviour of every other
window system integration.

Because no feedback is currently forwarded to the window when the vout
thread has drawn something, it means that we cannot synchronize the
rendering with the end of the resize event from the main thread, so the
resize is out-of-sync.

Having the UIView being resized by the resize callback is necessary
though to move the generation of buffers out of the MakeCurrent callback
and making it not faillible.
---
 .../apple/VLCOpenGLES2VideoView.m             | 64 +++++++++++--------
 1 file changed, 38 insertions(+), 26 deletions(-)

diff --git a/modules/video_output/apple/VLCOpenGLES2VideoView.m b/modules/video_output/apple/VLCOpenGLES2VideoView.m
index 394fb513ca..8be77ed48b 100644
--- a/modules/video_output/apple/VLCOpenGLES2VideoView.m
+++ b/modules/video_output/apple/VLCOpenGLES2VideoView.m
@@ -68,6 +68,7 @@
 
     GLuint _renderBuffer;
     GLuint _frameBuffer;
+    CGSize _size;
 
     struct vlc_gl_api _api;
 }
@@ -78,6 +79,7 @@
 - (void)presentRenderbuffer;
 - (void)didMoveToWindow;
 - (void)detachFromWindow;
+- (void)resize:(CGSize)size;
 @end
 
 /*****************************************************************************
@@ -115,6 +117,8 @@ static void Resize(vlc_gl_t *gl, unsigned width, unsigned height)
     VLC_UNUSED(gl); VLC_UNUSED(width); VLC_UNUSED(height);
     /* Use the parent frame size for now, resize is smoother and called
      * automatically from the main thread queue. */
+    VLCOpenGLES2VideoView *view = (__bridge VLCOpenGLES2VideoView *)gl->sys;
+    [view resize:CGSizeMake(width, height)];
 }
 
 static void Close(vlc_gl_t *gl)
@@ -167,8 +171,6 @@ static void Close(vlc_gl_t *gl)
     _layer.opaque = YES;
 
     /* Resize is done accordingly to the parent frame directly. */
-    self.autoresizingMask = UIViewAutoresizingFlexibleWidth
-                          | UIViewAutoresizingFlexibleHeight;
     self.contentMode = UIViewContentModeScaleToFill;
 
     /* Connect to the parent UIView which will contain this surface.
@@ -191,6 +193,8 @@ static void Close(vlc_gl_t *gl)
                                              selector:@selector(applicationStateChanged:)
                                                  name:UIApplicationDidBecomeActiveNotification
                                                object:nil];
+    if (_appActive)
+        [self resize:CGSizeMake(frame.size.width, frame.size.height)];
 
     /* Setup the usual vlc_gl_t callbacks before loading the API since we need
      * the get_proc_address symbol and a current context. */
@@ -287,7 +291,7 @@ static void Close(vlc_gl_t *gl)
     vlc_mutex_unlock(&_mutex);
 }
 
-- (BOOL)doResetBuffers:(vlc_gl_t *)gl
+- (BOOL)doResetBuffers
 {
     if (_frameBuffer != 0)
     {
@@ -334,28 +338,10 @@ static void Close(vlc_gl_t *gl)
     _previousEaglContext = [EAGLContext currentContext];
 
     assert(_eaglContext);
-    if (![EAGLContext setCurrentContext:_eaglContext])
-    {
-        vlc_mutex_unlock(&_mutex);
-        return NO;
-    }
-
-    BOOL resetBuffers = NO;
-
-
-    if (unlikely(_bufferNeedReset))
-    {
-        _bufferNeedReset = NO;
-        resetBuffers = YES;
-    }
+    BOOL result = [EAGLContext setCurrentContext:_eaglContext];
+    assert(result == YES);
 
     _gl_attached = YES;
-
-    if (resetBuffers && ![self doResetBuffers:_gl])
-    {
-        [self releaseCurrent];
-        return NO;
-    }
     return YES;
 }
 
@@ -367,9 +353,8 @@ static void Close(vlc_gl_t *gl)
     _gl_attached = NO;
     [EAGLContext setCurrentContext:_previousEaglContext];
     _previousEaglContext = nil;
-
-    vlc_mutex_unlock(&_mutex);
     vlc_cond_signal(&_gl_attached_wait);
+    vlc_mutex_unlock(&_mutex);
 }
 
 - (void)presentRenderbuffer
@@ -377,6 +362,32 @@ static void Close(vlc_gl_t *gl)
     [_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
 }
 
+- (void)resize:(CGSize)size
+{
+    vlc_mutex_lock(&_mutex);
+    _size = size;
+
+    CGRect rect = self.bounds;
+    rect.size = size;
+    /* Bitmap size = view size * contentScaleFactor, so we need to divide the
+     * scale factor to get the real view size. */
+    rect.size.width /= self.contentScaleFactor;
+    rect.size.height /= self.contentScaleFactor;
+
+    self.bounds = rect;
+
+    /* If size is NULL, rendering must be disabled */
+    if (size.width != 0 && size.height != 0)
+    {
+        EAGLContext *previousContext = [EAGLContext currentContext];
+        [EAGLContext setCurrentContext:_eaglContext];
+        [self doResetBuffers];
+        [EAGLContext setCurrentContext:previousContext];
+    }
+
+    vlc_mutex_unlock(&_mutex);
+}
+
 - (void)layoutSubviews
 {
     vlc_mutex_lock(&_mutex);
@@ -421,6 +432,7 @@ static void Close(vlc_gl_t *gl)
     else if ([[notification name] isEqualToString:UIApplicationWillEnterForegroundNotification])
     {
         _eaglEnabled = YES;
+        [self resize:self.frame.size];
         _appActive = YES;
     }
 
@@ -461,7 +473,7 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
         dispatch_sync(dispatch_get_main_queue(), ^{
             gl->sys = (__bridge_retained void*)[[VLCOpenGLES2VideoView alloc]
                // TODO better rect
-               initWithFrame:CGRectMake(0.,0.,320.,240.) gl:gl];
+               initWithFrame:CGRectMake(0.,0.,width,height) gl:gl];
         });
 
         if (gl->sys == NULL)
-- 
2.30.1



More information about the vlc-devel mailing list