1 /* 2 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.d3d; 27 28 import java.awt.Composite; 29 import java.awt.Transparency; 30 import java.awt.geom.AffineTransform; 31 import java.awt.image.AffineTransformOp; 32 import java.awt.image.BufferedImage; 33 import java.awt.image.BufferedImageOp; 34 import java.lang.ref.WeakReference; 35 import java.lang.annotation.Native; 36 import sun.java2d.ScreenUpdateManager; 37 import sun.java2d.SurfaceData; 38 import sun.java2d.loops.Blit; 39 import sun.java2d.loops.CompositeType; 40 import sun.java2d.loops.GraphicsPrimitive; 41 import sun.java2d.loops.GraphicsPrimitiveMgr; 42 import sun.java2d.loops.ScaledBlit; 43 import sun.java2d.loops.SurfaceType; 44 import sun.java2d.loops.TransformBlit; 45 import sun.java2d.pipe.Region; 46 import sun.java2d.pipe.RenderBuffer; 47 import sun.java2d.pipe.RenderQueue; 48 import static sun.java2d.pipe.BufferedOpCodes.*; 49 import sun.java2d.windows.GDIWindowSurfaceData; 50 51 final class D3DBlitLoops { 52 53 static void register() { 54 Blit blitIntArgbPreToSurface = 55 new D3DSwToSurfaceBlit(SurfaceType.IntArgbPre, 56 D3DSurfaceData.ST_INT_ARGB_PRE); 57 Blit blitIntArgbPreToTexture = 58 new D3DSwToTextureBlit(SurfaceType.IntArgbPre, 59 D3DSurfaceData.ST_INT_ARGB_PRE); 60 TransformBlit transformBlitIntArgbPreToSurface = 61 new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre, 62 D3DSurfaceData.ST_INT_ARGB_PRE); 63 GraphicsPrimitive[] primitives = { 64 // prevent D3DSurface -> Screen blits 65 new D3DSurfaceToGDIWindowSurfaceBlit(), 66 new D3DSurfaceToGDIWindowSurfaceScale(), 67 new D3DSurfaceToGDIWindowSurfaceTransform(), 68 69 // surface->surface ops 70 new D3DSurfaceToSurfaceBlit(), 71 new D3DSurfaceToSurfaceScale(), 72 new D3DSurfaceToSurfaceTransform(), 73 74 // render-to-texture surface->surface ops 75 new D3DRTTSurfaceToSurfaceBlit(), 76 new D3DRTTSurfaceToSurfaceScale(), 77 new D3DRTTSurfaceToSurfaceTransform(), 78 79 // surface->sw ops 80 new D3DSurfaceToSwBlit(SurfaceType.IntArgb, 81 D3DSurfaceData.ST_INT_ARGB), 82 83 // sw->surface ops 84 blitIntArgbPreToSurface, 85 new D3DSwToSurfaceBlit(SurfaceType.IntArgb, 86 D3DSurfaceData.ST_INT_ARGB), 87 new D3DSwToSurfaceBlit(SurfaceType.IntRgb, 88 D3DSurfaceData.ST_INT_RGB), 89 new D3DSwToSurfaceBlit(SurfaceType.IntBgr, 90 D3DSurfaceData.ST_INT_BGR), 91 new D3DSwToSurfaceBlit(SurfaceType.ThreeByteBgr, 92 D3DSurfaceData.ST_3BYTE_BGR), 93 new D3DSwToSurfaceBlit(SurfaceType.Ushort565Rgb, 94 D3DSurfaceData.ST_USHORT_565_RGB), 95 new D3DSwToSurfaceBlit(SurfaceType.Ushort555Rgb, 96 D3DSurfaceData.ST_USHORT_555_RGB), 97 new D3DSwToSurfaceBlit(SurfaceType.ByteIndexed, 98 D3DSurfaceData.ST_BYTE_INDEXED), 99 // REMIND: we don't have a native sw loop to back this loop up 100 // new D3DSwToSurfaceBlit(SurfaceType.ByteIndexedBm, 101 // D3DSurfaceData.ST_BYTE_INDEXED_BM), 102 new D3DGeneralBlit(D3DSurfaceData.D3DSurface, 103 CompositeType.AnyAlpha, 104 blitIntArgbPreToSurface), 105 106 new D3DSwToSurfaceScale(SurfaceType.IntArgb, 107 D3DSurfaceData.ST_INT_ARGB), 108 new D3DSwToSurfaceScale(SurfaceType.IntArgbPre, 109 D3DSurfaceData.ST_INT_ARGB_PRE), 110 new D3DSwToSurfaceScale(SurfaceType.IntRgb, 111 D3DSurfaceData.ST_INT_RGB), 112 new D3DSwToSurfaceScale(SurfaceType.IntBgr, 113 D3DSurfaceData.ST_INT_BGR), 114 new D3DSwToSurfaceScale(SurfaceType.ThreeByteBgr, 115 D3DSurfaceData.ST_3BYTE_BGR), 116 new D3DSwToSurfaceScale(SurfaceType.Ushort565Rgb, 117 D3DSurfaceData.ST_USHORT_565_RGB), 118 new D3DSwToSurfaceScale(SurfaceType.Ushort555Rgb, 119 D3DSurfaceData.ST_USHORT_555_RGB), 120 new D3DSwToSurfaceScale(SurfaceType.ByteIndexed, 121 D3DSurfaceData.ST_BYTE_INDEXED), 122 // REMIND: we don't have a native sw loop to back this loop up 123 // new D3DSwToSurfaceScale(SurfaceType.ByteIndexedBm, 124 // D3DSurfaceData.ST_BYTE_INDEXED_BM), 125 126 new D3DSwToSurfaceTransform(SurfaceType.IntArgb, 127 D3DSurfaceData.ST_INT_ARGB), 128 new D3DSwToSurfaceTransform(SurfaceType.IntRgb, 129 D3DSurfaceData.ST_INT_RGB), 130 new D3DSwToSurfaceTransform(SurfaceType.IntBgr, 131 D3DSurfaceData.ST_INT_BGR), 132 new D3DSwToSurfaceTransform(SurfaceType.ThreeByteBgr, 133 D3DSurfaceData.ST_3BYTE_BGR), 134 new D3DSwToSurfaceTransform(SurfaceType.Ushort565Rgb, 135 D3DSurfaceData.ST_USHORT_565_RGB), 136 new D3DSwToSurfaceTransform(SurfaceType.Ushort555Rgb, 137 D3DSurfaceData.ST_USHORT_555_RGB), 138 new D3DSwToSurfaceTransform(SurfaceType.ByteIndexed, 139 D3DSurfaceData.ST_BYTE_INDEXED), 140 // REMIND: we don't have a native sw loop to back this loop up 141 // new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm, 142 // D3DSurfaceData.ST_BYTE_INDEXED_BM), 143 transformBlitIntArgbPreToSurface, 144 145 new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface), 146 147 // texture->surface ops 148 new D3DTextureToSurfaceBlit(), 149 new D3DTextureToSurfaceScale(), 150 new D3DTextureToSurfaceTransform(), 151 152 // sw->texture ops 153 blitIntArgbPreToTexture, 154 new D3DSwToTextureBlit(SurfaceType.IntRgb, 155 D3DSurfaceData.ST_INT_RGB), 156 new D3DSwToTextureBlit(SurfaceType.IntArgb, 157 D3DSurfaceData.ST_INT_ARGB), 158 new D3DSwToTextureBlit(SurfaceType.IntBgr, 159 D3DSurfaceData.ST_INT_BGR), 160 new D3DSwToTextureBlit(SurfaceType.ThreeByteBgr, 161 D3DSurfaceData.ST_3BYTE_BGR), 162 new D3DSwToTextureBlit(SurfaceType.Ushort565Rgb, 163 D3DSurfaceData.ST_USHORT_565_RGB), 164 new D3DSwToTextureBlit(SurfaceType.Ushort555Rgb, 165 D3DSurfaceData.ST_USHORT_555_RGB), 166 new D3DSwToTextureBlit(SurfaceType.ByteIndexed, 167 D3DSurfaceData.ST_BYTE_INDEXED), 168 // REMIND: we don't have a native sw loop to back this loop up 169 // new D3DSwToTextureBlit(SurfaceType.ByteIndexedBm, 170 // D3DSurfaceData.ST_BYTE_INDEXED_BM), 171 new D3DGeneralBlit(D3DSurfaceData.D3DTexture, 172 CompositeType.SrcNoEa, 173 blitIntArgbPreToTexture), 174 }; 175 GraphicsPrimitiveMgr.register(primitives); 176 } 177 178 /** 179 * The following offsets are used to pack the parameters in 180 * createPackedParams(). (They are also used at the native level when 181 * unpacking the params.) 182 */ 183 @Native private static final int OFFSET_SRCTYPE = 16; 184 @Native private static final int OFFSET_HINT = 8; 185 @Native private static final int OFFSET_TEXTURE = 3; 186 @Native private static final int OFFSET_RTT = 2; 187 @Native private static final int OFFSET_XFORM = 1; 188 @Native private static final int OFFSET_ISOBLIT = 0; 189 190 /** 191 * Packs the given parameters into a single int value in order to save 192 * space on the rendering queue. 193 */ 194 private static int createPackedParams(boolean isoblit, boolean texture, 195 boolean rtt, boolean xform, 196 int hint, int srctype) 197 { 198 return 199 ((srctype << OFFSET_SRCTYPE) | 200 (hint << OFFSET_HINT ) | 201 ((texture ? 1 : 0) << OFFSET_TEXTURE) | 202 ((rtt ? 1 : 0) << OFFSET_RTT ) | 203 ((xform ? 1 : 0) << OFFSET_XFORM ) | 204 ((isoblit ? 1 : 0) << OFFSET_ISOBLIT)); 205 } 206 207 /** 208 * Enqueues a BLIT operation with the given parameters. Note that the 209 * RenderQueue lock must be held before calling this method. 210 */ 211 private static void enqueueBlit(RenderQueue rq, 212 SurfaceData src, SurfaceData dst, 213 int packedParams, 214 int sx1, int sy1, 215 int sx2, int sy2, 216 double dx1, double dy1, 217 double dx2, double dy2) 218 { 219 // assert rq.lock.isHeldByCurrentThread(); 220 RenderBuffer buf = rq.getBuffer(); 221 rq.ensureCapacityAndAlignment(72, 24); 222 buf.putInt(BLIT); 223 buf.putInt(packedParams); 224 buf.putInt(sx1).putInt(sy1); 225 buf.putInt(sx2).putInt(sy2); 226 buf.putDouble(dx1).putDouble(dy1); 227 buf.putDouble(dx2).putDouble(dy2); 228 buf.putLong(src.getNativeOps()); 229 buf.putLong(dst.getNativeOps()); 230 } 231 232 static void Blit(SurfaceData srcData, SurfaceData dstData, 233 Composite comp, Region clip, 234 AffineTransform xform, int hint, 235 int sx1, int sy1, 236 int sx2, int sy2, 237 double dx1, double dy1, 238 double dx2, double dy2, 239 int srctype, boolean texture) 240 { 241 int ctxflags = 0; 242 if (srcData.getTransparency() == Transparency.OPAQUE) { 243 ctxflags |= D3DContext.SRC_IS_OPAQUE; 244 } 245 246 D3DSurfaceData d3dDst = (D3DSurfaceData)dstData; 247 D3DRenderQueue rq = D3DRenderQueue.getInstance(); 248 rq.lock(); 249 try { 250 // make sure the RenderQueue keeps a hard reference to the 251 // source (sysmem) SurfaceData to prevent it from being 252 // disposed while the operation is processed on the QFT 253 rq.addReference(srcData); 254 255 if (texture) { 256 // make sure we have a current context before uploading 257 // the sysmem data to the texture object 258 D3DContext.setScratchSurface(d3dDst.getContext()); 259 } else { 260 D3DContext.validateContext(d3dDst, d3dDst, 261 clip, comp, xform, null, null, 262 ctxflags); 263 } 264 265 int packedParams = createPackedParams(false, texture, 266 false, xform != null, 267 hint, srctype); 268 enqueueBlit(rq, srcData, dstData, 269 packedParams, 270 sx1, sy1, sx2, sy2, 271 dx1, dy1, dx2, dy2); 272 273 // always flush immediately, since we (currently) have no means 274 // of tracking changes to the system memory surface 275 rq.flushNow(); 276 } finally { 277 rq.unlock(); 278 } 279 280 if (d3dDst.getType() == D3DSurfaceData.WINDOW) { 281 // flush immediately when copying to the screen to improve 282 // responsiveness of applications using VI or BI backbuffers 283 D3DScreenUpdateManager mgr = 284 (D3DScreenUpdateManager)ScreenUpdateManager.getInstance(); 285 mgr.runUpdateNow(); 286 } 287 } 288 289 /** 290 * Note: The srcImg and biop parameters are only used when invoked 291 * from the D3DBufImgOps.renderImageWithOp() method; in all other cases, 292 * this method can be called with null values for those two parameters, 293 * and they will be effectively ignored. 294 */ 295 static void IsoBlit(SurfaceData srcData, SurfaceData dstData, 296 BufferedImage srcImg, BufferedImageOp biop, 297 Composite comp, Region clip, 298 AffineTransform xform, int hint, 299 int sx1, int sy1, 300 int sx2, int sy2, 301 double dx1, double dy1, 302 double dx2, double dy2, 303 boolean texture) 304 { 305 int ctxflags = 0; 306 if (srcData.getTransparency() == Transparency.OPAQUE) { 307 ctxflags |= D3DContext.SRC_IS_OPAQUE; 308 } 309 310 D3DSurfaceData d3dDst = (D3DSurfaceData)dstData; 311 D3DRenderQueue rq = D3DRenderQueue.getInstance(); 312 boolean rtt = false; 313 rq.lock(); 314 try { 315 D3DSurfaceData d3dSrc = (D3DSurfaceData)srcData; 316 int srctype = d3dSrc.getType(); 317 D3DSurfaceData srcCtxData = d3dSrc; 318 if (srctype == D3DSurfaceData.TEXTURE) { 319 rtt = false; 320 } else { 321 // the source is a backbuffer, or render-to-texture 322 // surface; we set rtt to true to differentiate this kind 323 // of surface from a regular texture object 324 rtt = true; 325 } 326 327 D3DContext.validateContext(srcCtxData, d3dDst, 328 clip, comp, xform, null, null, 329 ctxflags); 330 331 if (biop != null) { 332 D3DBufImgOps.enableBufImgOp(rq, d3dSrc, srcImg, biop); 333 } 334 335 int packedParams = createPackedParams(true, texture, 336 rtt, xform != null, 337 hint, 0 /*unused*/); 338 enqueueBlit(rq, srcData, dstData, 339 packedParams, 340 sx1, sy1, sx2, sy2, 341 dx1, dy1, dx2, dy2); 342 343 if (biop != null) { 344 D3DBufImgOps.disableBufImgOp(rq, biop); 345 } 346 } finally { 347 rq.unlock(); 348 } 349 350 if (rtt && (d3dDst.getType() == D3DSurfaceData.WINDOW)) { 351 // we only have to flush immediately when copying from a 352 // (non-texture) surface to the screen; otherwise Swing apps 353 // might appear unresponsive until the auto-flush completes 354 D3DScreenUpdateManager mgr = 355 (D3DScreenUpdateManager)ScreenUpdateManager.getInstance(); 356 mgr.runUpdateNow(); 357 } 358 } 359 } 360 361 class D3DSurfaceToSurfaceBlit extends Blit { 362 363 D3DSurfaceToSurfaceBlit() { 364 super(D3DSurfaceData.D3DSurface, 365 CompositeType.AnyAlpha, 366 D3DSurfaceData.D3DSurface); 367 } 368 369 public void Blit(SurfaceData src, SurfaceData dst, 370 Composite comp, Region clip, 371 int sx, int sy, int dx, int dy, int w, int h) 372 { 373 D3DBlitLoops.IsoBlit(src, dst, 374 null, null, 375 comp, clip, null, 376 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 377 sx, sy, sx+w, sy+h, 378 dx, dy, dx+w, dy+h, 379 false); 380 } 381 } 382 383 class D3DSurfaceToSurfaceScale extends ScaledBlit { 384 385 D3DSurfaceToSurfaceScale() { 386 super(D3DSurfaceData.D3DSurface, 387 CompositeType.AnyAlpha, 388 D3DSurfaceData.D3DSurface); 389 } 390 391 public void Scale(SurfaceData src, SurfaceData dst, 392 Composite comp, Region clip, 393 int sx1, int sy1, 394 int sx2, int sy2, 395 double dx1, double dy1, 396 double dx2, double dy2) 397 { 398 D3DBlitLoops.IsoBlit(src, dst, 399 null, null, 400 comp, clip, null, 401 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 402 sx1, sy1, sx2, sy2, 403 dx1, dy1, dx2, dy2, 404 false); 405 } 406 } 407 408 class D3DSurfaceToSurfaceTransform extends TransformBlit { 409 410 D3DSurfaceToSurfaceTransform() { 411 super(D3DSurfaceData.D3DSurface, 412 CompositeType.AnyAlpha, 413 D3DSurfaceData.D3DSurface); 414 } 415 416 public void Transform(SurfaceData src, SurfaceData dst, 417 Composite comp, Region clip, 418 AffineTransform at, int hint, 419 int sx, int sy, int dx, int dy, 420 int w, int h) 421 { 422 D3DBlitLoops.IsoBlit(src, dst, 423 null, null, 424 comp, clip, at, hint, 425 sx, sy, sx+w, sy+h, 426 dx, dy, dx+w, dy+h, 427 false); 428 } 429 } 430 431 class D3DRTTSurfaceToSurfaceBlit extends Blit { 432 433 D3DRTTSurfaceToSurfaceBlit() { 434 super(D3DSurfaceData.D3DSurfaceRTT, 435 CompositeType.AnyAlpha, 436 D3DSurfaceData.D3DSurface); 437 } 438 439 public void Blit(SurfaceData src, SurfaceData dst, 440 Composite comp, Region clip, 441 int sx, int sy, int dx, int dy, int w, int h) 442 { 443 D3DBlitLoops.IsoBlit(src, dst, 444 null, null, 445 comp, clip, null, 446 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 447 sx, sy, sx+w, sy+h, 448 dx, dy, dx+w, dy+h, 449 true); 450 } 451 } 452 453 class D3DRTTSurfaceToSurfaceScale extends ScaledBlit { 454 455 D3DRTTSurfaceToSurfaceScale() { 456 super(D3DSurfaceData.D3DSurfaceRTT, 457 CompositeType.AnyAlpha, 458 D3DSurfaceData.D3DSurface); 459 } 460 461 public void Scale(SurfaceData src, SurfaceData dst, 462 Composite comp, Region clip, 463 int sx1, int sy1, 464 int sx2, int sy2, 465 double dx1, double dy1, 466 double dx2, double dy2) 467 { 468 D3DBlitLoops.IsoBlit(src, dst, 469 null, null, 470 comp, clip, null, 471 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 472 sx1, sy1, sx2, sy2, 473 dx1, dy1, dx2, dy2, 474 true); 475 } 476 } 477 478 class D3DRTTSurfaceToSurfaceTransform extends TransformBlit { 479 480 D3DRTTSurfaceToSurfaceTransform() { 481 super(D3DSurfaceData.D3DSurfaceRTT, 482 CompositeType.AnyAlpha, 483 D3DSurfaceData.D3DSurface); 484 } 485 486 public void Transform(SurfaceData src, SurfaceData dst, 487 Composite comp, Region clip, 488 AffineTransform at, int hint, 489 int sx, int sy, int dx, int dy, int w, int h) 490 { 491 D3DBlitLoops.IsoBlit(src, dst, 492 null, null, 493 comp, clip, at, hint, 494 sx, sy, sx+w, sy+h, 495 dx, dy, dx+w, dy+h, 496 true); 497 } 498 } 499 500 class D3DSurfaceToSwBlit extends Blit { 501 502 private int typeval; 503 504 // REMIND: destination will actually be opaque/premultiplied... 505 D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) { 506 super(D3DSurfaceData.D3DSurface, 507 CompositeType.SrcNoEa, 508 dstType); 509 this.typeval = typeval; 510 } 511 512 public void Blit(SurfaceData src, SurfaceData dst, 513 Composite comp, Region clip, 514 int sx, int sy, int dx, int dy, 515 int w, int h) 516 { 517 D3DRenderQueue rq = D3DRenderQueue.getInstance(); 518 rq.lock(); 519 try { 520 // make sure the RenderQueue keeps a hard reference to the 521 // destination (sysmem) SurfaceData to prevent it from being 522 // disposed while the operation is processed on the QFT 523 rq.addReference(dst); 524 525 RenderBuffer buf = rq.getBuffer(); 526 D3DContext.setScratchSurface(((D3DSurfaceData)src).getContext()); 527 528 rq.ensureCapacityAndAlignment(48, 32); 529 buf.putInt(SURFACE_TO_SW_BLIT); 530 buf.putInt(sx).putInt(sy); 531 buf.putInt(dx).putInt(dy); 532 buf.putInt(w).putInt(h); 533 buf.putInt(typeval); 534 buf.putLong(src.getNativeOps()); 535 buf.putLong(dst.getNativeOps()); 536 537 // always flush immediately 538 rq.flushNow(); 539 } finally { 540 rq.unlock(); 541 } 542 } 543 } 544 545 class D3DSwToSurfaceBlit extends Blit { 546 547 private int typeval; 548 549 D3DSwToSurfaceBlit(SurfaceType srcType, int typeval) { 550 super(srcType, 551 CompositeType.AnyAlpha, 552 D3DSurfaceData.D3DSurface); 553 this.typeval = typeval; 554 } 555 556 public void Blit(SurfaceData src, SurfaceData dst, 557 Composite comp, Region clip, 558 int sx, int sy, int dx, int dy, int w, int h) 559 { 560 D3DBlitLoops.Blit(src, dst, 561 comp, clip, null, 562 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 563 sx, sy, sx+w, sy+h, 564 dx, dy, dx+w, dy+h, 565 typeval, false); 566 } 567 } 568 569 class D3DSwToSurfaceScale extends ScaledBlit { 570 571 private int typeval; 572 573 D3DSwToSurfaceScale(SurfaceType srcType, int typeval) { 574 super(srcType, 575 CompositeType.AnyAlpha, 576 D3DSurfaceData.D3DSurface); 577 this.typeval = typeval; 578 } 579 580 public void Scale(SurfaceData src, SurfaceData dst, 581 Composite comp, Region clip, 582 int sx1, int sy1, 583 int sx2, int sy2, 584 double dx1, double dy1, 585 double dx2, double dy2) 586 { 587 D3DBlitLoops.Blit(src, dst, 588 comp, clip, null, 589 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 590 sx1, sy1, sx2, sy2, 591 dx1, dy1, dx2, dy2, 592 typeval, false); 593 } 594 } 595 596 class D3DSwToSurfaceTransform extends TransformBlit { 597 598 private int typeval; 599 600 D3DSwToSurfaceTransform(SurfaceType srcType, int typeval) { 601 super(srcType, 602 CompositeType.AnyAlpha, 603 D3DSurfaceData.D3DSurface); 604 this.typeval = typeval; 605 } 606 607 public void Transform(SurfaceData src, SurfaceData dst, 608 Composite comp, Region clip, 609 AffineTransform at, int hint, 610 int sx, int sy, int dx, int dy, int w, int h) 611 { 612 D3DBlitLoops.Blit(src, dst, 613 comp, clip, at, hint, 614 sx, sy, sx+w, sy+h, 615 dx, dy, dx+w, dy+h, 616 typeval, false); 617 } 618 } 619 620 class D3DSwToTextureBlit extends Blit { 621 622 private int typeval; 623 624 D3DSwToTextureBlit(SurfaceType srcType, int typeval) { 625 super(srcType, 626 CompositeType.SrcNoEa, 627 D3DSurfaceData.D3DTexture); 628 this.typeval = typeval; 629 } 630 631 public void Blit(SurfaceData src, SurfaceData dst, 632 Composite comp, Region clip, 633 int sx, int sy, int dx, int dy, int w, int h) 634 { 635 D3DBlitLoops.Blit(src, dst, 636 comp, clip, null, 637 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 638 sx, sy, sx+w, sy+h, 639 dx, dy, dx+w, dy+h, 640 typeval, true); 641 } 642 } 643 644 class D3DTextureToSurfaceBlit extends Blit { 645 646 D3DTextureToSurfaceBlit() { 647 super(D3DSurfaceData.D3DTexture, 648 CompositeType.AnyAlpha, 649 D3DSurfaceData.D3DSurface); 650 } 651 652 public void Blit(SurfaceData src, SurfaceData dst, 653 Composite comp, Region clip, 654 int sx, int sy, int dx, int dy, int w, int h) 655 { 656 D3DBlitLoops.IsoBlit(src, dst, 657 null, null, 658 comp, clip, null, 659 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 660 sx, sy, sx+w, sy+h, 661 dx, dy, dx+w, dy+h, 662 true); 663 } 664 } 665 666 class D3DTextureToSurfaceScale extends ScaledBlit { 667 668 D3DTextureToSurfaceScale() { 669 super(D3DSurfaceData.D3DTexture, 670 CompositeType.AnyAlpha, 671 D3DSurfaceData.D3DSurface); 672 } 673 674 public void Scale(SurfaceData src, SurfaceData dst, 675 Composite comp, Region clip, 676 int sx1, int sy1, 677 int sx2, int sy2, 678 double dx1, double dy1, 679 double dx2, double dy2) 680 { 681 D3DBlitLoops.IsoBlit(src, dst, 682 null, null, 683 comp, clip, null, 684 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 685 sx1, sy1, sx2, sy2, 686 dx1, dy1, dx2, dy2, 687 true); 688 } 689 } 690 691 class D3DTextureToSurfaceTransform extends TransformBlit { 692 693 D3DTextureToSurfaceTransform() { 694 super(D3DSurfaceData.D3DTexture, 695 CompositeType.AnyAlpha, 696 D3DSurfaceData.D3DSurface); 697 } 698 699 public void Transform(SurfaceData src, SurfaceData dst, 700 Composite comp, Region clip, 701 AffineTransform at, int hint, 702 int sx, int sy, int dx, int dy, 703 int w, int h) 704 { 705 D3DBlitLoops.IsoBlit(src, dst, 706 null, null, 707 comp, clip, at, hint, 708 sx, sy, sx+w, sy+h, 709 dx, dy, dx+w, dy+h, 710 true); 711 } 712 } 713 714 /** 715 * This general Blit implementation converts any source surface to an 716 * intermediate IntArgbPre surface, and then uses the more specific 717 * IntArgbPre->D3DSurface/Texture loop to get the intermediate 718 * (premultiplied) surface down to D3D using simple blit. 719 */ 720 class D3DGeneralBlit extends Blit { 721 722 private final Blit performop; 723 private WeakReference<SurfaceData> srcTmp; 724 725 D3DGeneralBlit(SurfaceType dstType, 726 CompositeType compType, 727 Blit performop) 728 { 729 super(SurfaceType.Any, compType, dstType); 730 this.performop = performop; 731 } 732 733 public synchronized void Blit(SurfaceData src, SurfaceData dst, 734 Composite comp, Region clip, 735 int sx, int sy, int dx, int dy, 736 int w, int h) 737 { 738 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 739 CompositeType.SrcNoEa, 740 SurfaceType.IntArgbPre); 741 742 SurfaceData cachedSrc = null; 743 if (srcTmp != null) { 744 // use cached intermediate surface, if available 745 cachedSrc = srcTmp.get(); 746 } 747 748 // convert source to IntArgbPre 749 src = convertFrom(convertsrc, src, sx, sy, w, h, 750 cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE); 751 752 // copy IntArgbPre intermediate surface to D3D surface 753 performop.Blit(src, dst, comp, clip, 754 0, 0, dx, dy, w, h); 755 756 if (src != cachedSrc) { 757 // cache the intermediate surface 758 srcTmp = new WeakReference<>(src); 759 } 760 } 761 } 762 763 /** 764 * This general TransformedBlit implementation converts any source surface to an 765 * intermediate IntArgbPre surface, and then uses the more specific 766 * IntArgbPre->D3DSurface/Texture loop to get the intermediate 767 * (premultiplied) surface down to D3D using simple transformBlit. 768 */ 769 final class D3DGeneralTransformedBlit extends TransformBlit { 770 771 private final TransformBlit performop; 772 private WeakReference<SurfaceData> srcTmp; 773 774 D3DGeneralTransformedBlit(final TransformBlit performop) { 775 super(SurfaceType.Any, CompositeType.AnyAlpha, 776 D3DSurfaceData.D3DSurface); 777 this.performop = performop; 778 } 779 780 @Override 781 public synchronized void Transform(SurfaceData src, SurfaceData dst, 782 Composite comp, Region clip, 783 AffineTransform at, int hint, int srcx, 784 int srcy, int dstx, int dsty, int width, 785 int height){ 786 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 787 CompositeType.SrcNoEa, 788 SurfaceType.IntArgbPre); 789 // use cached intermediate surface, if available 790 final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; 791 // convert source to IntArgbPre 792 src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, 793 BufferedImage.TYPE_INT_ARGB_PRE); 794 795 // transform IntArgbPre intermediate surface to D3D surface 796 performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, 797 width, height); 798 799 if (src != cachedSrc) { 800 // cache the intermediate surface 801 srcTmp = new WeakReference<>(src); 802 } 803 } 804 } 805 806 /* 807 * The following classes prohibit copying D3DSurfaces to the screen 808 * (the D3D->sysmem->GDI path is known to be very very slow). 809 * 810 * Note: we used to disable hw acceleration for the surafce manager associated 811 * with the source surface in these loops but it proved to be too cautious. 812 * 813 * In most cases d3d->screen copy happens only during some transitional 814 * period where the accelerated destination surface is being recreated or 815 * restored (for example, when Swing's backbuffer VI is copied to the screen 816 * but the D3DScreenSurfaceManager couldn't restore its surface). 817 * 818 * An exception is if for some reason we could not enable accelerated on-screen 819 * rendering for this window for some permanent reason (like window being too 820 * small, or a present BufferStrategy). 821 * 822 * This meant that we'd disable hw acceleration after the first failure 823 * completely (at least until the src image is recreated which in case of 824 * Swing back-buffer happens only after resize). 825 * 826 * Now we delegate to the VISM to figure out if the acceleration needs to 827 * be disabled or if we can wait for a while until the onscreen accelerated 828 * can resume (by marking the source surface lost and making sure the 829 * VISM has a chance to use the backup surface). 830 * 831 */ 832 833 class D3DSurfaceToGDIWindowSurfaceBlit extends Blit { 834 835 D3DSurfaceToGDIWindowSurfaceBlit() { 836 super(D3DSurfaceData.D3DSurface, 837 CompositeType.AnyAlpha, 838 GDIWindowSurfaceData.AnyGdi); 839 } 840 @Override 841 public void Blit(SurfaceData src, SurfaceData dst, 842 Composite comp, Region clip, 843 int sx, int sy, int dx, int dy, int w, int h) 844 { 845 // see comment above 846 D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst); 847 } 848 849 } 850 851 class D3DSurfaceToGDIWindowSurfaceScale extends ScaledBlit { 852 853 D3DSurfaceToGDIWindowSurfaceScale() { 854 super(D3DSurfaceData.D3DSurface, 855 CompositeType.AnyAlpha, 856 GDIWindowSurfaceData.AnyGdi); 857 } 858 @Override 859 public void Scale(SurfaceData src, SurfaceData dst, 860 Composite comp, Region clip, 861 int sx1, int sy1, 862 int sx2, int sy2, 863 double dx1, double dy1, 864 double dx2, double dy2) 865 { 866 // see comment above 867 D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst); 868 } 869 } 870 871 class D3DSurfaceToGDIWindowSurfaceTransform extends TransformBlit { 872 873 D3DSurfaceToGDIWindowSurfaceTransform() { 874 super(D3DSurfaceData.D3DSurface, 875 CompositeType.AnyAlpha, 876 GDIWindowSurfaceData.AnyGdi); 877 } 878 @Override 879 public void Transform(SurfaceData src, SurfaceData dst, 880 Composite comp, Region clip, 881 AffineTransform at, int hint, 882 int sx, int sy, int dx, int dy, 883 int w, int h) 884 { 885 // see comment above 886 D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst); 887 } 888 }