From 6894e04356d55532fb66b9e0968680d7e47dd2a0 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 30 Nov 2017 10:11:40 +0000 Subject: [PATCH] Android: Fixed an OpenGL crash that would occur due to failing to get a pointer to the native window --- .../juce_opengl/native/juce_OpenGL_android.h | 24 ++++++++++++++++--- modules/juce_opengl/native/juce_OpenGL_ios.h | 2 +- .../native/juce_OpenGL_linux_X11.h | 4 +++- modules/juce_opengl/native/juce_OpenGL_osx.h | 10 ++++---- .../juce_opengl/native/juce_OpenGL_win32.h | 7 +++++- .../juce_opengl/opengl/juce_OpenGLContext.cpp | 16 ++++++++++--- 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/modules/juce_opengl/native/juce_OpenGL_android.h b/modules/juce_opengl/native/juce_OpenGL_android.h index 91b9c05e23..a91d965db3 100644 --- a/modules/juce_opengl/native/juce_OpenGL_android.h +++ b/modules/juce_opengl/native/juce_OpenGL_android.h @@ -88,7 +88,7 @@ public: } //============================================================================== - void initialiseOnRenderThread (OpenGLContext& aContext) + bool initialiseOnRenderThread (OpenGLContext& aContext) { jassert (hasInitialised); @@ -100,9 +100,25 @@ public: // get a pointer to the native window ANativeWindow* window = nullptr; if (jobject jSurface = env->CallObjectMethod (surfaceView.get(), NativeSurfaceView.getNativeSurface)) - window = ANativeWindow_fromSurface (env, jSurface); + { + window = ANativeWindow_fromSurface(env, jSurface); + + // if we didn't succeed the first time, wait 25ms and try again + if (window == nullptr) + { + Thread::sleep (25); + window = ANativeWindow_fromSurface (env, jSurface); + } + } - jassert (window != nullptr); + if (window == nullptr) + { + // failed to get a pointer to the native window after second try so + // bail out + jassertfalse; + + return false; + } // create the surface surface = eglCreateWindowSurface(display, config, window, 0); @@ -116,6 +132,8 @@ public: jassert (context != EGL_NO_CONTEXT); juceContext = &aContext; + + return true; } void shutdownOnRenderThread() diff --git a/modules/juce_opengl/native/juce_OpenGL_ios.h b/modules/juce_opengl/native/juce_OpenGL_ios.h index a079a4d842..24a849b967 100644 --- a/modules/juce_opengl/native/juce_OpenGL_ios.h +++ b/modules/juce_opengl/native/juce_OpenGL_ios.h @@ -113,7 +113,7 @@ public: [view release]; } - void initialiseOnRenderThread (OpenGLContext&) {} + bool initialiseOnRenderThread (OpenGLContext&) { return true; } void shutdownOnRenderThread() { diff --git a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h index c1b17d46ce..9de02cb283 100644 --- a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h +++ b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h @@ -142,12 +142,14 @@ public: XWindowSystem::getInstance()->displayUnref(); } - void initialiseOnRenderThread (OpenGLContext& c) + bool initialiseOnRenderThread (OpenGLContext& c) { ScopedXLock xlock (display); renderContext = glXCreateContext (display, bestVisual, (GLXContext) contextToShareWith, GL_TRUE); c.makeActive(); context = &c; + + return true; } void shutdownOnRenderThread() diff --git a/modules/juce_opengl/native/juce_OpenGL_osx.h b/modules/juce_opengl/native/juce_OpenGL_osx.h index 4b61efd4bf..dd1784f533 100644 --- a/modules/juce_opengl/native/juce_OpenGL_osx.h +++ b/modules/juce_opengl/native/juce_OpenGL_osx.h @@ -111,12 +111,12 @@ public: } } - void initialiseOnRenderThread (OpenGLContext&) {} - void shutdownOnRenderThread() { deactivateCurrentContext(); } + bool initialiseOnRenderThread (OpenGLContext&) { return true; } + void shutdownOnRenderThread() { deactivateCurrentContext(); } - bool createdOk() const noexcept { return getRawContext() != nullptr; } - void* getRawContext() const noexcept { return static_cast (renderContext); } - GLuint getFrameBufferID() const noexcept { return 0; } + bool createdOk() const noexcept { return getRawContext() != nullptr; } + void* getRawContext() const noexcept { return static_cast (renderContext); } + GLuint getFrameBufferID() const noexcept { return 0; } bool makeActive() const noexcept { diff --git a/modules/juce_opengl/native/juce_OpenGL_win32.h b/modules/juce_opengl/native/juce_OpenGL_win32.h index 7cbd732b4b..7485675545 100644 --- a/modules/juce_opengl/native/juce_OpenGL_win32.h +++ b/modules/juce_opengl/native/juce_OpenGL_win32.h @@ -89,7 +89,12 @@ public: releaseDC(); } - void initialiseOnRenderThread (OpenGLContext& c) { context = &c; } + bool initialiseOnRenderThread (OpenGLContext& c) + { + context = &c; + return true; + } + void shutdownOnRenderThread() { deactivateCurrentContext(); context = nullptr; } static void deactivateCurrentContext() { wglMakeCurrent (0, 0); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index ce65b4adfd..e272b90222 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -438,7 +438,13 @@ public: } while (! mmLock.retryLock()); } - initialiseOnThread(); + if (! initialiseOnThread()) + { + hasInitialised = false; + + return ThreadPoolJob::jobHasFinished; + } + hasInitialised = true; while (! shouldExit()) @@ -468,7 +474,7 @@ public: return ThreadPoolJob::jobHasFinished; } - void initialiseOnThread() + bool initialiseOnThread() { // On android, this can get called twice, so drop any previous state.. associatedObjectNames.clear(); @@ -476,7 +482,9 @@ public: cachedImageFrameBuffer.release(); context.makeActive(); - nativeContext->initialiseOnRenderThread (context); + + if (! nativeContext->initialiseOnRenderThread (context)) + return false; #if JUCE_ANDROID // On android the context may be created in initialiseOnRenderThread @@ -506,6 +514,8 @@ public: if (context.renderer != nullptr) context.renderer->newOpenGLContextCreated(); + + return true; } void shutdownOnThread()