Float overflow in direct2d

Hi,

In my application, on windows, with latest develop, when I open some window that contains a lot of text I’m getting reproducible crashes after a few repaints (I have exceptions on float overflow enabled).

I’m getting float overflow exceptions in

void Direct2DGraphicsContext::drawGlyphs

The line

brush->GetTransform (&matrix);

returns a matrix where the _11 and _31 elements are abritrarily large (1e20, 1e30 etc..)

From what I can see the brush in Direct2DGraphicsContext::SavedState has already an invalid transform when SavedState is constructed

juce::Direct2DGraphicsContext::SavedState::SavedState                   - juce-git\modules\juce_graphics\native\juce_Direct2DGraphicsContextImpl_windows.cpp:325
juce::Direct2DGraphicsContext::Pimpl::pushFirstSavedState               - juce-git\modules\juce_graphics\native\juce_Direct2DGraphicsContextImpl_windows.cpp:699 
juce::Direct2DGraphicsContext::Pimpl::startFrame                        - juce-git\modules\juce_graphics\native\juce_Direct2DGraphicsContextImpl_windows.cpp:658 
juce::Direct2DHwndContext::HwndPimpl::startFrame                        - juce-git\modules\juce_gui_basics\native\juce_Direct2DHwndContext_windows.cpp:564       
juce::Direct2DGraphicsContext::startFrame                               - juce-git\modules\juce_graphics\native\juce_Direct2DGraphicsContext_windows.cpp:278     
juce::D2DRenderContext::WrappedD2DHwndContext::startFrame               - juce-git\modules\juce_gui_basics\native\juce_Windowing_windows.cpp:5346                
juce::D2DRenderContext::onSwapchainEvent                                - juce-git\modules\juce_gui_basics\native\juce_Windowing_windows.cpp:5293                
juce::Direct2DHwndContext::HwndPimpl::SwapChainThread::subclassWindowProc  - juce-git\modules\juce_gui_basics\native\juce_Direct2DHwndContext_windows.cpp:351    
DefSubclassProc                                                                                                                                                  
GetWindowSubclass                                                                                                                                                
CallWindowProcW                                                                                                                                                  
IsWindowUnicode                                                                                                                                                  
juce::InternalMessageQueue::dispatchNextMessage                         - juce-git\modules\juce_events\native\juce_Messaging_windows.cpp:160                     
juce::MessageManager::runDispatchLoop                                   - juce-git\modules\juce_events\messages\juce_MessageManager.cpp:124                      
juce::JUCEApplicationBase::main                                         - juce-git\modules\juce_events\messages\juce_ApplicationBase.cpp:281                                                               

I’m not sure how to investigate further..

Are you absolutely certain you’re using the latest develop? We pushed a change that affected the brush transform when drawing text yesterday:

I’d be interested to know whether you see the same issue before and after this commit.

Yes, I still have this transform issue with the latest develop, I do see that the patch you mention is applied. But it also happened before yesterday, so your patch did not break something.

1 Like

I’ve started investigating, but I can’t provoke the issue in the demo runner. I focused on testing the fonts demos and component-transforms demo. So, Im only able to guess at the problem.

The issue from yesterday was caused because the brush transform wasn’t reset on each frame, so each new transform would combine with the existing transform. I can imagine this causing overflows after a few frames, so maybe we’re still missing one or two places where the transform needs to be reset. I see that SavedState::getBrush only updates the current brush transform if it’s a gradient/image brush, so maybe we’re incorrectly transforming the plain colour brush.

Please could you try making the following change: In juce_Direct2DGraphicsContext_windows.cpp, replace lines 1143-1146 like so (effectively surrounding the existing lines with the new check):

if (brush != currentState->colourBrush)
{
    D2D1::Matrix3x2F matrix{};
    brush->GetTransform (&matrix);
    const auto brushTransform = D2DUtilities::matrixToTransform (matrix);
    brush->SetTransform (D2DUtilities::transformToMatrix (brushTransform.followedBy (textTransform.inverted())));
}

Does the program still render correctly for you with this change in place, and does this prevent the floating point exceptions?

If that doesn’t work, my next guess would be that we’re failing to correctly initialise a transform somewhere. In that case it’d be helpful to know whether you see different behaviour in release/debug, or perhaps when using a different compiler.

Thanks , it seems to fix it !

By the way I managed to reproduce the issue in DemoRunner this way:

in SavedState constructor add this:

        D2D1::Matrix3x2F matrix{};
	colourBrushIn->GetTransform (&matrix);
	if (std::abs(matrix._11) > 1000) {
		DBG("Strange: " << matrix._11);
	    }
	}

and then open the WidgetsDemo and continuously resize the DemoRunner window by shaking the mouse. Without your patch, the _11 value is continuously growing.

1 Like

Thanks for reporting this bug, it’s now fixed on develop: