vlc | branch: master | Thomas Guillem <tho...@gllm.fr> | Tue Mar 6 10:32:48 2018 +0100| [a0df71911458b6ca9ef2f659e19eabdb8f51e790] | committer: Thomas Guillem
vout: ios: don't wait for the MainThread from Control callback > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a0df71911458b6ca9ef2f659e19eabdb8f51e790 --- modules/video_output/ios.m | 217 ++++++++++++++++++++------------------------- 1 file changed, 96 insertions(+), 121 deletions(-) diff --git a/modules/video_output/ios.m b/modules/video_output/ios.m index 31fad7fbfa..3e3bb15c7f 100644 --- a/modules/video_output/ios.m +++ b/modules/video_output/ios.m @@ -95,9 +95,15 @@ vlc_module_end () BOOL _bufferNeedReset; BOOL _appActive; + BOOL _placeInvalidated; /* Written from MT, read locked from vout */ vout_display_place_t _place; + CGSize _viewSize; + CGFloat _scaleFactor; + + /* Written from vout, read locked from MT */ + vout_display_cfg_t _cfg; } @property (readonly) GLuint renderBuffer; @property (readonly) GLuint frameBuffer; @@ -107,14 +113,14 @@ vlc_module_end () - (id)initWithFrameAndVd:(CGRect)frame withVd:(vout_display_t*)vd; - (void)createBuffers; - (void)destroyBuffers; -- (void)resetBuffers; - (BOOL)makeCurrent:(EAGLContext **)previousEaglContext; +- (BOOL)makeCurrentWithGL:(EAGLContext **)previousEaglContext withGL:(vlc_gl_t *)gl; - (void)releaseCurrent:(EAGLContext *)previousEaglContext; -- (void)setPlace:(const vout_display_place_t *)place; +- (void)updateVoutCfg:(const vout_display_cfg_t *)cfg withVGL:(vout_display_opengl_t *)vgl; +- (void)getPlaceLocked:(vout_display_place_t *)place; - (void)reshape; - (void)propagateDimensionsToVoutCore; -- (CGSize)viewSize; @end struct vout_display_sys_t @@ -296,50 +302,18 @@ static int Control(vout_display_t *vd, int query, va_list ap) case VOUT_DISPLAY_CHANGE_SOURCE_CROP: case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: { - if (!vd->sys) - return VLC_EGENERIC; - - @autoreleasepool { - const vout_display_cfg_t *cfg; - - if (vlc_gl_MakeCurrent(sys->gl) != VLC_SUCCESS) - return VLC_EGENERIC; - - if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT || - query == VOUT_DISPLAY_CHANGE_SOURCE_CROP) { - cfg = vd->cfg; - } else { - cfg = (const vout_display_cfg_t*)va_arg(ap, const vout_display_cfg_t *); - } - - /* we don't adapt anything here regardless of what the vout core - * wants since we are not in a traditional desktop window */ - if (!cfg) - return VLC_EGENERIC; + const vout_display_cfg_t *cfg; - vout_display_cfg_t cfg_tmp = *cfg; - CGSize viewSize; - viewSize = [sys->glESView viewSize]; + if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT || + query == VOUT_DISPLAY_CHANGE_SOURCE_CROP) + cfg = vd->cfg; + else + cfg = (const vout_display_cfg_t*)va_arg(ap, const vout_display_cfg_t *); - /* on HiDPI displays, the point bounds don't equal the actual pixels */ - CGFloat scaleFactor = sys->glESView.contentScaleFactor; - cfg_tmp.display.width = viewSize.width * scaleFactor; - cfg_tmp.display.height = viewSize.height * scaleFactor; + assert(cfg); - vout_display_place_t place; - vout_display_PlacePicture(&place, &vd->source, &cfg_tmp, false); + [sys->glESView updateVoutCfg:cfg withVGL:glsys->vgl]; - [sys->glESView setPlace:&place]; - - vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)place.width / place.height); - - // x / y are top left corner, but we need the lower left one - if (query != VOUT_DISPLAY_CHANGE_DISPLAY_SIZE) - vout_display_opengl_Viewport(sys->vgl, place.x, - cfg_tmp.display.height - (place.y + place.height), - place.width, place.height); - vlc_gl_ReleaseCurrent(sys->gl); - } return VLC_SUCCESS; } @@ -404,10 +378,8 @@ static int GLESMakeCurrent(vlc_gl_t *gl) { struct gl_sys *sys = gl->sys; - if (![sys->glESView makeCurrent:&sys->previousEaglContext]) + if (![sys->glESView makeCurrentWithGL:&sys->previousEaglContext withGL:gl]) return VLC_EGENERIC; - - [sys->glESView resetBuffers]; return VLC_SUCCESS; } @@ -456,6 +428,7 @@ static void GLESSwap(vlc_gl_t *gl) return nil; _voutDisplay = vd; + _cfg = *_voutDisplay->cfg; vlc_mutex_init(&_mutex); @@ -553,7 +526,10 @@ static void GLESSwap(vlc_gl_t *gl) - (void)didMoveToWindow { self.contentScaleFactor = self.window.screen.scale; + + vlc_mutex_lock(&_mutex); _bufferNeedReset = YES; + vlc_mutex_unlock(&_mutex); } - (void)createBuffers @@ -612,16 +588,7 @@ static void GLESSwap(vlc_gl_t *gl) [self releaseCurrent:previousEaglContext]; } -- (void)resetBuffers -{ - if (unlikely(_bufferNeedReset)) { - [self destroyBuffers]; - [self createBuffers]; - _bufferNeedReset = NO; - } -} - -- (BOOL)makeCurrent:(EAGLContext **)previousEaglContext +- (BOOL)makeCurrentWithGL:(EAGLContext **)previousEaglContext withGL:(vlc_gl_t *)gl { vlc_mutex_lock(&_mutex); @@ -634,11 +601,45 @@ static void GLESSwap(vlc_gl_t *gl) *previousEaglContext = [EAGLContext currentContext]; BOOL success = [EAGLContext setCurrentContext:_eaglContext]; + BOOL resetBuffers = NO; + + if (success && gl != NULL) + { + struct gl_sys *glsys = gl->sys; + + if (unlikely(_bufferNeedReset)) + { + _bufferNeedReset = NO; + resetBuffers = YES; + } + if (unlikely(_placeInvalidated && glsys->vgl)) + { + _placeInvalidated = NO; + + vout_display_place_t place; + [self getPlaceLocked: &place]; + vout_display_opengl_SetWindowAspectRatio(glsys->vgl, (float)place.width / place.height); + + // x / y are top left corner, but we need the lower left one + glViewport(_place.x, _place.y, _place.width, _place.height); + } + } vlc_mutex_unlock(&_mutex); + + if (resetBuffers) + { + [self destroyBuffers]; + [self createBuffers]; + } return success; } +- (BOOL)makeCurrent:(EAGLContext **)previousEaglContext +{ + return [self makeCurrentWithGL:previousEaglContext withGL:nil]; +} + - (void)releaseCurrent:(EAGLContext *)previousEaglContext { [EAGLContext setCurrentContext:previousEaglContext]; @@ -648,7 +649,19 @@ static void GLESSwap(vlc_gl_t *gl) { [self reshape]; + vlc_mutex_lock(&_mutex); _bufferNeedReset = YES; + vlc_mutex_unlock(&_mutex); +} + +- (void)getPlaceLocked:(vout_display_place_t *)place +{ + vout_display_cfg_t cfg = _cfg; + + cfg.display.width = _viewSize.width * _scaleFactor; + cfg.display.height = _viewSize.height * _scaleFactor; + + vout_display_PlacePicture(place, &_voutDisplay->source, &cfg, false); } - (void)reshape @@ -661,27 +674,22 @@ static void GLESSwap(vlc_gl_t *gl) return; } - EAGLContext *previousEaglContext; - if (![self makeCurrent:&previousEaglContext]) - return; + vlc_mutex_lock(&_mutex); + _viewSize = [self bounds].size; + _scaleFactor = self.contentScaleFactor; - CGSize viewSize = [self bounds].size; - CGFloat scaleFactor = self.contentScaleFactor; vout_display_place_t place; + [self getPlaceLocked: &place]; - vout_display_cfg_t cfg_tmp = *(_voutDisplay->cfg); - - cfg_tmp.display.width = viewSize.width * scaleFactor; - cfg_tmp.display.height = viewSize.height * scaleFactor; - - vout_display_PlacePicture(&place, &_voutDisplay->source, &cfg_tmp, false); - vout_display_SendEventDisplaySize(_voutDisplay, viewSize.width * scaleFactor, - viewSize.height * scaleFactor); - [self setPlace:&place]; + if (memcmp(&place, &_place, sizeof(vout_display_place_t)) != 0) + { + _placeInvalidated = YES; + _place = place; + } + vout_display_SendEventDisplaySize(_voutDisplay, _viewSize.width * _scaleFactor, + _viewSize.height * _scaleFactor); - // x / y are top left corner, but we need the lower left one - glViewport(place.x, place.y, place.width, place.height); - [self releaseCurrent:previousEaglContext]; + vlc_mutex_unlock(&_mutex); } - (void)tapRecognized:(UITapGestureRecognizer *)tapRecognizer @@ -689,22 +697,31 @@ static void GLESSwap(vlc_gl_t *gl) UIGestureRecognizerState state = [tapRecognizer state]; CGPoint touchPoint = [tapRecognizer locationInView:self]; CGFloat scaleFactor = self.contentScaleFactor; - vlc_mutex_lock(&_mutex); - vout_display_place_t place = _place; - vlc_mutex_unlock(&_mutex); vout_display_SendMouseMovedDisplayCoordinates(_voutDisplay, ORIENT_NORMAL, (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor, - &place); + &_place); vout_display_SendEventMousePressed(_voutDisplay, MOUSE_BUTTON_LEFT); vout_display_SendEventMouseReleased(_voutDisplay, MOUSE_BUTTON_LEFT); } -- (void)setPlace:(const vout_display_place_t *)place +- (void)updateVoutCfg:(const vout_display_cfg_t *)cfg withVGL:(vout_display_opengl_t *)vgl { + if (memcmp(&_cfg, cfg, sizeof(vout_display_cfg_t)) == 0) + return; + vlc_mutex_lock(&_mutex); - _place = *place; + _cfg = *cfg; + + vout_display_place_t place; + [self getPlaceLocked: &place]; + vout_display_opengl_SetWindowAspectRatio(vgl, (float)place.width / place.height); + vlc_mutex_unlock(&_mutex); + + [self performSelectorOnMainThread:@selector(setNeedsUpdateConstraints) + withObject:nil + waitUntilDone:NO]; } - (void)applicationStateChanged:(NSNotification *)notification @@ -748,46 +765,4 @@ static void GLESSwap(vlc_gl_t *gl) vout_display_SendEventDisplaySize(_voutDisplay, viewSize.width * scaleFactor, viewSize.height * scaleFactor); } -- (void)mainThreadContentScaleFactor:(NSNumber *)scaleFactor -{ - id *ret = [scaleFactor pointerValue]; - *ret = [[NSNumber alloc] initWithFloat:[super contentScaleFactor]]; -} - -- (CGFloat)contentScaleFactor -{ - if ([NSThread isMainThread]) { - return [super contentScaleFactor]; - } - - NSNumber *scaleFactor; - [self performSelectorOnMainThread:@selector(mainThreadContentScaleFactor:) - withObject:[NSValue valueWithPointer:&scaleFactor] - waitUntilDone:YES]; - CGFloat ret = [scaleFactor floatValue]; - [scaleFactor release]; - return ret; -} - -- (void)mainThreadViewBounds:(NSValue *)viewBoundsString -{ - id *ret = [viewBoundsString pointerValue]; - *ret = [NSStringFromCGRect([super bounds]) retain]; -} - -- (CGSize)viewSize -{ - if ([NSThread isMainThread]) { - return self.bounds.size; - } - - NSString *viewBoundsString; - [self performSelectorOnMainThread:@selector(mainThreadViewBounds:) - withObject:[NSValue valueWithPointer:&viewBoundsString] - waitUntilDone:YES]; - CGRect bounds = CGRectFromString(viewBoundsString); - [viewBoundsString release]; - return bounds.size; -} - @end _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits