Commit 22f167dc authored by Felix Paul Kühne's avatar Felix Paul Kühne

iOS vout: move OpenGL context creation and drawing code off the main thread

This allows deployment in multi-threaded OpenGL scenarios without collisions
parent 74d8efac
...@@ -139,6 +139,7 @@ static void OpenglESSwap(vlc_gl_t *); ...@@ -139,6 +139,7 @@ static void OpenglESSwap(vlc_gl_t *);
static picture_pool_t *ZeroCopyPicturePool(vout_display_t *, unsigned); static picture_pool_t *ZeroCopyPicturePool(vout_display_t *, unsigned);
static void DestroyZeroCopyPoolPicture(picture_t *); static void DestroyZeroCopyPoolPicture(picture_t *);
static void ZeroCopyClean(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture);
static void ZeroCopyDisplay(vout_display_t *, picture_t *, subpicture_t *); static void ZeroCopyDisplay(vout_display_t *, picture_t *, subpicture_t *);
/** /**
...@@ -184,6 +185,8 @@ vlc_module_end () ...@@ -184,6 +185,8 @@ vlc_module_end ()
- (void)destroyBuffers; - (void)destroyBuffers;
- (void)resetBuffers; - (void)resetBuffers;
- (void)reshape;
- (void)setupZeroCopyGL; - (void)setupZeroCopyGL;
- (void)displayPixelBuffer:(CVPixelBufferRef)pixelBuffer; - (void)displayPixelBuffer:(CVPixelBufferRef)pixelBuffer;
@end @end
...@@ -303,7 +306,7 @@ static int Open(vlc_object_t *this) ...@@ -303,7 +306,7 @@ static int Open(vlc_object_t *this)
if (sys->zero_copy) { if (sys->zero_copy) {
vd->pool = ZeroCopyPicturePool; vd->pool = ZeroCopyPicturePool;
vd->prepare = NULL; vd->prepare = ZeroCopyClean;
vd->display = ZeroCopyDisplay; vd->display = ZeroCopyDisplay;
} else { } else {
vd->pool = PicturePool; vd->pool = PicturePool;
...@@ -328,9 +331,7 @@ static int Open(vlc_object_t *this) ...@@ -328,9 +331,7 @@ static int Open(vlc_object_t *this)
selector:@selector(applicationStateChanged:) selector:@selector(applicationStateChanged:)
name:UIApplicationDidBecomeActiveNotification name:UIApplicationDidBecomeActiveNotification
object:nil]; object:nil];
[sys->glESView performSelectorOnMainThread:@selector(reshape) [sys->glESView reshape];
withObject:nil
waitUntilDone:YES];
return VLC_SUCCESS; return VLC_SUCCESS;
bailout: bailout:
...@@ -565,6 +566,13 @@ static void DestroyZeroCopyPoolPicture(picture_t *picture) ...@@ -565,6 +566,13 @@ static void DestroyZeroCopyPoolPicture(picture_t *picture)
free(picture); free(picture);
} }
static void ZeroCopyClean(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
if (likely([sys->glESView isAppActive]))
[sys->glESView resetBuffers];
}
static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture) static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
...@@ -609,32 +617,26 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su ...@@ -609,32 +617,26 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su
if (unlikely(!_appActive)) if (unlikely(!_appActive))
return nil; return nil;
CAEAGLLayer * layer = (CAEAGLLayer *)self.layer; _eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
layer.drawableProperties = [NSDictionary dictionaryWithObject:kEAGLColorFormatRGBA8 forKey: kEAGLDrawablePropertyColorFormat];
layer.opaque = YES;
/* a client app may have already created a rendering context,
* so re-use it if it is valid */
EAGLContext *existingContext = [EAGLContext currentContext];
if (existingContext != nil)
_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: existingContext.sharegroup];
else
_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (unlikely(!_eaglContext)) if (unlikely(!_eaglContext))
return nil; return nil;
if (unlikely(![EAGLContext setCurrentContext:_eaglContext])) if (unlikely(![EAGLContext setCurrentContext:_eaglContext]))
return nil; return nil;
CAEAGLLayer *layer = (CAEAGLLayer *)self.layer;
layer.drawableProperties = [NSDictionary dictionaryWithObject:kEAGLColorFormatRGBA8 forKey: kEAGLDrawablePropertyColorFormat];
layer.opaque = YES;
_voutDisplay = vd; _voutDisplay = vd;
[self createBuffers];
if (zero_copy) { if (zero_copy) {
_preferredConversion = kColorConversion709; _preferredConversion = kColorConversion709;
[self setupZeroCopyGL]; [self setupZeroCopyGL];
} else }
[self performSelectorOnMainThread:@selector(createBuffers) withObject:nil waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(reshape) withObject:nil waitUntilDone:NO]; [self reshape];
[self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
_zeroCopy = zero_copy; _zeroCopy = zero_copy;
...@@ -705,36 +707,27 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su ...@@ -705,36 +707,27 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su
- (void)resetBuffers - (void)resetBuffers
{ {
EAGLContext *previousContext = [EAGLContext currentContext]; if (unlikely(_bufferNeedReset)) {
[EAGLContext setCurrentContext:_eaglContext]; EAGLContext *previousContext = [EAGLContext currentContext];
[EAGLContext setCurrentContext:_eaglContext];
if (_bufferNeedReset) {
[self destroyBuffers]; [self destroyBuffers];
[self createBuffers]; [self createBuffers];
_bufferNeedReset = NO; _bufferNeedReset = NO;
}
[EAGLContext setCurrentContext:previousContext]; [EAGLContext setCurrentContext:previousContext];
}
} }
- (void)layoutSubviews - (void)layoutSubviews
{ {
[self reshape]; [self reshape];
if (_zeroCopy) {
/* we don't have a clean event for 0-copy, so destory and re-create right here */ _bufferNeedReset = YES;
[self destroyBuffers];
[self createBuffers];
} else {
/* this method is called as soon as we are resized.
* so set a variable to re-create our buffers on the next clean event */
_bufferNeedReset = YES;
}
} }
- (void)reshape - (void)reshape
{ {
assert([[NSThread currentThread] isMainThread]);
EAGLContext *previousContext = [EAGLContext currentContext]; EAGLContext *previousContext = [EAGLContext currentContext];
[EAGLContext setCurrentContext:_eaglContext]; [EAGLContext setCurrentContext:_eaglContext];
...@@ -958,7 +951,6 @@ done: ...@@ -958,7 +951,6 @@ done:
{ {
EAGLContext *previousContext = [EAGLContext currentContext]; EAGLContext *previousContext = [EAGLContext currentContext];
[EAGLContext setCurrentContext:_eaglContext]; [EAGLContext setCurrentContext:_eaglContext];
[self createBuffers];
[self loadShaders]; [self loadShaders];
glUseProgram(self.shaderProgram); glUseProgram(self.shaderProgram);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment