JDK-4641396 : Loss of video memory causes screen to turn white, and then freeze.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-02-21
  • Updated: 2002-11-05
  • Resolved: 2002-09-25
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 Other
1.4.1_01 01Fixed 1.4.2Fixed
Related Reports
Duplicate :  
Description

Name: jl125535			Date: 02/21/2002


FULL PRODUCT VERSION :
java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

(Reproduced on 1.4 FCS as well.)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]



EXTRA RELEVANT SYSTEM CONFIGURATION :
256Megs of SDRAM, Pentium 3 500mhz, NVDA TNT 16Meg Graphics
card, Tested with both DirectX 6.0 and DirectX 8.1.

A DESCRIPTION OF THE PROBLEM :
I've recently encountered a problem with the Fullscreen API
causing it to freeze up whenever I alt-tab, or recieve a IM
while it's occupying the video memory. It opens up fine and
I've, by over-riding the setVisible method, been able to
find that when it opens setVisible is called and set to
true. However when I close it (by alt-tabbing), the
setVisible method never recieves a "setVisible(false)"
call, nor does my animation loop fall into the code below
the if(bufferStrategy.contentsLost()) statement that is
called every 32 milliseconds by a java.util.Timer. When I
alt-tab, if I place a print statement in the animation
thread, I can see that it's still displaying in the
background and still iterating, and not finding that the
contents of the frame have been lost allthough my desktop
has obviously claimed them. Now, when I return to the
frame, it apears as if it is still atempting to animate
because I find more print statements after I exit yet
again, but now it waits for a couple of seconds, and then
turns pure white and won't allow me to close it unless I
explicitly have my task manager kill the process.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Get a computer system similar to my own,
run "MultiBufferTest" included with the Fullscreen API
documentation.
2.Alt-tab once the program has had a chance to display.

3.Wait a second.

4.Alt-tab again and notice how the screen doesn't display
anything any more.

5.Alt-tab again.

6.Notice how screen turns completely white, and you cannot
exit the program without killing the process.


EXPECTED VERSUS ACTUAL BEHAVIOR :
The BufferStrategy object reclaims the memory upon re-
entering the window, and continues to animate the rest of
the full-color screens.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
It works with MultiBufferTest.java.
---------- END SOURCE ----------
(Review ID: 138539) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.1_01 mantis FIXED IN: 1.4.1_01 mantis INTEGRATED IN: 1.4.1_01 mantis mantis-b07
14-06-2004

EVALUATION This is the ALT-TAB issue mentioned originally in 4480734. Reproducible with Win2K / NVIDIA GeForce 3 and MultiBufferDuke, MultiBufferTest, FullScreenTest, or FullScreenTest2. Committing to mantis. ###@###.### 2002-05-22 The root cause of this is our multi-threaded use of DirectX. The DirectX docs specify that various operations should only be performed on the thread that created the window (in our case, the Windows event thread). In general, these recommendations do not tend to affect DirectX functionality. But in the case of fullscreen functionality, they apparently really mean it. I created a native app to duplicate the problem by creating the fullscreen window on a separate thread. When I alt-tabbed out of the app and back in, I got the exact same response: a white desktop and virtually no response from the OS. I could only quit the application and return to normality by using the Task Manager. So the fix to this bug involves putting fullscreen-related operations on the Windows thread. We do this by sending or posting event messages for the following operations: CreateSurface, SetDisplayMode, EnterFullscreen, ExitFullscreen, and RestoreDisplayMode. Only CreateSurface is performed synchronously (by using SendMessage() instead of PostMessage()); this operation must be finished when we return from the function so we have to do it serially. The other operations all use PostMessage and are thus performed asynchronously. Ideally, all of these events would happen synchronously, but there is always a danger of deadlocks in this code with too many thread dependencies. Note that eventually we should single-thread all DirectX (and probably all rendering) operations on the Windows thread to avoid the deadlock problem and other unknown DirectX problems (it could be that some unsolved DirectX artifact bugs are related to our threading issue). See 4641854 as we work on that problem. Other problems that are fixed as part of this bug are related to our creation and use of back buffers. Previously, we would get a new attached surface from the primary for every request of the back buffer. When we could not alt-tab out and back in again, this did not cause a big problem because there were not many requests for this buffer. But now that we are potentially going out and in again, changing display modes several times, there are lots of recreations of the primary and new requests for this buffer. the problem is that there is really only one back buffer associated with each primary; we should not be deleting or restoring that back buffer directly, nor should we be getting multiple pointers to it from GetAttachedSurface(). instead, we should get the buffer once and share that resource appropriately. All deletions and restorations of that surface happen implicitly via the primary surface.
11-06-2004