United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6596702 D3D: intermittent repainting issues in SwingSet after restoring from fs mode
JDK-6596702 : D3D: intermittent repainting issues in SwingSet after restoring from fs mode

Details
Type:
Bug
Submit Date:
2007-08-24
Status:
Closed
Updated Date:
2010-10-14
Project Name:
JDK
Resolved Date:
2008-01-08
Component:
client-libs
OS:
windows_vista,windows_xp
Sub-Component:
2d
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u5,6u10
Fixed Versions:
6u10 (b10)

Related Reports
Duplicate:
Relates:
Relates:

Sub Tasks

Description
From the description of 6593550

I have noticed few other issues -

1. When SwingSet2 is visible on the screen, I am pushing the command prompt to FS mode and restoring to enforce a surface loss. Doing this a few times makes some of the components appear black.

2. Push the command prompt to FS mode and restore it. After that, move the SwingSet2 from one screen to the other. The entire UI becomes garbled.

                                    

Comments
EVALUATION

Note that the second part from the description:
> 2. Push the command prompt to FS mode and restore it. After that, move the SwingSet2 from > one screen to the other. The entire UI becomes garbled.

is not reproducible, possibly  after the fix for 6593621.

The first issue appears to be caused by copies from VI to 
software surfaces.
It looks like at some point we get a software 
back-buffer, but some of the Swing's volatile images
(like those used for rendering gradients) are still
accelerated. May be they don't get restored properly
or something similar, and produce garbage when
copied to the sw backbuffer.

All issues disappear after a resize (when a new accelerated
back-buffer is created).

More investigation is needed.
                                     
2007-08-24
EVALUATION

The problem is caused by the D3DScreenUpdateManager.

In particular, if the onscreen surface is in the lost state when 
createGraphics() is called we call validate() which may 
restore the surface and return a graphics object with this 
surface.

However it doesn't issue a repaint after restoring
the surface (like we do in run() method), so the application 
assumes that its appearance is fine while in fact it may
not be.

Note that initially screen update manager is not
used because Swing uses buffer per window painting
mode (which uses BufferStrategy). However, if while in fs 
mode the application attempts to repaint and fail 
(meaning that the back-buffer will be lost) and attempts 
to restore the back-buffer fail as well then 
BufferStrategyPaintManager falls back
to the old repainting mechanism: a VI backbuffer copied
to the screen.

At this point D3DScreenUpdateManager will be able to
create a redirected screen surface because Swing disposes its
buffer strategy when switching to old painting mode.

The fix is simple: do the full repaint in the
validate() method so that we always repaint after
successful surface restoration.

Interesting fact: one would think that with Vista's DWM
video memory management there will be fewer situations
when surface loss event occurs than in XP (where it really
only happens when display mode changed, or some app goes
fs), but it is not so. In Vista with Aero every time user is 
prompted to elevate process privileges (or start any admin 
program) - which is unfortunately way too often -
a surface loss event occurs. Bummer.

This means that times when the on-screen surface may be lost
may be relatively often. 

We have a mechanism for preventing copies of accelerated surface 
directly to the screen - special blit (scale, transform) loops 
(d3d->gdi) which disable the acceleration in the source surface 
manager and mark the surface lost. So the first time an accelerated 
surface is attempted to be copied to the screen the 
corresponding surface manager forever loses acceleration.

This is done to prevent costly vram->sysmem->vram data
transfers. However this mechanism proved to be too
cautious - because of it we'd lose hw acceleration pretty
much every time Vista asks for permission elevation.

So instead of disabling hw acceleration in this case
we could mark the surface lost. The SunVolatileImage.validate()
will use the backup software surface, which can be copied to
the screen. Next time during validate it will attempt to restore
the surface. If it fails, we'll continue to use the backup
surface. If it succeeds, we'll get to the d3d->gdi blit loop
again and the surface will be marked lost again - and so on
until the condition preventing from creating the on-screen
accelerated surface goes away.

This assumes that the condition which caused the loss of the on-screen
surface is temporary, which will be the case in most situations.
In the worst case we'll continue restoring/losing the surface.
I don't see how to prevent that without introducing some complicated
heuristics for when to continue restoring the surface.
                                     
2007-12-19
SUGGESTED FIX

http://sa.sfbay.sun.com/projects/java2d_data/6u10/6596702.1
                                     
2007-12-21



Hardware and Software, Engineered to Work Together