| @@ -1612,6 +1612,47 @@ private: | |||||
| // avoid unnecessarily duplicating display-link threads. | // avoid unnecessarily duplicating display-link threads. | ||||
| SharedResourcePointer<PerScreenDisplayLinks> sharedDisplayLinks; | SharedResourcePointer<PerScreenDisplayLinks> sharedDisplayLinks; | ||||
| class AsyncRepainter : private AsyncUpdater | |||||
| { | |||||
| public: | |||||
| explicit AsyncRepainter (NSViewComponentPeer& o) : owner (o) {} | |||||
| ~AsyncRepainter() override { cancelPendingUpdate(); } | |||||
| void markUpdated (const CGDirectDisplayID x) | |||||
| { | |||||
| { | |||||
| const std::scoped_lock lock { mutex }; | |||||
| if (std::find (backgroundDisplays.cbegin(), backgroundDisplays.cend(), x) == backgroundDisplays.cend()) | |||||
| backgroundDisplays.push_back (x); | |||||
| } | |||||
| triggerAsyncUpdate(); | |||||
| } | |||||
| private: | |||||
| void handleAsyncUpdate() override | |||||
| { | |||||
| { | |||||
| const std::scoped_lock lock { mutex }; | |||||
| mainThreadDisplays = backgroundDisplays; | |||||
| backgroundDisplays.clear(); | |||||
| } | |||||
| for (const auto& display : mainThreadDisplays) | |||||
| if (auto* peerView = owner.view) | |||||
| if (auto* peerWindow = [peerView window]) | |||||
| if (display == ScopedDisplayLink::getDisplayIdForScreen ([peerWindow screen])) | |||||
| owner.setNeedsDisplayRectangles(); | |||||
| } | |||||
| NSViewComponentPeer& owner; | |||||
| std::mutex mutex; | |||||
| std::vector<CGDirectDisplayID> backgroundDisplays, mainThreadDisplays; | |||||
| }; | |||||
| AsyncRepainter asyncRepainter { *this }; | |||||
| /* Creates a function object that can be called from an arbitrary thread (probably a CVLink | /* Creates a function object that can be called from an arbitrary thread (probably a CVLink | ||||
| thread). When called, this function object will trigger a call to setNeedsDisplayRectangles | thread). When called, this function object will trigger a call to setNeedsDisplayRectangles | ||||
| as soon as possible on the main thread, for any peers currently on the provided NSScreen. | as soon as possible on the main thread, for any peers currently on the provided NSScreen. | ||||
| @@ -1620,17 +1661,7 @@ private: | |||||
| { | { | ||||
| sharedDisplayLinks->registerFactory ([this] (CGDirectDisplayID display) | sharedDisplayLinks->registerFactory ([this] (CGDirectDisplayID display) | ||||
| { | { | ||||
| return [peerRef = WeakReference<NSViewComponentPeer> { this }, display] | |||||
| { | |||||
| MessageManager::callAsync ([peerRef, display] | |||||
| { | |||||
| if (auto* peer = peerRef.get()) | |||||
| if (auto* peerView = peer->view) | |||||
| if (auto* peerWindow = [peerView window]) | |||||
| if (display == ScopedDisplayLink::getDisplayIdForScreen ([peerWindow screen])) | |||||
| peer->setNeedsDisplayRectangles(); | |||||
| }); | |||||
| }; | |||||
| return [this, display] { asyncRepainter.markUpdated (display); }; | |||||
| }) | }) | ||||
| }; | }; | ||||