Menu

#2420 Crash in d2d1.dll when using Scintilla with multiple GUI threads

Bug
closed-fixed
nobody
5
2024-03-05
2023-12-05
No

We are using Scintilla with Technology::DirectWrite in an application with multiple GUI threads where each GUI thread has its own Scintilla controls. Every now and then our application crashed in d2d1.dll when ScintillaWin::PaintDC() is executed.

We found the reason for this crash in the global variable ID2D1Factory *pD2DFactory (PlatWin.cxx) which is instantiated for single threaded use.

Creating a multi threaded version of the factory fixes the issue:

    hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, loadLibraryFlags);
    D2D1CFSig fnD2DCF = DLLFunction<D2D1CFSig>(hDLLD2D, "D2D1CreateFactory");
    if (fnD2DCF) {

-       // A single threaded factory as Scintilla always draw on the GUI thread
-       fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+       // A multi threaded factory in case Scintilla is used with multiple GUI threads
+       fnD2DCF(D2D1_FACTORY_TYPE_MULTI_THREADED,
            __uuidof(ID2D1Factory),
            nullptr,
            reinterpret_cast<IUnknown**>(&pD2DFactory));

Discussion

  • Neil Hodgson

    Neil Hodgson - 2023-12-06

    where each GUI thread has its own Scintilla controls

    That isn't a designed or tested configuration and may have more problems. More common is running instances of Scintilla on the GUI thread and using SendMessage from secondary threads to update the Scintilla controls.

    Creating a multi threaded version of the factory fixes the issue

    I'm worried about decreasing performance for such unusual circumstances,

     
    • Markus Nißl

      Markus Nißl - 2023-12-06

      I'm worried about decreasing performance for such unusual circumstances,

      The documentation on Developing Thread-Safe Apps that Call Only Direct2D APIs reads:

      You can create a multithreaded Direct2D factory instance. You can use and share a multithreaded factory and all its resources from more than one thread, but accesses to those resources (via Direct2D calls) are serialized by Direct2D, so no access conflicts occur. If your app calls only Direct2D APIs, such protection is automatically done by Direct2D in a granular level with minimum overhead.

       

      Last edit: Markus Nißl 2023-12-06
  • Neil Hodgson

    Neil Hodgson - 2024-01-17
    • labels: --> scintilla, direct2d
    • status: open --> open-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2024-01-17

    Committed as [d8e2ab].

    There appears to be a tiny (~0.5%) performance decrease with this option on a busy view with many rounded-rectangle highlights, concentrated in allocation / release methods like D2DGeometrySink<SingleThreadedTrait>::Close (0.02%) -> D2DGeometrySink<MultiThreadedTrait>::Close (0.04%).

     

    Related

    Commit: [d8e2ab]

  • Neil Hodgson

    Neil Hodgson - 2024-03-05
    • status: open-fixed --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB