mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
CGMetalRenderer: Avoid glitching when resizing views
This commit is contained in:
parent
fe09902e83
commit
9d50ab6c59
3 changed files with 215 additions and 122 deletions
|
|
@ -295,7 +295,7 @@ struct CADisplayLinkDeleter
|
|||
|
||||
@end
|
||||
|
||||
@interface JuceUIView : UIView
|
||||
@interface JuceUIView : UIView<CALayerDelegate>
|
||||
{
|
||||
@public
|
||||
UIViewComponentPeer* owner;
|
||||
|
|
@ -520,6 +520,12 @@ public:
|
|||
return UIKeyboardTypeDefault;
|
||||
}
|
||||
|
||||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||
std::unique_ptr<CoreGraphicsMetalLayerRenderer> metalRenderer;
|
||||
#endif
|
||||
|
||||
RectangleList<float> deferredRepaints;
|
||||
|
||||
private:
|
||||
void appStyleChanged() override
|
||||
{
|
||||
|
|
@ -545,9 +551,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<CoreGraphicsMetalLayerRenderer<UIView>> metalRenderer;
|
||||
RectangleList<float> deferredRepaints;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer)
|
||||
};
|
||||
|
|
@ -698,6 +701,26 @@ MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches;
|
|||
[super initWithFrame: frame];
|
||||
owner = peer;
|
||||
|
||||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||
if (@available (iOS 13.0, *))
|
||||
{
|
||||
auto* layer = (CAMetalLayer*) [self layer];
|
||||
layer.device = MTLCreateSystemDefaultDevice();
|
||||
layer.framebufferOnly = NO;
|
||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
|
||||
if (owner != nullptr)
|
||||
layer.opaque = owner->getComponent().isOpaque();
|
||||
|
||||
layer.presentsWithTransaction = YES;
|
||||
layer.needsDisplayOnBoundsChange = true;
|
||||
layer.presentsWithTransaction = true;
|
||||
layer.delegate = self;
|
||||
|
||||
layer.allowsNextDrawableTimeout = NO;
|
||||
}
|
||||
#endif
|
||||
|
||||
displayLink.reset ([CADisplayLink displayLinkWithTarget: self
|
||||
selector: @selector (displayLinkCallback:)]);
|
||||
[displayLink.get() addToRunLoop: [NSRunLoop mainRunLoop]
|
||||
|
|
@ -750,6 +773,41 @@ MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches;
|
|||
owner->displayLinkCallback();
|
||||
}
|
||||
|
||||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||
- (CALayer*) makeBackingLayer
|
||||
{
|
||||
auto* layer = [CAMetalLayer layer];
|
||||
|
||||
layer.device = MTLCreateSystemDefaultDevice();
|
||||
layer.framebufferOnly = NO;
|
||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
|
||||
if (owner != nullptr)
|
||||
layer.opaque = owner->getComponent().isOpaque();
|
||||
|
||||
layer.presentsWithTransaction = YES;
|
||||
layer.needsDisplayOnBoundsChange = true;
|
||||
layer.presentsWithTransaction = true;
|
||||
layer.delegate = self;
|
||||
|
||||
layer.allowsNextDrawableTimeout = NO;
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
- (void) displayLayer: (CALayer*) layer
|
||||
{
|
||||
if (owner != nullptr)
|
||||
{
|
||||
owner->deferredRepaints = owner->metalRenderer->drawRectangleList (static_cast<CAMetalLayer*> (layer),
|
||||
(float) [self contentScaleFactor],
|
||||
[self] (auto&&... args) { owner->drawRectWithContext (args...); },
|
||||
std::move (owner->deferredRepaints),
|
||||
false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
- (void) drawRect: (CGRect) r
|
||||
{
|
||||
|
|
@ -1680,7 +1738,7 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, int windowStyleFlags,
|
|||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||
if (@available (iOS 13, *))
|
||||
{
|
||||
metalRenderer = CoreGraphicsMetalLayerRenderer<UIView>::create (view, comp.isOpaque());
|
||||
metalRenderer = CoreGraphicsMetalLayerRenderer::create();
|
||||
jassert (metalRenderer != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2138,22 +2196,8 @@ void UIViewComponentPeer::displayLinkCallback()
|
|||
if (deferredRepaints.isEmpty())
|
||||
return;
|
||||
|
||||
auto dispatchRectangles = [this] ()
|
||||
{
|
||||
if (metalRenderer != nullptr)
|
||||
return metalRenderer->drawRectangleList (view,
|
||||
(float) view.contentScaleFactor,
|
||||
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
|
||||
deferredRepaints);
|
||||
|
||||
for (const auto& r : deferredRepaints)
|
||||
[view setNeedsDisplayInRect: convertToCGRect (r)];
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (dispatchRectangles())
|
||||
deferredRepaints.clear();
|
||||
for (const auto& r : deferredRepaints)
|
||||
[view setNeedsDisplayInRect: convertToCGRect (r)];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue