mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
macOS/iOS: Fix a scaled multiple-rects drawing issue
This commit is contained in:
parent
fc376eab3b
commit
61fd8827e1
3 changed files with 19 additions and 23 deletions
|
|
@ -1391,7 +1391,7 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, int windowStyleFlags,
|
||||||
|
|
||||||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||||
if (@available (iOS 13, *))
|
if (@available (iOS 13, *))
|
||||||
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<UIView>> (view, comp);
|
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<UIView>> (view, comp.isOpaque());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
|
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
|
||||||
|
|
@ -1857,8 +1857,6 @@ void UIViewComponentPeer::displayLinkCallback()
|
||||||
if (metalRenderer != nullptr)
|
if (metalRenderer != nullptr)
|
||||||
return metalRenderer->drawRectangleList (view,
|
return metalRenderer->drawRectangleList (view,
|
||||||
(float) view.contentScaleFactor,
|
(float) view.contentScaleFactor,
|
||||||
view.frame,
|
|
||||||
component,
|
|
||||||
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
|
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
|
||||||
deferredRepaints);
|
deferredRepaints);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,12 @@ class CoreGraphicsMetalLayerRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
CoreGraphicsMetalLayerRenderer (ViewType* view, const Component& comp)
|
CoreGraphicsMetalLayerRenderer (ViewType* view, bool isOpaque)
|
||||||
{
|
{
|
||||||
device.reset (MTLCreateSystemDefaultDevice());
|
device.reset (MTLCreateSystemDefaultDevice());
|
||||||
commandQueue.reset ([device.get() newCommandQueue]);
|
commandQueue.reset ([device.get() newCommandQueue]);
|
||||||
|
|
||||||
attach (view, comp);
|
attach (view, isOpaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CoreGraphicsMetalLayerRenderer()
|
~CoreGraphicsMetalLayerRenderer()
|
||||||
|
|
@ -52,7 +52,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach (ViewType* view, const Component& comp)
|
void attach (ViewType* view, bool isOpaque)
|
||||||
{
|
{
|
||||||
#if JUCE_MAC
|
#if JUCE_MAC
|
||||||
view.wantsLayer = YES;
|
view.wantsLayer = YES;
|
||||||
|
|
@ -65,7 +65,7 @@ public:
|
||||||
layer.device = device.get();
|
layer.device = device.get();
|
||||||
layer.framebufferOnly = NO;
|
layer.framebufferOnly = NO;
|
||||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||||
layer.opaque = comp.isOpaque();
|
layer.opaque = isOpaque;
|
||||||
layer.allowsNextDrawableTimeout = NO;
|
layer.allowsNextDrawableTimeout = NO;
|
||||||
|
|
||||||
attachedView = view;
|
attachedView = view;
|
||||||
|
|
@ -90,8 +90,6 @@ public:
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
bool drawRectangleList (ViewType* view,
|
bool drawRectangleList (ViewType* view,
|
||||||
float scaleFactor,
|
float scaleFactor,
|
||||||
CGRect viewFrame,
|
|
||||||
const Component& comp,
|
|
||||||
Callback&& drawRectWithContext,
|
Callback&& drawRectWithContext,
|
||||||
const RectangleList<float>& dirtyRegions)
|
const RectangleList<float>& dirtyRegions)
|
||||||
{
|
{
|
||||||
|
|
@ -117,14 +115,12 @@ public:
|
||||||
layer.contentsScale = scaleFactor;
|
layer.contentsScale = scaleFactor;
|
||||||
const auto drawableSizeTansform = CGAffineTransformMakeScale (layer.contentsScale,
|
const auto drawableSizeTansform = CGAffineTransformMakeScale (layer.contentsScale,
|
||||||
layer.contentsScale);
|
layer.contentsScale);
|
||||||
const auto transformedFrameSize = CGSizeApplyAffineTransform (viewFrame.size, drawableSizeTansform);
|
const auto transformedFrameSize = CGSizeApplyAffineTransform (view.frame.size, drawableSizeTansform);
|
||||||
|
|
||||||
const auto componentHeight = comp.getHeight();
|
|
||||||
|
|
||||||
if (resources == nullptr || ! CGSizeEqualToSize (layer.drawableSize, transformedFrameSize))
|
if (resources == nullptr || ! CGSizeEqualToSize (layer.drawableSize, transformedFrameSize))
|
||||||
{
|
{
|
||||||
layer.drawableSize = transformedFrameSize;
|
layer.drawableSize = transformedFrameSize;
|
||||||
resources = std::make_unique<Resources> (device.get(), layer, componentHeight);
|
resources = std::make_unique<Resources> (device.get(), layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gpuTexture = resources->getGpuTexture();
|
auto gpuTexture = resources->getGpuTexture();
|
||||||
|
|
@ -261,7 +257,7 @@ private:
|
||||||
class Resources
|
class Resources
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Resources (id<MTLDevice> metalDevice, CAMetalLayer* layer, int componentHeight)
|
Resources (id<MTLDevice> metalDevice, CAMetalLayer* layer)
|
||||||
{
|
{
|
||||||
const auto bytesPerRow = alignTo ((size_t) layer.drawableSize.width * 4, 256);
|
const auto bytesPerRow = alignTo ((size_t) layer.drawableSize.width * 4, 256);
|
||||||
|
|
||||||
|
|
@ -301,8 +297,8 @@ private:
|
||||||
CGColorSpaceCreateWithName (kCGColorSpaceSRGB),
|
CGColorSpaceCreateWithName (kCGColorSpaceSRGB),
|
||||||
(uint32_t) kCGImageAlphaPremultipliedFirst | (uint32_t) kCGBitmapByteOrder32Host));
|
(uint32_t) kCGImageAlphaPremultipliedFirst | (uint32_t) kCGBitmapByteOrder32Host));
|
||||||
|
|
||||||
CGContextScaleCTM (cgContext.get(), layer.contentsScale, layer.contentsScale);
|
CGContextTranslateCTM (cgContext.get(), 0, layer.drawableSize.height);
|
||||||
CGContextConcatCTM (cgContext.get(), CGAffineTransformMake (1, 0, 0, -1, 0, componentHeight));
|
CGContextScaleCTM (cgContext.get(), layer.contentsScale, -layer.contentsScale);
|
||||||
|
|
||||||
textureDesc.storageMode = MTLStorageModePrivate;
|
textureDesc.storageMode = MTLStorageModePrivate;
|
||||||
gpuTexturePool = std::make_unique<GpuTexturePool> (metalDevice, textureDesc);
|
gpuTexturePool = std::make_unique<GpuTexturePool> (metalDevice, textureDesc);
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ public:
|
||||||
#if USE_COREGRAPHICS_RENDERING
|
#if USE_COREGRAPHICS_RENDERING
|
||||||
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
|
||||||
if (@available (macOS 10.14, *))
|
if (@available (macOS 10.14, *))
|
||||||
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<NSView>> (view, getComponent());
|
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<NSView>> (view, getComponent().isOpaque());
|
||||||
#endif
|
#endif
|
||||||
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
|
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1047,7 +1047,11 @@ public:
|
||||||
|
|
||||||
if (metalRenderer != nullptr)
|
if (metalRenderer != nullptr)
|
||||||
{
|
{
|
||||||
const auto compBounds = getComponent().getLocalBounds().toFloat();
|
auto setDeferredRepaintsToWholeFrame = [this]
|
||||||
|
{
|
||||||
|
const auto frameSize = view.frame.size;
|
||||||
|
deferredRepaints = Rectangle<float> { (float) frameSize.width, (float) frameSize.height };
|
||||||
|
};
|
||||||
|
|
||||||
// If we are resizing we need to fall back to synchronous drawing to avoid artefacts
|
// If we are resizing we need to fall back to synchronous drawing to avoid artefacts
|
||||||
if ([window inLiveResize] || numFramesToSkipMetalRenderer > 0)
|
if ([window inLiveResize] || numFramesToSkipMetalRenderer > 0)
|
||||||
|
|
@ -1055,7 +1059,7 @@ public:
|
||||||
if (metalRenderer->isAttachedToView (view))
|
if (metalRenderer->isAttachedToView (view))
|
||||||
{
|
{
|
||||||
metalRenderer->detach();
|
metalRenderer->detach();
|
||||||
deferredRepaints = compBounds;
|
setDeferredRepaintsToWholeFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numFramesToSkipMetalRenderer > 0)
|
if (numFramesToSkipMetalRenderer > 0)
|
||||||
|
|
@ -1065,8 +1069,8 @@ public:
|
||||||
{
|
{
|
||||||
if (! metalRenderer->isAttachedToView (view))
|
if (! metalRenderer->isAttachedToView (view))
|
||||||
{
|
{
|
||||||
metalRenderer->attach (view, getComponent());
|
metalRenderer->attach (view, getComponent().isOpaque());
|
||||||
deferredRepaints = compBounds;
|
setDeferredRepaintsToWholeFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1076,8 +1080,6 @@ public:
|
||||||
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
|
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
|
||||||
return metalRenderer->drawRectangleList (view,
|
return metalRenderer->drawRectangleList (view,
|
||||||
(float) [[view window] backingScaleFactor],
|
(float) [[view window] backingScaleFactor],
|
||||||
view.frame,
|
|
||||||
getComponent(),
|
|
||||||
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
|
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
|
||||||
deferredRepaints);
|
deferredRepaints);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue