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