< prev index next >
src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
Print this page
@@ -498,24 +498,80 @@
}
class D3DSurfaceToSwBlit extends Blit {
private int typeval;
+ private WeakReference<SurfaceData> srcTmp;
- // REMIND: destination will actually be opaque/premultiplied...
+ // destination will actually be ArgbPre or Argb
D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) {
super(D3DSurfaceData.D3DSurface,
CompositeType.SrcNoEa,
dstType);
this.typeval = typeval;
}
+ private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy,
+ int w, int h) {
+ SurfaceData cachedSrc = null;
+ if (srcTmp != null) {
+ // use cached intermediate surface, if available
+ cachedSrc = srcTmp.get();
+ }
+
+ // We can convert argb_pre data from D3d surface in two places:
+ // - During D3d surface -> SW blit
+ // - During SW -> SW blit
+ // The first one is faster when we use opaque D3d surface, because in
+ // this case we simply skip conversion and use color components as is.
+ // Because of this we align intermediate buffer type with type of
+ // destination not source.
+ final int type = typeval == D3DSurfaceData.ST_INT_ARGB_PRE ?
+ BufferedImage.TYPE_INT_ARGB_PRE :
+ BufferedImage.TYPE_INT_ARGB;
+
+ src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);
+
+ // copy intermediate SW to destination SW using complex clip
+ final Blit performop = Blit.getFromCache(src.getSurfaceType(),
+ CompositeType.SrcNoEa,
+ dst.getSurfaceType());
+ performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
+
+ if (src != cachedSrc) {
+ // cache the intermediate surface
+ srcTmp = new WeakReference<>(src);
+ }
+ }
+
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
int w, int h)
{
+ if (clip != null) {
+ clip = clip.getIntersectionXYWH(dx, dy, w, h);
+ // At the end this method will flush the RenderQueue, we should exit
+ // from it as soon as possible.
+ if (clip.isEmpty()) {
+ return;
+ }
+ sx += clip.getLoX() - dx;
+ sy += clip.getLoY() - dy;
+ dx = clip.getLoX();
+ dy = clip.getLoY();
+ w = clip.getWidth();
+ h = clip.getHeight();
+
+ if (!clip.isRectangular()) {
+ complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
+ return;
+ }
+ }
+
D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock();
try {
// make sure the RenderQueue keeps a hard reference to the
// destination (sysmem) SurfaceData to prevent it from being
< prev index next >