7159455: Nimbus scrollbar rendering glitch with xrender enabled on i945GM
authorceisserer
Wed, 04 Sep 2013 12:38:00 +0400
changeset 19784 dadb86ec2b3f
parent 19783 88ce9a76c992
child 19785 3cc04826bb7f
7159455: Nimbus scrollbar rendering glitch with xrender enabled on i945GM Reviewed-by: prr, bae
jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Wed Sep 04 12:10:07 2013 +0400
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Wed Sep 04 12:38:00 2013 +0400
@@ -225,6 +225,9 @@
  * @author Clemens Eisserer
  */
 class XRPMTransformedBlit extends TransformBlit {
+    final Rectangle compositeBounds = new Rectangle();
+    final double[] srcCoords = new double[8];
+    final double[] dstCoords = new double[8];
 
     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
         super(srcType, CompositeType.AnyAlpha, dstType);
@@ -235,61 +238,68 @@
      * method is functionally equal to: Shape shp =
      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
      * but performs significantly better.
+     * Returns true if the destination shape is parallel to x/y axis
      */
-    public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
-        double[] compBounds = new double[8];
-        compBounds[0] = dstx;
-        compBounds[1] = dsty;
-        compBounds[2] = dstx + width;
-        compBounds[3] = dsty;
-        compBounds[4] = dstx + width;
-        compBounds[5] = dsty + height;
-        compBounds[6] = dstx;
-        compBounds[7] = dsty + height;
+    protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
+        srcCoords[0] = dstx;
+        srcCoords[1] = dsty;
+        srcCoords[2] = dstx + width;
+        srcCoords[3] = dsty;
+        srcCoords[4] = dstx + width;
+        srcCoords[5] = dsty + height;
+        srcCoords[6] = dstx;
+        srcCoords[7] = dsty + height;
+
+        tr.transform(srcCoords, 0, dstCoords, 0, 4);
 
-        tr.transform(compBounds, 0, compBounds, 0, 4);
+        double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
+        double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
+        double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
+        double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
 
-        double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
-        double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
-        double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
-        double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
+        minX = Math.round(minX);
+        minY = Math.round(minY);
+        maxX = Math.round(maxX);
+        maxY = Math.round(maxY);
 
-        minX = Math.floor(minX);
-        minY = Math.floor(minY);
-        maxX = Math.ceil(maxX);
-        maxY = Math.ceil(maxY);
+        compositeBounds.x = (int) minX;
+        compositeBounds.y = (int) minY;
+        compositeBounds.width = (int) (maxX - minX);
+        compositeBounds.height = (int) (maxY - minY);
 
-        return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));
+        boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]);
+        boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]);
+
+        return is0or180 || is90or270;
     }
 
-    public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
-            int dstx, int dsty, int width, int height) {
+    public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
+            int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
         try {
             SunToolkit.awtLock();
 
-            int filter = XRUtils.ATransOpToXRQuality(hint);
+            XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+            XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 
-            XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+            int filter = XRUtils.ATransOpToXRQuality(hint);
+            boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
+
             x11sdDst.validateAsDestination(null, clip);
-            XRSurfaceData x11sdSrc = (XRSurfaceData) src;
             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 
-            Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
-
-            AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
+            AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
             trx.concatenate(xform);
             AffineTransform maskTX = (AffineTransform) trx.clone();
-
             trx.translate(-srcx, -srcy);
 
             try {
                 trx.invert();
             } catch (NoninvertibleTransformException ex) {
                 trx.setToIdentity();
-                System.err.println("Reseted to identity!");
             }
 
-            boolean omitMask = isMaskOmittable(trx, comp, filter);
+            boolean omitMask = (filter == XRUtils.FAST)
+                    || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
 
             if (!omitMask) {
                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
@@ -297,33 +307,17 @@
                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
-                        0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
+                        0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
             } else {
                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
 
                 x11sdSrc.validateAsSource(trx, repeat, filter);
-                x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
+                x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
             }
         } finally {
             SunToolkit.awtUnlock();
         }
     }
-
-    /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
-    protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
-        return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
-                                                                                            * If
-                                                                                            * translate
-                                                                                            * is
-                                                                                            * integer
-                                                                                            * only
-                                                                                            */
-                && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
-                // 90 degree
-                // rotation
-                || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
-        // ExtraAlpha!=1
-    }
 }
 
 class XrSwToPMBlit extends Blit {