Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/classes/sun/java2d/metal/MTLBlitLoops.java
41159 views
1
/*
2
* Copyright (c) 2019, 2021, 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.metal;
27
28
import sun.java2d.SurfaceData;
29
import sun.java2d.loops.Blit;
30
import sun.java2d.loops.CompositeType;
31
import sun.java2d.loops.GraphicsPrimitive;
32
import sun.java2d.loops.GraphicsPrimitiveMgr;
33
import sun.java2d.loops.ScaledBlit;
34
import sun.java2d.loops.SurfaceType;
35
import sun.java2d.loops.TransformBlit;
36
import sun.java2d.pipe.Region;
37
import sun.java2d.pipe.RenderBuffer;
38
import sun.java2d.pipe.RenderQueue;
39
import sun.java2d.pipe.hw.AccelSurface;
40
41
import java.awt.AlphaComposite;
42
import java.awt.Composite;
43
import java.awt.Transparency;
44
import java.awt.geom.AffineTransform;
45
import java.awt.image.AffineTransformOp;
46
import java.awt.image.BufferedImage;
47
import java.awt.image.BufferedImageOp;
48
import java.lang.annotation.Native;
49
import java.lang.ref.WeakReference;
50
51
import static sun.java2d.pipe.BufferedOpCodes.BLIT;
52
import static sun.java2d.pipe.BufferedOpCodes.SURFACE_TO_SW_BLIT;
53
54
final class MTLBlitLoops {
55
56
static void register() {
57
Blit blitIntArgbPreToSurface =
58
new MTLSwToSurfaceBlit(SurfaceType.IntArgbPre,
59
MTLSurfaceData.PF_INT_ARGB_PRE);
60
Blit blitIntArgbPreToTexture =
61
new MTLSwToTextureBlit(SurfaceType.IntArgbPre,
62
MTLSurfaceData.PF_INT_ARGB_PRE);
63
TransformBlit transformBlitIntArgbPreToSurface =
64
new MTLSwToSurfaceTransform(SurfaceType.IntArgbPre,
65
MTLSurfaceData.PF_INT_ARGB_PRE);
66
MTLSurfaceToSwBlit blitSurfaceToIntArgbPre =
67
new MTLSurfaceToSwBlit(SurfaceType.IntArgbPre,
68
MTLSurfaceData.PF_INT_ARGB_PRE);
69
70
GraphicsPrimitive[] primitives = {
71
// surface->surface ops
72
new MTLSurfaceToSurfaceBlit(),
73
new MTLSurfaceToSurfaceScale(),
74
new MTLSurfaceToSurfaceTransform(),
75
76
// render-to-texture surface->surface ops
77
new MTLRTTSurfaceToSurfaceBlit(),
78
new MTLRTTSurfaceToSurfaceScale(),
79
new MTLRTTSurfaceToSurfaceTransform(),
80
81
// surface->sw ops
82
new MTLSurfaceToSwBlit(SurfaceType.IntArgb,
83
MTLSurfaceData.PF_INT_ARGB),
84
blitSurfaceToIntArgbPre,
85
86
// sw->surface ops
87
blitIntArgbPreToSurface,
88
new MTLSwToSurfaceBlit(SurfaceType.IntRgb,
89
MTLSurfaceData.PF_INT_RGB),
90
new MTLSwToSurfaceBlit(SurfaceType.IntRgbx,
91
MTLSurfaceData.PF_INT_RGBX),
92
new MTLSwToSurfaceBlit(SurfaceType.IntBgr,
93
MTLSurfaceData.PF_INT_BGR),
94
new MTLSwToSurfaceBlit(SurfaceType.IntBgrx,
95
MTLSurfaceData.PF_INT_BGRX),
96
new MTLGeneralBlit(MTLSurfaceData.MTLSurface,
97
CompositeType.AnyAlpha,
98
blitIntArgbPreToSurface),
99
100
new MTLAnyCompositeBlit(MTLSurfaceData.MTLSurface,
101
blitSurfaceToIntArgbPre,
102
blitSurfaceToIntArgbPre,
103
blitIntArgbPreToSurface),
104
new MTLAnyCompositeBlit(SurfaceType.Any,
105
null,
106
blitSurfaceToIntArgbPre,
107
blitIntArgbPreToSurface),
108
109
new MTLSwToSurfaceScale(SurfaceType.IntRgb,
110
MTLSurfaceData.PF_INT_RGB),
111
new MTLSwToSurfaceScale(SurfaceType.IntRgbx,
112
MTLSurfaceData.PF_INT_RGBX),
113
new MTLSwToSurfaceScale(SurfaceType.IntBgr,
114
MTLSurfaceData.PF_INT_BGR),
115
new MTLSwToSurfaceScale(SurfaceType.IntBgrx,
116
MTLSurfaceData.PF_INT_BGRX),
117
new MTLSwToSurfaceScale(SurfaceType.IntArgbPre,
118
MTLSurfaceData.PF_INT_ARGB_PRE),
119
120
new MTLSwToSurfaceTransform(SurfaceType.IntRgb,
121
MTLSurfaceData.PF_INT_RGB),
122
new MTLSwToSurfaceTransform(SurfaceType.IntRgbx,
123
MTLSurfaceData.PF_INT_RGBX),
124
new MTLSwToSurfaceTransform(SurfaceType.IntBgr,
125
MTLSurfaceData.PF_INT_BGR),
126
new MTLSwToSurfaceTransform(SurfaceType.IntBgrx,
127
MTLSurfaceData.PF_INT_BGRX),
128
transformBlitIntArgbPreToSurface,
129
130
new MTLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
131
132
// texture->surface ops
133
new MTLTextureToSurfaceBlit(),
134
new MTLTextureToSurfaceScale(),
135
new MTLTextureToSurfaceTransform(),
136
137
// sw->texture ops
138
blitIntArgbPreToTexture,
139
new MTLSwToTextureBlit(SurfaceType.IntRgb,
140
MTLSurfaceData.PF_INT_RGB),
141
new MTLSwToTextureBlit(SurfaceType.IntRgbx,
142
MTLSurfaceData.PF_INT_RGBX),
143
new MTLSwToTextureBlit(SurfaceType.IntBgr,
144
MTLSurfaceData.PF_INT_BGR),
145
new MTLSwToTextureBlit(SurfaceType.IntBgrx,
146
MTLSurfaceData.PF_INT_BGRX),
147
new MTLGeneralBlit(MTLSurfaceData.MTLTexture,
148
CompositeType.SrcNoEa,
149
blitIntArgbPreToTexture),
150
};
151
GraphicsPrimitiveMgr.register(primitives);
152
}
153
154
/**
155
* The following offsets are used to pack the parameters in
156
* createPackedParams(). (They are also used at the native level when
157
* unpacking the params.)
158
*/
159
@Native private static final int OFFSET_SRCTYPE = 16;
160
@Native private static final int OFFSET_HINT = 8;
161
@Native private static final int OFFSET_TEXTURE = 3;
162
@Native private static final int OFFSET_RTT = 2;
163
@Native private static final int OFFSET_XFORM = 1;
164
@Native private static final int OFFSET_ISOBLIT = 0;
165
166
/**
167
* Packs the given parameters into a single int value in order to save
168
* space on the rendering queue.
169
*/
170
private static int createPackedParams(boolean isoblit, boolean texture,
171
boolean rtt, boolean xform,
172
int hint, int srctype)
173
{
174
return
175
((srctype << OFFSET_SRCTYPE) |
176
(hint << OFFSET_HINT ) |
177
((texture ? 1 : 0) << OFFSET_TEXTURE) |
178
((rtt ? 1 : 0) << OFFSET_RTT ) |
179
((xform ? 1 : 0) << OFFSET_XFORM ) |
180
((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
181
}
182
183
/**
184
* Enqueues a BLIT operation with the given parameters. Note that the
185
* RenderQueue lock must be held before calling this method.
186
*/
187
private static void enqueueBlit(RenderQueue rq,
188
SurfaceData src, SurfaceData dst,
189
int packedParams,
190
int sx1, int sy1,
191
int sx2, int sy2,
192
double dx1, double dy1,
193
double dx2, double dy2)
194
{
195
// assert rq.lock.isHeldByCurrentThread();
196
RenderBuffer buf = rq.getBuffer();
197
rq.ensureCapacityAndAlignment(72, 24);
198
buf.putInt(BLIT);
199
buf.putInt(packedParams);
200
buf.putInt(sx1).putInt(sy1);
201
buf.putInt(sx2).putInt(sy2);
202
buf.putDouble(dx1).putDouble(dy1);
203
buf.putDouble(dx2).putDouble(dy2);
204
buf.putLong(src.getNativeOps());
205
buf.putLong(dst.getNativeOps());
206
}
207
208
static void Blit(SurfaceData srcData, SurfaceData dstData,
209
Composite comp, Region clip,
210
AffineTransform xform, int hint,
211
int sx1, int sy1,
212
int sx2, int sy2,
213
double dx1, double dy1,
214
double dx2, double dy2,
215
int srctype, boolean texture)
216
{
217
int ctxflags = 0;
218
if (srcData.getTransparency() == Transparency.OPAQUE) {
219
ctxflags |= MTLContext.SRC_IS_OPAQUE;
220
}
221
222
MTLRenderQueue rq = MTLRenderQueue.getInstance();
223
rq.lock();
224
try {
225
// make sure the RenderQueue keeps a hard reference to the
226
// source (sysmem) SurfaceData to prevent it from being
227
// disposed while the operation is processed on the QFT
228
rq.addReference(srcData);
229
230
MTLSurfaceData mtlDst = (MTLSurfaceData)dstData;
231
if (texture) {
232
// make sure we have a current context before uploading
233
// the sysmem data to the texture object
234
MTLGraphicsConfig gc = mtlDst.getMTLGraphicsConfig();
235
MTLContext.setScratchSurface(gc);
236
} else {
237
MTLContext.validateContext(mtlDst, mtlDst,
238
clip, comp, xform, null, null,
239
ctxflags);
240
}
241
242
int packedParams = createPackedParams(false, texture,
243
false /*unused*/, xform != null,
244
hint, srctype);
245
enqueueBlit(rq, srcData, dstData,
246
packedParams,
247
sx1, sy1, sx2, sy2,
248
dx1, dy1, dx2, dy2);
249
250
// always flush immediately, since we (currently) have no means
251
// of tracking changes to the system memory surface
252
rq.flushNow();
253
} finally {
254
rq.unlock();
255
}
256
}
257
258
/**
259
* Note: The srcImg and biop parameters are only used when invoked
260
* from the MTLBufImgOps.renderImageWithOp() method; in all other cases,
261
* this method can be called with null values for those two parameters,
262
* and they will be effectively ignored.
263
*/
264
static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
265
BufferedImage srcImg, BufferedImageOp biop,
266
Composite comp, Region clip,
267
AffineTransform xform, int hint,
268
int sx1, int sy1,
269
int sx2, int sy2,
270
double dx1, double dy1,
271
double dx2, double dy2,
272
boolean texture)
273
{
274
int ctxflags = 0;
275
if (srcData.getTransparency() == Transparency.OPAQUE) {
276
ctxflags |= MTLContext.SRC_IS_OPAQUE;
277
}
278
279
MTLRenderQueue rq = MTLRenderQueue.getInstance();
280
rq.lock();
281
try {
282
MTLSurfaceData mtlSrc = (MTLSurfaceData)srcData;
283
MTLSurfaceData mtlDst = (MTLSurfaceData)dstData;
284
int srctype = mtlSrc.getType();
285
boolean rtt;
286
MTLSurfaceData srcCtxData;
287
if (srctype == MTLSurfaceData.TEXTURE) {
288
// the source is a regular texture object; we substitute
289
// the destination surface for the purposes of making a
290
// context current
291
rtt = false;
292
srcCtxData = mtlDst;
293
} else {
294
// the source is a pbuffer, backbuffer, or render-to-texture
295
// surface; we set rtt to true to differentiate this kind
296
// of surface from a regular texture object
297
rtt = true;
298
if (srctype == AccelSurface.RT_TEXTURE) {
299
srcCtxData = mtlDst;
300
} else {
301
srcCtxData = mtlSrc;
302
}
303
}
304
305
MTLContext.validateContext(srcCtxData, mtlDst,
306
clip, comp, xform, null, null,
307
ctxflags);
308
309
if (biop != null) {
310
MTLBufImgOps.enableBufImgOp(rq, mtlSrc, srcImg, biop);
311
}
312
313
int packedParams = createPackedParams(true, texture,
314
false /*unused*/, xform != null,
315
hint, 0 /*unused*/);
316
enqueueBlit(rq, srcData, dstData,
317
packedParams,
318
sx1, sy1, sx2, sy2,
319
dx1, dy1, dx2, dy2);
320
321
if (biop != null) {
322
MTLBufImgOps.disableBufImgOp(rq, biop);
323
}
324
325
if (rtt && mtlDst.isOnScreen()) {
326
// we only have to flush immediately when copying from a
327
// (non-texture) surface to the screen; otherwise Swing apps
328
// might appear unresponsive until the auto-flush completes
329
rq.flushNow();
330
}
331
} finally {
332
rq.unlock();
333
}
334
}
335
}
336
337
class MTLSurfaceToSurfaceBlit extends Blit {
338
339
MTLSurfaceToSurfaceBlit() {
340
super(MTLSurfaceData.MTLSurface,
341
CompositeType.AnyAlpha,
342
MTLSurfaceData.MTLSurface);
343
}
344
345
public void Blit(SurfaceData src, SurfaceData dst,
346
Composite comp, Region clip,
347
int sx, int sy, int dx, int dy, int w, int h)
348
{
349
MTLBlitLoops.IsoBlit(src, dst,
350
null, null,
351
comp, clip, null,
352
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
353
sx, sy, sx+w, sy+h,
354
dx, dy, dx+w, dy+h,
355
false);
356
}
357
}
358
359
class MTLSurfaceToSurfaceScale extends ScaledBlit {
360
361
MTLSurfaceToSurfaceScale() {
362
super(MTLSurfaceData.MTLSurface,
363
CompositeType.AnyAlpha,
364
MTLSurfaceData.MTLSurface);
365
}
366
367
public void Scale(SurfaceData src, SurfaceData dst,
368
Composite comp, Region clip,
369
int sx1, int sy1,
370
int sx2, int sy2,
371
double dx1, double dy1,
372
double dx2, double dy2)
373
{
374
MTLBlitLoops.IsoBlit(src, dst,
375
null, null,
376
comp, clip, null,
377
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
378
sx1, sy1, sx2, sy2,
379
dx1, dy1, dx2, dy2,
380
false);
381
}
382
}
383
384
class MTLSurfaceToSurfaceTransform extends TransformBlit {
385
386
MTLSurfaceToSurfaceTransform() {
387
super(MTLSurfaceData.MTLSurface,
388
CompositeType.AnyAlpha,
389
MTLSurfaceData.MTLSurface);
390
}
391
392
public void Transform(SurfaceData src, SurfaceData dst,
393
Composite comp, Region clip,
394
AffineTransform at, int hint,
395
int sx, int sy, int dx, int dy,
396
int w, int h)
397
{
398
MTLBlitLoops.IsoBlit(src, dst,
399
null, null,
400
comp, clip, at, hint,
401
sx, sy, sx+w, sy+h,
402
dx, dy, dx+w, dy+h,
403
false);
404
}
405
}
406
407
class MTLRTTSurfaceToSurfaceBlit extends Blit {
408
409
MTLRTTSurfaceToSurfaceBlit() {
410
super(MTLSurfaceData.MTLSurfaceRTT,
411
CompositeType.AnyAlpha,
412
MTLSurfaceData.MTLSurface);
413
}
414
415
public void Blit(SurfaceData src, SurfaceData dst,
416
Composite comp, Region clip,
417
int sx, int sy, int dx, int dy, int w, int h)
418
{
419
MTLBlitLoops.IsoBlit(src, dst,
420
null, null,
421
comp, clip, null,
422
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
423
sx, sy, sx+w, sy+h,
424
dx, dy, dx+w, dy+h,
425
true);
426
}
427
}
428
429
class MTLRTTSurfaceToSurfaceScale extends ScaledBlit {
430
431
MTLRTTSurfaceToSurfaceScale() {
432
super(MTLSurfaceData.MTLSurfaceRTT,
433
CompositeType.AnyAlpha,
434
MTLSurfaceData.MTLSurface);
435
}
436
437
public void Scale(SurfaceData src, SurfaceData dst,
438
Composite comp, Region clip,
439
int sx1, int sy1,
440
int sx2, int sy2,
441
double dx1, double dy1,
442
double dx2, double dy2)
443
{
444
MTLBlitLoops.IsoBlit(src, dst,
445
null, null,
446
comp, clip, null,
447
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
448
sx1, sy1, sx2, sy2,
449
dx1, dy1, dx2, dy2,
450
true);
451
}
452
}
453
454
class MTLRTTSurfaceToSurfaceTransform extends TransformBlit {
455
456
MTLRTTSurfaceToSurfaceTransform() {
457
super(MTLSurfaceData.MTLSurfaceRTT,
458
CompositeType.AnyAlpha,
459
MTLSurfaceData.MTLSurface);
460
}
461
462
public void Transform(SurfaceData src, SurfaceData dst,
463
Composite comp, Region clip,
464
AffineTransform at, int hint,
465
int sx, int sy, int dx, int dy, int w, int h)
466
{
467
MTLBlitLoops.IsoBlit(src, dst,
468
null, null,
469
comp, clip, at, hint,
470
sx, sy, sx+w, sy+h,
471
dx, dy, dx+w, dy+h,
472
true);
473
}
474
}
475
476
final class MTLSurfaceToSwBlit extends Blit {
477
478
private final int typeval;
479
private WeakReference<SurfaceData> srcTmp;
480
481
// destination will actually be ArgbPre or Argb
482
MTLSurfaceToSwBlit(final SurfaceType dstType, final int typeval) {
483
super(MTLSurfaceData.MTLSurface,
484
CompositeType.SrcNoEa,
485
dstType);
486
this.typeval = typeval;
487
}
488
489
private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,
490
Composite comp, Region clip,
491
int sx, int sy, int dx, int dy,
492
int w, int h) {
493
SurfaceData cachedSrc = null;
494
if (srcTmp != null) {
495
// use cached intermediate surface, if available
496
cachedSrc = srcTmp.get();
497
}
498
499
// We can convert argb_pre data from MTL surface in two places:
500
// - During MTL surface -> SW blit
501
// - During SW -> SW blit
502
// The first one is faster when we use opaque MTL surface, because in
503
// this case we simply skip conversion and use color components as is.
504
// Because of this we align intermediate buffer type with type of
505
// destination not source.
506
final int type = typeval == MTLSurfaceData.PF_INT_ARGB_PRE ?
507
BufferedImage.TYPE_INT_ARGB_PRE :
508
BufferedImage.TYPE_INT_ARGB;
509
510
src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);
511
512
// copy intermediate SW to destination SW using complex clip
513
final Blit performop = Blit.getFromCache(src.getSurfaceType(),
514
CompositeType.SrcNoEa,
515
dst.getSurfaceType());
516
performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
517
518
if (src != cachedSrc) {
519
// cache the intermediate surface
520
srcTmp = new WeakReference<>(src);
521
}
522
}
523
524
public void Blit(SurfaceData src, SurfaceData dst,
525
Composite comp, Region clip,
526
int sx, int sy, int dx, int dy,
527
int w, int h)
528
{
529
if (clip != null) {
530
clip = clip.getIntersectionXYWH(dx, dy, w, h);
531
// At the end this method will flush the RenderQueue, we should exit
532
// from it as soon as possible.
533
if (clip.isEmpty()) {
534
return;
535
}
536
sx += clip.getLoX() - dx;
537
sy += clip.getLoY() - dy;
538
dx = clip.getLoX();
539
dy = clip.getLoY();
540
w = clip.getWidth();
541
h = clip.getHeight();
542
543
if (!clip.isRectangular()) {
544
complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
545
return;
546
}
547
}
548
549
MTLRenderQueue rq = MTLRenderQueue.getInstance();
550
rq.lock();
551
try {
552
// make sure the RenderQueue keeps a hard reference to the
553
// destination (sysmem) SurfaceData to prevent it from being
554
// disposed while the operation is processed on the QFT
555
rq.addReference(dst);
556
557
RenderBuffer buf = rq.getBuffer();
558
MTLContext.validateContext((MTLSurfaceData)src);
559
560
rq.ensureCapacityAndAlignment(48, 32);
561
buf.putInt(SURFACE_TO_SW_BLIT);
562
buf.putInt(sx).putInt(sy);
563
buf.putInt(dx).putInt(dy);
564
buf.putInt(w).putInt(h);
565
buf.putInt(typeval);
566
buf.putLong(src.getNativeOps());
567
buf.putLong(dst.getNativeOps());
568
569
// always flush immediately
570
rq.flushNow();
571
} finally {
572
rq.unlock();
573
}
574
}
575
}
576
577
class MTLSwToSurfaceBlit extends Blit {
578
579
private int typeval;
580
581
MTLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
582
super(srcType,
583
CompositeType.AnyAlpha,
584
MTLSurfaceData.MTLSurface);
585
this.typeval = typeval;
586
}
587
588
public void Blit(SurfaceData src, SurfaceData dst,
589
Composite comp, Region clip,
590
int sx, int sy, int dx, int dy, int w, int h)
591
{
592
MTLBlitLoops.Blit(src, dst,
593
comp, clip, null,
594
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
595
sx, sy, sx+w, sy+h,
596
dx, dy, dx+w, dy+h,
597
typeval, false);
598
}
599
}
600
601
class MTLSwToSurfaceScale extends ScaledBlit {
602
603
private int typeval;
604
605
MTLSwToSurfaceScale(SurfaceType srcType, int typeval) {
606
super(srcType,
607
CompositeType.AnyAlpha,
608
MTLSurfaceData.MTLSurface);
609
this.typeval = typeval;
610
}
611
612
public void Scale(SurfaceData src, SurfaceData dst,
613
Composite comp, Region clip,
614
int sx1, int sy1,
615
int sx2, int sy2,
616
double dx1, double dy1,
617
double dx2, double dy2)
618
{
619
MTLBlitLoops.Blit(src, dst,
620
comp, clip, null,
621
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
622
sx1, sy1, sx2, sy2,
623
dx1, dy1, dx2, dy2,
624
typeval, false);
625
}
626
}
627
628
class MTLSwToSurfaceTransform extends TransformBlit {
629
630
private int typeval;
631
632
MTLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
633
super(srcType,
634
CompositeType.AnyAlpha,
635
MTLSurfaceData.MTLSurface);
636
this.typeval = typeval;
637
}
638
639
public void Transform(SurfaceData src, SurfaceData dst,
640
Composite comp, Region clip,
641
AffineTransform at, int hint,
642
int sx, int sy, int dx, int dy, int w, int h)
643
{
644
MTLBlitLoops.Blit(src, dst,
645
comp, clip, at, hint,
646
sx, sy, sx+w, sy+h,
647
dx, dy, dx+w, dy+h,
648
typeval, false);
649
}
650
}
651
652
class MTLSwToTextureBlit extends Blit {
653
654
private int typeval;
655
656
MTLSwToTextureBlit(SurfaceType srcType, int typeval) {
657
super(srcType,
658
CompositeType.SrcNoEa,
659
MTLSurfaceData.MTLTexture);
660
this.typeval = typeval;
661
}
662
663
public void Blit(SurfaceData src, SurfaceData dst,
664
Composite comp, Region clip,
665
int sx, int sy, int dx, int dy, int w, int h)
666
{
667
MTLBlitLoops.Blit(src, dst,
668
comp, clip, null,
669
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
670
sx, sy, sx+w, sy+h,
671
dx, dy, dx+w, dy+h,
672
typeval, true);
673
}
674
}
675
676
class MTLTextureToSurfaceBlit extends Blit {
677
678
MTLTextureToSurfaceBlit() {
679
super(MTLSurfaceData.MTLTexture,
680
CompositeType.AnyAlpha,
681
MTLSurfaceData.MTLSurface);
682
}
683
684
public void Blit(SurfaceData src, SurfaceData dst,
685
Composite comp, Region clip,
686
int sx, int sy, int dx, int dy, int w, int h)
687
{
688
MTLBlitLoops.IsoBlit(src, dst,
689
null, null,
690
comp, clip, null,
691
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
692
sx, sy, sx+w, sy+h,
693
dx, dy, dx+w, dy+h,
694
true);
695
}
696
}
697
698
class MTLTextureToSurfaceScale extends ScaledBlit {
699
700
MTLTextureToSurfaceScale() {
701
super(MTLSurfaceData.MTLTexture,
702
CompositeType.AnyAlpha,
703
MTLSurfaceData.MTLSurface);
704
}
705
706
public void Scale(SurfaceData src, SurfaceData dst,
707
Composite comp, Region clip,
708
int sx1, int sy1,
709
int sx2, int sy2,
710
double dx1, double dy1,
711
double dx2, double dy2)
712
{
713
MTLBlitLoops.IsoBlit(src, dst,
714
null, null,
715
comp, clip, null,
716
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
717
sx1, sy1, sx2, sy2,
718
dx1, dy1, dx2, dy2,
719
true);
720
}
721
}
722
723
class MTLTextureToSurfaceTransform extends TransformBlit {
724
725
MTLTextureToSurfaceTransform() {
726
super(MTLSurfaceData.MTLTexture,
727
CompositeType.AnyAlpha,
728
MTLSurfaceData.MTLSurface);
729
}
730
731
public void Transform(SurfaceData src, SurfaceData dst,
732
Composite comp, Region clip,
733
AffineTransform at, int hint,
734
int sx, int sy, int dx, int dy,
735
int w, int h)
736
{
737
MTLBlitLoops.IsoBlit(src, dst,
738
null, null,
739
comp, clip, at, hint,
740
sx, sy, sx+w, sy+h,
741
dx, dy, dx+w, dy+h,
742
true);
743
}
744
}
745
746
/**
747
* This general Blit implementation converts any source surface to an
748
* intermediate IntArgbPre surface, and then uses the more specific
749
* IntArgbPre->MTLSurface/Texture loop to get the intermediate
750
* (premultiplied) surface down to Metal using simple blit.
751
*/
752
class MTLGeneralBlit extends Blit {
753
754
private final Blit performop;
755
private WeakReference<SurfaceData> srcTmp;
756
757
MTLGeneralBlit(SurfaceType dstType,
758
CompositeType compType,
759
Blit performop)
760
{
761
super(SurfaceType.Any, compType, dstType);
762
this.performop = performop;
763
}
764
765
public synchronized void Blit(SurfaceData src, SurfaceData dst,
766
Composite comp, Region clip,
767
int sx, int sy, int dx, int dy,
768
int w, int h)
769
{
770
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
771
CompositeType.SrcNoEa,
772
SurfaceType.IntArgbPre);
773
774
SurfaceData cachedSrc = null;
775
if (srcTmp != null) {
776
// use cached intermediate surface, if available
777
cachedSrc = srcTmp.get();
778
}
779
780
// convert source to IntArgbPre
781
src = convertFrom(convertsrc, src, sx, sy, w, h,
782
cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
783
784
// copy IntArgbPre intermediate surface to Metal surface
785
performop.Blit(src, dst, comp, clip,
786
0, 0, dx, dy, w, h);
787
788
if (src != cachedSrc) {
789
// cache the intermediate surface
790
srcTmp = new WeakReference<>(src);
791
}
792
}
793
}
794
795
/**
796
* This general TransformedBlit implementation converts any source surface to an
797
* intermediate IntArgbPre surface, and then uses the more specific
798
* IntArgbPre->MTLSurface/Texture loop to get the intermediate
799
* (premultiplied) surface down to Metal using simple transformBlit.
800
*/
801
final class MTLGeneralTransformedBlit extends TransformBlit {
802
803
private final TransformBlit performop;
804
private WeakReference<SurfaceData> srcTmp;
805
806
MTLGeneralTransformedBlit(final TransformBlit performop) {
807
super(SurfaceType.Any, CompositeType.AnyAlpha,
808
MTLSurfaceData.MTLSurface);
809
this.performop = performop;
810
}
811
812
@Override
813
public synchronized void Transform(SurfaceData src, SurfaceData dst,
814
Composite comp, Region clip,
815
AffineTransform at, int hint, int srcx,
816
int srcy, int dstx, int dsty, int width,
817
int height){
818
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
819
CompositeType.SrcNoEa,
820
SurfaceType.IntArgbPre);
821
// use cached intermediate surface, if available
822
final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
823
// convert source to IntArgbPre
824
src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
825
BufferedImage.TYPE_INT_ARGB_PRE);
826
827
// transform IntArgbPre intermediate surface to Metal surface
828
performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
829
width, height);
830
831
if (src != cachedSrc) {
832
// cache the intermediate surface
833
srcTmp = new WeakReference<>(src);
834
}
835
}
836
}
837
838
/**
839
* This general MTLAnyCompositeBlit implementation can convert any source/target
840
* surface to an intermediate surface using convertsrc/convertdst loops, applies
841
* necessary composite operation, and then uses convertresult loop to get the
842
* intermediate surface down to Metal.
843
*/
844
final class MTLAnyCompositeBlit extends Blit {
845
846
private WeakReference<SurfaceData> dstTmp;
847
private WeakReference<SurfaceData> srcTmp;
848
private final Blit convertsrc;
849
private final Blit convertdst;
850
private final Blit convertresult;
851
852
MTLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,
853
Blit convertresult) {
854
super(srctype, CompositeType.Any, MTLSurfaceData.MTLSurface);
855
this.convertsrc = convertsrc;
856
this.convertdst = convertdst;
857
this.convertresult = convertresult;
858
}
859
860
public synchronized void Blit(SurfaceData src, SurfaceData dst,
861
Composite comp, Region clip,
862
int sx, int sy, int dx, int dy,
863
int w, int h)
864
{
865
if (convertsrc != null) {
866
SurfaceData cachedSrc = null;
867
if (srcTmp != null) {
868
// use cached intermediate surface, if available
869
cachedSrc = srcTmp.get();
870
}
871
// convert source to IntArgbPre
872
src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc,
873
BufferedImage.TYPE_INT_ARGB_PRE);
874
if (src != cachedSrc) {
875
// cache the intermediate surface
876
srcTmp = new WeakReference<>(src);
877
}
878
}
879
880
SurfaceData cachedDst = null;
881
882
if (dstTmp != null) {
883
// use cached intermediate surface, if available
884
cachedDst = dstTmp.get();
885
}
886
887
// convert destination to IntArgbPre
888
SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
889
cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
890
Region bufferClip =
891
clip == null ? null : clip.getTranslatedRegion(-dx, -dy);
892
893
Blit performop = Blit.getFromCache(src.getSurfaceType(),
894
CompositeType.Any, dstBuffer.getSurfaceType());
895
performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);
896
897
if (dstBuffer != cachedDst) {
898
// cache the intermediate surface
899
dstTmp = new WeakReference<>(dstBuffer);
900
}
901
// now blit the buffer back to the destination
902
convertresult.Blit(dstBuffer, dst, AlphaComposite.Src, clip, 0, 0, dx,
903
dy, w, h);
904
}
905
}
906
907