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 | 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 private WeakReference<SurfaceData> srcTmp; 504 505 // REMIND: destination will actually be opaque/premultiplied... 506 D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) { 507 super(D3DSurfaceData.D3DSurface, 508 CompositeType.SrcNoEa, 509 dstType); 510 this.typeval = typeval; 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 570 public void Blit(SurfaceData src, SurfaceData dst, 571 Composite comp, Region clip, 572 int sx, int sy, int dx, int dy, 573 int w, int h) 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 604 D3DRenderQueue rq = D3DRenderQueue.getInstance(); 605 rq.lock(); 606 try { 607 // make sure the RenderQueue keeps a hard reference to the 608 // destination (sysmem) SurfaceData to prevent it from being 609 // disposed while the operation is processed on the QFT 610 rq.addReference(dst); 611 612 RenderBuffer buf = rq.getBuffer(); 613 D3DContext.setScratchSurface(((D3DSurfaceData)src).getContext()); 614 615 rq.ensureCapacityAndAlignment(48, 32); 616 buf.putInt(SURFACE_TO_SW_BLIT); 617 buf.putInt(sx).putInt(sy); 618 buf.putInt(dx).putInt(dy); 619 buf.putInt(w).putInt(h); 620 buf.putInt(typeval); 621 buf.putLong(src.getNativeOps()); 622 buf.putLong(dst.getNativeOps()); 623 |