Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
41159 views
1
/*
2
* Copyright (c) 2007, 2014, 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 java.lang.annotation.Native;
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
final class D3DBlitLoops {
52
53
static void register() {
54
Blit blitIntArgbPreToSurface =
55
new D3DSwToSurfaceBlit(SurfaceType.IntArgbPre,
56
D3DSurfaceData.ST_INT_ARGB_PRE);
57
Blit blitIntArgbPreToTexture =
58
new D3DSwToTextureBlit(SurfaceType.IntArgbPre,
59
D3DSurfaceData.ST_INT_ARGB_PRE);
60
TransformBlit transformBlitIntArgbPreToSurface =
61
new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
62
D3DSurfaceData.ST_INT_ARGB_PRE);
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.IntRgb,
129
D3DSurfaceData.ST_INT_RGB),
130
new D3DSwToSurfaceTransform(SurfaceType.IntBgr,
131
D3DSurfaceData.ST_INT_BGR),
132
new D3DSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
133
D3DSurfaceData.ST_3BYTE_BGR),
134
new D3DSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
135
D3DSurfaceData.ST_USHORT_565_RGB),
136
new D3DSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
137
D3DSurfaceData.ST_USHORT_555_RGB),
138
new D3DSwToSurfaceTransform(SurfaceType.ByteIndexed,
139
D3DSurfaceData.ST_BYTE_INDEXED),
140
// REMIND: we don't have a native sw loop to back this loop up
141
// new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,
142
// D3DSurfaceData.ST_BYTE_INDEXED_BM),
143
transformBlitIntArgbPreToSurface,
144
145
new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
146
147
// texture->surface ops
148
new D3DTextureToSurfaceBlit(),
149
new D3DTextureToSurfaceScale(),
150
new D3DTextureToSurfaceTransform(),
151
152
// sw->texture ops
153
blitIntArgbPreToTexture,
154
new D3DSwToTextureBlit(SurfaceType.IntRgb,
155
D3DSurfaceData.ST_INT_RGB),
156
new D3DSwToTextureBlit(SurfaceType.IntArgb,
157
D3DSurfaceData.ST_INT_ARGB),
158
new D3DSwToTextureBlit(SurfaceType.IntBgr,
159
D3DSurfaceData.ST_INT_BGR),
160
new D3DSwToTextureBlit(SurfaceType.ThreeByteBgr,
161
D3DSurfaceData.ST_3BYTE_BGR),
162
new D3DSwToTextureBlit(SurfaceType.Ushort565Rgb,
163
D3DSurfaceData.ST_USHORT_565_RGB),
164
new D3DSwToTextureBlit(SurfaceType.Ushort555Rgb,
165
D3DSurfaceData.ST_USHORT_555_RGB),
166
new D3DSwToTextureBlit(SurfaceType.ByteIndexed,
167
D3DSurfaceData.ST_BYTE_INDEXED),
168
// REMIND: we don't have a native sw loop to back this loop up
169
// new D3DSwToTextureBlit(SurfaceType.ByteIndexedBm,
170
// D3DSurfaceData.ST_BYTE_INDEXED_BM),
171
new D3DGeneralBlit(D3DSurfaceData.D3DTexture,
172
CompositeType.SrcNoEa,
173
blitIntArgbPreToTexture),
174
};
175
GraphicsPrimitiveMgr.register(primitives);
176
}
177
178
/**
179
* The following offsets are used to pack the parameters in
180
* createPackedParams(). (They are also used at the native level when
181
* unpacking the params.)
182
*/
183
@Native private static final int OFFSET_SRCTYPE = 16;
184
@Native private static final int OFFSET_HINT = 8;
185
@Native private static final int OFFSET_TEXTURE = 3;
186
@Native private static final int OFFSET_RTT = 2;
187
@Native private static final int OFFSET_XFORM = 1;
188
@Native private static final int OFFSET_ISOBLIT = 0;
189
190
/**
191
* Packs the given parameters into a single int value in order to save
192
* space on the rendering queue.
193
*/
194
private static int createPackedParams(boolean isoblit, boolean texture,
195
boolean rtt, boolean xform,
196
int hint, int srctype)
197
{
198
return
199
((srctype << OFFSET_SRCTYPE) |
200
(hint << OFFSET_HINT ) |
201
((texture ? 1 : 0) << OFFSET_TEXTURE) |
202
((rtt ? 1 : 0) << OFFSET_RTT ) |
203
((xform ? 1 : 0) << OFFSET_XFORM ) |
204
((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
205
}
206
207
/**
208
* Enqueues a BLIT operation with the given parameters. Note that the
209
* RenderQueue lock must be held before calling this method.
210
*/
211
private static void enqueueBlit(RenderQueue rq,
212
SurfaceData src, SurfaceData dst,
213
int packedParams,
214
int sx1, int sy1,
215
int sx2, int sy2,
216
double dx1, double dy1,
217
double dx2, double dy2)
218
{
219
// assert rq.lock.isHeldByCurrentThread();
220
RenderBuffer buf = rq.getBuffer();
221
rq.ensureCapacityAndAlignment(72, 24);
222
buf.putInt(BLIT);
223
buf.putInt(packedParams);
224
buf.putInt(sx1).putInt(sy1);
225
buf.putInt(sx2).putInt(sy2);
226
buf.putDouble(dx1).putDouble(dy1);
227
buf.putDouble(dx2).putDouble(dy2);
228
buf.putLong(src.getNativeOps());
229
buf.putLong(dst.getNativeOps());
230
}
231
232
static void Blit(SurfaceData srcData, SurfaceData dstData,
233
Composite comp, Region clip,
234
AffineTransform xform, int hint,
235
int sx1, int sy1,
236
int sx2, int sy2,
237
double dx1, double dy1,
238
double dx2, double dy2,
239
int srctype, boolean texture)
240
{
241
int ctxflags = 0;
242
if (srcData.getTransparency() == Transparency.OPAQUE) {
243
ctxflags |= D3DContext.SRC_IS_OPAQUE;
244
}
245
246
D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;
247
D3DRenderQueue rq = D3DRenderQueue.getInstance();
248
rq.lock();
249
try {
250
// make sure the RenderQueue keeps a hard reference to the
251
// source (sysmem) SurfaceData to prevent it from being
252
// disposed while the operation is processed on the QFT
253
rq.addReference(srcData);
254
255
if (texture) {
256
// make sure we have a current context before uploading
257
// the sysmem data to the texture object
258
D3DContext.setScratchSurface(d3dDst.getContext());
259
} else {
260
D3DContext.validateContext(d3dDst, d3dDst,
261
clip, comp, xform, null, null,
262
ctxflags);
263
}
264
265
int packedParams = createPackedParams(false, texture,
266
false, xform != null,
267
hint, srctype);
268
enqueueBlit(rq, srcData, dstData,
269
packedParams,
270
sx1, sy1, sx2, sy2,
271
dx1, dy1, dx2, dy2);
272
273
// always flush immediately, since we (currently) have no means
274
// of tracking changes to the system memory surface
275
rq.flushNow();
276
} finally {
277
rq.unlock();
278
}
279
280
if (d3dDst.getType() == D3DSurfaceData.WINDOW) {
281
// flush immediately when copying to the screen to improve
282
// responsiveness of applications using VI or BI backbuffers
283
D3DScreenUpdateManager mgr =
284
(D3DScreenUpdateManager)ScreenUpdateManager.getInstance();
285
mgr.runUpdateNow();
286
}
287
}
288
289
/**
290
* Note: The srcImg and biop parameters are only used when invoked
291
* from the D3DBufImgOps.renderImageWithOp() method; in all other cases,
292
* this method can be called with null values for those two parameters,
293
* and they will be effectively ignored.
294
*/
295
static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
296
BufferedImage srcImg, BufferedImageOp biop,
297
Composite comp, Region clip,
298
AffineTransform xform, int hint,
299
int sx1, int sy1,
300
int sx2, int sy2,
301
double dx1, double dy1,
302
double dx2, double dy2,
303
boolean texture)
304
{
305
int ctxflags = 0;
306
if (srcData.getTransparency() == Transparency.OPAQUE) {
307
ctxflags |= D3DContext.SRC_IS_OPAQUE;
308
}
309
310
D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;
311
D3DRenderQueue rq = D3DRenderQueue.getInstance();
312
boolean rtt = false;
313
rq.lock();
314
try {
315
D3DSurfaceData d3dSrc = (D3DSurfaceData)srcData;
316
int srctype = d3dSrc.getType();
317
D3DSurfaceData srcCtxData = d3dSrc;
318
if (srctype == D3DSurfaceData.TEXTURE) {
319
rtt = false;
320
} else {
321
// the source is a backbuffer, or render-to-texture
322
// surface; we set rtt to true to differentiate this kind
323
// of surface from a regular texture object
324
rtt = true;
325
}
326
327
D3DContext.validateContext(srcCtxData, d3dDst,
328
clip, comp, xform, null, null,
329
ctxflags);
330
331
if (biop != null) {
332
D3DBufImgOps.enableBufImgOp(rq, d3dSrc, srcImg, biop);
333
}
334
335
int packedParams = createPackedParams(true, texture,
336
rtt, xform != null,
337
hint, 0 /*unused*/);
338
enqueueBlit(rq, srcData, dstData,
339
packedParams,
340
sx1, sy1, sx2, sy2,
341
dx1, dy1, dx2, dy2);
342
343
if (biop != null) {
344
D3DBufImgOps.disableBufImgOp(rq, biop);
345
}
346
} finally {
347
rq.unlock();
348
}
349
350
if (rtt && (d3dDst.getType() == D3DSurfaceData.WINDOW)) {
351
// we only have to flush immediately when copying from a
352
// (non-texture) surface to the screen; otherwise Swing apps
353
// might appear unresponsive until the auto-flush completes
354
D3DScreenUpdateManager mgr =
355
(D3DScreenUpdateManager)ScreenUpdateManager.getInstance();
356
mgr.runUpdateNow();
357
}
358
}
359
}
360
361
class D3DSurfaceToSurfaceBlit extends Blit {
362
363
D3DSurfaceToSurfaceBlit() {
364
super(D3DSurfaceData.D3DSurface,
365
CompositeType.AnyAlpha,
366
D3DSurfaceData.D3DSurface);
367
}
368
369
public void Blit(SurfaceData src, SurfaceData dst,
370
Composite comp, Region clip,
371
int sx, int sy, int dx, int dy, int w, int h)
372
{
373
D3DBlitLoops.IsoBlit(src, dst,
374
null, null,
375
comp, clip, null,
376
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
377
sx, sy, sx+w, sy+h,
378
dx, dy, dx+w, dy+h,
379
false);
380
}
381
}
382
383
class D3DSurfaceToSurfaceScale extends ScaledBlit {
384
385
D3DSurfaceToSurfaceScale() {
386
super(D3DSurfaceData.D3DSurface,
387
CompositeType.AnyAlpha,
388
D3DSurfaceData.D3DSurface);
389
}
390
391
public void Scale(SurfaceData src, SurfaceData dst,
392
Composite comp, Region clip,
393
int sx1, int sy1,
394
int sx2, int sy2,
395
double dx1, double dy1,
396
double dx2, double dy2)
397
{
398
D3DBlitLoops.IsoBlit(src, dst,
399
null, null,
400
comp, clip, null,
401
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
402
sx1, sy1, sx2, sy2,
403
dx1, dy1, dx2, dy2,
404
false);
405
}
406
}
407
408
class D3DSurfaceToSurfaceTransform extends TransformBlit {
409
410
D3DSurfaceToSurfaceTransform() {
411
super(D3DSurfaceData.D3DSurface,
412
CompositeType.AnyAlpha,
413
D3DSurfaceData.D3DSurface);
414
}
415
416
public void Transform(SurfaceData src, SurfaceData dst,
417
Composite comp, Region clip,
418
AffineTransform at, int hint,
419
int sx, int sy, int dx, int dy,
420
int w, int h)
421
{
422
D3DBlitLoops.IsoBlit(src, dst,
423
null, null,
424
comp, clip, at, hint,
425
sx, sy, sx+w, sy+h,
426
dx, dy, dx+w, dy+h,
427
false);
428
}
429
}
430
431
class D3DRTTSurfaceToSurfaceBlit extends Blit {
432
433
D3DRTTSurfaceToSurfaceBlit() {
434
super(D3DSurfaceData.D3DSurfaceRTT,
435
CompositeType.AnyAlpha,
436
D3DSurfaceData.D3DSurface);
437
}
438
439
public void Blit(SurfaceData src, SurfaceData dst,
440
Composite comp, Region clip,
441
int sx, int sy, int dx, int dy, int w, int h)
442
{
443
D3DBlitLoops.IsoBlit(src, dst,
444
null, null,
445
comp, clip, null,
446
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
447
sx, sy, sx+w, sy+h,
448
dx, dy, dx+w, dy+h,
449
true);
450
}
451
}
452
453
class D3DRTTSurfaceToSurfaceScale extends ScaledBlit {
454
455
D3DRTTSurfaceToSurfaceScale() {
456
super(D3DSurfaceData.D3DSurfaceRTT,
457
CompositeType.AnyAlpha,
458
D3DSurfaceData.D3DSurface);
459
}
460
461
public void Scale(SurfaceData src, SurfaceData dst,
462
Composite comp, Region clip,
463
int sx1, int sy1,
464
int sx2, int sy2,
465
double dx1, double dy1,
466
double dx2, double dy2)
467
{
468
D3DBlitLoops.IsoBlit(src, dst,
469
null, null,
470
comp, clip, null,
471
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
472
sx1, sy1, sx2, sy2,
473
dx1, dy1, dx2, dy2,
474
true);
475
}
476
}
477
478
class D3DRTTSurfaceToSurfaceTransform extends TransformBlit {
479
480
D3DRTTSurfaceToSurfaceTransform() {
481
super(D3DSurfaceData.D3DSurfaceRTT,
482
CompositeType.AnyAlpha,
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
624
// always flush immediately
625
rq.flushNow();
626
} finally {
627
rq.unlock();
628
}
629
}
630
}
631
632
class D3DSwToSurfaceBlit extends Blit {
633
634
private int typeval;
635
636
D3DSwToSurfaceBlit(SurfaceType srcType, int typeval) {
637
super(srcType,
638
CompositeType.AnyAlpha,
639
D3DSurfaceData.D3DSurface);
640
this.typeval = typeval;
641
}
642
643
public void Blit(SurfaceData src, SurfaceData dst,
644
Composite comp, Region clip,
645
int sx, int sy, int dx, int dy, int w, int h)
646
{
647
D3DBlitLoops.Blit(src, dst,
648
comp, clip, null,
649
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
650
sx, sy, sx+w, sy+h,
651
dx, dy, dx+w, dy+h,
652
typeval, false);
653
}
654
}
655
656
class D3DSwToSurfaceScale extends ScaledBlit {
657
658
private int typeval;
659
660
D3DSwToSurfaceScale(SurfaceType srcType, int typeval) {
661
super(srcType,
662
CompositeType.AnyAlpha,
663
D3DSurfaceData.D3DSurface);
664
this.typeval = typeval;
665
}
666
667
public void Scale(SurfaceData src, SurfaceData dst,
668
Composite comp, Region clip,
669
int sx1, int sy1,
670
int sx2, int sy2,
671
double dx1, double dy1,
672
double dx2, double dy2)
673
{
674
D3DBlitLoops.Blit(src, dst,
675
comp, clip, null,
676
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
677
sx1, sy1, sx2, sy2,
678
dx1, dy1, dx2, dy2,
679
typeval, false);
680
}
681
}
682
683
class D3DSwToSurfaceTransform extends TransformBlit {
684
685
private int typeval;
686
687
D3DSwToSurfaceTransform(SurfaceType srcType, int typeval) {
688
super(srcType,
689
CompositeType.AnyAlpha,
690
D3DSurfaceData.D3DSurface);
691
this.typeval = typeval;
692
}
693
694
public void Transform(SurfaceData src, SurfaceData dst,
695
Composite comp, Region clip,
696
AffineTransform at, int hint,
697
int sx, int sy, int dx, int dy, int w, int h)
698
{
699
D3DBlitLoops.Blit(src, dst,
700
comp, clip, at, hint,
701
sx, sy, sx+w, sy+h,
702
dx, dy, dx+w, dy+h,
703
typeval, false);
704
}
705
}
706
707
class D3DSwToTextureBlit extends Blit {
708
709
private int typeval;
710
711
D3DSwToTextureBlit(SurfaceType srcType, int typeval) {
712
super(srcType,
713
CompositeType.SrcNoEa,
714
D3DSurfaceData.D3DTexture);
715
this.typeval = typeval;
716
}
717
718
public void Blit(SurfaceData src, SurfaceData dst,
719
Composite comp, Region clip,
720
int sx, int sy, int dx, int dy, int w, int h)
721
{
722
D3DBlitLoops.Blit(src, dst,
723
comp, clip, null,
724
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
725
sx, sy, sx+w, sy+h,
726
dx, dy, dx+w, dy+h,
727
typeval, true);
728
}
729
}
730
731
class D3DTextureToSurfaceBlit extends Blit {
732
733
D3DTextureToSurfaceBlit() {
734
super(D3DSurfaceData.D3DTexture,
735
CompositeType.AnyAlpha,
736
D3DSurfaceData.D3DSurface);
737
}
738
739
public void Blit(SurfaceData src, SurfaceData dst,
740
Composite comp, Region clip,
741
int sx, int sy, int dx, int dy, int w, int h)
742
{
743
D3DBlitLoops.IsoBlit(src, dst,
744
null, null,
745
comp, clip, null,
746
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
747
sx, sy, sx+w, sy+h,
748
dx, dy, dx+w, dy+h,
749
true);
750
}
751
}
752
753
class D3DTextureToSurfaceScale extends ScaledBlit {
754
755
D3DTextureToSurfaceScale() {
756
super(D3DSurfaceData.D3DTexture,
757
CompositeType.AnyAlpha,
758
D3DSurfaceData.D3DSurface);
759
}
760
761
public void Scale(SurfaceData src, SurfaceData dst,
762
Composite comp, Region clip,
763
int sx1, int sy1,
764
int sx2, int sy2,
765
double dx1, double dy1,
766
double dx2, double dy2)
767
{
768
D3DBlitLoops.IsoBlit(src, dst,
769
null, null,
770
comp, clip, null,
771
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
772
sx1, sy1, sx2, sy2,
773
dx1, dy1, dx2, dy2,
774
true);
775
}
776
}
777
778
class D3DTextureToSurfaceTransform extends TransformBlit {
779
780
D3DTextureToSurfaceTransform() {
781
super(D3DSurfaceData.D3DTexture,
782
CompositeType.AnyAlpha,
783
D3DSurfaceData.D3DSurface);
784
}
785
786
public void Transform(SurfaceData src, SurfaceData dst,
787
Composite comp, Region clip,
788
AffineTransform at, int hint,
789
int sx, int sy, int dx, int dy,
790
int w, int h)
791
{
792
D3DBlitLoops.IsoBlit(src, dst,
793
null, null,
794
comp, clip, at, hint,
795
sx, sy, sx+w, sy+h,
796
dx, dy, dx+w, dy+h,
797
true);
798
}
799
}
800
801
/**
802
* This general Blit implementation converts any source surface to an
803
* intermediate IntArgbPre surface, and then uses the more specific
804
* IntArgbPre->D3DSurface/Texture loop to get the intermediate
805
* (premultiplied) surface down to D3D using simple blit.
806
*/
807
class D3DGeneralBlit extends Blit {
808
809
private final Blit performop;
810
private WeakReference<SurfaceData> srcTmp;
811
812
D3DGeneralBlit(SurfaceType dstType,
813
CompositeType compType,
814
Blit performop)
815
{
816
super(SurfaceType.Any, compType, dstType);
817
this.performop = performop;
818
}
819
820
public synchronized void Blit(SurfaceData src, SurfaceData dst,
821
Composite comp, Region clip,
822
int sx, int sy, int dx, int dy,
823
int w, int h)
824
{
825
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
826
CompositeType.SrcNoEa,
827
SurfaceType.IntArgbPre);
828
829
SurfaceData cachedSrc = null;
830
if (srcTmp != null) {
831
// use cached intermediate surface, if available
832
cachedSrc = srcTmp.get();
833
}
834
835
// convert source to IntArgbPre
836
src = convertFrom(convertsrc, src, sx, sy, w, h,
837
cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
838
839
// copy IntArgbPre intermediate surface to D3D surface
840
performop.Blit(src, dst, comp, clip,
841
0, 0, dx, dy, w, h);
842
843
if (src != cachedSrc) {
844
// cache the intermediate surface
845
srcTmp = new WeakReference<>(src);
846
}
847
}
848
}
849
850
/**
851
* This general TransformedBlit implementation converts any source surface to an
852
* intermediate IntArgbPre surface, and then uses the more specific
853
* IntArgbPre->D3DSurface/Texture loop to get the intermediate
854
* (premultiplied) surface down to D3D using simple transformBlit.
855
*/
856
final class D3DGeneralTransformedBlit extends TransformBlit {
857
858
private final TransformBlit performop;
859
private WeakReference<SurfaceData> srcTmp;
860
861
D3DGeneralTransformedBlit(final TransformBlit performop) {
862
super(SurfaceType.Any, CompositeType.AnyAlpha,
863
D3DSurfaceData.D3DSurface);
864
this.performop = performop;
865
}
866
867
@Override
868
public synchronized void Transform(SurfaceData src, SurfaceData dst,
869
Composite comp, Region clip,
870
AffineTransform at, int hint, int srcx,
871
int srcy, int dstx, int dsty, int width,
872
int height){
873
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
874
CompositeType.SrcNoEa,
875
SurfaceType.IntArgbPre);
876
// use cached intermediate surface, if available
877
final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
878
// convert source to IntArgbPre
879
src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
880
BufferedImage.TYPE_INT_ARGB_PRE);
881
882
// transform IntArgbPre intermediate surface to D3D surface
883
performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
884
width, height);
885
886
if (src != cachedSrc) {
887
// cache the intermediate surface
888
srcTmp = new WeakReference<>(src);
889
}
890
}
891
}
892
893
/*
894
* The following classes prohibit copying D3DSurfaces to the screen
895
* (the D3D->sysmem->GDI path is known to be very very slow).
896
*
897
* Note: we used to disable hw acceleration for the surafce manager associated
898
* with the source surface in these loops but it proved to be too cautious.
899
*
900
* In most cases d3d->screen copy happens only during some transitional
901
* period where the accelerated destination surface is being recreated or
902
* restored (for example, when Swing's backbuffer VI is copied to the screen
903
* but the D3DScreenSurfaceManager couldn't restore its surface).
904
*
905
* An exception is if for some reason we could not enable accelerated on-screen
906
* rendering for this window for some permanent reason (like window being too
907
* small, or a present BufferStrategy).
908
*
909
* This meant that we'd disable hw acceleration after the first failure
910
* completely (at least until the src image is recreated which in case of
911
* Swing back-buffer happens only after resize).
912
*
913
* Now we delegate to the VISM to figure out if the acceleration needs to
914
* be disabled or if we can wait for a while until the onscreen accelerated
915
* can resume (by marking the source surface lost and making sure the
916
* VISM has a chance to use the backup surface).
917
*
918
*/
919
920
class D3DSurfaceToGDIWindowSurfaceBlit extends Blit {
921
922
D3DSurfaceToGDIWindowSurfaceBlit() {
923
super(D3DSurfaceData.D3DSurface,
924
CompositeType.AnyAlpha,
925
GDIWindowSurfaceData.AnyGdi);
926
}
927
@Override
928
public void Blit(SurfaceData src, SurfaceData dst,
929
Composite comp, Region clip,
930
int sx, int sy, int dx, int dy, int w, int h)
931
{
932
// see comment above
933
D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
934
}
935
936
}
937
938
class D3DSurfaceToGDIWindowSurfaceScale extends ScaledBlit {
939
940
D3DSurfaceToGDIWindowSurfaceScale() {
941
super(D3DSurfaceData.D3DSurface,
942
CompositeType.AnyAlpha,
943
GDIWindowSurfaceData.AnyGdi);
944
}
945
@Override
946
public void Scale(SurfaceData src, SurfaceData dst,
947
Composite comp, Region clip,
948
int sx1, int sy1,
949
int sx2, int sy2,
950
double dx1, double dy1,
951
double dx2, double dy2)
952
{
953
// see comment above
954
D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
955
}
956
}
957
958
class D3DSurfaceToGDIWindowSurfaceTransform extends TransformBlit {
959
960
D3DSurfaceToGDIWindowSurfaceTransform() {
961
super(D3DSurfaceData.D3DSurface,
962
CompositeType.AnyAlpha,
963
GDIWindowSurfaceData.AnyGdi);
964
}
965
@Override
966
public void Transform(SurfaceData src, SurfaceData dst,
967
Composite comp, Region clip,
968
AffineTransform at, int hint,
969
int sx, int sy, int dx, int dy,
970
int w, int h)
971
{
972
// see comment above
973
D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
974
}
975
}
976
977