|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-11 by Raw Material Software Ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the GNU General
- Public License (Version 2), as published by the Free Software Foundation.
- A copy of the license is included in the JUCE distribution, or can be found
- online at www.gnu.org/licenses.
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.rawmaterialsoftware.com/juce for more information.
-
- ==============================================================================
- */
-
-
- #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
- METHOD (layout, "layout", "(IIII)V") \
- METHOD (requestRender, "requestRender", "()V") \
-
- DECLARE_JNI_CLASS (OpenGLView, JUCE_ANDROID_ACTIVITY_CLASSPATH "$OpenGLView");
- #undef JNI_CLASS_MEMBERS
-
- jobject createOpenGLView (ComponentPeer*);
-
- //==============================================================================
- class AndroidGLContext : public OpenGLContext
- {
- public:
- AndroidGLContext (OpenGLComponent* const component_,
- ComponentPeer* peer,
- const OpenGLPixelFormat& pixelFormat,
- const AndroidGLContext* const sharedContext,
- const bool isGLES2_)
- : component (component_),
- lastWidth (0), lastHeight (0),
- isGLES2 (isGLES2_),
- isInsideGLCallback (false)
- {
- jassert (peer != nullptr);
-
- glView = GlobalRef (createOpenGLView (peer));
-
- const ScopedLock sl (getContextListLock());
- getContextList().add (this);
- }
-
- ~AndroidGLContext()
- {
- properties.clear(); // to release any stored programs, etc that may be held in properties.
-
- android.activity.callVoidMethod (JuceAppActivity.deleteView, glView.get());
- glView.clear();
-
- const ScopedLock sl (getContextListLock());
- getContextList().removeValue (this);
- }
-
- //==============================================================================
- bool makeActive() const noexcept { return isInsideGLCallback; }
- bool makeInactive() const noexcept { return true; }
- bool isActive() const noexcept { return isInsideGLCallback; }
-
- void swapBuffers() {}
-
- void* getRawContext() const noexcept { return glView.get(); }
- unsigned int getFrameBufferID() const { return 0; }
-
- int getWidth() const { return lastWidth; }
- int getHeight() const { return lastHeight; }
-
- bool areShadersAvailable() const { return isGLES2; }
-
- void updateWindowPosition (const Rectangle<int>& bounds)
- {
- if (lastWidth != bounds.getWidth() || lastHeight != bounds.getHeight())
- {
- lastWidth = bounds.getWidth();
- lastHeight = bounds.getHeight();
-
- glView.callVoidMethod (OpenGLView.layout,
- bounds.getX(), bounds.getY(),
- bounds.getRight(), bounds.getBottom());
- }
- }
-
- bool setSwapInterval (const int /*numFramesPerSwap*/) { return false; }
- int getSwapInterval() const { return 0; }
-
- //==============================================================================
- void contextCreatedCallback()
- {
- properties.clear();
-
- isInsideGLCallback = true;
-
- if (component != nullptr)
- dynamic_cast <OpenGLComponent*> (component.get())->newOpenGLContextCreated();
-
- isInsideGLCallback = false;
- }
-
- void renderCallback()
- {
- isInsideGLCallback = true;
-
- if (component != nullptr)
- dynamic_cast <OpenGLComponent*> (component.get())->performRender();
-
- isInsideGLCallback = false;
- }
-
- //==============================================================================
- static CriticalSection& getContextListLock()
- {
- static CriticalSection lock;
- return lock;
- }
-
- static Array<AndroidGLContext*>& getContextList()
- {
- static Array <AndroidGLContext*> contexts;
- return contexts;
- }
-
- static AndroidGLContext* findContextFor (JNIEnv* env, jobject glView)
- {
- const ScopedLock sl (getContextListLock());
- const Array<AndroidGLContext*>& contexts = getContextList();
-
- for (int i = contexts.size(); --i >= 0;)
- {
- AndroidGLContext* const c = contexts.getUnchecked(i);
-
- if (env->IsSameObject (c->glView.get(), glView))
- return c;
- }
-
- return nullptr;
- }
-
- static bool isAnyContextActive()
- {
- const ScopedLock sl (getContextListLock());
- const Array<AndroidGLContext*>& contexts = getContextList();
-
- for (int i = contexts.size(); --i >= 0;)
- {
- const AndroidGLContext* const c = contexts.getUnchecked(i);
-
- if (c->isInsideGLCallback)
- return true;
- }
-
- return false;
- }
-
- //==============================================================================
- GlobalRef glView;
-
- private:
- WeakReference<Component> component;
- int lastWidth, lastHeight;
- bool isGLES2;
- bool isInsideGLCallback;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidGLContext);
- };
-
- //==============================================================================
- OpenGLContext* OpenGLComponent::createContext()
- {
- ComponentPeer* peer = getTopLevelComponent()->getPeer();
-
- if (peer != nullptr)
- return new AndroidGLContext (this, peer, preferredPixelFormat,
- dynamic_cast <const AndroidGLContext*> (contextToShareListsWith),
- (flags & openGLES1) == 0);
-
- return nullptr;
- }
-
- void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>& bounds)
- {
- const ScopedLock sl (contextLock);
-
- if (context != nullptr)
- static_cast <AndroidGLContext*> (context.get())->updateWindowPosition (bounds);
- }
-
- bool OpenGLHelpers::isContextActive()
- {
- return AndroidGLContext::isAnyContextActive();
- }
-
- void triggerAndroidOpenGLRepaint (OpenGLContext* context)
- {
- AndroidGLContext* c = dynamic_cast <AndroidGLContext*> (context);
-
- if (c != nullptr)
- c->glView.callVoidMethod (OpenGLView.requestRender);
- }
-
- //==============================================================================
- JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024OpenGLView), contextCreated, void, (JNIEnv* env, jobject view))
- {
- JUCE_CHECK_OPENGL_ERROR
-
- for (int i = 100; --i >= 0;)
- {
- AndroidGLContext* const context = AndroidGLContext::findContextFor (env, view);
-
- if (context != nullptr)
- {
- context->contextCreatedCallback();
- JUCE_CHECK_OPENGL_ERROR
- return;
- }
-
- Thread::sleep (20);
- }
-
- jassertfalse;
- }
-
- JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024OpenGLView), render, void, (JNIEnv* env, jobject view))
- {
- AndroidGLContext* const context = AndroidGLContext::findContextFor (env, view);
-
- if (context != nullptr)
- context->renderCallback();
- }
|