diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm index ef1040c8457..8d10bcf0de7 100644 --- a/backends/platform/ios7/ios7_osys_video.mm +++ b/backends/platform/ios7/ios7_osys_video.mm @@ -276,33 +276,26 @@ bool OSystem_iOS7::isKeyboardShown() const { } uint OSystem_iOS7::createOpenGLContext() { - // TODO: Implement creation of OpenGL context - // The context will be used by scummvm system running on - // background thread. - return 0; + return [[iOS7AppDelegate iPhoneView] createOpenGLContext]; } void OSystem_iOS7::destroyOpenGLContext() { - // TODO: Implement destroy of OpenGL context + [[iOS7AppDelegate iPhoneView] destroyOpenGLContext]; } void OSystem_iOS7::refreshScreen() const { - // TODO: Implement presentation of the renderBuffer - // Present the renderBuffer on the openGLContext + [[iOS7AppDelegate iPhoneView] refreshScreen]; } int OSystem_iOS7::getScreenWidth() const { - // TODO: Return width of screen buffer - return 0; + return [[iOS7AppDelegate iPhoneView] getScreenWidth]; } int OSystem_iOS7::getScreenHeight() const { - // TODO: Return height of screen buffer - return 0; + return [[iOS7AppDelegate iPhoneView] getScreenHeight]; } float OSystem_iOS7::getSystemHiDPIScreenFactor() const { - // TODO: Return HiDPI screen factor - return 0.0; + return [[UIScreen mainScreen] scale]; } diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h index f790110a0cd..d36a97320de 100644 --- a/backends/platform/ios7/ios7_video.h +++ b/backends/platform/ios7/ios7_video.h @@ -54,7 +54,8 @@ uint getSizeNextPOT(uint size); UIBackgroundTaskIdentifier _backgroundSaveStateTask; - EAGLContext *_context; + EAGLContext *_mainContext; + EAGLContext *_openGLContext; GLuint _viewRenderbuffer; GLuint _viewFramebuffer; GLuint _screenTexture; @@ -100,6 +101,12 @@ uint getSizeNextPOT(uint size); - (VideoContext *)getVideoContext; +- (uint)createOpenGLContext; +- (void)destroyOpenGLContext; +- (void)refreshScreen; +- (int)getScreenWidth; +- (int)getScreenHeight; + - (void)setGameScreenCoords; - (void)initSurface; - (void)setViewTransformation; diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm index 6d12886efd5..6c57d2823be 100644 --- a/backends/platform/ios7/ios7_video.mm +++ b/backends/platform/ios7/ios7_video.mm @@ -123,22 +123,56 @@ uint getSizeNextPOT(uint size) { kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8, }; - _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + _mainContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; // In case creating the OpenGL ES context failed, we will error out here. - if (_context == nil) { + if (_mainContext == nil) { printError("Could not create OpenGL ES context."); abort(); } - if ([EAGLContext setCurrentContext:_context]) { - // glEnableClientState(GL_TEXTURE_COORD_ARRAY); printOpenGLError(); - // glEnableClientState(GL_VERTEX_ARRAY); printOpenGLError(); - [self setupOpenGL]; + // main thread will always use _mainContext + [EAGLContext setCurrentContext:_mainContext]; +} + +- (uint)createOpenGLContext { + // Create OpenGL context with the sharegroup from the context + // connected to the Apple Core Animation layer + if (!_openGLContext && _mainContext) { + _openGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:_mainContext.sharegroup]; + + if (_openGLContext == nil) { + printError("Could not create OpenGL ES context using sharegroup"); + abort(); + } + // background thread will always use _openGLContext + if ([EAGLContext setCurrentContext:_openGLContext]) { + [self setupRenderBuffer]; + } } + return _viewRenderbuffer; +} + +- (void)destroyOpenGLContext { + [_openGLContext release]; + _openGLContext = nil; +} + +- (void)refreshScreen { + glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer); + [_openGLContext presentRenderbuffer:GL_RENDERBUFFER]; +} + +- (int)getScreenWidth { + return _renderBufferWidth; +} + +- (int)getScreenHeight { + return _renderBufferHeight; } - (void)setupOpenGL { + [self setupRenderBuffer]; [self setupFramebuffer]; [self createOverlaySurface]; [self compileShaders]; @@ -163,6 +197,7 @@ uint getSizeNextPOT(uint size) { [self deleteVBOs]; [self deleteShaders]; [self deleteFramebuffer]; + [self deleteRenderbuffer]; } - (void)rebuildFrameBuffer { @@ -172,32 +207,41 @@ uint getSizeNextPOT(uint size) { } - (void)setupFramebuffer { - glGenRenderbuffers(1, &_viewRenderbuffer); - printOpenGLError(); - glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer); - printOpenGLError(); - [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id ) self.layer]; - - glGenFramebuffers(1, &_viewFramebuffer); - printOpenGLError(); + if (!_viewFramebuffer) { + glGenFramebuffers(1, &_viewFramebuffer); + printOpenGLError(); + } glBindFramebuffer(GL_FRAMEBUFFER, _viewFramebuffer); printOpenGLError(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _viewRenderbuffer); printOpenGLError(); - // Retrieve the render buffer size. This *should* match the frame size, - // i.e. g_fullWidth and g_fullHeight. - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_renderBufferWidth); - printOpenGLError(); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_renderBufferHeight); - printOpenGLError(); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatus(GL_FRAMEBUFFER)); return; } } +- (void)setupRenderBuffer { + execute_on_main_thread(^{ + if (!_viewRenderbuffer) { + glGenRenderbuffers(1, &_viewRenderbuffer); + printOpenGLError(); + } + glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer); + printOpenGLError(); + if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id ) self.layer]) { + printError("Failed renderbufferStorage"); + } + // Retrieve the render buffer size. This *should* match the frame size, + // i.e. g_fullWidth and g_fullHeight. + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_renderBufferWidth); + printOpenGLError(); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_renderBufferHeight); + printOpenGLError(); + }); +} + - (void)createOverlaySurface { uint overlayWidth = (uint) MAX(_renderBufferWidth, _renderBufferHeight); uint overlayHeight = (uint) MIN(_renderBufferWidth, _renderBufferHeight); @@ -221,8 +265,11 @@ uint getSizeNextPOT(uint size) { _videoContext.overlayTexture.create((uint16) overlayTextureWidthPOT, (uint16) overlayTextureHeightPOT, Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)); } -- (void)deleteFramebuffer { +- (void)deleteRenderbuffer { glDeleteRenderbuffers(1, &_viewRenderbuffer); +} + +- (void)deleteFramebuffer { glDeleteFramebuffers(1, &_viewFramebuffer); } @@ -538,7 +585,7 @@ uint getSizeNextPOT(uint size) { if (_videoContext.mouseIsVisible) [self updateMouseSurface]; - [_context presentRenderbuffer:GL_RENDERBUFFER]; + [_mainContext presentRenderbuffer:GL_RENDERBUFFER]; glFinish(); } @@ -682,9 +729,7 @@ uint getSizeNextPOT(uint size) { } - (void)initSurface { - if (_context) { - [self rebuildFrameBuffer]; - } + [self setupRenderBuffer]; #if TARGET_OS_IOS UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown; @@ -715,10 +760,6 @@ uint getSizeNextPOT(uint size) { [self showKeyboard]; } - glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer); printOpenGLError(); - - [self clearColorBuffer]; - GLfloat adjustedWidth = _videoContext.screenWidth; GLfloat adjustedHeight = _videoContext.screenHeight; if (_videoContext.asprectRatioCorrection) { @@ -842,7 +883,7 @@ uint getSizeNextPOT(uint size) { int clearCount = 5; while (clearCount-- > 0) { glClear(GL_COLOR_BUFFER_BIT); printOpenGLError(); - [_context presentRenderbuffer:GL_RENDERBUFFER]; + [_mainContext presentRenderbuffer:GL_RENDERBUFFER]; glFinish(); } }