Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4833528
Votes 43
Synopsis InternalException, "not yet implemented" thrown with CustomComposite
Category java:classes_2d
Reported Against 1.4 , 1.4.1
Release Fixed
State 6-Fix Understood, bug
Priority: 4-Low
Related Bugs
Submit Date 17-MAR-2003
Description


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

FULL OS VERSION :
 customer  Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
ATI Rage Mobility 7200


A DESCRIPTION OF THE PROBLEM :
Exception dump:
java.lang.InternalError: not implemented yet
   at sun.awt.windows.Win32OffScreenSurfaceData.getRaster
   at sun.java2d.pipe.GeneralCompositePipe.renderPathTile
   at sun.java2d.pipe.TextRenderer.drawGlyphList
   at sun.java2d.pipe.GlyphListPipe.drawGlyphVector
   at sun.java2d.SunGraphics2D.drawGlyphVector

Our Code:


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the sample code as java -cp . Test

EXPECTED VERSUS ACTUAL BEHAVIOR :
The string should render without exception.
An exception is thrown, see Error Messages

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception dump:
java.lang.InternalError: not implemented yet
   at sun.awt.windows.Win32OffScreenSurfaceData.getRaster
   at sun.java2d.pipe.GeneralCompositePipe.renderPathTile
   at sun.java2d.pipe.TextRenderer.drawGlyphList
   at sun.java2d.pipe.GlyphListPipe.drawGlyphVector
   at sun.java2d.SunGraphics2D.drawGlyphVector


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.image.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;

public class Test
{
   public static void main(String[] args)
   {
      TestPanel panel = new TestPanel();
      JDialog dialog = new JDialog();
      dialog.getContentPane().add(panel);
      dialog.setSize(400,400);
      dialog.setVisible(true);
   }
}

class TestPanel extends JPanel
{
   /** We override the paint method to handle all painting our selves */
   public void paint(Graphics p_graphics)
   {
      // Convert the passing graphics to the Graphics2D  customer  that is must be
      Graphics2D g = (Graphics2D)p_graphics;
      
      // Get the size we are working with
      Dimension size = getSize();
      
      // Render the page
      g.setComposite(ORComposite.DEFAULT);

      String testString = "Testing String...";
      float x = 20;
      float advance = 0.10f;
      FontRenderContext frc = g.getFontRenderContext();
      Font font = g.getFont();
      char[] c = new char[1];
      for (int i = 0; i < testString.length(); i++)
      {
         c[0] = testString.charAt(i);
         GlyphVector gv = font.createGlyphVector(frc, c);
         g.drawGlyphVector(gv, x, 20);
         x += advance;
      }
   }
}

/** Returns the CompositeContext that will correctly
 * handle summing the source and destination pixels in a way that mirrors ink
 * being put down on a page. The standard composites could not support this
 * behavior since we are not working with semi-transparent color and using
 * the alpha channel was not going to work. */
class ORComposite implements Composite
{ 
   /** Only one of these is, so a static  customer  is creatd. */
   public final static ORComposite DEFAULT = new ORComposite();
   
   /** Create the CompositeContext that will be used. It keeps no state, so
    * we really only need one of them. Since this class is a Singleton, there
    * will only be one instance of CompositContext created as only one
    * Composite is created */
   private final ORCompositeContext m_context = new ORCompositeContext();
   
   /** The class is a singleton, so the constuctor is hidden as a private. */
   private ORComposite()
   {
   }
  
   /** Return the composite the implements the ink paradigm */
   public CompositeContext createContext(ColorModel p_sCM, ColorModel p_dCM,
                                         RenderingHints p_hints)
   {
      return m_context;
   }

   /** Implements the idea of a composite that mirrors putting ink down on a
    * piece of paper. */
   class ORCompositeContext implements CompositeContext
   {
      /** There is state kept, so there is nothing to this function. */
      public void dispose()
      {
      }
  
