|
|
|
@@ -186,12 +186,22 @@ public: |
|
|
|
{
|
|
|
|
renderThread->remove (this);
|
|
|
|
|
|
|
|
if ((state.fetch_and (~StateFlags::initialised) & StateFlags::initialised) != 0)
|
|
|
|
{
|
|
|
|
context.makeActive();
|
|
|
|
shutdownOnThread();
|
|
|
|
OpenGLContext::deactivateCurrentContext();
|
|
|
|
}
|
|
|
|
if ((state.fetch_and (~StateFlags::initialised) & StateFlags::initialised) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ScopedContextActivator activator;
|
|
|
|
activator.activate (context);
|
|
|
|
|
|
|
|
if (context.renderer != nullptr)
|
|
|
|
context.renderer->openGLContextClosing();
|
|
|
|
|
|
|
|
if (vertexArrayObject != 0)
|
|
|
|
context.extensions.glDeleteVertexArrays (1, &vertexArrayObject);
|
|
|
|
|
|
|
|
associatedObjectNames.clear();
|
|
|
|
associatedObjects.clear();
|
|
|
|
cachedImageFrameBuffer.release();
|
|
|
|
nativeContext->shutdownOnRenderThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
void resume()
|
|
|
|
@@ -375,12 +385,12 @@ public: |
|
|
|
abortScope = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! contextActivator.activate (context))
|
|
|
|
return RenderStatus::noWork;
|
|
|
|
|
|
|
|
{
|
|
|
|
NativeContext::Locker locker (*nativeContext);
|
|
|
|
|
|
|
|
if (! contextActivator.activate (context))
|
|
|
|
return RenderStatus::noWork;
|
|
|
|
|
|
|
|
JUCE_CHECK_OPENGL_ERROR
|
|
|
|
|
|
|
|
doWorkWhileWaitingForLock (contextActivator);
|
|
|
|
@@ -416,7 +426,7 @@ public: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nativeContext->swapBuffers();
|
|
|
|
bufferSwapper.swap();
|
|
|
|
return RenderStatus::nominal;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -520,9 +530,6 @@ public: |
|
|
|
paintOwner (*g);
|
|
|
|
JUCE_CHECK_OPENGL_ERROR
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! context.isActive())
|
|
|
|
context.makeActive();
|
|
|
|
}
|
|
|
|
|
|
|
|
JUCE_CHECK_OPENGL_ERROR
|
|
|
|
@@ -667,20 +674,6 @@ public: |
|
|
|
return InitResult::success;
|
|
|
|
}
|
|
|
|
|
|
|
|
void shutdownOnThread()
|
|
|
|
{
|
|
|
|
if (context.renderer != nullptr)
|
|
|
|
context.renderer->openGLContextClosing();
|
|
|
|
|
|
|
|
if (vertexArrayObject != 0)
|
|
|
|
context.extensions.glDeleteVertexArrays (1, &vertexArrayObject);
|
|
|
|
|
|
|
|
associatedObjectNames.clear();
|
|
|
|
associatedObjects.clear();
|
|
|
|
cachedImageFrameBuffer.release();
|
|
|
|
nativeContext->shutdownOnRenderThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns true if the context requires a non-zero vertex array object (VAO) to be bound.
|
|
|
|
|
|
|
|
If the context is a compatibility context, we can just pretend that VAOs don't exist,
|
|
|
|
@@ -840,7 +833,6 @@ public: |
|
|
|
case RenderStatus::nominal: result = RenderStatus::nominal; break;
|
|
|
|
case RenderStatus::messageThreadAborted: return RenderStatus::messageThreadAborted;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
@@ -950,6 +942,49 @@ public: |
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
class BufferSwapper : private AsyncUpdater
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit BufferSwapper (CachedImage& img)
|
|
|
|
: image (img) {}
|
|
|
|
|
|
|
|
~BufferSwapper() override
|
|
|
|
{
|
|
|
|
cancelPendingUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap()
|
|
|
|
{
|
|
|
|
static const auto swapBuffersOnMainThread = []
|
|
|
|
{
|
|
|
|
const auto os = SystemStats::getOperatingSystemType();
|
|
|
|
|
|
|
|
if ((os & SystemStats::MacOSX) != 0)
|
|
|
|
return (os != SystemStats::MacOSX && os < SystemStats::MacOSX_10_14);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}();
|
|
|
|
|
|
|
|
if (swapBuffersOnMainThread && ! MessageManager::getInstance()->isThisTheMessageThread())
|
|
|
|
triggerAsyncUpdate();
|
|
|
|
else
|
|
|
|
image.nativeContext->swapBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void handleAsyncUpdate() override
|
|
|
|
{
|
|
|
|
ScopedContextActivator activator;
|
|
|
|
activator.activate (image.context);
|
|
|
|
|
|
|
|
NativeContext::Locker locker (*image.nativeContext);
|
|
|
|
image.nativeContext->swapBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
CachedImage& image;
|
|
|
|
};
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
friend class NativeContext;
|
|
|
|
std::unique_ptr<NativeContext> nativeContext;
|
|
|
|
@@ -977,6 +1012,7 @@ public: |
|
|
|
#endif
|
|
|
|
bool textureNpotSupported = false;
|
|
|
|
std::chrono::steady_clock::time_point lastMMLockReleaseTime{};
|
|
|
|
BufferSwapper bufferSwapper { *this };
|
|
|
|
|
|
|
|
#if JUCE_MAC
|
|
|
|
NSView* getCurrentView() const
|
|
|
|
@@ -1055,9 +1091,6 @@ public: |
|
|
|
pendingDestruction = 1 << 2,
|
|
|
|
initialised = 1 << 3,
|
|
|
|
|
|
|
|
// Flags that may change state after each frame
|
|
|
|
transient = pendingRender | paintComponents,
|
|
|
|
|
|
|
|
// Flags that should retain their state after each frame
|
|
|
|
persistent = initialised | pendingDestruction
|
|
|
|
};
|
|
|
|
|