Browse Source

NSViewComponentPeer: Avoid allocating a std::function on every frame

v7.0.9
reuk 3 years ago
parent
commit
4fc958bcda
No known key found for this signature in database GPG Key ID: FCB43929F012EE5C
1 changed files with 42 additions and 11 deletions
  1. +42
    -11
      modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm

+ 42
- 11
modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -1612,6 +1612,47 @@ private:
// avoid unnecessarily duplicating display-link threads.
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
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.
@@ -1620,17 +1661,7 @@ private:
{
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); };
})
};


Loading…
Cancel
Save