JDK-8117239 : NullPointerException when rendering image
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 7u6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2012-06-02
  • Updated: 2015-06-17
  • Resolved: 2012-06-19
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.
JDK 7
7u6Fixed
Related Reports
Relates :  
Relates :  
Description
The attached program loads an image in the background
and is then supposed to render it when it is fully loaded.
This worked until recently but now results in a NPE
with the latest build of JavaFX (2.2 b11).

Progress: 10.0%
Progress: 21.0%
Progress: 32.0%
Progress: 43.0%
Progress: 54.0%
Progress: 65.0%
Progress: 76.0%
Progress: 86.0%
Progress: 97.0%
Progress: 100.0%
java.lang.NullPointerException
	at com.sun.prism.impl.BaseGraphics.drawTextureVO(BaseGraphics.java:418)
	at com.sun.prism.impl.BaseGraphics.drawTexture(BaseGraphics.java:351)
	at com.sun.prism.image.Coords.draw(Coords.java:29)
	at com.sun.prism.image.CompoundCoords.draw(CompoundCoords.java:83)
	at com.sun.javafx.sg.prism.NGImageView.renderContent(NGImageView.java:127)
	at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:187)
	at com.sun.javafx.sg.prism.NGImageView.doRender(NGImageView.java:97)
	at com.sun.javafx.sg.prism.NGImageView.doRender(NGImageView.java:20)
	at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1133)
	at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:204)
	at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:420)
	at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:187)
	at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:39)
	at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1133)
	at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:117)
	at com.sun.javafx.tk.quantum.AbstractPainter.paintImpl(AbstractPainter.java:181)
	at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:73)
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
	at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
	at com.sun.prism.render.RenderJob.run(RenderJob.java:37)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:96)
	at java.lang.Thread.run(Unknown Source)

Comments
Submitter confirmed the fix. Will close the issue.
27-07-2012

Since this is a graphics-card-specific bug (and requires rendering in order to test it), there is no Unit Test for this.
19-06-2012

Pushed the following changeset: http://jfxsrc.us.oracle.com/javafx/2.2/scrum/graphics/rt-closed/rev/46f1d00666c8 By default, we will clamp the max texture size reported by the graphics card to 4096. For debugging purposes only, we have added a new system property "prism.maxTextureSize" which takes an integer representing the max size that we will clamp to. -Dprism.maxTextureSize=2048 // clamp to 2048 -Dprism.maxTextureSize=0 // unlimited (no clamping) This will be in 2.2-b14
19-06-2012

One thing to try is to run with slightly less memory or to try running a 64-bit JDK. On my system, if I use -Xmx1000m (instead of 1024m) it manages to load one 8K x 8K texture, at least running the simple test app. Similarly, when I run on a 64-bit JDK, it is able to load one 8K x 8K texture. We still plan to limit to 4k for the 2.2 release until we are ready to handle runtime failures, since it will greatly reduce the chance of failure. As part of this, we will include a System property (for testing) to allow the limit to be changed.
15-06-2012

I although think that this doesn't appear to be a driver problem, but rather an issue with not enough memory on the card. The long term solution is to detect a failure to allocate a large texture and successively back off to a smaller texture size until one is found that will work. For 2.2, we will likely address this problem by just clamping the size to 4096 which we hope will resolve it for the majority of use cases.
13-06-2012

I have recently updated the driver on my machine (see attached new NVIDIA System Information) going from version 188.43 to the latest 296.70 but the problem is still the same. This suggests that it is not a specific driver problem.
13-06-2012

I just have tested this on my laptop with NVS boad, the driver and the graphics information is attached The huge image gets loaded without issues. The card reported that max sizeis 8192 and it successfully created an image with size 8192 * 8912. I do not think that clamping max size is a nice solution. It definitely some kind of driver problem. Different drivers should be tested.
13-06-2012

I verified that this is not a regression; JavaFX 2.1 fails in the same manner on my system, so I am removing the "regression" keyword.
06-06-2012

I very much doubt that this is a driver problem. It seems to be a simple texture memory allocation limit. Here is what I discovered on my system. In this test, I allocate some extra textures the first time rendering happens (note that there are a couple initial textures that have already been allocated by Prism at the time I do this, specifically the RTT used by the Swap Chain): 8K * 2K : Can create 6 such textures, the 7th fails 4K * 4K : Can create 6 such textures, the 7th fails 8K * 4K : Can create 1 such texture, the 2nd fails 8K * 8K : Cannot create any of this size, the 1st fails Given memory alignment issues, etc, this all seems consistent with a lack of texture memory.
06-06-2012

Given that we have image tiling code in place, it seems reasonable for FX 2.2 to clamp the maximum texture size reported by getMaximumTextureSize() to a smaller value, such as 4096. Note that an 8192 * 8192 RGBA texture is 256 Mbytes.
06-06-2012