      /** Do the work of composing the souce and the destination into the
       * output raster.
       * @see java.awt.CompositeContext#compose(Raster, Raster, WritableRaster)
       */
      public void compose(Raster p_srcIn, Raster p_dstIn,
                          WritableRaster p_dstOut)
      {
         // Walk the entire destination
         for (int x=0; x < p_dstOut.getWidth(); x++)
         {
            for (int y = 0; y < p_dstOut.getHeight(); y++)
            {
               //   Get the source pixels
               int[] src = new int[4];
               p_srcIn.getPixel(x, y, src);
            
               int[] dst = new int[4];
               p_dstIn.getPixel(x, y, dst);
             
               // Create a logaction for the result
               int[] result = new int[4];
            
               // OR the pixels together
               // We need to do the ^ 0xFFFFFF to invert the colors since the
               // screen sees 0xFFFFFF as white and 0x000000 as black, but we
               // want to sum up the underlying greyscales and make them
               // darker, as it would work with ink, so everything gets
               // inverted.
               result[0] = (src[0] ^ 0xFFFFFF) | (dst[0] ^ 0xFFFFFF);
               result[0] = result[0] ^ 0xFFFFFF;
               result[1] = (src[1] ^ 0xFFFFFF) | (dst[1] ^ 0xFFFFFF);
               result[1] = result[1] ^ 0xFFFFFF;
               result[2] = (src[2] ^ 0xFFFFFF) | (dst[2] ^ 0xFFFFFF);
               result[2] = result[2] ^ 0xFFFFFF;

               // Set the pixel with the values we have calulated
               p_dstOut.setPixel(x, y, result);
            }
         }
      }
   }
} 

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

CUSTOMER SUBMITTED WORKAROUND :
Passing in sun.java2d.noddraw=true flag will work, but this is completely
unacceptabel as a work around since we cannot expect out client base to
be using the Java Control Panel to set this value, and we cannot set the
value from the Object tag used to load the applet.
(Review ID: 182679) 
======================================================================
  xxxxx@xxxxx   10/21/04 14:52 GMT
Work Around
Perform custom composite operations on an image buffer instead of the
screen.  This workaround has several advantages:

- The performance will not be hindered by slow readback of screen
  pixels from most modern accelerated graphics cards.

- The correctness of the compositing algorithm will not depend on
  which mode the screen is in because the image buffer can be
  created with a known pixel format (by constructing a BufferedImage
  directly with a specified type).

- And lastly, this bug will not be encountered.
Evaluation
We currently don't have a way for our "SurfaceData" objects to supply the
Raster needed for a Java level algorithm to directly modify them.  We hope
to fix this in the not too distant future, but it is important to note the
caveats in the WorkAround field to realize that this bug fix may not be
the solution that everyone wants in the long run and that they are better
off moving to an offscreen buffer for their custom compositing operations
for practical reasons that go beyond simply avoiding this bug.

In particular, the supplied test case assumes a given pixel format in
its operations and will fail miserably if the screen is in 256 color
mode (producing random colors) or is a grayscale display.  If the
screen is in 16-bit color mode then the accuracy of the results will
be less than optimal and will accumulate errors more quickly than
operating on a 24 or 32-bit display.  These issues can be worked
around in the implementation of the custom composite, but such an
effort would be a major undertaking to ensure compatibility with
the many pixel formats that are possible to specify within our
system.

Further, the performance of reading the pixels back from the screen
for most modern graphics cards is horrible - much worse than most
developers might expect.  Todays graphics cards are heavily geared
towards a "write only" access model for the fastest possible gaming
performance.  I have little doubt that if we fixed this bug, the
first thing that an implementor of a custom composite would do with
the fixed runtime would be to switch to an offscreen image for
performance reasons unless performance was of very little concern
to them.  There is even talk of a new breed of cards under
development that will not have any capability to read pixels back
from the screen.  When running on any of those new cards we would
actually be prevented from satisfying this request by the hardware
we were running on.

