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 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);


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

@@ -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 componentHeight = comp.getHeight();
const auto transformedFrameSize = CGSizeApplyAffineTransform (view.frame.size, drawableSizeTansform);
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);
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; textureDesc.storageMode = MTLStorageModePrivate;
gpuTexturePool = std::make_unique<GpuTexturePool> (metalDevice, textureDesc); 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 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());
deferredRepaints = compBounds;
metalRenderer->attach (view, getComponent().isOpaque());
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…
Cancel
Save