jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
changeset 19784 dadb86ec2b3f
parent 8940 7a0c1d4e2982
child 21236 ee742f4ec299
equal deleted inserted replaced
19783:88ce9a76c992 19784:dadb86ec2b3f
   223  * Called also if scale+transform is set
   223  * Called also if scale+transform is set
   224  *
   224  *
   225  * @author Clemens Eisserer
   225  * @author Clemens Eisserer
   226  */
   226  */
   227 class XRPMTransformedBlit extends TransformBlit {
   227 class XRPMTransformedBlit extends TransformBlit {
       
   228     final Rectangle compositeBounds = new Rectangle();
       
   229     final double[] srcCoords = new double[8];
       
   230     final double[] dstCoords = new double[8];
   228 
   231 
   229     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
   232     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
   230         super(srcType, CompositeType.AnyAlpha, dstType);
   233         super(srcType, CompositeType.AnyAlpha, dstType);
   231     }
   234     }
   232 
   235 
   233     /*
   236     /*
   234      * Calculates the composite-rectangle required for transformed blits. This
   237      * Calculates the composite-rectangle required for transformed blits. This
   235      * method is functionally equal to: Shape shp =
   238      * method is functionally equal to: Shape shp =
   236      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
   239      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
   237      * but performs significantly better.
   240      * but performs significantly better.
       
   241      * Returns true if the destination shape is parallel to x/y axis
   238      */
   242      */
   239     public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
   243     protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
   240         double[] compBounds = new double[8];
   244         srcCoords[0] = dstx;
   241         compBounds[0] = dstx;
   245         srcCoords[1] = dsty;
   242         compBounds[1] = dsty;
   246         srcCoords[2] = dstx + width;
   243         compBounds[2] = dstx + width;
   247         srcCoords[3] = dsty;
   244         compBounds[3] = dsty;
   248         srcCoords[4] = dstx + width;
   245         compBounds[4] = dstx + width;
   249         srcCoords[5] = dsty + height;
   246         compBounds[5] = dsty + height;
   250         srcCoords[6] = dstx;
   247         compBounds[6] = dstx;
   251         srcCoords[7] = dsty + height;
   248         compBounds[7] = dsty + height;
   252 
   249 
   253         tr.transform(srcCoords, 0, dstCoords, 0, 4);
   250         tr.transform(compBounds, 0, compBounds, 0, 4);
   254 
   251 
   255         double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
   252         double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
   256         double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
   253         double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
   257         double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
   254         double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
   258         double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
   255         double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
   259 
   256 
   260         minX = Math.round(minX);
   257         minX = Math.floor(minX);
   261         minY = Math.round(minY);
   258         minY = Math.floor(minY);
   262         maxX = Math.round(maxX);
   259         maxX = Math.ceil(maxX);
   263         maxY = Math.round(maxY);
   260         maxY = Math.ceil(maxY);
   264 
   261 
   265         compositeBounds.x = (int) minX;
   262         return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));
   266         compositeBounds.y = (int) minY;
   263     }
   267         compositeBounds.width = (int) (maxX - minX);
   264 
   268         compositeBounds.height = (int) (maxY - minY);
   265     public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
   269 
   266             int dstx, int dsty, int width, int height) {
   270         boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]);
       
   271         boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]);
       
   272 
       
   273         return is0or180 || is90or270;
       
   274     }
       
   275 
       
   276     public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
       
   277             int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
   267         try {
   278         try {
   268             SunToolkit.awtLock();
   279             SunToolkit.awtLock();
   269 
   280 
       
   281             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
       
   282             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
       
   283 
   270             int filter = XRUtils.ATransOpToXRQuality(hint);
   284             int filter = XRUtils.ATransOpToXRQuality(hint);
   271 
   285             boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
   272             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
   286 
   273             x11sdDst.validateAsDestination(null, clip);
   287             x11sdDst.validateAsDestination(null, clip);
   274             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
       
   275             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
   288             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
   276 
   289 
   277             Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
   290             AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
   278 
       
   279             AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
       
   280             trx.concatenate(xform);
   291             trx.concatenate(xform);
   281             AffineTransform maskTX = (AffineTransform) trx.clone();
   292             AffineTransform maskTX = (AffineTransform) trx.clone();
   282 
       
   283             trx.translate(-srcx, -srcy);
   293             trx.translate(-srcx, -srcy);
   284 
   294 
   285             try {
   295             try {
   286                 trx.invert();
   296                 trx.invert();
   287             } catch (NoninvertibleTransformException ex) {
   297             } catch (NoninvertibleTransformException ex) {
   288                 trx.setToIdentity();
   298                 trx.setToIdentity();
   289                 System.err.println("Reseted to identity!");
   299             }
   290             }
   300 
   291 
   301             boolean omitMask = (filter == XRUtils.FAST)
   292             boolean omitMask = isMaskOmittable(trx, comp, filter);
   302                     || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
   293 
   303 
   294             if (!omitMask) {
   304             if (!omitMask) {
   295                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
   305                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
   296 
   306 
   297                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
   307                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
   298                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
   308                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
   299                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
   309                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
   300                         0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
   310                         0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
   301             } else {
   311             } else {
   302                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
   312                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
   303 
   313 
   304                 x11sdSrc.validateAsSource(trx, repeat, filter);
   314                 x11sdSrc.validateAsSource(trx, repeat, filter);
   305                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
   315                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
   306             }
   316             }
   307         } finally {
   317         } finally {
   308             SunToolkit.awtUnlock();
   318             SunToolkit.awtUnlock();
   309         }
   319         }
   310     }
       
   311 
       
   312     /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
       
   313     protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
       
   314         return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
       
   315                                                                                             * If
       
   316                                                                                             * translate
       
   317                                                                                             * is
       
   318                                                                                             * integer
       
   319                                                                                             * only
       
   320                                                                                             */
       
   321                 && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
       
   322                 // 90 degree
       
   323                 // rotation
       
   324                 || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
       
   325         // ExtraAlpha!=1
       
   326     }
   320     }
   327 }
   321 }
   328 
   322 
   329 class XrSwToPMBlit extends Blit {
   323 class XrSwToPMBlit extends Blit {
   330     Blit pmToSurfaceBlit;
   324     Blit pmToSurfaceBlit;