@@ -304,7 +304,21 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
304
304
if (auto * peer = component.getPeer ())
305
305
{
306
306
auto localBounds = component.getLocalBounds ();
307
- auto displayScale = Desktop::getInstance ().getDisplays ().getDisplayForRect (component.getTopLevelComponent ()->getScreenBounds ())->scale ;
307
+ const auto currentDisplay = Desktop::getInstance ().getDisplays ().getDisplayForRect (component.getTopLevelComponent ()->getScreenBounds ());
308
+
309
+ if (currentDisplay != lastDisplay)
310
+ {
311
+ #if JUCE_MAC
312
+ if (cvDisplayLinkWrapper != nullptr )
313
+ {
314
+ cvDisplayLinkWrapper->updateActiveDisplay (currentDisplay->totalArea .getTopLeft ());
315
+ nativeContext->setNominalVideoRefreshPeriodS (cvDisplayLinkWrapper->getNominalVideoRefreshPeriodS ());
316
+ }
317
+ #endif
318
+ lastDisplay = currentDisplay;
319
+ }
320
+
321
+ const auto displayScale = currentDisplay->scale ;
308
322
309
323
auto newArea = peer->getComponent ().getLocalArea (&component, localBounds).withZeroOrigin () * displayScale;
310
324
@@ -345,7 +359,10 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
345
359
auto screenBounds = component.getTopLevelComponent ()->getScreenBounds ();
346
360
347
361
if (lastScreenBounds != screenBounds)
362
+ {
348
363
updateViewportSize (true );
364
+ lastScreenBounds = screenBounds;
365
+ }
349
366
}
350
367
351
368
void paintComponent ()
@@ -494,7 +511,7 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
494
511
break ;
495
512
496
513
#if JUCE_MAC
497
- if (cvDisplayLinkWrapper != nullptr )
514
+ if (context. continuousRepaint )
498
515
{
499
516
repaintEvent.wait (-1 );
500
517
renderFrame ();
@@ -561,8 +578,8 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
561
578
context.renderer ->newOpenGLContextCreated ();
562
579
563
580
#if JUCE_MAC
564
- if (context. continuousRepaint )
565
- cvDisplayLinkWrapper = std::make_unique<CVDisplayLinkWrapper> ( this );
581
+ cvDisplayLinkWrapper = std::make_unique<CVDisplayLinkWrapper> (* this );
582
+ nativeContext-> setNominalVideoRefreshPeriodS ( cvDisplayLinkWrapper-> getNominalVideoRefreshPeriodS () );
566
583
#endif
567
584
568
585
return true ;
@@ -680,6 +697,7 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
680
697
OpenGLFrameBuffer cachedImageFrameBuffer;
681
698
RectangleList<int > validArea;
682
699
Rectangle<int > viewportArea, lastScreenBounds;
700
+ const Displays::Display* lastDisplay = nullptr ;
683
701
double scale = 1.0 ;
684
702
AffineTransform transform;
685
703
GLuint vertexArrayObject = 0 ;
@@ -700,11 +718,40 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
700
718
#if JUCE_MAC
701
719
struct CVDisplayLinkWrapper
702
720
{
703
- CVDisplayLinkWrapper (CachedImage* im)
721
+ CVDisplayLinkWrapper (CachedImage& cachedImageIn) : cachedImage (cachedImageIn),
722
+ continuousRepaint (cachedImageIn.context.continuousRepaint.load())
704
723
{
705
724
CVDisplayLinkCreateWithActiveCGDisplays (&displayLink);
706
- CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, im );
725
+ CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, this );
707
726
CVDisplayLinkStart (displayLink);
727
+
728
+ const auto topLeftOfCurrentScreen = Desktop::getInstance ()
729
+ .getDisplays ()
730
+ .getDisplayForRect (cachedImage.component .getTopLevelComponent ()->getScreenBounds ())
731
+ ->totalArea .getTopLeft ();
732
+ updateActiveDisplay (topLeftOfCurrentScreen);
733
+ }
734
+
735
+ double getNominalVideoRefreshPeriodS () const
736
+ {
737
+ const auto nominalVideoRefreshPeriod = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (displayLink);
738
+
739
+ if ((nominalVideoRefreshPeriod.flags & kCVTimeIsIndefinite ) == 0 )
740
+ return (double ) nominalVideoRefreshPeriod.timeValue / (double ) nominalVideoRefreshPeriod.timeScale ;
741
+
742
+ return 0.0 ;
743
+ }
744
+
745
+ void updateActiveDisplay (Point <int > topLeftOfDisplay)
746
+ {
747
+ CGPoint point { (CGFloat ) topLeftOfDisplay.getX (), (CGFloat ) topLeftOfDisplay.getY () };
748
+ CGDirectDisplayID displayID;
749
+ uint32_t numDisplays = 0 ;
750
+ constexpr uint32_t maxNumDisplays = 1 ;
751
+ CGGetDisplaysWithPoint (point, maxNumDisplays, &displayID, &numDisplays);
752
+
753
+ if (numDisplays == 1 )
754
+ CVDisplayLinkSetCurrentCGDisplay (displayLink, displayID);
708
755
}
709
756
710
757
~CVDisplayLinkWrapper ()
@@ -716,11 +763,16 @@ class OpenGLContext::CachedImage : public CachedComponentImage,
716
763
static CVReturn displayLinkCallback (CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*,
717
764
CVOptionFlags, CVOptionFlags*, void * displayLinkContext)
718
765
{
719
- auto * self = (CachedImage*) displayLinkContext;
720
- self->repaintEvent .signal ();
766
+ auto * self = reinterpret_cast <CVDisplayLinkWrapper*> (displayLinkContext);
767
+
768
+ if (self->continuousRepaint )
769
+ self->cachedImage .repaintEvent .signal ();
770
+
721
771
return kCVReturnSuccess ;
722
772
}
723
773
774
+ CachedImage& cachedImage;
775
+ const bool continuousRepaint;
724
776
CVDisplayLinkRef displayLink;
725
777
};
726
778
0 commit comments