Browse Source

NSViewComponentPeer: Avoid using metal renderer if view has changed size since repaints were requested

The main change is that the numFramesToSkipMetalRenderer member has been
removed. The old mechanism had some problems in AU plugins in Logic.
Specifically, when opening a temporary window, repaints would be ignored
until the numFramesToSkipMetalRenderer counter had been decremented to
zero. In practice, this meant that a PopupMenu might not repaint until
the highlighted item had changed five times or more.

With this change applied, repaints that were requested for a particular
window size will use the metal renderer as long as the window hasn't
changed size in the meantime.
v7.0.9
reuk 2 years ago
parent
commit
ee976f0f0d
No known key found for this signature in database GPG Key ID: FCB43929F012EE5C
1 changed files with 22 additions and 35 deletions
  1. +22
    -35
      modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm

+ 22
- 35
modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -341,10 +341,7 @@ public:
}
if (oldViewSize.width != r.size.width || oldViewSize.height != r.size.height)
{
numFramesToSkipMetalRenderer = 5;
[view setNeedsDisplay: true];
}
}
Rectangle<int> getBounds (const bool global) const
@@ -1013,6 +1010,8 @@ public:
// As a work around for this, we use a RectangleList to do our own coalescing of regions before
// asynchronously asking the OS to repaint them.
deferredRepaints.add (area.toFloat());
const auto frameSize = view.frame.size;
boundsWhenRepaintsDeferred = { (float) frameSize.width, (float) frameSize.height };
}
static bool shouldThrottleRepaint()
@@ -1043,43 +1042,31 @@ public:
if (msSinceLastRepaint < minimumRepaintInterval && shouldThrottleRepaint())
return;
if (metalRenderer != nullptr)
{
auto setDeferredRepaintsToWholeFrame = [this]
{
const auto frameSize = view.frame.size;
deferredRepaints = Rectangle<float> { (float) frameSize.width, (float) frameSize.height };
};
const auto frameSize = view.frame.size;
const Rectangle currentBounds { (float) frameSize.width, (float) frameSize.height };
// If we are resizing we need to fall back to synchronous drawing to avoid artefacts
if ([window inLiveResize] || numFramesToSkipMetalRenderer > 0)
{
if (metalRenderer->isAttachedToView (view))
{
metalRenderer->detach();
setDeferredRepaintsToWholeFrame();
}
if (boundsWhenRepaintsDeferred != currentBounds)
{
deferredRepaints = currentBounds;
if (numFramesToSkipMetalRenderer > 0)
--numFramesToSkipMetalRenderer;
}
else
{
if (! metalRenderer->isAttachedToView (view))
{
metalRenderer->attach (view, getComponent().isOpaque());
setDeferredRepaintsToWholeFrame();
}
}
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
metalRenderer->detach();
}
else
{
if (metalRenderer != nullptr && ! metalRenderer->isAttachedToView (view))
metalRenderer->attach (view, getComponent().isOpaque());
}
auto dispatchRectangles = [this]
{
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
return metalRenderer->drawRectangleList (view,
(float) [[view window] backingScaleFactor],
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
deferredRepaints);
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
{
return metalRenderer->drawRectangleList (view,
(float) [[view window] backingScaleFactor],
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
deferredRepaints);
}
for (auto& i : deferredRepaints)
[view setNeedsDisplayInRect: makeNSRect (i)];
@@ -1704,6 +1691,7 @@ public:
int startOfMarkedTextInTextInputTarget = 0;
Rectangle<float> lastSizeBeforeZoom;
Rectangle<float> boundsWhenRepaintsDeferred;
RectangleList<float> deferredRepaints;
uint32 lastRepaintTime;
@@ -1946,7 +1934,6 @@ private:
}
//==============================================================================
int numFramesToSkipMetalRenderer = 0;
std::unique_ptr<CoreGraphicsMetalLayerRenderer<NSView>> metalRenderer;
std::vector<ScopedNotificationCenterObserver> scopedObservers;


Loading…
Cancel
Save