I tried different values for clamping the max texture size, and see the following performance on my NVIDIA NVS (for a single imageview using the image attached to this bug report): 64 : crash // we end up trying to load too many textures and some of them fail. The app goes non-responsive and eventually crashed. 128 : 48 fps // noticeably slower loading the image 256 : 104 fps 512 : 105 fps 1024 : 125 fps 2048 : 140 fps 4096 : 143 fps
06-06-2012

Interesting. The following D3D device initialization code reports 8192x8192 : D3DCAPS9 *caps = pCtx->GetDeviceCaps(); DWORD maxw = caps->MaxTextureWidth; DWORD maxh = caps->MaxTextureHeight; Also, I verified that creating a texture of 8192 x 4096 succeeds, but I cannot create two such textures. A single texture of 8192 x 8192 fails. It appears that we just cannot create a texture that large on this particular card even though both dimensions (width and height) are OK.
06-06-2012

according to DxCaps_DIAG log you card has 4096 as a maximum of texture dimentions.
05-06-2012

Additional testing on a Mac mini with Intel HD graphics shows a different failure mode when running the test program using the default max size of 8192. Instead of an NPE it just renders garbage for the 8192x8192 texture. If I clamp it to 4096 it renders fine. We still need to get to the root cause, but it seems we may have a simple workaround / solution by clamping the max texture size to 4096.
05-06-2012

I did some testing and discovered that if I clamp the max texture size to 4096, instead of the 8192 that the NVIDIA card reports, the program works fine. So it seems that this is either an NVIDIA driver bug, or else there is some other condition we aren't checking that can cause texture allocation to fail for large dimensions.
05-06-2012

Here is the output of prism.verbose=true on my system with NVIDIA NVS 4200M. I will attach the output of DirectXCapsViewer shortly. Prism pipeline init order: d3d j2d Using t2k for text rasterization Using dirty region optimizations Prism pipeline name = com.sun.prism.d3d.D3DPipeline Loading D3D native library ... succeeded. Direct3D initialization succeeded (X) Got class = class com.sun.prism.d3d.D3DPipeline Initialized prism pipeline: com.sun.prism.d3d.D3DPipeline OS Information: Windows 7 build 7601 D3D Driver Information: NVIDIA NVS 4200M \\.\DISPLAY1 Driver nvumdshim.dll, version 8.17.12.6696 Pixel Shader version 3.0 Device : ven_10DE, dev_1056, subsys_14941028 RESIZE: 440936118320282 w: 800 h: 800 Progress: 10.0% Progress: 21.0% Progress: 32.0% Progress: 43.0% Progress: 54.0% Progress: 65.0% Progress: 76.0% Progress: 86.0% Progress: 97.0% Progress: 100.0% java.lang.NullPointerException at com.sun.prism.impl.BaseGraphics.drawTextureVO(BaseGraphics.java:418) at com.sun.prism.impl.BaseGraphics.drawTexture(BaseGraphics.java:351) at com.sun.prism.image.Coords.draw(Coords.java:29) at com.sun.prism.image.CompoundCoords.draw(CompoundCoords.java:83) at com.sun.javafx.sg.prism.NGImageView.renderContent(NGImageView.java:127) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:187) at com.sun.javafx.sg.prism.NGImageView.doRender(NGImageView.java:97) at com.sun.javafx.sg.prism.NGImageView.doRender(NGImageView.java:20) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1133) at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:204) at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:420) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:187) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:39) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1133) at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:117) at com.sun.javafx.tk.quantum.AbstractPainter.paintImpl(AbstractPainter.java:181) at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:73) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178) at com.sun.prism.render.RenderJob.run(RenderJob.java:37) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:96) at java.lang.Thread.run(Thread.java:722) QuantumRenderer: shutdown
05-06-2012

Can you please run DirectXCapsViewer and print D3DDevice\Quadro FX 2800M subtree to a file and attach it to the issue ? Thanks
05-06-2012

I guess you meant -Xmx1024m. That's the same setting that I have used. I just repeated the test and it still fails. I run on a laptop Dell precision M6500 with Windows 7 (32bit) JDK 7 u4. I've also attached the NVIDIA System Information.
05-06-2012

It runs fine for me, with a heap size of -X1024m (I didn't try it with smaller, but it does need more than the default).
05-06-2012

I am glad you could finally reproduce it. I know that bugs which only show up under certain circumstances or environments are a pain. But now there is hope for a fix :-)
05-06-2012

I can now reproduce this with the current build if I use an NVIDIA graphics card. My laptop has both an Nvidia and Intel HD graphics chipset, and I usually run the Intel HD for better battery life. If I switch to the NVIDIA I get the same exception you reported.
05-06-2012

Yes, I meant -Xmx1024m. I also was running JDK 7u4 32-bit on Windows 7 on a Dell laptop. I will retry with FX 2.2-b11 (I was running a local build with post-b11 changes that go into b12, but I don't think there are any substantive differences in image rendering).
05-06-2012