jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
changeset 36467 836382b377d9
parent 27500 d291fa015bf9
equal deleted inserted replaced
36466:64a41d6ef451 36467:836382b377d9
   498 }
   498 }
   499 
   499 
   500 class D3DSurfaceToSwBlit extends Blit {
   500 class D3DSurfaceToSwBlit extends Blit {
   501 
   501 
   502     private int typeval;
   502     private int typeval;
       
   503     private WeakReference<SurfaceData> srcTmp;
   503 
   504 
   504     // REMIND: destination will actually be opaque/premultiplied...
   505     // REMIND: destination will actually be opaque/premultiplied...
   505     D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) {
   506     D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) {
   506         super(D3DSurfaceData.D3DSurface,
   507         super(D3DSurfaceData.D3DSurface,
   507               CompositeType.SrcNoEa,
   508               CompositeType.SrcNoEa,
   508               dstType);
   509               dstType);
   509         this.typeval = typeval;
   510         this.typeval = typeval;
   510     }
   511     }
   511 
   512 
       
   513     /*
       
   514      * Clip value is ignored in D3D SurfaceToSw blit.
       
   515      * Root Cause: The native interfaces to D3D use StretchRect API followed
       
   516      * by custom copy of pixels from Surface to Sysmem. As a result, clipping
       
   517      * in D3DSurfaceToSw works 'only' for Rect clips, provided, proper srcX,
       
   518      * srcY, dstX, dstY, width and height are passed to native interfaces.
       
   519      * Non rect clips (For example: Shape clips) are ignored completely.
       
   520      *
       
   521      * Solution: There are three solutions possible to fix this issue.
       
   522      * 1. Convert the entire Surface to Sysmem and perform regular Blit.
       
   523      *    An optimized version of this is to take up the conversion only
       
   524      *    when Shape clips are needed. Existing native interface will suffice
       
   525      *    for supporting Rect clips.
       
   526      * 2. With help of existing classes we could perform SwToSurface,
       
   527      *    SurfaceToSurface (implements clip) and SurfaceToSw (complete copy)
       
   528      *    in order.
       
   529      * 3. Modify the native D3D interface to accept clip and perform same logic
       
   530      *    as the second approach but at native side.
       
   531      *
       
   532      * Upon multiple experiments, the first approach has been found to be
       
   533      * faster than the others as it deploys 1-draw/copy operation for rect clip
       
   534      * and 2-draw/copy operations for shape clip compared to 3-draws/copy
       
   535      * operations deployed by the remaining approaches.
       
   536      *
       
   537      * complexClipBlit method helps to convert or copy the contents from
       
   538      * D3DSurface onto Sysmem and perform a regular Blit with the clip
       
   539      * information as required. This method is used when non-rectangular
       
   540      * clip is needed.
       
   541      */
       
   542     private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,
       
   543                                               Composite comp, Region clip,
       
   544                                               int sx, int sy, int dx, int dy,
       
   545                                               int w, int h) {
       
   546         SurfaceData cachedSrc = null;
       
   547         if (srcTmp != null) {
       
   548             // use cached intermediate surface, if available
       
   549             cachedSrc = srcTmp.get();
       
   550         }
       
   551 
       
   552         // Type- indicates the pixel format of Sysmem based BufferedImage.
       
   553         // Native d3d interfaces support on the fly conversion of pixels from
       
   554         // d3d surface to destination sysmem memory of type IntARGB only.
       
   555         final int type = BufferedImage.TYPE_INT_ARGB;
       
   556         src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);
       
   557 
       
   558         // copy intermediate SW to destination SW using complex clip
       
   559         final Blit performop = Blit.getFromCache(src.getSurfaceType(),
       
   560                                                  CompositeType.SrcNoEa,
       
   561                                                  dst.getSurfaceType());
       
   562         performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
       
   563 
       
   564         if (src != cachedSrc) {
       
   565             // cache the intermediate surface
       
   566             srcTmp = new WeakReference<>(src);
       
   567         }
       
   568     }
       
   569 
   512     public void Blit(SurfaceData src, SurfaceData dst,
   570     public void Blit(SurfaceData src, SurfaceData dst,
   513                      Composite comp, Region clip,
   571                      Composite comp, Region clip,
   514                      int sx, int sy, int dx, int dy,
   572                      int sx, int sy, int dx, int dy,
   515                      int w, int h)
   573                      int w, int h)
   516     {
   574     {
       
   575         if (clip != null) {
       
   576             clip = clip.getIntersectionXYWH(dx, dy, w, h);
       
   577             // At the end this method will flush the RenderQueue, we should exit
       
   578             // from it as soon as possible.
       
   579             if (clip.isEmpty()) {
       
   580                 return;
       
   581             }
       
   582 
       
   583             // Adjust final dst(x,y) and src(x,y) based on the clip. The
       
   584             // logic is that, when clip limits drawing on the destination,
       
   585             // corresponding pixels from the src should be skipped.
       
   586             sx += clip.getLoX() - dx;
       
   587             sy += clip.getLoY() - dy;
       
   588             dx = clip.getLoX();
       
   589             dy = clip.getLoY();
       
   590             w = clip.getWidth();
       
   591             h = clip.getHeight();
       
   592 
       
   593             // Check if the clip is Rectangular. For non-rectangular clips
       
   594             // complexClipBlit will convert Surface To Sysmem and perform
       
   595             // regular Blit.
       
   596             if (!clip.isRectangular()) {
       
   597                 complexClipBlit(src, dst, comp, clip,
       
   598                                 sx, sy, dx, dy,
       
   599                                 w, h);
       
   600                 return;
       
   601             }
       
   602         }
       
   603 
   517         D3DRenderQueue rq = D3DRenderQueue.getInstance();
   604         D3DRenderQueue rq = D3DRenderQueue.getInstance();
   518         rq.lock();
   605         rq.lock();
   519         try {
   606         try {
   520             // make sure the RenderQueue keeps a hard reference to the
   607             // make sure the RenderQueue keeps a hard reference to the
   521             // destination (sysmem) SurfaceData to prevent it from being
   608             // destination (sysmem) SurfaceData to prevent it from being