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 }