JDK-8313648 : JavaFX application continues to show a black screen after graphic card driver crash
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: jfx17
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2023-07-26
  • Updated: 2023-12-08
  • Resolved: 2023-11-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
jfx21.0.2Fixed
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
JavaFX: tested with 17.0.8, but presumably also an issue in the newest version
OS: Windows 10
HW: Notebook with integrated Intel HD Graphics 520

A DESCRIPTION OF THE PROBLEM :
After a graphic card driver crash, in the Windows 10 event log is protocolled "Display driver igfx stopped responding and has successfully recovered.", yet the JavaFX application only continues to show a black screen. Input events are still registered, which indicates a Prism issue.

With prism.verbose debug output, the console shows "D3DContext::testLostStateAndReset : Unknown D3D error 0x88760874"
0x88760874 is the error code for D3DERR_DEVICEHUNG (D3D9_Ex_ (!)) which corresponds to the error in the Windows event log. In D3DContext.java#testLostStateAndReset this error is not specifically handled.


CUSTOMER SUBMITTED WORKAROUND :
A try-and-error approach with the following  changes in D3DContext.java#testLostStateAndReset:

	public static final int D3DERR_DEVICEHUNG    	= 0X88760874;
	
	if (hr == D3DERR_DEVICEHUNG) {
		setLost();

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

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

			if (cooperativeLevel == D3D_OK) {
				break;
			} else {
				try {
					Thread.sleep(sleepMillis);
				} 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();
	}
		
has been sucessful and rendering is working again. The System.err output generated inside the loop only showed again 21 times the D3DERR_DEVICEHUNG error code (equals to 20 seconds in the retry loop), and after that it showed the D3D initialization output. This indicates, that the pd3dDeviceEx->CheckDeviceState returns D3D_OK at some point, but this maybe only apply to the HAL-adapter state, but imho the D3D9(Ex) state has actually been corrupted. As documented here https://learn.microsoft.com/en-us/windows/win32/direct3d9/dx9lh#device-behavior-changes ("If hardware hangs, texture memory is lost. After a driver is stopped, the IDirect9Ex object must be recreated to resume rendering."), it seems that D3DPipeline.getInstance().reinitialize() does the trick.


Comments
Per the discussion in these PR comments [1] [2], I have just now integrated the backport of this bug fix to jfx21u for JavaFX 21.0.2, which will be released in January. [~jvos] (or someone else) can do this for jfx17u if desired. [1] https://git.openjdk.org/jfx/pull/1199#issuecomment-1832413688 [2] https://git.openjdk.org/jfx/pull/1199#issuecomment-1832499586
01-12-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jfx21u/pull/37 Date: 2023-12-01 13:24:17 +0000
01-12-2023

Approved to backport to jfx21u.
29-11-2023

Changeset: b80ec391 Author: Thorsten Fischer <39555455+tsx84@users.noreply.github.com> Committer: Kevin Rushforth <kcr@openjdk.org> Date: 2023-11-29 12:01:52 +0000 URL: https://git.openjdk.org/jfx/commit/b80ec391cbba72d84b4b862b3f1b8db2ff8eb6e2
29-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jfx/pull/1199 Date: 2023-08-05 12:28:16 +0000
01-10-2023

As indicated in the description, we might be able to fix this by detecting D3DERR_DEVICEHUNG, and calling the same reinitialization logic added in JDK-8239589 for the case of D3DERR_DEVICEREMOVED.
02-08-2023

No, this has nothing to do with JDK-8298796. That is a specific repaint issue for SwingNode. This bug is a graphics bug relating to the D3D pipeline.
02-08-2023

Looks like duplicate of JDK-8298796, Moving to JDK Project for review.
02-08-2023