United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6439274 OGL: overlapping LCD glyphs not rendered properly
JDK-6439274 : OGL: overlapping LCD glyphs not rendered properly

Details
Type:
Bug
Submit Date:
2006-06-15
Status:
Resolved
Updated Date:
2008-02-06
Project Name:
JDK
Resolved Date:
2006-07-17
Component:
client-libs
OS:
solaris_10
Sub-Component:
2d
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports

Sub Tasks

Description
A small bug was introduced with the recent changes for 6274813 (accelerate LCD glyphs
for OGL pipeline) that causes overlapping LCD glyphs to look wacky.  To reproduce,
start SwingSet2 with (requires shader-level hardware):
  -Dsun.java2d.opengl=True \
  -Dsun.java2d.opengl.lcdshader=true \
  -Dawt.useSystemAAFontSettings=lcd

The problem is easiest to see if you enable bold fonts.  Look closely at certain words
like "Save" where the fringes of the 'a' and 'v' overlap, and notice that the 'v' seems
to obscure part of the 'a' when it should really be blended with the 'a'.

                                    

Comments
EVALUATION

This code was working at one point, so I must have broken it just before the putback
of 6274813.  I noticed the visual problems recently but while debugging some unrelated
code I noticed that glGetError() was returning non-zero error codes after rendering
overlapping LCD glyphs.  It turns out that there is a silly bug in
OGLTR_UpdateCachedDestination() when handling the overlapping case where we pass
a negative xoffset to glCopyTexSubImage2D(), which results in a GL_INVALID_VALUE
error to be generated and the operation fails.  This explains why the readback fails
and the overlapping glyph is not blended properly with the previous glyph.

The problem is that we were calling:
    j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
                            cachedDestBounds.x1 - dx1,
                            cachedDestBounds.y2 - dy2, ...

The x/y values are relative to an upper-left origin, so dx1 will always be >=
cachedDestBounds.x1, and dy2 will always be <= cachedDestBounds.y2.  So the y
calculation is okay (it will always be non-negative), but the x calculation is
broken such that it will always be non-positive.  The fix is easy, we just need
to reverse the x calculation:
                            dx1 - cachedDestBounds.x1,
so that the xoffset is always non-negative.
                                     
2006-06-15



Hardware and Software, Engineered to Work Together