JDK-4652373 : REGRESSION: InternalError in sun.java2d.loops.MaskFill when unlocking computer
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-03-13
  • Updated: 2003-04-12
  • Resolved: 2002-09-16
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
1.4.2 mantisFixed
Description

Name: gm110360			Date: 03/13/2002


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

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

EXTRA RELEVANT SYSTEM CONFIGURATION :
Computer: HP Omnibook 6000 Laptop
Videocard: ATI RAGE MOBILITY-M AGP (1600*1200@24bits)

have also seen this problem on other hw configurations.

A DESCRIPTION OF THE PROBLEM :
When unlocking the computer an internal error occurs in
sun.java2d.loops.MaskFill.makePrimitive when painting with
a GradientPaint object.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run a program containing the code.
2. Lock the workstation (press ctrl-alt-del, and
select 'Lock Computer')
3. Unlock workstation.
4. Component fails to paint and stack trace is visible.

The program prints out this before the stacktrace happens:
java.awt.Rectangle[x=0,y=0,width=500,height=500] w:500 h:500
java.awt.Rectangle[x=0,y=0,width=500,height=500] w:500 h:500

On my system this produces a stacktrace most of the time.

EXPECTED VERSUS ACTUAL BEHAVIOR :
I expect this to throw no exceptions and paint normally.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.InternalError: MaskFill can only fill with colors
	at sun.java2d.loops.MaskFill.makePrimitive(MaskFill.java:120)
	at sun.java2d.loops.GraphicsPrimitiveMgr.locate
(GraphicsPrimitiveMgr.java:167)
	at sun.java2d.loops.MaskFill.locate(MaskFill.java:46)
	at sun.java2d.loops.FillRect$General.<init>(FillRect.java:83)
	at sun.java2d.loops.FillRect.makePrimitive(FillRect.java:72)
	at sun.java2d.loops.GraphicsPrimitiveMgr.locate
(GraphicsPrimitiveMgr.java:167)
	at sun.java2d.loops.FillRect.locate(FillRect.java:38)
	at sun.java2d.SurfaceData.makeRenderLoops(SurfaceData.java:473)
	at sun.java2d.SurfaceData.getRenderLoops(SurfaceData.java:456)
	at sun.awt.image.BufImgSurfaceData.getRenderLoops
(BufImgSurfaceData.java:306)
	at sun.java2d.SunGraphics2D.revalidateAll(SunGraphics2D.java:2123)
	at sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:2103)
	at Bug.paintComponent(Bug.java:16)
	at javax.swing.JComponent.paint(JComponent.java:804)
	at javax.swing.JComponent.paintChildren(JComponent.java:643)
	at javax.swing.JComponent.paint(JComponent.java:813)
	at javax.swing.JComponent.paintChildren(JComponent.java:643)
	at javax.swing.JComponent.paint(JComponent.java:813)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:552)
	at javax.swing.JComponent.paintChildren(JComponent.java:643)
	at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4742)
	at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4688)
	at javax.swing.JComponent.paint(JComponent.java:794)
	at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
	at sun.awt.SunGraphicsCallback.runOneComponent
(SunGraphicsCallback.java:60)
	at sun.awt.SunGraphicsCallback.runComponents
(SunGraphicsCallback.java:97)
	at java.awt.Container.paint(Container.java:1123)
	at sun.awt.RepaintArea.paint(RepaintArea.java:180)
	at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:260)
	at java.awt.Component.dispatchEventImpl(Component.java:3586)
	at java.awt.Container.dispatchEventImpl(Container.java:1437)
	at java.awt.Window.dispatchEventImpl(Window.java:1566)
	at java.awt.Component.dispatchEvent(Component.java:3367)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy
(EventDispatchThread.java:190)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy
(EventDispatchThread.java:144)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)


This bug can be reproduced often.

---------- BEGIN SOURCE ----------

import javax.swing.*;
import java.awt.*;

public class Bug extends JComponent
{
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;

        Insets insets = getInsets();
        Rectangle rect = new Rectangle(insets.left, insets.top, getWidth() -
insets.right - insets.left, getHeight() - insets.top - insets.bottom);
        g2d.setPaint(new GradientPaint(rect.x, rect.y, Color.white,
rect.x+rect.width, rect.y, Color.black));

        System.out.println(rect + " w:" + getWidth() + " h:"+getHeight());

        g2d.fillRect(0, 0, getWidth(), getHeight());
    }


    public static void main(String[] args)
    {
        JFrame frame = new JFrame("bug");
        Bug bug = new Bug();
        bug.setPreferredSize(new Dimension(500, 500));
        frame.getContentPane().add(bug);
        frame.pack();
        frame.setVisible(true);
    }
}

---------- END SOURCE ----------

Release Regression From : 1.3.1_02
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 143160) 
======================================================================

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

EVALUATION This seems tied to ddraw problems because of the surface loss mechanism that kicks in after a ctl-alt-del operation (or any other occurrence that causes surface loss). However, it is actually a problem tied to pipeline validation that just happens to be triggered because surface loss causes revalidation. This can be verified by changing the code in SunGraphics2D slightly. In fillRect(), if you insert a call to revalidateAll() (which should be a valid, if unnecessary, operation), then you will get the same exact failure - only this way you get it without anything happening to the surface. It seems that we are not properly validating the pipelines based on current state. Without the change to SunGraphics2D.fillRect(), we validate the pipelines using some standard which does not go through BufImgSurfaceData.getRenderLoops(). But when we make the change to sg2d.fillRect(), we call BISD.getRenderLoops(), which detects (correctly) that the sg2d paint state is not SOLIDCOLOR, so it returns the renderloops from its superclass. This eventually percolates down to a call to makePrimitive in MaskFill with a non-opaque surface type (Paint Object), which MaskFill apparently cannot handle. Since this is not related to ddraw/win32, but is instead coming from a problem with pipeline validation, I'm forwarding the bug to Jim. ###@###.### 2002-03-15 It looks like the revalidateAll() code always tries to reconstruct the primitive operation loops (i.e. calls getRenderLoops which may or may not call makeRenderLoops). As it so happens, the primitive operation loops are only used during certain forms of basic rendering (i.e. not when GradientPaint is being used) and trying to construct loops under other conditions will fail. The pipeline validation code knows when to try to construct the list of primitive operation loops and when not to, but the code that revalidates a Graphics2D when the surface is reconfigured seems to always do it. The revalidateAll() code needs to be modified so that it only tries to reconstruct the loops when they are needed. Alternately, this code could simply call invalidate() and validate() to achieve the same effect with the proper protection against invalid loops. ###@###.### 2002-07-17
2002-07-17