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