On the latest tip of juce8 I hit this assertion when clicking Button 1
in the Demo’s ComponentTransformsDemo
:
Stack trace:
Then there’s the same assertion getting hit when clicking the following slider in the same demo:
Stack trace:
On the latest tip of juce8 I hit this assertion when clicking Button 1
in the Demo’s ComponentTransformsDemo
:
Stack trace:
Then there’s the same assertion getting hit when clicking the following slider in the same demo:
Stack trace:
Looks like it’s an error in the assert. Thanks for catching that. Should be easy enough to sort out.
Matt
The assert also needed to check if the layer transform is axis aligned. I’ve attached a patch.
Or, you can replace the assert you highlighted and the isGeometryAxisAligned function with this:
#if JUCE_DEBUG
// Check if this should be an axis-aligned clip layer (per the D2D debug layer)
//
// D2D DEBUG INFO - PERF - A layer is being used with a NULL opacity mask, 1.0 opacity, and an axis aligned rectangular geometric mask.The Push / Pop Clip API should achieve the same results with higher performance.
auto checkAxisAlignedClipLayer = [&]()
{
struct Sink : public ComBaseClassHelper<ID2D1SimplifiedGeometrySink>
{
D2D1_POINT_2F lastPoint {};
bool axisAlignedLines = true;
UINT32 lineCount = 0;
STDMETHOD_ (void, SetFillMode)
(D2D1_FILL_MODE) override { return; }
STDMETHOD_ (void, SetSegmentFlags)
(D2D1_PATH_SEGMENT) override { return; }
STDMETHOD_ (void, BeginFigure)
(D2D1_POINT_2F p, D2D1_FIGURE_BEGIN) override
{
lastPoint = p;
return;
}
STDMETHOD_ (void, AddLines)
(const D2D1_POINT_2F* points, UINT32 count) override
{
for (UINT32 i = 0; i < count; ++i)
{
auto p = points[i];
axisAlignedLines &= approximatelyEqual (p.x, lastPoint.x) || approximatelyEqual (p.y, lastPoint.y);
lastPoint = p;
}
lineCount += count;
return;
}
STDMETHOD_ (void, AddBeziers)
(const D2D1_BEZIER_SEGMENT*, UINT32) override
{
axisAlignedLines = false;
return;
}
STDMETHOD_ (void, EndFigure)
(D2D1_FIGURE_END) override
{
return;
}
STDMETHOD (Close)
() override { return S_OK; }
} sink;
if (layerParameters.opacity != 1.0f)
return false;
if (layerParameters.opacityBrush)
return false;
if (! layerParameters.geometricMask)
return false;
if (layerParameters.maskTransform.m12 != 0.0f || layerParameters.maskTransform.m21 != 0.0f)
return false;
layerParameters.geometricMask->Simplify (D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
D2D1::Matrix3x2F::Identity(),
1.0f,
&sink);
//
// Check for 3 lines; BeginFigure counts as 1 line
//
return sink.axisAlignedLines && sink.lineCount == 3;
};
jassert (! checkAxisAlignedClipLayer());
#endif
Matt
direct2d_axis_aligned_assert.patch (5.3 KB)
That seems to do the trick.
I’m also having this problem on the latest juce8 branch with an svg drawable, like so:
svg->drawAt (g, x, y, 1.0f);
I tried the patch, but this still asserts:
jassert (! checkAxisAlignedClipLayer());
We’ve added a fix for these assertions here:
It’s a bit different to the patch posted above. Please let us know if you’re still seeing issues with this change applied.
For me the assertion still fires when using a reduceClipRegion with a rounded path. I can’t run the debug version of our projects anymore, unless I comment out the assert. In release mode, everything seems to behave correctly, so not sure what the assertion is supposed to warn me about.
Here is more context:
I have no idea where this weird contentBounds
comes from.
These assertions get triggered if I nest two juce::Graphics::ScopedSaveState
inside each other, with the second reduceClipRect within the first.
// Keep all rendering within the rounded parent rectangle
auto ss = juce::Graphics::ScopedSaveState ( g );
auto p = juce::Path ();
p.addRoundedRectangle ( getLocalBounds ().toFloat (), 5.0 );
g.reduceClipRect ( p );
{
// Keep image within its own quadrant AND inside the rounded parent
auto sss = juce::Graphics::ScopedSaveState ( g );
g.reduceClipRect ( 0, 0, 50, 50 );
g.drawImage...
}
Why does the assertion check that opacity != 1.0f
? Shouldn’t it instead make sure that it’s 1.0? If I change that assertion to opacity == 1.0f
, then the debug mode works fine again…
The assert is checking if the renderer is using the correct type of clipping layer. Specifically, the assert checks if the renderer is using a slower, more general-purpose clipping layer when it could be using a faster axis-aligned rectangular clipping layer.
The Direct2D docs recommend using an axis-aligned clipping layer whenever possible. The specific conditions in the assert are taken from a message generated by the Direct2D debug layer:
D2D DEBUG INFO - PERF - A layer is being used with a NULL opacity mask, 1.0 opacity, and an axis aligned rectangular geometric mask. The Push/Pop Clip API should achieve the same results with higher performance.
The renderer will still operate correctly in either case; the assert is just there to help improve performance.
Matt
I’m trying to reproduce your results.
Matt
That is fine for your internal purposes but not for us as users of JUCE. This is a complete and utter show-stopper, as we can no longer run the debug version of our products.
Maybe put this assertion under a new #define until everything has been optimized, JUCE8 has officially been released, and the assertion can be removed?
Feel free to Skype me and we can run the app together and you can browse around
Same here. Happens with normal rectangles too.
We’re sorting this one out; for now I recommend commenting out that assertion.
Matt
Yep, it turns out it triggers for all paths that are just rectangles. So my first Path (with the rounded rectangle) doesn’t trigger the assertion, but the second Path (just a path consisting of a rectangle) triggers it.
I can’t use the g.reduceClipRegion ( juce::Rectangle<int> );
version, because it only accepts integer rectangles, but I need a float rectangle here.
Is this still not fixed? I just spent the last two days drilling down trying to find out which of my components was causing this weird assertion, only to find that if I comment that assertion out, everything works perfectly.
If this was listed in the breaking changes doc it would have saved me alot of wasted time.
On the plus side: the fonts look nice!
I’m not sure what the official decision is here. For now I recommend changing preprocessor directive to #if JUCE_DEBUG && JUCE_DIRECT2D_METRICS
Matt