Browse Source

macOS/iOS: Fix a scaled multiple-rects drawing issue

v7.0.9
Tom Poole 2 years ago
parent
commit
61fd8827e1
3 changed files with 19 additions and 23 deletions
  1. +1
    -3
      modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm
  2. +9
    -13
      modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h
  3. +9
    -7
      modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm

+ 1
- 3
modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm View File

@@ -1391,7 +1391,7 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, int windowStyleFlags,
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
if (@available (iOS 13, *))
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<UIView>> (view, comp);
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<UIView>> (view, comp.isOpaque());
#endif
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
@@ -1857,8 +1857,6 @@ void UIViewComponentPeer::displayLinkCallback()
if (metalRenderer != nullptr)
return metalRenderer->drawRectangleList (view,
(float) view.contentScaleFactor,
view.frame,
component,
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
deferredRepaints);


+ 9
- 13
modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h View File

@@ -35,12 +35,12 @@ class CoreGraphicsMetalLayerRenderer
{
public:
//==============================================================================
CoreGraphicsMetalLayerRenderer (ViewType* view, const Component& comp)
CoreGraphicsMetalLayerRenderer (ViewType* view, bool isOpaque)
{
device.reset (MTLCreateSystemDefaultDevice());
commandQueue.reset ([device.get() newCommandQueue]);
attach (view, comp);
attach (view, isOpaque);
}
~CoreGraphicsMetalLayerRenderer()
@@ -52,7 +52,7 @@ public:
}
}
void attach (ViewType* view, const Component& comp)
void attach (ViewType* view, bool isOpaque)
{
#if JUCE_MAC
view.wantsLayer = YES;
@@ -65,7 +65,7 @@ public:
layer.device = device.get();
layer.framebufferOnly = NO;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
layer.opaque = comp.isOpaque();
layer.opaque = isOpaque;
layer.allowsNextDrawableTimeout = NO;
attachedView = view;
@@ -90,8 +90,6 @@ public:
template <typename Callback>
bool drawRectangleList (ViewType* view,
float scaleFactor,
CGRect viewFrame,
const Component& comp,
Callback&& drawRectWithContext,
const RectangleList<float>& dirtyRegions)
{
@@ -117,14 +115,12 @@ public:
layer.contentsScale = scaleFactor;
const auto drawableSizeTansform = CGAffineTransformMakeScale (layer.contentsScale,
layer.contentsScale);
const auto transformedFrameSize = CGSizeApplyAffineTransform (viewFrame.size, drawableSizeTansform);
const auto componentHeight = comp.getHeight();
const auto transformedFrameSize = CGSizeApplyAffineTransform (view.frame.size, drawableSizeTansform);
if (resources == nullptr || ! CGSizeEqualToSize (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();
@@ -261,7 +257,7 @@ private:
class Resources
{
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);
@@ -301,8 +297,8 @@ private:
CGColorSpaceCreateWithName (kCGColorSpaceSRGB),
(uint32_t) kCGImageAlphaPremultipliedFirst | (uint32_t) kCGBitmapByteOrder32Host));
CGContextScaleCTM (cgContext.get(), layer.contentsScale, layer.contentsScale);
CGContextConcatCTM (cgContext.get(), CGAffineTransformMake (1, 0, 0, -1, 0, componentHeight));
CGContextTranslateCTM (cgContext.get(), 0, layer.drawableSize.height);
CGContextScaleCTM (cgContext.get(), layer.contentsScale, -layer.contentsScale);
textureDesc.storageMode = MTLStorageModePrivate;
gpuTexturePool = std::make_unique<GpuTexturePool> (metalDevice, textureDesc);


+ 9
- 7
modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -151,7 +151,7 @@ public:
#if USE_COREGRAPHICS_RENDERING
#if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS
if (@available (macOS 10.14, *))
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<NSView>> (view, getComponent());
metalRenderer = std::make_unique<CoreGraphicsMetalLayerRenderer<NSView>> (view, getComponent().isOpaque());
#endif
if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0)
{
@@ -1047,7 +1047,11 @@ public:
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 ([window inLiveResize] || numFramesToSkipMetalRenderer > 0)
@@ -1055,7 +1059,7 @@ public:
if (metalRenderer->isAttachedToView (view))
{
metalRenderer->detach();
deferredRepaints = compBounds;
setDeferredRepaintsToWholeFrame();
}
if (numFramesToSkipMetalRenderer > 0)
@@ -1065,8 +1069,8 @@ public:
{
if (! metalRenderer->isAttachedToView (view))
{
metalRenderer->attach (view, getComponent());
deferredRepaints = compBounds;
metalRenderer->attach (view, getComponent().isOpaque());
setDeferredRepaintsToWholeFrame();
}
}
}
@@ -1076,8 +1080,6 @@ public:
if (metalRenderer != nullptr && metalRenderer->isAttachedToView (view))
return metalRenderer->drawRectangleList (view,
(float) [[view window] backingScaleFactor],
view.frame,
getComponent(),
[this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); },
deferredRepaints);


Loading…
Cancel
Save