Given the many positive features of the primary workaround of using
an offscreen image to do the custom compositing, we are not assigning
a very high priority to fixing this bug and recommending that developers
double buffer their custom composite operations.  This bug serves
more as a reminder that there is a theoretical hole in our implementation
than an identification of a practical loss for the developers.

  xxxxx@xxxxx   2003-09-15
Comments
  
  Include a link with my name & email   

Submitted On 18-APR-2003
psynek
I experience the same problem with Graphics2D.setComposite(...).
It seems only AlphaComposite may be used as argument for
this method... 

But custom Composite object that performes for example AND
pixel operation can't be used with Java 1.4.1 at all...


Submitted On 22-APR-2003
lars.joreteg
I am experiencing the same issue - It's very frustrating!

I have found two workarounds:
1. Disable windows display hardware acceleration
2. Pass the following parameter to the VM: -
DSwingVolatileImageBuffer=false
(Both of these really fo the same thing - Disable the use of 
half-implemented VolativeImage, which is the root of this 
problem)

Unfortunately either of these workaround is completely 
unacceptable for our large customer base!


Submitted On 21-AUG-2003
eijckron
I experience the same problem when using fullscreen exclusive 
mode and switching to the windows desktop and back. This is 
on windows 2000 with a intel and ati videocards and different 
versions of directX including 9.0b.


Submitted On 15-SEP-2003
mrsimoncox
I have the same problem on a redhat linux machine (kernel
2.4.20), however i don't seem to be able to fix it with
either the DSwingVolatileImageBuffer=false or
sun.java2d.noddraw=true JVM flags.

The stack trace i get is:

java.lang.InternalError: not implemented yet
        at
sun.awt.X11SurfaceData.getRaster(X11SurfaceData.java:157)
        at
sun.java2d.pipe.GeneralCompositePipe.renderPathTile(GeneralCompositePipe.java:82)
        at
sun.java2d.pipe.SpanShapeRenderer$Composite.renderBox(SpanShapeRenderer.java:42)
        at
sun.java2d.pipe.SpanShapeRenderer.renderRect(SpanShapeRenderer.java:168)
        at
sun.java2d.pipe.SpanShapeRenderer.fill(SpanShapeRenderer.java:119)
        at
sun.java2d.pipe.PixelToShapeConverter.fillRect(PixelToShapeConverter.java:44)
        at
sun.java2d.pipe.ValidatePipe.fillRect(ValidatePipe.java:46)
        at
sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:2065)


Submitted On 24-NOV-2003
pvercesi
I think that workaround and evaluation descriptions should
be added to Graphics2D API.
 


Submitted On 20-JAN-2005
JN_
Who says you have to read the data back from the video buffer?  If swing double-buffering is enabled, the data should be right there.  What use is a setComposite() method if it doesn't work?


Submitted On 26-MAY-2005
twalljava
The custom composite doesn't even have to do anything (the exception is thrown before the composite is ever used).  


Submitted On 28-JUN-2005
StewartPratt
Whilst the evaluation makes fine sense for applications, double buffering large images within applets is unfortunately not an option.


Submitted On 29-JUN-2005
Brent
I too am experiencing this problem displaying from a solaris box (java1.5) to my WindowsXP box.  The exact same source works just wonderfully on windows alone


Submitted On 18-FEB-2008
Shayesteh
I have this problem on ubuntu 7.10.
BlendCompositeDemo, a sample in filthy rich clients



Submitted On 01-APR-2008
hrj
I second lars, JN_ and twaljava's comments.

I am not even accessing any of the Raster's. Just implementing a dummy Composite and doing a setComposite() throws this exception.

This is really frustrating, and what use is a setComposite if it can't be used!?


Submitted On 15-MAY-2008
"We hope
to fix this in the not too distant future" (written well over 4 years ago and still no fix).

What's the point of providing a Graphics2D method that doesn't work on one major platform?  Something to the effect of "has worked fine on Windows for 5 years, but don't assume it will work on any other platform" would probably fit the bill.



PLEASE NOTE: JDK6 is formerly known as Project Mustang