src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java

Print this page




 161 
 162             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 163             x11sdDst.validateAsDestination(null, clip);
 164             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 165             x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
 166 
 167             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 168 
 169             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, sx, sy, dx, dy, w, h);
 170         } finally {
 171             SunToolkit.awtUnlock();
 172         }
 173     }
 174 }
 175 
 176 class XRPMScaledBlit extends ScaledBlit {
 177     public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
 178         super(srcType, CompositeType.AnyAlpha, dstType);
 179     }
 180 
 181     /*
 182      * TODO: This breaks scales with non-integer coordinates!?!?!
 183      */
 184     public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
 185             double dx2, double dy2) {
 186         try {
 187             SunToolkit.awtLock();
 188 
 189             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 190             x11sdDst.validateAsDestination(null, clip);
 191             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 192             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 193 
 194             double xScale = (dx2 - dx1) / (sx2 - sx1);
 195             double yScale = (dy2 - dy1) / (sy2 - sy1);
 196 
 197             sx1 *= xScale;
 198             sx2 *= xScale;
 199             sy1 *= yScale;
 200             sy2 *= yScale;
 201 





 202             AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
 203 
 204             x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST); /*
 205                                                                                  * TODO:
 206                                                                                  * padded
 207                                                                                  * blit
 208                                                                                  * required
 209                                                                                  * :
 210                                                                                  * -
 211                                                                                  * /
 212                                                                                  * ?
 213                                                                                  * ?
 214                                                                                  */
 215             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
 216         } finally {
 217             SunToolkit.awtUnlock();
 218         }
 219     }
 220 }
 221 
 222 /**
 223  * Called also if scale+transform is set
 224  *
 225  * @author Clemens Eisserer
 226  */
 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];
 231 
 232     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
 233         super(srcType, CompositeType.AnyAlpha, dstType);
 234     }
 235 
 236     /*
 237      * Calculates the composite-rectangle required for transformed blits. This
 238      * method is functionally equal to: Shape shp =
 239      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
 240      * but performs significantly better.
 241      * Returns true if the destination shape is parallel to x/y axis
 242      */
 243     protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {

 244         srcCoords[0] = dstx;
 245         srcCoords[1] = dsty;
 246         srcCoords[2] = dstx + width;
 247         srcCoords[3] = dsty;
 248         srcCoords[4] = dstx + width;















 249         srcCoords[5] = dsty + height;
 250         srcCoords[6] = dstx;
 251         srcCoords[7] = dsty + height;
 252 
 253         tr.transform(srcCoords, 0, dstCoords, 0, 4);
 254 
 255         double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
 256         double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
 257         double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
 258         double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
 259 
 260         minX = Math.round(minX);
 261         minY = Math.round(minY);
 262         maxX = Math.round(maxX);
 263         maxY = Math.round(maxY);

 264 
 265         compositeBounds.x = (int) minX;
 266         compositeBounds.y = (int) minY;
 267         compositeBounds.width = (int) (maxX - minX);
 268         compositeBounds.height = (int) (maxY - minY);
 269 
 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) {
 278         try {
 279             SunToolkit.awtLock();
 280 
 281             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 282             XRSurfaceData x11sdSrc = (XRSurfaceData) src;

 283 

 284             int filter = XRUtils.ATransOpToXRQuality(hint);
 285             boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);


 286 
 287             x11sdDst.validateAsDestination(null, clip);
 288             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 289 
 290             AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
 291             trx.concatenate(xform);
 292             AffineTransform maskTX = (AffineTransform) trx.clone();
 293             trx.translate(-srcx, -srcy);
 294 
 295             try {
 296                 trx.invert();
 297             } catch (NoninvertibleTransformException ex) {
 298                 trx.setToIdentity();
 299             }
 300 
 301             boolean omitMask = (filter == XRUtils.FAST)
 302                     || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
 303 
 304             if (!omitMask) {
 305                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
 306 





 307                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
 308                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
 309                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
 310                         0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
 311             } else {
 312                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
 313 
 314                 x11sdSrc.validateAsSource(trx, repeat, filter);
 315                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);



 316             }
 317         } finally {
 318             SunToolkit.awtUnlock();
 319         }
 320     }
 321 }
 322 
 323 class XrSwToPMBlit extends Blit {
 324     Blit pmToSurfaceBlit;
 325 
 326     XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {
 327         super(srcType, CompositeType.AnyAlpha, dstType);
 328         pmToSurfaceBlit = new XRPMBlit(dstType, dstType);
 329     }
 330 
 331     public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
 332         /*
 333          * If the blit is write-only (putimge), no need for a temporary VI.
 334          */
 335         if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {
 336             Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());
 337             opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
 338         } else {
 339             try {
 340                 SunToolkit.awtLock();
 341 
 342                 XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);
 343                 pmToSurfaceBlit.Blit(vImgSurface, dst, comp, clip, 0, 0, dx, dy, w, h);
 344             } finally {
 345                 SunToolkit.awtUnlock();
 346             }
 347         }
 348     }
 349 }
 350 
 351 class XrSwToPMScaledBlit extends ScaledBlit {
 352     ScaledBlit pmToSurfaceBlit;
 353 
 354     XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {




 161 
 162             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 163             x11sdDst.validateAsDestination(null, clip);
 164             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 165             x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
 166 
 167             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 168 
 169             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, sx, sy, dx, dy, w, h);
 170         } finally {
 171             SunToolkit.awtUnlock();
 172         }
 173     }
 174 }
 175 
 176 class XRPMScaledBlit extends ScaledBlit {
 177     public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
 178         super(srcType, CompositeType.AnyAlpha, dstType);
 179     }
 180 



 181     public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
 182             double dx2, double dy2) {
 183         try {
 184             SunToolkit.awtLock();
 185 
 186             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 187             x11sdDst.validateAsDestination(null, clip);
 188             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 189             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 190 
 191             double xScale = (dx2 - dx1) / (sx2 - sx1);
 192             double yScale = (dy2 - dy1) / (sy2 - sy1);
 193 
 194             sx1 *= xScale;
 195             sx2 *= xScale;
 196             sy1 *= yScale;
 197             sy2 *= yScale;
 198             
 199             dx1 = Math.ceil(dx1 - 0.5);
 200             dy1 = Math.ceil(dy1 - 0.5);
 201             dx2 = Math.ceil(dx2 - 0.5);
 202             dy2 = Math.ceil(dy2 - 0.5);
 203 
 204             AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
 205 
 206             x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);










 207             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
 208         } finally {
 209             SunToolkit.awtUnlock();
 210         }
 211     }
 212 }
 213 
 214 /**
 215  * Called also if scale+transform is set
 216  *
 217  * @author Clemens Eisserer
 218  */
 219 class XRPMTransformedBlit extends TransformBlit {
 220     final Rectangle compositeBounds = new Rectangle();
 221     final double[] srcCoords = new double[8];
 222     final double[] dstCoords = new double[8];
 223 
 224     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
 225         super(srcType, CompositeType.AnyAlpha, dstType);
 226     }
 227 
 228     /*
 229      * Calculates the composition-rectangle required for transformed blits.
 230      * For composite operations where the composition-rectangle defines 
 231      * the modified destination area, coordinates are rounded.
 232      * Otherwise the composition window rectangle is sized large enough 
 233      * to not clip away any pixels.
 234      */
 235     protected void adjustCompositeBounds(boolean isQuadrantRotated, AffineTransform tr, 
 236             int dstx, int dsty, int width, int height) {
 237         srcCoords[0] = dstx;
 238         srcCoords[1] = dsty;
 239         srcCoords[2] = dstx + width;
 240         srcCoords[3] = dsty + height;
 241 
 242         double minX, minY, maxX, maxY;
 243         if (isQuadrantRotated) {
 244             tr.transform(srcCoords, 0, dstCoords, 0, 2);
 245             
 246             minX = Math.min(dstCoords[0], dstCoords[2]);
 247             minY = Math.min(dstCoords[1], dstCoords[3]);
 248             maxX = Math.max(dstCoords[0], dstCoords[2]);
 249             maxY = Math.max(dstCoords[1], dstCoords[3]);
 250             
 251             minX = Math.ceil(minX - 0.5);
 252             minY = Math.ceil(minY - 0.5);
 253             maxX = Math.ceil(maxX - 0.5);
 254             maxY = Math.ceil(maxY - 0.5); 
 255         } else {
 256             srcCoords[4] = dstx;
 257             srcCoords[5] = dsty + height;
 258             srcCoords[6] = dstx + width;
 259             srcCoords[7] = dsty;
 260             
 261             tr.transform(srcCoords, 0, dstCoords, 0, 4);
 262         
 263             minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
 264             minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
 265             maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
 266             maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
 267             
 268             minX = Math.floor(minX);
 269             minY = Math.floor(minY);
 270             maxX = Math.ceil(maxX);
 271             maxY = Math.ceil(maxY);     
 272         }
 273 
 274         compositeBounds.x = (int) minX;
 275         compositeBounds.y = (int) minY;
 276         compositeBounds.width = (int) (maxX - minX);
 277         compositeBounds.height = (int) (maxY - minY);





 278     }
 279 
 280     public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
 281             int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
 282         try {
 283             SunToolkit.awtLock();
 284 
 285             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 286             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 287             XRCompositeManager xrMgr = XRCompositeManager.getInstance(x11sdSrc);
 288             
 289             float extraAlpha = ((AlphaComposite) comp).getAlpha();
 290             int filter = XRUtils.ATransOpToXRQuality(hint);
 291             boolean isQuadrantRotated = XRUtils.isTransformQuadrantRotated(xform); 
 292             
 293             adjustCompositeBounds(isQuadrantRotated, xform, dstx, dsty, width, height);
 294 
 295             x11sdDst.validateAsDestination(null, clip);
 296             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 297 
 298             AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
 299             trx.concatenate(xform);
 300             AffineTransform maskTX = (AffineTransform) trx.clone();
 301             trx.translate(-srcx, -srcy);
 302 
 303             try {
 304                 trx.invert();
 305             } catch (NoninvertibleTransformException ex) {
 306                 trx.setToIdentity();
 307             }
 308 
 309             if (filter != XRUtils.FAST && (!isQuadrantRotated || extraAlpha != 1.0f)) {



 310                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
 311 
 312                 // For quadrant-transformed blits geometry is not stored inside the mask
 313                 // therefore we can use a repeating 1x1 mask for applying extra alpha.
 314                 int maskPicture = isQuadrantRotated ? xrMgr.getExtraAlphaMask() 
 315                         : mask.prepareBlitMask(x11sdDst, maskTX, width, height);
 316                 
 317                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
 318                 x11sdDst.maskBuffer.con.renderComposite(xrMgr.getCompRule(), x11sdSrc.picture, 
 319                         maskPicture, x11sdDst.picture, 0, 0, 0, 0, compositeBounds.x, compositeBounds.y, 
 320                         compositeBounds.width, compositeBounds.height);
 321             } else {
 322                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
 323 
 324                 x11sdSrc.validateAsSource(trx, repeat, filter);
 325                 
 326                 // compositeBlit takes care of extra alpha
 327                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, 
 328                         compositeBounds.y, compositeBounds.width, compositeBounds.height);
 329             }
 330         } finally {
 331             SunToolkit.awtUnlock();
 332         }
 333     }
 334 }
 335 
 336 class XrSwToPMBlit extends Blit {
 337     Blit pmToSurfaceBlit;
 338 
 339     XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {
 340         super(srcType, CompositeType.AnyAlpha, dstType);
 341         pmToSurfaceBlit = new XRPMBlit(dstType, dstType);
 342     }
 343 
 344     public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
 345         // If the blit is write-only (putimge), no need for a temporary VI.         


 346         if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {
 347             Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());
 348             opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
 349         } else {
 350             try {
 351                 SunToolkit.awtLock();
 352 
 353                 XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);
 354                 pmToSurfaceBlit.Blit(vImgSurface, dst, comp, clip, 0, 0, dx, dy, w, h);
 355             } finally {
 356                 SunToolkit.awtUnlock();
 357             }
 358         }
 359     }
 360 }
 361 
 362 class XrSwToPMScaledBlit extends ScaledBlit {
 363     ScaledBlit pmToSurfaceBlit;
 364 
 365     XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {