<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=DE link=blue vlink="#954F72" style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal>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:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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<o:p></o:p></p><p class=MsoNormal>    if (hr == D3DERR_DEVICELOST) {<o:p></o:p></p><p class=MsoNormal>        // Reinitialize the D3DPipeline. This will dispose and recreate<o:p></o:p></p><p class=MsoNormal>        // the resource factory and context for each adapter.<o:p></o:p></p><p class=MsoNormal>        D3DPipeline.getInstance().reinitialize();<o:p></o:p></p><p class=MsoNormal>    }<o:p></o:p></p><p class=MsoNormal>then rendering works again.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>2. D3DContextInit.cc seem to lack the implementation for D3D9Ex to call ResetEx<o:p></o:p></p><p class=MsoNormal>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 <a href="https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9ex-resetex">https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3ddevice9ex-resetex</a>), I'm not sure if ResetEx should be called instead of Reset.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='border:none;padding:0cm'><b>Von: </b><a href="mailto:Thorsten_Fischer@gmx.de">Thorsten Fischer</a><br><b>Gesendet: </b>Freitag, 21. Juli 2023 10:48<br><b>An: </b><a href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a><br><b>Betreff: </b>JavaFX does not recover after graphic card driver crash</p></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Hi all,<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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 :)<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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).<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>           public static final int D3DERR_DEVICEHUNG       = 0X88760874;<o:p></o:p></p><p class=MsoNormal>           <o:p></o:p></p><p class=MsoNormal>           and at the end:<o:p></o:p></p><p class=MsoNormal>           <o:p></o:p></p><p class=MsoNormal>                                if (hr == D3DERR_DEVICEHUNG) {<o:p></o:p></p><p class=MsoNormal>                                setLost();<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                long retryMillis = TimeUnit.MINUTES.toMillis(5);<o:p></o:p></p><p class=MsoNormal>                                long sleepingMillis = TimeUnit.SECONDS.toMillis(1);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                for (int i = 0; i < retryMillis; i += sleepingMillis) {<o:p></o:p></p><p class=MsoNormal>                                          int cooperativeLevel = D3DResourceFactory.nTestCooperativeLevel(pContext);<o:p></o:p></p><p class=MsoNormal>                                          System.err.println("Checking Cooperative Level: " + cooperativeLevel);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                          if (cooperativeLevel == D3D_OK) {<o:p></o:p></p><p class=MsoNormal>                                                     break;<o:p></o:p></p><p class=MsoNormal>                                          } else {<o:p></o:p></p><p class=MsoNormal>                                                     try {<o:p></o:p></p><p class=MsoNormal>                                                                Thread.sleep(sleepingMillis);<o:p></o:p></p><p class=MsoNormal>                                                     } catch (InterruptedException e) {<o:p></o:p></p><p class=MsoNormal>                                                                e.printStackTrace();<o:p></o:p></p><p class=MsoNormal>                                                     }<o:p></o:p></p><p class=MsoNormal>                                          }<o:p></o:p></p><p class=MsoNormal>                                }<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                // reinitialize after 5 mins anyway, even if result is not OK.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                // Reinitialize the D3DPipeline. This will dispose and recreate<o:p></o:p></p><p class=MsoNormal>                                // the resource factory and context for each adapter.<o:p></o:p></p><p class=MsoNormal>                                D3DPipeline.getInstance().reinitialize();<o:p></o:p></p><p class=MsoNormal>                     }<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>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.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Very obviously Thread.sleep is not a good solution. To avoid it I thought about introducing another flag like isLost (-> "isHung") and<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                     if (hr == D3DERR_DEVICEHUNG) {<o:p></o:p></p><p class=MsoNormal>                                setLost();<o:p></o:p></p><p class=MsoNormal>                                setHung();<o:p></o:p></p><p class=MsoNormal>                     }<o:p></o:p></p><p class=MsoNormal>                     <o:p></o:p></p><p class=MsoNormal>                     if (isHung && hr == D3D_OK) {<o:p></o:p></p><p class=MsoNormal>                                isLost = false; // ?<o:p></o:p></p><p class=MsoNormal>                                isHung = false;<o:p></o:p></p><p class=MsoNormal>                                <o:p></o:p></p><p class=MsoNormal>            // Reinitialize the D3DPipeline. This will dispose and recreate<o:p></o:p></p><p class=MsoNormal>            // the resource factory and context for each adapter.<o:p></o:p></p><p class=MsoNormal>            D3DPipeline.getInstance().reinitialize();<o:p></o:p></p><p class=MsoNormal>                     }<o:p></o:p></p><p class=MsoNormal>                     <o:p></o:p></p><p class=MsoNormal>                     <o:p></o:p></p><p class=MsoNormal>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?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Thank you,<o:p></o:p></p><p class=MsoNormal>Thorsten<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>