I now opened a bug report for my issue. But as I'm trying to figure out the 
implementation of the D3D pipeline I found two things:

1. Only somewhat related to my issue, but I found that the existing recovery 
method for D3DERR_DEVICELOST / D3DERR_DEVICENOTRESET is not working when a 
device lost error is forced via the command line "dxcap -forcetdr". To 
reproduce: just run any JavaFX app with prism.verbose and run the command (in 
an admin console). The window will stay white and 
D3DContext::testLostStateAndReset : D3DERR_DEVICELOST is printed over and over. 
I'm unsure if this test method is valid, but regardless: the app does not come 
into the D3DERR_DEVICENOTRESET state and therefore nResetDevice will not be 
called. When I'm chaning the implementation to
    if (hr == D3DERR_DEVICELOST) {
        // Reinitialize the D3DPipeline. This will dispose and recreate
        // the resource factory and context for each adapter.
        D3DPipeline.getInstance().reinitialize();
    }
then rendering works again.

2. D3DContextInit.cc seem to lack the implementation for D3D9Ex to call ResetEx
But as Reset and ResetEx behave differently ("Unlike previous versions of 
DirectX, calling IDirect3DDevice9Ex::ResetEx does not cause surfaces, textures 
or state information to be lost.", regarding to this doc 
https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9ex-resetex),
 I'm not sure if ResetEx should be called instead of Reset.

Von: Thorsten Fischer
Gesendet: Freitag, 21. Juli 2023 10:48
An: openjfx-dev@openjdk.org
Betreff: JavaFX does not recover after graphic card driver crash

Hi all,

first off all I want to say ‚thank you‘ to everyone in this community for all 
the effort you put in. I'm using JavaFX for years now and I'm really happy to 
work with it :)

I have the following issue/question: One of my customers experiences an 
application crash when running their JavaFX application for a longer period on 
a notebook with integrated Intel graphics. First of all, I think JavaFX does 
not cause the issue, but is rather affected by it. We built a workaround in 
JavaFX, but I'd like to discuss what a good solution would look like, so that 
it can be integrated into the JFX code base.

So, randomly between a couple of days to about 3 weeks the graphic card driver 
crashes. In the Windows (10) event log you can read: "Display driver igfx 
stopped responding and has successfully recovered.". In the console of the app 
it says: "D3DContext::testLostStateAndReset : Unknown D3D error 0x88760874". 
The app then just shows a black screen and keeps printing this error over and 
over to the console (rendering is triggered regularly in this app) and never 
recovers, even though the driver has been recovered and the whole system is 
running and is usable (again).

The error code 0x88760874 translates to D3DERR_DEVICEHUNG 
(https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3derr), what 
corresponds to the error in the Windows event log.

Now our initial workaround (within D3DContext.java#testLostStateAndReset) is 
basically the same as for D3DERR_DEVICEREMOVED, but with a loop to give the OS 
time to recover:

           public static final int D3DERR_DEVICEHUNG       = 0X88760874;
           
           and at the end:
           
                                if (hr == D3DERR_DEVICEHUNG) {
                                setLost();

                                long retryMillis = TimeUnit.MINUTES.toMillis(5);
                                long sleepingMillis = 
TimeUnit.SECONDS.toMillis(1);

                                for (int i = 0; i < retryMillis; i += 
sleepingMillis) {
                                          int cooperativeLevel = 
D3DResourceFactory.nTestCooperativeLevel(pContext);
                                          System.err.println("Checking 
Cooperative Level: " + cooperativeLevel);

                                          if (cooperativeLevel == D3D_OK) {
                                                     break;
                                          } else {
                                                     try {
                                                                
Thread.sleep(sleepingMillis);
                                                     } catch 
(InterruptedException e) {
                                                                
e.printStackTrace();
                                                     }
                                          }
                                }

                                // reinitialize after 5 mins anyway, even if 
result is not OK.

                                // Reinitialize the D3DPipeline. This will 
dispose and recreate
                                // the resource factory and context for each 
adapter.
                                D3DPipeline.getInstance().reinitialize();
                     }

Yesterday we experienced with this workaround, that the app did actually 
recover after 20 seconds. The System.err output generated inside the loop only 
showed again the D3DERR_DEVICEHUNG error code, and after 20 sec. console showed 
the initialization output.

Very obviously Thread.sleep is not a good solution. To avoid it I thought about 
introducing another flag like isLost (-> "isHung") and

                     if (hr == D3DERR_DEVICEHUNG) {
                                setLost();
                                setHung();
                     }
                     
                     if (isHung && hr == D3D_OK) {
                                isLost = false; // ?
                                isHung = false;
                                
            // Reinitialize the D3DPipeline. This will dispose and recreate
            // the resource factory and context for each adapter.
            D3DPipeline.getInstance().reinitialize();
                     }
                     
                     
But before I continue with this direction (and because it takes weeks to 
reproduce this): Can anybody confidently tell me what a better/good solution 
may look like?

Thank you,
Thorsten

Reply via email to