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 side D3D interface supports copying surface contents to 554 // ST_INT_ARGB, ST_INT_ARGB_PRE and other pixel formats 555 final int type = typeval == D3DSurfaceData.ST_INT_ARGB_PRE ? 556 BufferedImage.TYPE_INT_ARGB_PRE : 557 BufferedImage.TYPE_INT_ARGB; 558 559 src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type); 560 561 // copy intermediate SW to destination SW using complex clip 562 final Blit performop = Blit.getFromCache(src.getSurfaceType(), 563 CompositeType.SrcNoEa, 564 dst.getSurfaceType()); 565 performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h); 566 567 if (src != cachedSrc) { 568 // cache the intermediate surface 569 srcTmp = new WeakReference<>(src); 570 } 571 } 572 573 public void Blit(SurfaceData src, SurfaceData dst, 574 Composite comp, Region clip, 575 int sx, int sy, int dx, int dy, 576 int w, int h) 577 { 578 if (clip != null) { 579 clip = clip.getIntersectionXYWH(dx, dy, w, h); 580 // At the end this method will flush the RenderQueue, we should exit 581 // from it as soon as possible. 582 if (clip.isEmpty()) { 583 return; 584 } 585 586 // Adjust final dst(x,y) and src(x,y) based on the clip. The 587 // logic is that, when clip limits drawing on the destination, 588 // corresponding pixels from the src should be skipped. 589 sx += clip.getLoX() - dx; 590 sy += clip.getLoY() - dy; 591 dx = clip.getLoX(); 592 dy = clip.getLoY(); 593 w = clip.getWidth(); 594 h = clip.getHeight(); 595 596 // Check if the clip is Rectangular. For non-rectangular clips 597 // complexClipBlit will convert Surface To Sysmem and perform 598 // regular Blit. 599 if (!clip.isRectangular()) { 600 complexClipBlit(src, dst, comp, clip, 601 sx, sy, dx, dy, 602 w, h); 603 return; 604 } 605 } 606 607 D3DRenderQueue rq = D3DRenderQueue.getInstance(); 608 rq.lock(); 609 try { 610 // make sure the RenderQueue keeps a hard reference to the 611 // destination (sysmem) SurfaceData to prevent it from being 612 // disposed while the operation is processed on the QFT 613 rq.addReference(dst); 614 615 RenderBuffer buf = rq.getBuffer(); 616 D3DContext.setScratchSurface(((D3DSurfaceData)src).getContext()); 617 618 rq.ensureCapacityAndAlignment(48, 32); 619 buf.putInt(SURFACE_TO_SW_BLIT); 620 buf.putInt(sx).putInt(sy); 621 buf.putInt(dx).putInt(dy); 622 buf.putInt(w).putInt(h); 623 buf.putInt(typeval); 624 buf.putLong(src.getNativeOps()); 625 buf.putLong(dst.getNativeOps()); 626 |