Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java
41159 views
1
/*
2
* Copyright (c) 1997, 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
/*
27
* @author Charlton Innovations, Inc.
28
*/
29
30
package sun.java2d.loops;
31
32
import java.awt.AlphaComposite;
33
import java.awt.Rectangle;
34
import java.awt.image.BufferedImage;
35
import java.io.FileNotFoundException;
36
import java.io.FileOutputStream;
37
import java.io.PrintStream;
38
import java.lang.reflect.Field;
39
import java.security.AccessController;
40
import java.security.PrivilegedAction;
41
import java.util.HashMap;
42
import java.util.Iterator;
43
import java.util.Map;
44
import java.util.StringTokenizer;
45
46
import sun.awt.image.BufImgSurfaceData;
47
import sun.awt.util.ThreadGroupUtils;
48
import sun.java2d.SurfaceData;
49
import sun.java2d.pipe.Region;
50
import sun.security.action.GetPropertyAction;
51
52
/**
53
* defines interface for primitives which can be placed into
54
* the graphic component manager framework
55
*/
56
public abstract class GraphicsPrimitive {
57
58
protected static interface GeneralBinaryOp {
59
/**
60
* This method allows the setupGeneralBinaryOp method to set
61
* the converters into the General version of the Primitive.
62
*/
63
public void setPrimitives(Blit srcconverter,
64
Blit dstconverter,
65
GraphicsPrimitive genericop,
66
Blit resconverter);
67
68
/**
69
* These 4 methods are implemented automatically for any
70
* GraphicsPrimitive. They are used by setupGeneralBinaryOp
71
* to retrieve the information needed to find the right
72
* converter primitives.
73
*/
74
public SurfaceType getSourceType();
75
public CompositeType getCompositeType();
76
public SurfaceType getDestType();
77
public String getSignature();
78
public int getPrimTypeID();
79
}
80
81
protected static interface GeneralUnaryOp {
82
/**
83
* This method allows the setupGeneralUnaryOp method to set
84
* the converters into the General version of the Primitive.
85
*/
86
public void setPrimitives(Blit dstconverter,
87
GraphicsPrimitive genericop,
88
Blit resconverter);
89
90
/**
91
* These 3 methods are implemented automatically for any
92
* GraphicsPrimitive. They are used by setupGeneralUnaryOp
93
* to retrieve the information needed to find the right
94
* converter primitives.
95
*/
96
public CompositeType getCompositeType();
97
public SurfaceType getDestType();
98
public String getSignature();
99
public int getPrimTypeID();
100
}
101
102
/**
103
* INSTANCE DATA MEMBERS DESCRIBING CHARACTERISTICS OF THIS PRIMITIVE
104
**/
105
106
// Making these be instance data members (instead of virtual methods
107
// overridden by subclasses) is actually cheaper, since each class
108
// is a singleton. As instance data members with final accessors,
109
// accesses can be inlined.
110
private String methodSignature;
111
private int uniqueID;
112
private static int unusedPrimID = 1;
113
114
private SurfaceType sourceType;
115
private CompositeType compositeType;
116
private SurfaceType destType;
117
118
private long pNativePrim; // Native blit loop info
119
120
public static final synchronized int makePrimTypeID() {
121
if (unusedPrimID > 255) {
122
throw new InternalError("primitive id overflow");
123
}
124
return unusedPrimID++;
125
}
126
127
public static final synchronized int makeUniqueID(int primTypeID,
128
SurfaceType src,
129
CompositeType cmp,
130
SurfaceType dst)
131
{
132
return (primTypeID << 24) |
133
(dst.getUniqueID() << 16) |
134
(cmp.getUniqueID() << 8) |
135
(src.getUniqueID());
136
}
137
138
/**
139
* Create a new GraphicsPrimitive with all of the required
140
* descriptive information.
141
*/
142
protected GraphicsPrimitive(String methodSignature,
143
int primTypeID,
144
SurfaceType sourceType,
145
CompositeType compositeType,
146
SurfaceType destType)
147
{
148
this.methodSignature = methodSignature;
149
this.sourceType = sourceType;
150
this.compositeType = compositeType;
151
this.destType = destType;
152
153
if(sourceType == null || compositeType == null || destType == null) {
154
this.uniqueID = primTypeID << 24;
155
} else {
156
this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
157
sourceType,
158
compositeType,
159
destType);
160
}
161
}
162
163
/**
164
* Create a new GraphicsPrimitive for native invocation
165
* with all of the required descriptive information.
166
*/
167
protected GraphicsPrimitive(long pNativePrim,
168
String methodSignature,
169
int primTypeID,
170
SurfaceType sourceType,
171
CompositeType compositeType,
172
SurfaceType destType)
173
{
174
this.pNativePrim = pNativePrim;
175
this.methodSignature = methodSignature;
176
this.sourceType = sourceType;
177
this.compositeType = compositeType;
178
this.destType = destType;
179
180
if(sourceType == null || compositeType == null || destType == null) {
181
this.uniqueID = primTypeID << 24;
182
} else {
183
this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
184
sourceType,
185
compositeType,
186
destType);
187
}
188
}
189
190
/**
191
* METHODS TO DESCRIBE THE SURFACES PRIMITIVES
192
* CAN OPERATE ON AND THE FUNCTIONALITY THEY IMPLEMENT
193
**/
194
195
/**
196
* Gets instance ID of this graphics primitive.
197
*
198
* Instance ID is comprised of four distinct ids (ORed together)
199
* that uniquely identify each instance of a GraphicsPrimitive
200
* object. The four ids making up instance ID are:
201
* 1. primitive id - identifier shared by all primitives of the
202
* same type (eg. all Blits have the same primitive id)
203
* 2. sourcetype id - identifies source surface type
204
* 3. desttype id - identifies destination surface type
205
* 4. compositetype id - identifies composite used
206
*
207
* @return instance ID
208
*/
209
public final int getUniqueID() {
210
return uniqueID;
211
}
212
213
/**
214
*/
215
public final String getSignature() {
216
return methodSignature;
217
}
218
219
/**
220
* Gets unique id for this GraphicsPrimitive type.
221
*
222
* This id is used to identify the TYPE of primitive (Blit vs. BlitBg)
223
* as opposed to INSTANCE of primitive.
224
*
225
* @return primitive ID
226
*/
227
public final int getPrimTypeID() {
228
return uniqueID >>> 24;
229
}
230
231
/**
232
*/
233
public final long getNativePrim() {
234
return pNativePrim;
235
}
236
237
/**
238
*/
239
public final SurfaceType getSourceType() {
240
return sourceType;
241
}
242
243
/**
244
*/
245
public final CompositeType getCompositeType() {
246
return compositeType;
247
}
248
249
/**
250
*/
251
public final SurfaceType getDestType() {
252
return destType;
253
}
254
255
/**
256
* Return true if this primitive can be used for the given signature
257
* surfaces, and composite.
258
*
259
* @param signature The signature of the given operation. Must be
260
* == (not just .equals) the signature string given by the
261
* abstract class that declares the operation.
262
* @param srctype The surface type for the source of the operation
263
* @param comptype The composite type for the operation
264
* @param dsttype The surface type for the destination of the operation
265
*/
266
public final boolean satisfies(String signature,
267
SurfaceType srctype,
268
CompositeType comptype,
269
SurfaceType dsttype)
270
{
271
if (signature != methodSignature) {
272
return false;
273
}
274
while (true) {
275
if (srctype == null) {
276
return false;
277
}
278
if (srctype.equals(sourceType)) {
279
break;
280
}
281
srctype = srctype.getSuperType();
282
}
283
while (true) {
284
if (comptype == null) {
285
return false;
286
}
287
if (comptype.equals(compositeType)) {
288
break;
289
}
290
comptype = comptype.getSuperType();
291
}
292
while (true) {
293
if (dsttype == null) {
294
return false;
295
}
296
if (dsttype.equals(destType)) {
297
break;
298
}
299
dsttype = dsttype.getSuperType();
300
}
301
return true;
302
}
303
304
//
305
// A version of satisfies used for regression testing
306
//
307
final boolean satisfiesSameAs(GraphicsPrimitive other) {
308
return (methodSignature == other.methodSignature &&
309
sourceType.equals(other.sourceType) &&
310
compositeType.equals(other.compositeType) &&
311
destType.equals(other.destType));
312
}
313
314
/**
315
* Produces specific primitive loop if the current object is registered as a
316
* general loop, otherwise the {@code InternalError} is thrown.
317
*
318
* @see GraphicsPrimitiveMgr#registerGeneral
319
*/
320
protected GraphicsPrimitive makePrimitive(SurfaceType srctype,
321
CompositeType comptype,
322
SurfaceType dsttype) {
323
throw new InternalError("%s not implemented for %s, comp: %s, dst: %s".
324
formatted(getClass().getName(), srctype, comptype, dsttype));
325
}
326
327
public abstract GraphicsPrimitive traceWrap();
328
329
static HashMap<Object, int[]> traceMap;
330
331
public static int traceflags;
332
public static String tracefile;
333
public static PrintStream traceout;
334
335
public static final int TRACELOG = 1;
336
public static final int TRACETIMESTAMP = 2;
337
public static final int TRACECOUNTS = 4;
338
339
static {
340
GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace");
341
@SuppressWarnings("removal")
342
String trace = AccessController.doPrivileged(gpa);
343
if (trace != null) {
344
boolean verbose = false;
345
int traceflags = 0;
346
StringTokenizer st = new StringTokenizer(trace, ",");
347
while (st.hasMoreTokens()) {
348
String tok = st.nextToken();
349
if (tok.equalsIgnoreCase("count")) {
350
traceflags |= GraphicsPrimitive.TRACECOUNTS;
351
} else if (tok.equalsIgnoreCase("log")) {
352
traceflags |= GraphicsPrimitive.TRACELOG;
353
} else if (tok.equalsIgnoreCase("timestamp")) {
354
traceflags |= GraphicsPrimitive.TRACETIMESTAMP;
355
} else if (tok.equalsIgnoreCase("verbose")) {
356
verbose = true;
357
} else if (tok.regionMatches(true, 0, "out:", 0, 4)) {
358
tracefile = tok.substring(4);
359
} else {
360
if (!tok.equalsIgnoreCase("help")) {
361
System.err.println("unrecognized token: "+tok);
362
}
363
System.err.println("usage: -Dsun.java2d.trace="+
364
"[log[,timestamp]],[count],"+
365
"[out:<filename>],[help],[verbose]");
366
}
367
}
368
if (verbose) {
369
System.err.print("GraphicsPrimitive logging ");
370
if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {
371
System.err.println("enabled");
372
System.err.print("GraphicsPrimitive timetamps ");
373
if ((traceflags & GraphicsPrimitive.TRACETIMESTAMP) != 0) {
374
System.err.println("enabled");
375
} else {
376
System.err.println("disabled");
377
}
378
} else {
379
System.err.println("[and timestamps] disabled");
380
}
381
System.err.print("GraphicsPrimitive invocation counts ");
382
if ((traceflags & GraphicsPrimitive.TRACECOUNTS) != 0) {
383
System.err.println("enabled");
384
} else {
385
System.err.println("disabled");
386
}
387
System.err.print("GraphicsPrimitive trace output to ");
388
if (tracefile == null) {
389
System.err.println("System.err");
390
} else {
391
System.err.println("file '"+tracefile+"'");
392
}
393
}
394
GraphicsPrimitive.traceflags = traceflags;
395
}
396
}
397
398
public static boolean tracingEnabled() {
399
return (traceflags != 0);
400
}
401
402
private static PrintStream getTraceOutputFile() {
403
if (traceout == null) {
404
if (tracefile != null) {
405
@SuppressWarnings("removal")
406
FileOutputStream o = AccessController.doPrivileged(
407
new PrivilegedAction<FileOutputStream>() {
408
public FileOutputStream run() {
409
try {
410
return new FileOutputStream(tracefile);
411
} catch (FileNotFoundException e) {
412
return null;
413
}
414
}
415
});
416
if (o != null) {
417
traceout = new PrintStream(o);
418
} else {
419
traceout = System.err;
420
}
421
} else {
422
traceout = System.err;
423
}
424
}
425
return traceout;
426
}
427
428
public static class TraceReporter implements Runnable {
429
@SuppressWarnings("removal")
430
public static void setShutdownHook() {
431
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
432
TraceReporter t = new TraceReporter();
433
Thread thread = new Thread(
434
ThreadGroupUtils.getRootThreadGroup(), t,
435
"TraceReporter", 0, false);
436
thread.setContextClassLoader(null);
437
Runtime.getRuntime().addShutdownHook(thread);
438
return null;
439
});
440
}
441
442
public void run() {
443
PrintStream ps = getTraceOutputFile();
444
Iterator<Map.Entry<Object, int[]>> iterator =
445
traceMap.entrySet().iterator();
446
long total = 0;
447
int numprims = 0;
448
while (iterator.hasNext()) {
449
Map.Entry<Object, int[]> me = iterator.next();
450
Object prim = me.getKey();
451
int[] count = me.getValue();
452
if (count[0] == 1) {
453
ps.print("1 call to ");
454
} else {
455
ps.print(count[0]+" calls to ");
456
}
457
ps.println(prim);
458
numprims++;
459
total += count[0];
460
}
461
if (numprims == 0) {
462
ps.println("No graphics primitives executed");
463
} else if (numprims > 1) {
464
ps.println(total+" total calls to "+
465
numprims+" different primitives");
466
}
467
}
468
}
469
470
public static synchronized void tracePrimitive(Object prim) {
471
if ((traceflags & TRACECOUNTS) != 0) {
472
if (traceMap == null) {
473
traceMap = new HashMap<>();
474
TraceReporter.setShutdownHook();
475
}
476
int[] o = traceMap.get(prim);
477
if (o == null) {
478
o = new int[1];
479
traceMap.put(prim, o);
480
}
481
o[0]++;
482
}
483
if ((traceflags & TRACELOG) != 0) {
484
PrintStream ps = getTraceOutputFile();
485
if ((traceflags & TRACETIMESTAMP) != 0) {
486
ps.print(System.currentTimeMillis()+": ");
487
}
488
ps.println(prim);
489
}
490
}
491
492
protected void setupGeneralBinaryOp(GeneralBinaryOp gbo) {
493
int primID = gbo.getPrimTypeID();
494
String methodSignature = gbo.getSignature();
495
SurfaceType srctype = gbo.getSourceType();
496
CompositeType comptype = gbo.getCompositeType();
497
SurfaceType dsttype = gbo.getDestType();
498
Blit convertsrc, convertdst, convertres;
499
GraphicsPrimitive performop;
500
501
convertsrc = createConverter(srctype, SurfaceType.IntArgb);
502
performop = GraphicsPrimitiveMgr.locatePrim(primID,
503
SurfaceType.IntArgb,
504
comptype, dsttype);
505
if (performop != null) {
506
convertdst = null;
507
convertres = null;
508
} else {
509
performop = getGeneralOp(primID, comptype);
510
if (performop == null) {
511
throw new InternalError("Cannot construct general op for "+
512
methodSignature+" "+comptype);
513
}
514
convertdst = createConverter(dsttype, SurfaceType.IntArgb);
515
convertres = createConverter(SurfaceType.IntArgb, dsttype);
516
}
517
518
gbo.setPrimitives(convertsrc, convertdst, performop, convertres);
519
}
520
521
protected void setupGeneralUnaryOp(GeneralUnaryOp guo) {
522
int primID = guo.getPrimTypeID();
523
String methodSignature = guo.getSignature();
524
CompositeType comptype = guo.getCompositeType();
525
SurfaceType dsttype = guo.getDestType();
526
527
Blit convertdst = createConverter(dsttype, SurfaceType.IntArgb);
528
GraphicsPrimitive performop = getGeneralOp(primID, comptype);
529
Blit convertres = createConverter(SurfaceType.IntArgb, dsttype);
530
if (convertdst == null || performop == null || convertres == null) {
531
throw new InternalError("Cannot construct binary op for "+
532
comptype+" "+dsttype);
533
}
534
535
guo.setPrimitives(convertdst, performop, convertres);
536
}
537
538
protected static Blit createConverter(SurfaceType srctype,
539
SurfaceType dsttype)
540
{
541
if (srctype.equals(dsttype)) {
542
return null;
543
}
544
Blit cv = Blit.getFromCache(srctype, CompositeType.SrcNoEa, dsttype);
545
if (cv == null) {
546
throw new InternalError("Cannot construct converter for "+
547
srctype+"=>"+dsttype);
548
}
549
return cv;
550
}
551
552
protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
553
int srcX, int srcY, int w, int h,
554
SurfaceData dstData)
555
{
556
return convertFrom(ob, srcData,
557
srcX, srcY, w, h, dstData,
558
BufferedImage.TYPE_INT_ARGB);
559
}
560
561
protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
562
int srcX, int srcY, int w, int h,
563
SurfaceData dstData, int type)
564
{
565
if (dstData != null) {
566
Rectangle r = dstData.getBounds();
567
if (w > r.width || h > r.height) {
568
dstData = null;
569
}
570
}
571
if (dstData == null) {
572
BufferedImage dstBI = new BufferedImage(w, h, type);
573
dstData = BufImgSurfaceData.createData(dstBI);
574
}
575
ob.Blit(srcData, dstData, AlphaComposite.Src, null,
576
srcX, srcY, 0, 0, w, h);
577
return dstData;
578
}
579
580
protected static void convertTo(Blit ob,
581
SurfaceData srcImg, SurfaceData dstImg,
582
Region clip,
583
int dstX, int dstY, int w, int h)
584
{
585
if (ob != null) {
586
ob.Blit(srcImg, dstImg, AlphaComposite.Src, clip,
587
0, 0, dstX, dstY, w, h);
588
}
589
}
590
591
protected static GraphicsPrimitive getGeneralOp(int primID,
592
CompositeType comptype)
593
{
594
return GraphicsPrimitiveMgr.locatePrim(primID,
595
SurfaceType.IntArgb,
596
comptype,
597
SurfaceType.IntArgb);
598
}
599
600
public static String simplename(Field[] fields, Object o) {
601
for (int i = 0; i < fields.length; i++) {
602
Field f = fields[i];
603
try {
604
if (o == f.get(null)) {
605
return f.getName();
606
}
607
} catch (Exception e) {
608
}
609
}
610
return "\""+o.toString()+"\"";
611
}
612
613
public static String simplename(SurfaceType st) {
614
return simplename(SurfaceType.class.getDeclaredFields(), st);
615
}
616
617
public static String simplename(CompositeType ct) {
618
return simplename(CompositeType.class.getDeclaredFields(), ct);
619
}
620
621
private String cachedname;
622
623
public String toString() {
624
if (cachedname == null) {
625
String sig = methodSignature;
626
int index = sig.indexOf('(');
627
if (index >= 0) {
628
sig = sig.substring(0, index);
629
}
630
cachedname = (getClass().getName()+"::"+
631
sig+"("+
632
simplename(sourceType)+", "+
633
simplename(compositeType)+", "+
634
simplename(destType)+")");
635
}
636
return cachedname;
637
}
638
}
639
640