|
|
@@ -304,7 +304,21 @@ public: |
|
|
if (auto* peer = component.getPeer())
|
|
|
if (auto* peer = component.getPeer())
|
|
|
{
|
|
|
{
|
|
|
auto localBounds = component.getLocalBounds();
|
|
|
auto localBounds = component.getLocalBounds();
|
|
|
auto displayScale = Desktop::getInstance().getDisplays().getDisplayForRect (component.getTopLevelComponent()->getScreenBounds())->scale;
|
|
|
|
|
|
|
|
|
const auto currentDisplay = Desktop::getInstance().getDisplays().getDisplayForRect (component.getTopLevelComponent()->getScreenBounds());
|
|
|
|
|
|
|
|
|
|
|
|
if (currentDisplay != lastDisplay)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if JUCE_MAC
|
|
|
|
|
|
if (cvDisplayLinkWrapper != nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
cvDisplayLinkWrapper->updateActiveDisplay (currentDisplay->totalArea.getTopLeft());
|
|
|
|
|
|
nativeContext->setNominalVideoRefreshPeriodS (cvDisplayLinkWrapper->getNominalVideoRefreshPeriodS());
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
lastDisplay = currentDisplay;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const auto displayScale = currentDisplay->scale;
|
|
|
|
|
|
|
|
|
auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin() * displayScale;
|
|
|
auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin() * displayScale;
|
|
|
|
|
|
|
|
|
@@ -345,7 +359,10 @@ public: |
|
|
auto screenBounds = component.getTopLevelComponent()->getScreenBounds();
|
|
|
auto screenBounds = component.getTopLevelComponent()->getScreenBounds();
|
|
|
|
|
|
|
|
|
if (lastScreenBounds != screenBounds)
|
|
|
if (lastScreenBounds != screenBounds)
|
|
|
|
|
|
{
|
|
|
updateViewportSize (true);
|
|
|
updateViewportSize (true);
|
|
|
|
|
|
lastScreenBounds = screenBounds;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void paintComponent()
|
|
|
void paintComponent()
|
|
|
@@ -494,7 +511,7 @@ public: |
|
|
break;
|
|
|
break;
|
|
|
|
|
|
|
|
|
#if JUCE_MAC
|
|
|
#if JUCE_MAC
|
|
|
if (cvDisplayLinkWrapper != nullptr)
|
|
|
|
|
|
|
|
|
if (context.continuousRepaint)
|
|
|
{
|
|
|
{
|
|
|
repaintEvent.wait (-1);
|
|
|
repaintEvent.wait (-1);
|
|
|
renderFrame();
|
|
|
renderFrame();
|
|
|
@@ -561,8 +578,8 @@ public: |
|
|
context.renderer->newOpenGLContextCreated();
|
|
|
context.renderer->newOpenGLContextCreated();
|
|
|
|
|
|
|
|
|
#if JUCE_MAC
|
|
|
#if JUCE_MAC
|
|
|
if (context.continuousRepaint)
|
|
|
|
|
|
cvDisplayLinkWrapper = std::make_unique<CVDisplayLinkWrapper> (this);
|
|
|
|
|
|
|
|
|
cvDisplayLinkWrapper = std::make_unique<CVDisplayLinkWrapper> (*this);
|
|
|
|
|
|
nativeContext->setNominalVideoRefreshPeriodS (cvDisplayLinkWrapper->getNominalVideoRefreshPeriodS());
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
return true;
|
|
|
return true;
|
|
|
@@ -680,6 +697,7 @@ public: |
|
|
OpenGLFrameBuffer cachedImageFrameBuffer;
|
|
|
OpenGLFrameBuffer cachedImageFrameBuffer;
|
|
|
RectangleList<int> validArea;
|
|
|
RectangleList<int> validArea;
|
|
|
Rectangle<int> viewportArea, lastScreenBounds;
|
|
|
Rectangle<int> viewportArea, lastScreenBounds;
|
|
|
|
|
|
const Displays::Display* lastDisplay = nullptr;
|
|
|
double scale = 1.0;
|
|
|
double scale = 1.0;
|
|
|
AffineTransform transform;
|
|
|
AffineTransform transform;
|
|
|
GLuint vertexArrayObject = 0;
|
|
|
GLuint vertexArrayObject = 0;
|
|
|
@@ -700,11 +718,40 @@ public: |
|
|
#if JUCE_MAC
|
|
|
#if JUCE_MAC
|
|
|
struct CVDisplayLinkWrapper
|
|
|
struct CVDisplayLinkWrapper
|
|
|
{
|
|
|
{
|
|
|
CVDisplayLinkWrapper (CachedImage* im)
|
|
|
|
|
|
|
|
|
CVDisplayLinkWrapper (CachedImage& cachedImageIn) : cachedImage (cachedImageIn),
|
|
|
|
|
|
continuousRepaint (cachedImageIn.context.continuousRepaint.load())
|
|
|
{
|
|
|
{
|
|
|
CVDisplayLinkCreateWithActiveCGDisplays (&displayLink);
|
|
|
CVDisplayLinkCreateWithActiveCGDisplays (&displayLink);
|
|
|
CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, im);
|
|
|
|
|
|
|
|
|
CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, this);
|
|
|
CVDisplayLinkStart (displayLink);
|
|
|
CVDisplayLinkStart (displayLink);
|
|
|
|
|
|
|
|
|
|
|
|
const auto topLeftOfCurrentScreen = Desktop::getInstance()
|
|
|
|
|
|
.getDisplays()
|
|
|
|
|
|
.getDisplayForRect (cachedImage.component.getTopLevelComponent()->getScreenBounds())
|
|
|
|
|
|
->totalArea.getTopLeft();
|
|
|
|
|
|
updateActiveDisplay (topLeftOfCurrentScreen);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double getNominalVideoRefreshPeriodS() const
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto nominalVideoRefreshPeriod = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (displayLink);
|
|
|
|
|
|
|
|
|
|
|
|
if ((nominalVideoRefreshPeriod.flags & kCVTimeIsIndefinite) == 0)
|
|
|
|
|
|
return (double) nominalVideoRefreshPeriod.timeValue / (double) nominalVideoRefreshPeriod.timeScale;
|
|
|
|
|
|
|
|
|
|
|
|
return 0.0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void updateActiveDisplay (Point<int> topLeftOfDisplay)
|
|
|
|
|
|
{
|
|
|
|
|
|
CGPoint point { (CGFloat) topLeftOfDisplay.getX(), (CGFloat) topLeftOfDisplay.getY() };
|
|
|
|
|
|
CGDirectDisplayID displayID;
|
|
|
|
|
|
uint32_t numDisplays = 0;
|
|
|
|
|
|
constexpr uint32_t maxNumDisplays = 1;
|
|
|
|
|
|
CGGetDisplaysWithPoint (point, maxNumDisplays, &displayID, &numDisplays);
|
|
|
|
|
|
|
|
|
|
|
|
if (numDisplays == 1)
|
|
|
|
|
|
CVDisplayLinkSetCurrentCGDisplay (displayLink, displayID);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
~CVDisplayLinkWrapper()
|
|
|
~CVDisplayLinkWrapper()
|
|
|
@@ -716,11 +763,16 @@ public: |
|
|
static CVReturn displayLinkCallback (CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*,
|
|
|
static CVReturn displayLinkCallback (CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*,
|
|
|
CVOptionFlags, CVOptionFlags*, void* displayLinkContext)
|
|
|
CVOptionFlags, CVOptionFlags*, void* displayLinkContext)
|
|
|
{
|
|
|
{
|
|
|
auto* self = (CachedImage*) displayLinkContext;
|
|
|
|
|
|
self->repaintEvent.signal();
|
|
|
|
|
|
|
|
|
auto* self = reinterpret_cast<CVDisplayLinkWrapper*> (displayLinkContext);
|
|
|
|
|
|
|
|
|
|
|
|
if (self->continuousRepaint)
|
|
|
|
|
|
self->cachedImage.repaintEvent.signal();
|
|
|
|
|
|
|
|
|
return kCVReturnSuccess;
|
|
|
return kCVReturnSuccess;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CachedImage& cachedImage;
|
|
|
|
|
|
const bool continuousRepaint;
|
|
|
CVDisplayLinkRef displayLink;
|
|
|
CVDisplayLinkRef displayLink;
|
|
|
};
|
|
|
};
|
|
|
|
|
|
|
|
|
|