Compare commits

...

904 Commits

Author SHA1 Message Date
Alexey Ushakov
14390bfdd0 8252796: Lanai: Shape clip test artifacts on MacBook Air 2020
Wait for previous ops results before rendering clip spans
2020-09-22 18:53:44 +03:00
Vitaly Provodin
39bef2a6c8 updated JTreg exclude list 2020-09-22 05:00:21 +03:00
denis.konoplev
48cdcabee7 Add gradle project for lanai branch 2020-09-22 05:00:21 +03:00
Vitaly Provodin
cfda13b5ab updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
7081e8d769 updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
9acebfb5dd updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
bb1cb2029b remove the Nashorn JavaScript Engine
see http://openjdk.java.net/jeps/372,
https://bugs.openjdk.java.net/browse/JDK-8236933 and https://bugs.openjdk.java.net/browse/JDK-8241749
2020-09-22 05:00:20 +03:00
Vitaly Provodin
510f810617 updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
b65d5ea94b updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
38a32ca578 updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
25aad68390 updated JTreg exclude list 2020-09-22 05:00:20 +03:00
Vitaly Provodin
4ea67036ac updated JTreg exclude list 2020-09-22 05:00:19 +03:00
Vitaly Provodin
800679ce2e add notarization scripts 2020-09-22 05:00:19 +03:00
Vitaly Provodin
c4ff457916 JBR-2212 add JBR building scripts 2020-09-22 05:00:19 +03:00
Vitaly Provodin
ff8c7e38c3 updated JTreg exclude list 2020-09-22 05:00:19 +03:00
Vitaly Provodin
56bfa44851 JBR-1988: switch building onto 10.13 2020-09-22 05:00:19 +03:00
Vitaly Provodin
a727f988ba updated JTreg exclude list 2020-09-22 05:00:19 +03:00
Vitaly Provodin
f098f53ac4 updated JTreg exclude list 2020-09-22 05:00:19 +03:00
Vitaly Provodin
43b16962f9 updated JTreg exclude list 2020-09-22 05:00:19 +03:00
Vitaly Provodin
3bcbc468d4 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
0a8802ec75 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
8893a49c5a updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
9e97e77614 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
9541570ea6 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
37b12b0715 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly.Provodin
affec42dca updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
64203ed296 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
Vitaly Provodin
6fd394ec05 updated JTreg exclude list 2020-09-22 05:00:18 +03:00
duke
84058e38e3 Automatic merge of jdk:master into master 2020-09-21 03:01:15 +00:00
duke
57c551e09d Automatic merge of jdk:master into master 2020-09-20 03:00:59 +00:00
duke
5fab7690f1 Automatic merge of jdk:master into master 2020-09-19 03:00:41 +00:00
Ajit Ghaisas
057fc7c24d 8252499: UI text of application with metal pipeline is lost when another application is launched with OpenGL pipeline 2020-09-18 05:35:43 +00:00
duke
ee23dcda71 Automatic merge of jdk:master into master 2020-09-18 03:01:30 +00:00
Alexey Ushakov
1e5a5c9c10 8253301: Lanai: Memory leak in MTLContext code 2020-09-17 17:25:18 +00:00
duke
c4433bd988 Automatic merge of jdk:master into master 2020-09-17 13:43:07 +00:00
duke
a1aa4d9188 Automatic merge of jdk:master into master 2020-09-17 13:41:08 +00:00
duke
08527778b5 Automatic merge of jdk:master into master 2020-09-17 13:10:14 +00:00
duke
64c145afc4 Automatic merge of jdk:master into master 2020-09-17 13:04:44 +00:00
duke
a7c59e75b7 Automatic merge of jdk:master into master 2020-09-17 10:06:22 +00:00
duke
7964f7f878 Automatic merge of jdk:master into master 2020-09-17 10:03:00 +00:00
duke
b60294f464 Automatic merge of jdk:master into master 2020-09-17 07:59:03 +00:00
duke
507a093794 Automatic merge of jdk:master into master 2020-09-17 07:27:29 +00:00
duke
ac7f36b767 Automatic merge of jdk:master into master 2020-09-17 04:33:19 +00:00
duke
28cdf8acf8 Automatic merge of jdk:master into master 2020-09-16 22:45:50 +00:00
duke
cfab014f6c Automatic merge of jdk:master into master 2020-09-16 20:23:38 +00:00
duke
f62fdf6836 Automatic merge of jdk:master into master 2020-09-16 18:59:29 +00:00
Kevin Rushforth
1553e9a1d1 Merge jdk:master 2020-09-16 18:35:26 +00:00
Kevin Rushforth
1e88cd03ea 8253260: Fix whitespace errors in .m and .metal files in lanai repo 2020-09-16 18:14:50 +00:00
duke
df33968cc6 Automatic merge of jdk:master into master 2020-09-16 12:24:34 +00:00
duke
52becacc85 Automatic merge of jdk:master into master 2020-09-16 12:18:16 +00:00
duke
12363abf0a Automatic merge of jdk:master into master 2020-09-16 11:55:44 +00:00
duke
6461f3754e Automatic merge of jdk:master into master 2020-09-16 11:20:18 +00:00
duke
fe76452a6c Automatic merge of jdk:master into master 2020-09-16 11:17:49 +00:00
duke
f6e488b273 Automatic merge of jdk:master into master 2020-09-16 10:50:41 +00:00
duke
f095de66af Automatic merge of jdk:master into master 2020-09-16 09:49:15 +00:00
duke
971434904d Automatic merge of jdk:master into master 2020-09-16 09:27:43 +00:00
duke
ddc7693e7c Automatic merge of jdk:master into master 2020-09-16 06:50:19 +00:00
duke
0e9118f2ad Automatic merge of jdk:master into master 2020-09-16 06:42:04 +00:00
duke
248576ae65 Automatic merge of jdk:master into master 2020-09-16 06:39:46 +00:00
duke
de1213f107 Automatic merge of jdk:master into master 2020-09-16 05:55:11 +00:00
duke
746ea173ee Automatic merge of jdk:master into master 2020-09-15 22:15:43 +00:00
duke
ca6f3cac48 Automatic merge of jdk:master into master 2020-09-15 21:33:22 +00:00
Alexey Ushakov
243c841996 8252795: Lanai: Refactor native implementation of MTLPaint 2020-09-15 20:58:38 +00:00
duke
d638a78e91 Automatic merge of jdk:master into master 2020-09-15 20:44:46 +00:00
duke
aa75d33288 Automatic merge of jdk:master into master 2020-09-15 20:31:12 +00:00
duke
06db9a2811 Automatic merge of jdk:master into master 2020-09-15 19:02:13 +00:00
duke
3409cb7dcc Automatic merge of jdk:master into master 2020-09-15 16:41:21 +00:00
duke
ce13b0f1e2 Automatic merge of jdk:master into master 2020-09-15 15:30:54 +00:00
duke
b776c5abab Automatic merge of jdk:master into master 2020-09-15 14:35:11 +00:00
duke
0794d75af7 Automatic merge of jdk:master into master 2020-09-15 13:51:53 +00:00
duke
6aacf1d087 Automatic merge of jdk:master into master 2020-09-15 12:23:30 +00:00
duke
b369c73961 Automatic merge of jdk:master into master 2020-09-15 12:19:43 +00:00
denis.konoplev
d07e71c880 8251023: Clipping of Image doesnt work when Alpha composite is enabled in J2DDemo 2020-09-15 10:58:30 +00:00
duke
69998b371e Automatic merge of jdk:master into master 2020-09-15 10:54:51 +00:00
duke
66518371cf Automatic merge of jdk:master into master 2020-09-15 10:21:37 +00:00
duke
30b446ce88 Automatic merge of jdk:master into master 2020-09-15 07:08:34 +00:00
duke
34cdd52696 Automatic merge of jdk:master into master 2020-09-15 05:14:55 +00:00
duke
4b3046e7b4 Automatic merge of jdk:master into master 2020-09-15 04:36:34 +00:00
duke
9bf8b49c7e Automatic merge of jdk:master into master 2020-09-15 02:37:48 +00:00
duke
05dba46171 Automatic merge of jdk:master into master 2020-09-14 20:44:16 +00:00
duke
6dcee9f01d Automatic merge of jdk:master into master 2020-09-14 17:36:18 +00:00
duke
8c3d37f4be Automatic merge of jdk:master into master 2020-09-14 17:23:37 +00:00
duke
17047c22a7 Automatic merge of jdk:master into master 2020-09-14 08:14:34 +00:00
duke
faaac4bdbb Automatic merge of jdk:master into master 2020-09-14 07:49:32 +00:00
duke
aa2e7e7e0d Automatic merge of jdk:master into master 2020-09-14 07:21:29 +00:00
duke
b43461e7b5 Automatic merge of jdk:master into master 2020-09-14 07:08:43 +00:00
duke
558f5b04cd Automatic merge of jdk:master into master 2020-09-14 03:40:16 +00:00
duke
27eab83a03 Automatic merge of jdk:master into master 2020-09-13 19:22:19 +00:00
duke
5e7ff8853a Automatic merge of jdk:master into master 2020-09-13 14:46:16 +00:00
duke
2b54a293d2 Automatic merge of jdk:master into master 2020-09-12 05:27:38 +00:00
duke
2026fc1402 Automatic merge of jdk:master into master 2020-09-11 23:12:00 +00:00
duke
3f04475fd1 Automatic merge of jdk:master into master 2020-09-11 23:05:10 +00:00
duke
4eb5cb72e3 Automatic merge of jdk:master into master 2020-09-11 17:24:23 +00:00
Kevin Rushforth
e7823d8202 Merge jdk:master 2020-09-11 16:51:45 +00:00
duke
82e504bbd6 Automatic merge of jdk:master into master 2020-09-11 14:47:57 +00:00
duke
3f2cc917f7 Automatic merge of jdk:master into master 2020-09-11 13:37:06 +00:00
duke
521ad857be Automatic merge of jdk:master into master 2020-09-11 12:00:12 +00:00
duke
994240ff9d Automatic merge of jdk:master into master 2020-09-11 11:57:43 +00:00
duke
69bc41be53 Automatic merge of jdk:master into master 2020-09-11 07:24:38 +00:00
duke
f638c5b050 Automatic merge of jdk:master into master 2020-09-11 07:10:04 +00:00
duke
e77f8f17a3 Automatic merge of jdk:master into master 2020-09-11 04:05:53 +00:00
duke
389eab6fe8 Automatic merge of jdk:master into master 2020-09-11 01:32:07 +00:00
duke
4a8f2d21cc Automatic merge of jdk:master into master 2020-09-10 21:48:29 +00:00
duke
23aeda1cba Automatic merge of jdk:master into master 2020-09-10 21:28:10 +00:00
duke
c9dcc4d4d0 Automatic merge of jdk:master into master 2020-09-10 19:28:30 +00:00
Alexey Ushakov
272da50636 8252880: Image operations are not working with metal 2020-09-10 16:24:49 +00:00
duke
9be21072a2 Automatic merge of jdk:master into master 2020-09-10 16:07:19 +00:00
duke
571e894e2b Automatic merge of jdk:master into master 2020-09-10 14:39:51 +00:00
duke
426647994a Automatic merge of jdk:master into master 2020-09-10 14:22:26 +00:00
Kevin Rushforth
bfcf110242 Merge jdk:master 2020-09-09 19:01:27 +00:00
Alexey Ushakov
bcb31edf1f 8252895: Black background in SwingSet2 in Nimbus LAF 2020-09-09 15:34:13 +00:00
Ajit Ghaisas
6cecbedbae 8252949: Shape clip should use identity transform for drawing clip spans 2020-09-09 06:51:59 +00:00
Alexey Ushakov
2c50c0f4fb 8252845: Regressions in Sanity tests after JDK-8251032 2020-09-07 09:53:11 +00:00
Jayathirth D V
ab213f56af 8252798: Cleanup LCD text rendering code 2020-09-07 06:13:43 +00:00
Alexey Ushakov
db306e2f09 8252386: Lanai: Implement RadialGradientPaint in shader 2020-09-03 17:20:16 +00:00
Jayathirth D V
d3bbb05e12 8252706: Enable usage of rowBytesOffset for LCD non cache rendering 2020-09-02 12:16:26 +00:00
denis.konoplev
bcc85aa76e 8251032: Colors with texture background look different with Alpha Com… 2020-09-02 11:14:30 +00:00
duke
a3d5998513 Automatic merge of client:master into master 2020-09-01 12:24:53 +00:00
Prasanta Sadhukhan
b79f4f0301 Merge 2020-09-01 17:50:05 +05:30
duke
74560722e4 Automatic merge of client:master into master 2020-09-01 07:27:02 +00:00
Tejpal Rebari
57bf93dda2 8251122: doclint html5 errors in java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html
Reviewed-by: serb, aivanov
2020-09-01 12:53:28 +05:30
Aleksey Shipilev
b5a80794cc 8252592: Non-PCH build is broken after JDK-8251560
Reviewed-by: zgu, iklam
2020-09-01 07:06:18 +02:00
duke
7bc726537f Automatic merge of client:master into master 2020-09-01 04:34:38 +00:00
Naoto Sato
898c29ffbe 8252552: DecimalFormat javadoc contains HTML tags in example code
Reviewed-by: lancea, joehw
2020-08-31 15:32:29 -07:00
Sergey Bylokhov
197d72e351 8198334: java/awt/FileDialog/8003399/bug8003399.java fails in headless mode
Reviewed-by: pbansal, psadhukhan
2020-08-31 22:30:04 +01:00
duke
39dcd31ec0 Automatic merge of client:master into master 2020-08-31 20:06:44 +00:00
Phil Race
238655b025 Merge 2020-08-31 12:26:58 -07:00
Alexey Ushakov
bc7caad91e 8252385: Lanai: Implement LinearGradient paint in shader 2020-08-31 17:16:53 +00:00
duke
75f133c004 Automatic merge of client:master into master 2020-08-31 16:10:39 +00:00
Anton Litvinov
ba7eb53bca 8249183: JVM crash in "AwtFrame::WmSize" method
Reviewed-by: serb, aivanov
2020-08-31 17:06:41 +01:00
Patrick Concannon
83e0ecb953 8238286: Add new flatMap stream operation that is more amenable to pushing
This patch adds a new flatmap-like operation called mapMulti to the java.util.Stream class as well as the primitive variations of this operation i.e. mapMultiToInt, IntStream mapMulti, etc.

Reviewed-by: psandoz, smarks
2020-08-31 16:12:32 +01:00
Ioi Lam
208b1206fe 8251560: Remove excessive header file inclusion from systemDictionary.hpp and others
Reviewed-by: coleenp
2020-08-31 08:05:08 -07:00
Coleen Phillimore
d4ef7fae99 8230052: MLVM findDeadlock test timed out
Add logging for debugging for the next timeout

Reviewed-by: iignatyev, iklam, pchilanomate, dholmes
2020-08-31 09:32:44 -04:00
duke
93913adbc9 Automatic merge of client:master into master 2020-08-31 13:23:52 +00:00
Phil Race
2d93ba3755 8245400: Upgrade to LittleCMS 2.11
Reviewed-by: serb, jdv
2020-08-31 06:14:42 -07:00
duke
580efd590e Automatic merge of client:master into master 2020-08-31 12:27:40 +00:00
Prasanta Sadhukhan
058a4aecaf 8040914: Test javax/swing/JLabel/6596966/bug6596966.java fails : comboBox isn't focus owner
Reviewed-by: prr
2020-08-31 17:53:04 +05:30
duke
af4203a015 Automatic merge of client:master into master 2020-08-31 10:33:30 +00:00
Pankaj Bansal
cbd7b826f5 8249548: backward focus traversal gets stuck in button group
Reviewed-by: serb
2020-08-31 15:58:57 +05:30
Christian Hagedorn
b8d14fc5ba 8249607: C2: assert(!had_error) failed: bad dominance
Fix prevented igvn optimization in SplitIf for LoadNodes which resulted in dominanance errors with loop strip mining.

Reviewed-by: roland, kvn
2020-08-31 12:10:25 +02:00
Yuri Nesterenko
e4d4828a3b 8252497: Incorrect numeric currency code for ROL
Reviewed-by: naoto
2020-08-31 12:26:13 +03:00
Stefan Karlsson
44ad9322e6 8252368: Undo JDK-8245002: Windows GDI functions don't support NUMA interleaving
Reviewed-by: eosterlund, sjohanss
2020-08-31 11:02:47 +02:00
Stefan Karlsson
e95e1381cd 8252367: Undo JDK-8245000: Windows GDI functions don't support large pages
Reviewed-by: eosterlund, sjohanss
2020-08-31 11:01:57 +02:00
Stefan Karlsson
9ac3073307 8139800: Remove OopsInGenClosure
Reviewed-by: kbarrett, sjohanss
2020-08-31 09:57:44 +02:00
duke
76b0dc5f6c Automatic merge of client:master into master 2020-08-29 17:15:36 +00:00
Phil Race
45d8d4ca12 8074844: Resolve disabled warnings for libfontmanager
Reviewed-by: serb, ihse, erikj
2020-08-29 10:07:22 -07:00
duke
ef91729062 Automatic merge of client:master into master 2020-08-29 07:14:23 +00:00
Dmitry Markov
a7d1a64cb6 8252470: java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java fails on Windows
Reviewed-by: serb, prr
2020-08-29 08:10:18 +01:00
duke
e590fc9098 Automatic merge of client:master into master 2020-08-29 05:48:09 +00:00
Prasanta Sadhukhan
2289fbb230 Merge 2020-08-29 11:14:49 +05:30
Prasanta Sadhukhan
cc188e6e31 Merge 2020-08-29 11:10:16 +05:30
duke
4ca27927a5 Automatic merge of client:master into master 2020-08-29 03:24:27 +00:00
Sergey Bylokhov
22afbe5649 8252349: Delete the "sun.awt.X11.checkSTRUT" property
Reviewed-by: kizune, prr
2020-08-28 22:55:38 +01:00
Erik Joelsson
5414b6fabb 8252233: Put debug symbols in symbols-image
Reviewed-by: ihse, aleonard
2020-08-28 12:03:50 -07:00
Vipin Sharma
e038528e97 8252265: Replace @exception with @throws java.util.logging package
@exception should be updated with @throws.

Reviewed-by: dfuchs, lancea
2020-08-29 00:00:10 +05:30
Alexander Scherbatiy
fe0c2ad903 8252248: __SIGRTMAX is not declared in musl libc
Reviewed-by: alanb, vtewari, stuefe
2020-08-31 11:18:20 +03:00
Aleksei Voitylov
3746ed3370 8252250: isnanf is obsolete
Reviewed-by: dcubed, mikael
2020-08-31 09:28:32 +03:00
Dean Long
f042a4e0de 8209961: [AOT] crash in Graal stub when -XX:+VerifyOops is used
Reviewed-by: kvn
2020-08-30 15:53:46 -07:00
Daniel D. Daugherty
acc03fe0ec 8252551: JDK-8250630 causes build error on Win*
Reviewed-by: dsamersoff
2020-08-30 12:20:59 -04:00
Dmitry Samersoff
ffd78a95b2 8250630: test/jdk/com/sun/jdi/JdwpListenTest.java fails on Alpine Linux
Make sure that IN6ADDR_ANY is preferred over mapped INADDR_ANY

Reviewed-by: amenkov, sspitsyn
2020-08-30 15:48:16 +03:00
Rajan Halade
5eaef6de03 8249176: Update GlobalSignR6CA test certificates
Reviewed-by: xuelei
2020-08-29 13:55:48 -07:00
Rahul Yadav
a0ddd7a9e6 8245308: Replace ThreadLocalCoders decoder/encoder cache in java.net.URI
This fix updates java.net.URI and replaces the ThreadLocalCoders optimization.

Reviewed-by: alanb, dfuchs
2020-08-28 18:05:20 +01:00
Igor Ignatyev
de84793a57 8252401: Introduce Utils.TEST_NATIVE_PATH
Reviewed-by: sspitsyn
2020-08-28 10:28:06 -07:00
Stefan Karlsson
d372b52789 8252294: Remove OopsInGenClosure usage from younger_refs_iterate
Reviewed-by: sjohanss, kbarrett
2020-08-28 17:20:19 +02:00
Stefan Karlsson
98f5ae24c7 8252289: Remove usage of OopsInGenClosure from full_process_roots
Reviewed-by: sjohanss, kbarrett
2020-08-28 17:20:13 +02:00
Stefan Karlsson
ed8324eaad 8252245: Remove ScanClosure
Reviewed-by: pliden, sjohanss
2020-08-28 17:20:08 +02:00
Pavel Rappo
5a56a00605 8252172: Improve prettiness of printing HTML attributes by DocPretty
Reviewed-by: jjg
2020-08-28 15:26:34 +01:00
Erik Joelsson
02857c2ba7 8252145: Unify Info.plist files with correct version strings
Reviewed-by: ihse, serb
2020-08-28 06:23:41 -07:00
duke
80d4f49031 Automatic merge of client:master into master 2020-08-28 12:33:20 +00:00
Prasanta Sadhukhan
f9ed6b5681 Merge 2020-08-28 17:58:18 +05:30
Aleksei Efimov
fa036c8f54 8251182: Fix "no comment" warnings in java.naming
Reviewed-by: lancea, rriggs, dfuchs
2020-08-28 13:10:32 +01:00
duke
f443628fb2 Automatic merge of client:master into master 2020-08-28 11:45:38 +00:00
Prasanta Sadhukhan
cb14b33c76 6542439: Significant memory leak in BasicComboBoxUI and MetalComboBoxButton
Reviewed-by: serb
2020-08-28 17:12:50 +05:30
Ajit Ghaisas
0e024b33ef 8243547: Lanai - Netbeans IDE has BLACK background for the Toolbar and Statusbar
8240164: Test java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java fails for metal
8240074: Test java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java fails for metal
2020-08-28 10:17:05 +00:00
Daniel Fuchs
b02054be18 8245462: HttpClient send throws InterruptedException when interrupted but does not cancel request
Allows an HTTP operation to be cancelled by calling CompletableFuture::cancel(true)

Reviewed-by: michaelm, chegar, alanb
2020-08-28 10:48:17 +01:00
Robbin Ehn
19216ac7c7 8252414: Redundant suspend check when determining if a java thread is safe
Reviewed-by: dholmes, dcubed, coleenp
2020-08-28 10:30:02 +02:00
Attila Szegedi
85eca9be05 8251538: Modernize and lint Dynalink code
Reviewed-by: sundar
2020-08-28 10:23:21 +02:00
Jayathirth D V
6173a38bc6 8251027: DrawString with TexturePaint is corrupted 2020-08-28 06:57:27 +00:00
Ioi Lam
3af532e7df 8251557: Avoid dumping unused symbols/strings into the CDS archive
Reviewed-by: minqi, ccheung
2020-08-27 22:24:28 -07:00
duke
47ea44d7bd Automatic merge of client:master into master 2020-08-28 03:50:54 +00:00
Prasanta Sadhukhan
015c0b5aa9 8252469: Backout JDK-8250935 fix
Reviewed-by: prr, serb
2020-08-28 09:17:47 +05:30
Joe Darcy
1845dd2a4a 8251921: Expand default constructor warning to cover more cases
Reviewed-by: jjg, abuckley
2020-08-27 13:01:41 -07:00
Jan Lahoda
461a4d5e75 8252458: Test tools/javac/parser/JavacParserTest.java fails on Windows after JDK-8237041
Reviewed-by: vromero
2020-08-27 20:20:39 +02:00
Vladimir Kozlov
074cabcb6d 8252467: AOT need to process new markId DEOPT_MH_HANDLER_ENTRY in compiled code
Reviewed-by: dlong
2020-08-27 10:51:48 -07:00
Jan Lahoda
2665df9304 8237041: AssertionError in parsing
Avoid parser crash for deeply nested classes without closing braces, improve error recovery for classes without an opening brace.

Reviewed-by: vromero
2020-08-27 16:15:11 +02:00
duke
c4bcb12905 Automatic merge of client:master into master 2020-08-27 11:41:47 +00:00
Prasanta Sadhukhan
86e953b5a9 8250935: JFileChooser incorrectly placed "Date" value in "Type" field
Reviewed-by: prr
2020-08-27 17:07:56 +05:30
Alexey Ushakov
a9a6e4f7cd 8242920: Gradient Paint doesn't work with metal 2020-08-26 17:17:08 +00:00
duke
1e4c6aff8b Automatic merge of client:master into master 2020-08-26 16:36:42 +00:00
Phil Race
b20264e377 8247867: Upgrade to freetype 2.10.2
Reviewed-by: serb
2020-08-26 09:28:03 -07:00
Jayathirth D V
0e80c21f1a 8252371: LCD text rendered with Metal pipeline is corrupted 2020-08-26 12:07:23 +00:00
duke
ca68b1854b Automatic merge of client:master into master 2020-08-26 11:53:49 +00:00
Prasanta Sadhukhan
d5e8f23555 8250853: Address reliance on default constructors in the javax.swing APIs
Reviewed-by: serb
2020-08-26 17:20:05 +05:30
duke
80f1b6a031 Automatic merge of client:master into master 2020-08-26 09:21:04 +00:00
Prasanta Sadhukhan
e0763c5907 8250850: Address reliance on default constructors in the javax.swing.plaf.metal APIs
Reviewed-by: serb
2020-08-26 14:47:38 +05:30
duke
4f978172b4 Automatic merge of client:master into master 2020-08-26 07:17:43 +00:00
Dmitry Markov
1a24996ca3 8232114: JVM crashed at imjpapi.dll in native code
Reviewed-by: serb, alitvinov
2020-08-26 08:13:33 +01:00
Alexey Ushakov
e3e4d1ac78 8252217: Crash in metal pipeline which running J2DBench test 2020-08-25 18:25:12 +00:00
duke
3282e70c55 Automatic merge of client:master into master 2020-08-25 04:34:32 +00:00
Sergey Bylokhov
655b45f2db 8250858: Address reliance on default constructors in the Java Sound APIs
Reviewed-by: prr
2020-08-24 22:12:26 +01:00
Kumar Abhishek
cbeab12fd8 8136363: Nimbus-LaF: background color cleared when setting component name of JToolBar
Reviewed-by: serb, aivanov, dmarkov
2020-08-24 22:48:26 +01:00
Roland Westrelin
e292f04264 8252292: 8240795 may cause anti-dependence to be missed
Reviewed-by: thartmann, kvn
2020-08-24 11:29:40 +02:00
Erik Helin
e6f39e177e 8251552: Add minimal CONTRIBUTING.md file
Reviewed-by: iris, ihse
2020-08-27 14:41:33 +02:00
Erik Helin
bfe17acf0b 8251551: Use .md filename extension for README
Reviewed-by: mr, ihse, darcy
2020-08-27 14:33:42 +02:00
duke
84215334c8 Automatic merge of client:master into master 2020-08-23 23:44:39 +00:00
Sergey Bylokhov
87e1ab5298 8251558: J2DBench should support shaped and translucent windows
Reviewed-by: avu
2020-08-24 00:34:35 +01:00
duke
64ae0bb2bf Automatic merge of client:master into master 2020-08-23 07:52:38 +00:00
Pankaj Bansal
1e90934b33 8251252: Add automated testcase for fix done in JDK-8214253
Reviewed-by: serb, psadhukhan
2020-08-23 13:18:47 +05:30
duke
6842061ad2 Automatic merge of client:master into master 2020-08-23 07:43:44 +00:00
Pankaj Bansal
ba36dbcc3b 8251254: Add automated test for fix done in JDK-8218472
Reviewed-by: serb
2020-08-23 13:09:00 +05:30
duke
91ff090341 Automatic merge of client:master into master 2020-08-22 05:03:02 +00:00
Prasanta Sadhukhan
ea02307411 Merge 2020-08-22 10:23:35 +05:30
Igor Ignatyev
b2237008cc 8251998: remove usage of PropertyResolvingWrapper in vmTestbase/jit/t
Reviewed-by: kvn
2020-08-21 19:00:52 -07:00
Calvin Cheung
ac4a6c9989 8251918: [Graal] Crash in DumpTimeSharedClassInfo::add_verification_constraint
Add NULL check on the return value of SystemDictionaryShared::find_or_allocate_info_for().

Reviewed-by: iklam, minqi
2020-08-22 00:09:23 +00:00
Alex Menkov
59d5f4dcc7 8251384: [TESTBUG] jvmti tests should not be executed with minimal VM
Reviewed-by: sspitsyn, iignatyev
2020-08-21 15:49:09 -07:00
Daniel D. Daugherty
8c53a97973 8252125: add an "inflating" entry to the "table" of bit patterns in share/oops/markWord.hpp
Reviewed-by: tschatzl, coleenp
2020-08-21 16:01:46 -04:00
Daniel D. Daugherty
81c501e521 8252126: 'GVars.stw_random = os::random()' lost by JDK-8246476
Reviewed-by: eosterlund
2020-08-21 16:00:11 -04:00
Lance Andersen
0261de472a 8252128: Remove javax.transaction Exception references
Reviewed-by: rriggs
2020-08-21 13:10:04 -04:00
Roland Westrelin
3ccb4939b7 8241486: G1/Z give warning when using LoopStripMiningIter and turn off LoopStripMiningIter (0)
Reviewed-by: thartmann, kvn
2020-08-21 17:41:57 +02:00
Patrick Concannon
fefb9c89f1 8189744: Deprecate the JDK-specific API for setting socket options, jdk.net.Sockets
The JDK-specific API `jdk.net.Sockets` has been redundant since Java SE 9 added standard methods to get/set socket options and retrieve per-Socket supported options. This fix deprecates the class and its public methods.

Reviewed-by: chegar, dfuchs
2020-08-27 10:57:13 +01:00
Stefan Karlsson
46b5560bd0 8247759: ZGC: Replace ZGC specific array implementations with GrowableArray
Reviewed-by: pliden
2020-08-27 09:54:32 +02:00
Stefan Karlsson
c24e7ba0b4 8252224: ZGC: Convert ZValue to use alias templates
Reviewed-by: pliden, kbarrett
2020-08-27 09:53:31 +02:00
Stefan Karlsson
75a8c715f9 8252223: ZGC: Convert ZPage to use delegating constructor
Reviewed-by: pliden, sjohanss, kbarrett
2020-08-27 09:52:22 +02:00
Roland Westrelin
a9298a07c5 8252296: Shenandoah: crash in CallNode::extract_projections
Reviewed-by: chagedorn
2020-08-25 14:25:53 +02:00
Jie Fu
b55df03ed6 8252404: compiler/c1/TestTraceLinearScanLevel.java fails with release VMs
Reviewed-by: kvn, thartmann
2020-08-27 10:35:00 +08:00
Aleksey Shipilev
53e266d8d8 8252215: Remove VerifyOptoOopOffsets flag
Reviewed-by: thartmann, kvn
2020-08-27 06:34:27 +02:00
Aleksey Shipilev
ea029715c1 8252362: C2: Remove no-op checking for callee-saved-floats
Reviewed-by: vlivanov
2020-08-27 06:34:24 +02:00
Jesper Wilhelmsson
319348b4ce Added tag jdk-16+13 for changeset fd07cdb26fc7 2020-08-27 04:40:05 +02:00
Igor Ignatyev
329cc86959 8251127: clean up FileInstaller $test.src $cwd in remaining vmTestbase_vm_compiler tests
Reviewed-by: kvn
2020-08-26 17:06:15 -07:00
Jie Fu
e1a7832e2a 8252264: tools/javac/flags/LockedFlagClash.java fails to compile
Reviewed-by: jlahoda
2020-08-25 12:46:18 +08:00
Ioi Lam
6fe09318c5 8252398: minimal debug build broken - CURRENT_PC undefined in resourceArea.inline.hpp
Reviewed-by: kbarrett
2020-08-26 14:44:23 -07:00
Ioi Lam
21a2bc9188 8252151: Remove excessive inclusion of arguments.hpp
Reviewed-by: coleenp, stuefe
2020-08-26 14:42:07 -07:00
Joe Wang
0cfd010246 8251561: Fix doclint warnings in the java.xml package
Reviewed-by: lancea, naoto, rriggs, erikj, alanb
2020-08-26 17:48:41 +00:00
Sean Mullan
6a50cb6b9c 8241003: Deprecate "denigrated" java.security.cert APIs that represent DNs as Principal or String objects
Reviewed-by: xuelei, valeriep, weijun
2020-08-26 13:31:10 -04:00
Rajan Halade
cad4272fa2 8238157: Remove intermittent key from AmazonCA.java
Reviewed-by: xuelei
2020-08-26 10:22:21 -07:00
Vicente Romero
f01c72a255 8230918: j.l.NASE in javap
Reviewed-by: jjg
2020-08-26 13:08:39 -04:00
Christian Hagedorn
33f1d05b13 8251093: Improve C1 register allocator logging and debugging support
Various printing and debug improvements to better analyze C1 register allocator problems.

Reviewed-by: kvn, thartmann
2020-08-26 13:46:46 +02:00
Christian Hagedorn
f7737da205 8252037: Optimized build is broken
Fix some optimized build issues.

Reviewed-by: vlivanov, tschatzl, thartmann, kbarrett
2020-08-26 13:41:49 +02:00
Coleen Phillimore
6fbbd9b11b 8244386: convert runtime/Safepoint/AssertSafepointCheckConsistency tests to gtest
Reviewed-by: stuefe, lfoltan, dcubed
2020-08-26 07:55:05 -04:00
Yasumasa Suenaga
080b9eae81 8250598: Hyper-V is detected in spite of running on host OS
Reviewed-by: mbaesken, mdoerr, dholmes
2020-08-26 19:21:09 +09:00
Joshua Zhu
8919329cd3 8252259: AArch64: Adjust default value of FLOATPRESSURE
Reviewed-by: aph
2020-08-26 17:34:48 +08:00
Nick Gasson
19c4f8b158 8252108: Modify nsk/stress/stack tests to check page size
Reviewed-by: hseigel, stuefe
2020-08-26 11:28:10 +08:00
Aleksey Shipilev
0776cc78a0 8252291: C2: Assignment in conditional in loopUnswitch.cpp
Reviewed-by: thartmann
2020-08-26 09:29:46 +02:00
Aleksey Shipilev
b3653ac439 8252290: Remove unused enum in CallGenerator
Reviewed-by: thartmann, rrich
2020-08-26 09:29:37 +02:00
duke
63a4356325 Automatic merge of client:master into master 2020-08-21 09:10:52 +00:00
Prasanta Sadhukhan
57e72cfbf9 Merge 2020-08-21 14:35:52 +05:30
Aleksey Shipilev
24ea96f2b5 8252120: compiler/oracle/TestCompileCommand.java misspells "occured"
Reviewed-by: iignatyev
2020-08-21 09:38:27 +02:00
Igor Ignatyev
49e4022c3c 8251996: remove usage of PropertyResolvingWrapper in vm/compiler/complog/uninit
Reviewed-by: kvn, epavlova
2020-08-20 20:17:44 -07:00
Valerie Peng
256cb2b121 8246383: NullPointerException in JceSecurity.getVerificationResult when using Entrust provider
Removed the static SecureRandom object in JceSecurity whose instantion caused NPE

Reviewed-by: xuelei
2020-08-21 03:09:42 +00:00
duke
8a4cf7f868 Automatic merge of client:master into master 2020-08-20 22:25:29 +00:00
Kumar Abhishek
14d6adc003 8200281: Add missing @Override annotations in ImageIO plugins
Reviewed-by: prr, dmarkov, aivanov
2020-08-20 23:18:29 +01:00
Igor Ignatyev
860a529c13 8252005: narrow disabling of allowSmartActionArgs in vmTestbase
Reviewed-by: sspitsyn
2020-08-20 11:12:00 -07:00
Mikael Vidstedt
7d30450314 8252051: Make mlvmJvmtiUtils strncpy uses GCC 10.x friendly
Reviewed-by: iignatyev, kvn
2020-08-20 11:09:25 -07:00
Alexey Ushakov
f85fcbbe8a 8252057: Crash in metal pipeline when dragging any Swing app to other… 2020-08-20 17:27:54 +00:00
Lance Andersen
7c8ed857b9 8251208: Add missing javadoc comments to java.sql and java.sql.rowsets
Reviewed-by: joehw
2020-08-20 12:38:39 -04:00
Kevin Walls
f8eca6520e 8248295: serviceability/jvmti/CompiledMethodLoad/Zombie.java failure with Graal
Reviewed-by: kvn, sspitsyn
2020-08-20 11:42:12 +01:00
Jesper Wilhelmsson
ab151c3e99 Added tag jdk-16+12 for changeset fc8e62b399bd 2020-08-20 11:43:46 +02:00
Jan Lahoda
1eb98fc127 8252031: --patch-module java.base= may fail with \"cyclic inheritance involving Object\"
Avoiding clash in use of Flags.LOCKED between Types.asSuper and Check.checkNonCyclic.

Reviewed-by: jjg
2020-08-20 10:48:36 +02:00
Nick Gasson
52a8e0f858 8251923: "Invalid JNI handle" assertion failure in JVMCICompiler::force_comp_at_level_simple()
Reviewed-by: kvn, dnsimon
2020-08-20 09:32:01 +08:00
Naoto Sato
f0e5824f35 8251499: no-placeholder compact number patterns throw IllegalArgumentException
Reviewed-by: joehw, rriggs
2020-08-19 13:41:08 -07:00
Harold Seigel
a0cde95b67 8251490: [TESTBUG] The Java thread stack size specified is too small for nsk/stress/stack. Specify at least 448k
Increase the -Xss stack size for some tests, mark other tests as not runnable on AArch64.

Reviewed-by: gziemski, lfoltan
2020-08-19 19:40:46 +00:00
Alexey Ushakov
a9e6747954 8251484: Performace drop in FlatBoxAA renderperf test for metal pipeline 2020-08-19 18:11:26 +00:00
Pavel Rappo
f8257688c5 8251454: Wrong "self type" in DCTree.DCEndElement
Reviewed-by: jjg
2020-08-19 17:51:14 +01:00
Pavel Rappo
1da978d352 8251357: [DocCommentParser] Infinite loop while looking for the end of a preamble
Reviewed-by: jjg
2020-08-19 17:44:14 +01:00
Conor Cleary
8eed9aad77 8246047: Replace LinkedList impl in net.http.websocket.BuilderImpl
Replaced usages of LinkedList with ArrayList in http.websocket.BuilderImpl

Reviewed-by: chegar, dfuchs
2020-08-19 16:27:16 +01:00
Ajit Ghaisas
3fe2535719 8251242: Tile based rendering results in artifacts in last column while using metal pipeline 2020-08-19 10:28:27 +00:00
Kim Barrett
dd8d78a367 8251888: Move HotSpot Style Guide wiki subpages to jdk/jdk/doc
Copy unit-test page from wiki, merge jtreg names page into hotspot-style.md

Reviewed-by: kvn, iignatyev
2020-08-19 06:11:15 -04:00
Roland Westrelin
562dd2d04c 8251527: CTW: C2 (Shenandoah) compilation fails with SEGV due to unhandled catchproj == NULL
Reviewed-by: chagedorn, kvn
2020-08-19 10:56:08 +02:00
Coleen Phillimore
3596e7ed84 8252149: Compilation error after JDK-8252043
Reviewed-by: hseigel
2020-08-21 11:23:45 -04:00
Patricio Chilano Mateo
d91817e75b 8242263: Diagnose synchronization on primitive wrappers
Added diagnostic flag DiagnoseSyncOnPrimitiveWrappers

Reviewed-by: dholmes, mdoerr, dcubed, coleenp, egahlin, mgronlun
2020-08-21 15:04:02 +00:00
Coleen Phillimore
f27024b750 8252043: Move inner class metaspace cleaning out of safepoint cleanup tasks
Clean up inner metaspaces from ServiceThread if cleanup is needed for concurrent GCs.

Reviewed-by: eosterlund, pchilanomate
2020-08-21 10:01:40 -04:00
Christoph Dreis
ddd632e238 8252127: Optimize sun.invoke.util.BytecodeDescriptor.unparse
Reviewed-by: mchung, rriggs
2020-08-21 09:29:08 -04:00
Thomas Schatzl
96616eae2a 8252086: G1: Remove g1_rs in G1CollectedHeap::initialize
Reviewed-by: sjohanss
2020-08-21 11:57:55 +02:00
Thomas Schatzl
f19d554955 8252034: G1: Remove *g1_reserved* methods
Remove duplicate methods.

Reviewed-by: sjohanss, kbarrett
2020-08-21 11:54:34 +02:00
Thomas Schatzl
3b9aface5d 8252038: G1: Remove unused G1MarkStatsCache::_num_stats
Reviewed-by: sjohanss, kbarrett
2020-08-21 11:54:33 +02:00
Ziyi Luo
951b12a622 8245511: G1 adaptive IHOP does not account for reclamation of humongous objects by young GC
Discount humongous object eager reclaim in IHOP allocation rate.

Reviewed-by: tschatzl, sjohanss
2020-08-21 11:54:32 +02:00
duke
ecf41658ed Automatic merge of client:master into master 2020-08-19 06:24:08 +00:00
duke
15cb764bc9 Automatic merge of client:master into master 2020-08-19 06:21:10 +00:00
Prasanta Sadhukhan
20ed11da49 8250852: Address reliance on default constructors in the javax.swing.plaf.basic APIs
Reviewed-by: serb, aivanov
2020-08-19 11:49:54 +05:30
Prasanta Sadhukhan
306ad64007 8250851: Address reliance on default constructors in the javax.swing.plaf.synth APIs
Reviewed-by: serb
2020-08-19 11:47:48 +05:30
Rahul Yadav
e361a58a54 8251715: Throw UncheckedIOException in place of InternalError when HttpClient fails due to unavailability of underlying resources required by SSLContext
This fix updates jdk.internal.net.http.HttpClientImpl to throw an UncheckedIOException instead of InternalError.

Reviewed-by: chegar, dfuchs
2020-08-18 16:44:42 +01:00
Evan Whelan
ac7f8f89c2 8250748: Doc of URL(String, String, int, String, URLStreamHandler) does not use link
Reviewed-by: dfuchs
2020-08-19 08:58:00 +00:00
Vicente Romero
94fadf1d1c 8249902: tools/javac/records/mandated_members/read_resolve_method/CheckReadResolveMethodTest.java uses @ignore w/o bug-id
Reviewed-by: jjg
2020-08-18 19:23:58 -04:00
Anton Kozlov
b9462e2957 8251930: Native types mismatch in hotspot
Reviewed-by: aph
2020-08-18 01:34:46 -07:00
duke
f597b5895f Automatic merge of client:master into master 2020-08-18 01:14:57 +00:00
Sergey Bylokhov
d2d4a20f64 8251469: Better cleanup for test/jdk/javax/imageio/SetOutput.java
Reviewed-by: prr, pbansal
2020-08-18 00:08:21 +01:00
Sergey Bylokhov
f0897c8a25 8022535: [TEST BUG] javax/swing/text/html/parser/Test8017492.java fails
Reviewed-by: prr, pbansal
2020-08-18 00:06:57 +01:00
duke
6f28c2a23a Automatic merge of client:master into master 2020-08-17 08:29:36 +00:00
Prasanta Sadhukhan
e2a95a27de 8250849: Address reliance on default constructors in the javax.swing.plaf APIs
Reviewed-by: prr, serb
2020-08-17 13:36:36 +05:30
duke
9e403d1f88 Automatic merge of client:master into master 2020-08-17 06:29:13 +00:00
Pankaj Bansal
5153ff087f 8239137: JAWS does not always announce the value of JSliders in JColorChooser
Reviewed-by: serb, prr, kizune
2020-08-17 11:55:31 +05:30
duke
bb00b05eee Automatic merge of client:master into master 2020-08-17 05:57:30 +00:00
duke
0244642b7f Automatic merge of client:master into master 2020-08-17 05:51:59 +00:00
Tejpal Rebari
f243aba573 8251125: doclint errors about missing references in Swing javadoc
Reviewed-by: psadhukhan, pbansal
2020-08-17 11:20:44 +05:30
Tejpal Rebari
be5517884c 8249674: Redo: Nimbus JTree renderer properties persist across L&F changes
Reviewed-by: psadhukhan, prr
2020-08-17 11:18:19 +05:30
duke
b324345623 Automatic merge of client:master into master 2020-08-16 06:28:36 +00:00
Pankaj Bansal
f47f30ed09 8251124: doclint errors about missing accessibility support in HTML files
Reviewed-by: serb
2020-08-16 11:53:50 +05:30
duke
9c5d0fdb8f Automatic merge of client:master into master 2020-08-16 06:19:59 +00:00
Pankaj Bansal
81ffb36296 8251166: Add automated testcases for changes done in JDK-8214112
Reviewed-by: serb
2020-08-16 11:44:05 +05:30
duke
7ead8f46a6 Automatic merge of client:master into master 2020-08-15 05:45:25 +00:00
Prasanta Sadhukhan
9e29d3e251 Merge 2020-08-15 11:06:44 +05:30
Gerard Ziemski
51cc98fdce 8237591: Mac: include OS X version in hs_err_pid crash log file
Added macOS and build version to crash lof report

Reviewed-by: dholmes, dcubed
2020-08-14 13:24:24 -05:00
Charlie Gracie
28b409f56d 8241065: Shenandoah: remove leftover code after JDK-8231086
Reviewed-by: rkennke
2020-08-14 18:23:43 +02:00
Harold Seigel
00a596f733 8251414: Add test that invokeinterface of a protected method in java.lang.Object throws NoSuchMethodError
Add the missing test cases to existing test InterfaceObjectTest.java

Reviewed-by: lfoltan, coleenp
2020-08-14 15:42:09 +00:00
Brian Burkhalter
d0b46ecf4f 8181919: Refactor test/java/io/File/GetXSpace.sh to java test
Reviewed-by: naoto
2020-08-14 08:12:13 -07:00
duke
7a2831e5c6 Automatic merge of client:master into master 2020-08-14 10:40:42 +00:00
Prasanta Sadhukhan
373e96dd29 Merge 2020-08-14 15:49:27 +05:30
Christian Hagedorn
4741abbacc 8248791: sun/util/resources/cldr/TimeZoneNamesTest.java fails with -XX:-ReduceInitialCardMarks -XX:-ReduceBulkZeroing
Fix wrong replacement of loads by zero for non-completed InitializationNodes belonging to a clone when ReduceBulkZeroing is disabled.

Reviewed-by: kvn, thartmann
2020-08-14 10:30:51 +02:00
duke
7f51f48185 Automatic merge of client:master into master 2020-08-12 14:05:47 +00:00
Prasanta Sadhukhan
3f6b473653 8250811: Address reliance on default constructors in the javax.swing.plaf.multi APIs
Reviewed-by: prr, serb
2020-08-12 19:32:29 +05:30
duke
9cb870f068 Automatic merge of client:master into master 2020-08-11 22:25:57 +00:00
duke
3c23d2deba Automatic merge of client:master into master 2020-08-11 18:31:41 +00:00
Phil Race
84c0e7e715 Merge 2020-08-11 10:56:30 -07:00
Sergey Bylokhov
c1749c1e3d 8078228: Default file manager and web browser didn't launch and got SecurityException
Reviewed-by: jdv, dmarkov
2020-08-11 06:03:16 +01:00
Martin Desruisseaux
00c89251a5 8166038: BufferedImage methods getTileGridXOffset() and getTileGridYOffset() return a non 0 value for sub images
Reviewed-by: jdv, serb
2020-08-11 05:52:35 +01:00
Sergey Bylokhov
b3d6b110be 8250857: Address reliance on default constructors in the Java Beans API
Reviewed-by: prr
2020-08-11 05:34:33 +01:00
Sergey Bylokhov
58fa31ef8b 8250856: Address reliance on default constructors in the AWT APIs
Reviewed-by: prr
2020-08-11 05:30:52 +01:00
duke
28725af444 Automatic merge of client:master into master 2020-08-11 04:21:06 +00:00
Phil Race
02dea52021 8251367: [windows] harfbuzz.dll not found causes failure to load sun.font.SunFontManager
Reviewed-by: serb
2020-08-10 21:12:47 -07:00
Patric Hedlin
7bffa1395a 8250848: [aarch64] nativeGotJump_at() missing call to verify()
Reviewed-by: aph
2020-08-10 17:36:46 +02:00
Magnus Ihse Bursie
09105bbefe 8251399: JDK-8248701 had incorrect indentation
Reviewed-by: erikj
2020-08-11 16:07:04 +02:00
Coleen Phillimore
f70b5a38f6 8251302: Create dedicated OopStorages for Management and Jvmti
Reviewed-by: sspitsyn, dholmes
2020-08-11 07:29:45 -04:00
Dmitry Cherepanov
89be6f1e48 8251365: Build failure on AIX after 8250636
Reviewed-by: dholmes
2020-08-11 13:03:15 +03:00
Hannes Wallnöfer
d7b6bc7131 8250954: Avoid multiple warnings for external docs with mismatching modularity
Reviewed-by: jjg
2020-08-11 08:38:47 +02:00
Xiaohong Gong
1076f6f3be 8250808: Re-associate loop invariants with other associative operations
Reviewed-by: kvn, thartmann
2020-08-11 06:00:43 +00:00
Mikael Vidstedt
3169011aca Merge 2020-08-10 22:25:26 -07:00
Vladimir Kozlov
512374628d 8251369: [JVMCI] Backout 8246347 changes
Reviewed-by: dholmes
2020-08-10 16:26:08 -07:00
Vladimir Kozlov
84057fea55 8249749: modify a primitive array through a stream and a for cycle causes jre crash
Check align_to_ref for NULL early and bailout SuperWord optimization.

Reviewed-by: vlivanov, thartmann
2020-08-10 15:31:01 -07:00
Mandy Chung
4e9881f8fe Merge 2020-08-10 14:57:53 -07:00
Doug Simon
445ac9d18f 8246347: [JVMCI] Set is_method_handle_invoke flag accordingly when describing scope in jvmciCodeInstaller
Reviewed-by: kvn, dlong
2020-08-10 21:52:02 +02:00
Vladimir Kempik
3f8f82876c 8250876: Fix issues with cross-compile on macos
Reviewed-by: erikj, ihse
2020-08-10 22:42:09 +03:00
Evgeny Nikitin
7f0f62bad5 8069411: OutOfMemoryError in OverloadCompileQueueTest.java
OOME seems to have happened in older version and does not show up in modern VM, hence the test OverloadCompileQueueTest.java gets un-quarantined.

Reviewed-by: iignatyev
2020-08-10 16:11:40 +02:00
Evgeny Nikitin
1459ec5b3b 8251349: Add TestCaseImpl to OverloadCompileQueueTest.java's build dependencies
Reviewed-by: iignatyev, kvn
2020-08-10 20:31:27 +02:00
Claes Redestad
8902fb180d 8251459: Compute caller save exclusion RegMasks once
Reviewed-by: kvn, vlivanov
2020-08-18 15:34:28 -07:00
Zhengyu Gu
a9f94bde3e 8251910: Shenandoah: Handshake threads between weak-roots and reset phases
Reviewed-by: rkennke
2020-08-18 13:34:10 -04:00
Pavel Rappo
9d8d5097b3 8251939: Fix copy-paste issues and address TODOs
Reviewed-by: jjg
2020-08-18 17:34:59 +01:00
Magnus Ihse Bursie
4e9ae3219d 8251541: "no symbols" printed when building hotspot
Reviewed-by: erikj
2020-08-18 17:35:38 +02:00
Evan Whelan
64cf9ce2d7 8249691: jdk/lambda/vm/StrictfpDefault.java file can be removed
Reviewed-by: coffeys
2020-08-18 14:43:28 +00:00
Per Lidén
2e7508c2b5 8248266: ZGC: TestUncommit.java fails due to "Exception: Uncommitted too fast" again
Reviewed-by: shade, eosterlund
2020-08-18 16:37:09 +02:00
Dong Bo
754006d60b 8251885: aarch64: aarch64-asmtest.py script generates unpredictable instructions
Reviewed-by: aph
2020-08-18 10:20:23 +08:00
Aleksey Shipilev
0bf69016b0 8251924: 32-bit build failures after JDK-8235765
Reviewed-by: dholmes
2020-08-18 12:46:33 +02:00
Daniel Fuchs
23edf8dbff 8251160: Fix "no comment" warnings in java.logging
Add missing documentation to the Serialized Form of Level and LogRecord.

Reviewed-by: lancea, mchung
2020-08-18 11:37:17 +01:00
Albert Mingkun Yang
354dcda373 8251463: Obsolete -XX:ForceNUMA option
Reviewed-by: kbarrett, sjohanss, lkorinth
2020-08-18 11:43:24 +02:00
Pavel Rappo
2388590911 8251550: Clean up jdk.javadoc and the related parts of jdk.compiler
Reviewed-by: jjg
2020-08-18 10:29:06 +01:00
Joe Darcy
607b761ff8 8071961: Add javac lint warning when a default constructor is created
Reviewed-by: jjg, jlahoda, abuckley, erikj, mcimadamore
2020-08-17 18:58:20 -07:00
Rajan Halade
9ddc381962 8251859: sun/security/validator/PKIXValAndRevCheckTests.java fails
Reviewed-by: jnimeh
2020-08-17 17:26:30 -07:00
Jesper Wilhelmsson
f44f50f284 Merge 2020-08-18 01:08:18 +02:00
Vicente Romero
b95e50aad1 8246804: Incorrect copyright header in TypeAnnotationParser.java
Reviewed-by: darcy, psandoz
2020-08-17 17:33:51 -04:00
Alexander Matveev
d812ec38a5 8250803: pkgbuild failed with exit code 134
Reviewed-by: herrick, asemenyuk
2020-08-17 13:41:22 -07:00
Calvin Cheung
c8a85b41a3 8247529: Crash in runtime/cds/appcds/dynamicArchive/LambdaProxyCallerIsHidden.java with Graal
Avoid inserting InstanceKlass into the DumpTimeSharedClassTable after dynamic CDS dumping has started. Acquire the DumpTimeTable_lock before iterations on _dumptime_table to ensure memory order correctness.

Reviewed-by: iklam, minqi
2020-08-17 18:46:38 +00:00
Andy Herrick
e20fe4a07e 8250611: Cannot display splash screen on Windows
Reviewed-by: asemenyuk, almatvee, prr
2020-08-17 11:59:36 -04:00
Coleen Phillimore
178c45c8db 8235765: Use of the long type should be avoided in shared code
Changed some long declarations to uint64_t/int64_t or unsigned int, depending on context.

Reviewed-by: lfoltan, kvn, dholmes
2020-08-17 10:08:36 -04:00
Stefan Karlsson
69a95c6741 8251837: Rename get_safepoint_workers to safepoint_workers
Reviewed-by: tschatzl
2020-08-17 11:36:09 +02:00
Patrick Concannon
1de354a056 7164518: No PortUnreachableException when connecting to a non-existing DatagramSocket (mac)
This fix changes the test to run with the new impl of DatagramSocket, which remedies the issue that caused the test to fail with a wrong expection and can now be taken off the ProblemList.

Reviewed-by: dfuchs
2020-08-17 10:36:20 +01:00
Stefan Karlsson
8d2f237d2f 8251835: JDK-8251374 breaks jmap -dump:all
Reviewed-by: phh, sspitsyn
2020-08-17 11:34:49 +02:00
Stefan Karlsson
444ace6221 8251570: JDK-8215624 causes assert(worker_id <' _n_workers) failed: Invalid worker_id
Reviewed-by: kbarrett, sjohanss
2020-08-17 11:32:26 +02:00
Stefan Karlsson
cfc0f227aa 8233281: Obsolete UseSemaphoreGCThreadsSynchronization
Reviewed-by: tschatzl, kbarrett, ayang
2020-08-17 11:30:09 +02:00
Thomas Schatzl
0080bb63c5 8245721: Refactor the TaskTerminator
Improve the structure of the TaskTerminator code to make it more understandable and amenable to improvements.

Reviewed-by: zgu, kbarrett, lkorinth
2020-08-17 11:23:54 +02:00
Martin Doerr
7ff77a54c3 8251846: Replace __linux which is no longer defined
Reviewed-by: dholmes, goetz
2020-08-17 10:40:46 +02:00
Nick Gasson
203ab1b07c 8251517: [TESTBUG] com/sun/net/httpserver/bugs/B6393710.java does not scale socket timeout
Reviewed-by: dfuchs
2020-08-14 18:08:30 +08:00
Ioi Lam
397ce2de6a 8251559: Remove empty file utilities/sizes.cpp
Reviewed-by: ccheung, dholmes
2020-08-15 18:13:49 -07:00
Daniel D. Daugherty
65de2224b4 8251543: add mention of INFLATING() to share/oops/markWord.hpp header comment
Reviewed-by: kbarrett
2020-08-15 16:02:29 -04:00
duke
0a126f157e Automatic merge of client:master into master 2020-08-09 09:04:18 +00:00
Pankaj Bansal
13c2eac172 8247753: UIManager.getSytemLookAndFeelClassName() returns wrong value on Fedora 32
Reviewed-by: prr, psadhukhan
2020-08-09 14:30:02 +05:30
Nick Gasson
3ef68753a4 8247354: [aarch64] PopFrame causes assert(oopDesc::is_oop(obj)) failed: not an oop
Reviewed-by: adinn
2020-08-07 14:10:55 +08:00
Ioi Lam
eb0aaef256 8250990: Consolidate object copying code for CDS static/dynamic archive dumping
Reviewed-by: coleenp, ccheung
2020-08-13 18:40:51 -07:00
Lin Zang
6521b6f6d6 8251374: jmap -dump could accept invalid options
Emit usage(1) in dump() argument loop

Reviewed-by: sspitsyn, phh
2020-08-13 13:57:12 -07:00
Daniel D. Daugherty
93e5c3acf5 Merge 2020-08-13 15:42:21 -04:00
Xue-Lei Andrew Fan
83dc820d83 8250839: Improve test template SSLEngineTemplate with SSLContextTemplate
Reviewed-by: ascarpino
2020-08-13 12:31:12 -07:00
Lin Zang
53f926a063 8215624: Add parallel heap iteration for jmap –histo
Chunk and parallelize the heap scan

Reviewed-by: sspitsyn, stefank, phh
2020-08-13 11:31:37 -07:00
Paul Hohensee
1fc2faadee 8215624: Add parallel heap iteration for jmap –histo
Chunk and parallelize the heap scan

Reviewed-by: sspitsyn, stefank, phh
2020-08-13 11:31:37 -07:00
Igor Ignatyev
146169b8e3 8251526: CTW fails to build after JDK-8251121
Reviewed-by: shade
2020-08-13 10:33:51 -07:00
Rahul Yadav
10213a152f 8249773: Upgrade ReceiveISA.java test to be resilient to failure due to stray packets and interference
This fix upgrades java/nio/channels/DatagramChannel/ReceiveISA.java so it can handle interference from stray packets.

Reviewed-by: alanb, dfuchs
2020-08-13 17:48:15 +01:00
Brian Burkhalter
8efe76838c 8245304: Re-examine ThreadLocal usage in java.math.BigDecimal
Reviewed-by: darcy, alanb
2020-08-13 09:33:28 -07:00
Patricio Chilano Mateo
8a37ddf992 8251118: BiasedLocking::preserve_marks should not have a HandleMark
Removed HandleMark from BiasedLocking::preserve_marks() method

Reviewed-by: hseigel, coleenp, dcubed, tschatzl, dholmes
2020-08-13 15:42:41 +00:00
Magnus Ihse Bursie
2ec9c6f236 8251516: VSCode IDE configuration specifies c++03
Reviewed-by: erikj
2020-08-13 17:34:31 +02:00
Magnus Ihse Bursie
11e1028122 8251533: MacOS build of libjimage explicitly adds C++ standard library
Reviewed-by: erikj
2020-08-13 17:10:48 +02:00
Patrick Concannon
919f276985 8240901: Add a test to check that large datagrams are sent/received on the network correctly
This fix updates `java/net/DatagramSocket/SendReceiveMaxSize.java` and `java/net/DatagramSocket/SendReceiveMaxSize.java` to check (on all platforms) that the sending/receiving of large datagrams across a network are sent, fragmented, and re-assembled correctly

Reviewed-by: alanb, dfuchs
2020-08-13 15:40:13 +01:00
Kim Barrett
c716ccfa98 8250597: G1: Improve inlining around trim_queue
Refactor, using NOINLINE and (new) ATTRIBUTE_FLATTEN for control.

Reviewed-by: tschatzl, sjohanss
2020-08-13 10:02:35 -04:00
Tobias Hartmann
99aa00b4f9 8251458: Parse::do_lookupswitch fails with "assert(_cnt >= 0) failed"
Limit the counter value to max_jint.

Reviewed-by: kvn, vlivanov, chagedorn
2020-08-13 16:01:45 +02:00
Tobias Hartmann
cd26a39135 8251456: [TESTBUG] compiler/vectorization/TestVectorsNotSavedAtSafepoint.java failed OutOfMemoryError
Removed allocation of large arrays to avoid OOME.

Reviewed-by: kvn, chagedorn
2020-08-13 15:59:12 +02:00
duke
f21835aff6 Automatic merge of client:master into master 2020-08-07 03:57:30 +00:00
duke
94a969e5d4 Automatic merge of client:master into master 2020-08-07 03:55:29 +00:00
Prasanta Sadhukhan
a13a2aa9fd 8249838: javax.swing.JLayeredPane has used valueOf twice in example code in documentation
Reviewed-by: jdv, pbansal
2020-08-07 09:23:54 +05:30
Prasanta Sadhukhan
f275a8b63a 8251187: Mark BasicComboNPE regression test as headful
Reviewed-by: prr
2020-08-07 09:21:46 +05:30
duke
6fa9578e99 Automatic merge of client:master into master 2020-08-06 16:44:20 +00:00
Phil Race
e61611f084 8240487: Cleanup whitespace in .cc, .hh, .m, and .mm files
Reviewed-by: serb, kizune, kcr, cjplummer
2020-08-06 09:43:10 -07:00
Alexey Ushakov
454407b58e 8249659: [Lanai] Crash while running RenderPerfTest with metal pipeli… 2020-08-06 15:39:16 +00:00
Mandy Chung
fb44e873b8 8250929: Missing "classpath exception" in LambdaProxyClassArchive.java
Reviewed-by: sundar
2020-08-05 13:24:53 -07:00
Leonid Mesnik
5991dbb379 8244537: JDI tests fail due to "ERROR: Exception : nsk.share.jdi.JDITestRuntimeException: JDITestRuntimeException : ** event IS NOT a breakpoint **"
Reviewed-by: sspitsyn, amenkov
2020-08-05 10:48:55 -07:00
Igor Ignatyev
d94a7c401a 8251190: nsk jdi tests failing "TestBug: Exception during config file parsing: java.io.FileNotFoundException"
Reviewed-by: dholmes, sspitsyn
2020-08-05 08:57:21 -07:00
duke
69ed4f9804 Automatic merge of client:master into master 2020-08-05 12:22:43 +00:00
Prasanta Sadhukhan
5e053c9458 6709913: BasicComboBoxUI.isPopupVisible returns NullPointerException
Reviewed-by: serb
2020-08-05 17:49:11 +05:30
Ajit Ghaisas
47f6e1bd6b 8251167: Drawing polyline twice in XOR mode leaves out some traces on screen (only with uiScale=1.0) 2020-08-05 11:33:32 +00:00
Galder Zamarreno
2144fcc400 8248158: Configure fails with autoconf not found even though it's installed
Reviewed-by: erikj, ihse, stooke
2020-08-05 11:59:10 +02:00
Coleen Phillimore
f9e00a2600 8235573: Move JFR ObjectSample oop into OopStorage
Reviewed-by: mgronlun, dholmes, kbarrett
2020-08-05 10:25:49 -04:00
Harold Seigel
ceb4ae8e07 8139875: [TESTBUG] Improve nsk/stress/stack/* tests
Use -Xss200k to limit the stack size, avoid running with -Xcomp, and, in one test, reduce iterations.

Reviewed-by: dholmes, lfoltan
2020-08-05 13:27:43 +00:00
Boris Ulasevich
5e9aeb3ae3 8248445: Use of AbsI/AbsL nodes should be limited to supported platforms
Reviewed-by: kvn, vlivanov
2020-08-05 06:31:32 -04:00
duke
108d17432c Automatic merge of client:master into master 2020-08-05 09:55:09 +00:00
Alexander Zuev
e9654634bf 8212226: SurfaceManager throws "Invalid Image variant" for MultiResolutionImage (Windows)
Reviewed-by: serb
2020-08-05 12:52:33 +03:00
Joe Darcy
c3c969d58d 8250920: Increase @jls usage in core reflection
Reviewed-by: mchung
2020-08-04 20:31:57 -07:00
Igor Ignatyev
ac1f04f2cd 8249030: clean up FileInstaller $test.src $cwd in vmTestbase_nsk_jdi tests
Reviewed-by: dholmes, sspitsyn
2020-08-04 20:05:47 -07:00
Igor Ignatyev
88265996ea 8251128: remove vmTestbase/vm/compiler/jbe/combine
Reviewed-by: kvn
2020-08-04 20:04:47 -07:00
Jie Fu
26d736db49 8251031: Some vmTestbase/nsk/monitoring/RuntimeMXBean tests fail with hostnames starting from digits
Reviewed-by: dholmes, cjplummer, sspitsyn
2020-08-05 10:54:18 +08:00
David Holmes
d523e838cd 8248906: runtime/Thread/ThreadObjAccessAtExit.java fails due to OutOfMemoryErrors
Reviewed-by: mdoerr
2020-08-04 21:11:45 -04:00
Alexander Matveev
fb8ea97df3 8250646: hdiutil detach fix JDK-8245311 still fails sometimes
Reviewed-by: herrick, asemenyuk
2020-08-04 17:47:51 -07:00
Yasumasa Suenaga
96fdc0ed0d 8250826: jhsdb does not work with coredump which comes from Substrate VM
Reviewed-by: cjplummer, sspitsyn
2020-08-05 09:24:02 +09:00
Chris Plummer
51a9431735 8247516: DSO.closestSymbolToPC() should use dbg.lookup() rather than rely on java ELF file support
Reviewed-by: sspitsyn, ysuenaga
2020-08-04 13:58:11 -07:00
Zdenek Zambersky
16075ea255 8251117: Cannot check P11Key size in P11Cipher and P11AEADCipher
Reviewed-by: valeriep
2020-08-04 17:19:21 -03:00
Charlie Gracie
88297c1316 8251361: Potential race between Logger configuration and GCs in HttpURLConWithProxy test
Keep a static reference to the logger to prevent its inadvertent garbage collection while the test is running.

Reviewed-by: dfuchs
2020-08-10 19:21:50 +01:00
Brian Burkhalter
b09b36acac Merge 2020-08-10 10:32:27 -07:00
Brian Burkhalter
18f53dcfe3 8251017: java/io/File/GetXSpace.java fails on UNIX
Reviewed-by: naoto
2020-08-10 10:25:17 -07:00
Joe Wang
f0f26043a6 8246816: XMLGregorianCalendar.hashCode() produces far too many identical hashes
Reviewed-by: naoto, rriggs
2020-08-10 17:16:56 +00:00
Brian Burkhalter
da8bffffaf 8249703: test/jdk/java/io/File/GetXSpace.java fails on macos
Reviewed-by: naoto
2020-08-10 09:54:34 -07:00
Tagir F. Valeev
6a66ac34e9 8247605: Avoid array allocation when concatenating with empty string
Reviewed-by: redestad, plevart
2020-08-10 16:14:03 +00:00
Rahul Yadav
bdac412f01 8248006: Revisit exceptions thrown when creating an HttpClient fails due to unavailability of underlying resources
This fix updates jdk.internal.net.http.HttpClientImpl to throw an UncheckedIOException instead of InternalError.

Reviewed-by: chegar, dfuchs
2020-08-10 15:15:10 +01:00
Kim Barrett
785aa0f844 8251322: Improve BitMap::iterate
Rewrite and inline BitMap::iterate.

Reviewed-by: stuefe, dholmes, tschatzl
2020-08-10 10:54:56 -04:00
Thomas Stuefe
fc913d485d 8251255: [linux] Add process-memory information to hs-err and VM.info
Reviewed-by: dholmes, mdoerr
2020-08-10 15:42:20 +02:00
Nikola Grcevski
ff76801f48 8250521: Configure initial RTO to use minimal retry for loopback connections on Windows
Reviewed-by: alanb
2020-08-10 12:57:38 +01:00
Charlie Gracie
14bc361d40 8251303: C2: remove unused _site_invoke_ratio and related code from InlineTree
Reviewed-by: vlivanov, thartmann
2020-08-10 12:12:40 +03:00
Dmitry Cherepanov
1408a8f868 8250636: iso8601_time returns incorrect offset part on MacOS
Reviewed-by: dholmes, gziemski
2020-08-10 11:25:38 +03:00
Charlie Gracie
bfbfd928c7 8241574: Shenandoah: remove ShenandoahAssertToSpaceClosure
Reviewed-by: zgu, bmathiske, shade
2020-08-10 08:37:05 +02:00
Nikola Grcevski
a80a39eb9d 8241007: Shenandoah: remove ShenandoahCriticalControlThreadPriority support
Reviewed-by: adityam, shade
2020-08-10 08:36:56 +02:00
Tobias Hartmann
a98c638ae7 8249608: Vector register used by C2 compiled method corrupted at safepoint
Always update 'max_vlen_in_bytes'.

Reviewed-by: kvn, vlivanov, chagedorn
2020-08-10 08:21:14 +02:00
Ioi Lam
b4c17693a5 8251213: [TESTBUG] CDS tests shouldn't write output files into test.classes directory
Reviewed-by: minqi, ccheung
2020-08-09 20:56:04 -07:00
Chris Plummer
3dc1bed616 8241951: SA core file tests failed to find core file for signed binaries on OSX 10.15
Reviewed-by: amenkov, dcubed
2020-08-09 19:38:51 -07:00
Thomas Stuefe
4a21d0da38 8251257: NMT: jcmd VM.native_memory scale=1 crashes target VM
Reviewed-by: zgu, dholmes
2020-08-09 09:20:02 +02:00
Abdul Kolarkunnu
dcb4a8d1d9 8248745: Add jarsigner and keytool tests for restricted algorithms
Reviewed-by: mullan, hchao
2020-08-08 20:29:27 -07:00
Jatin Bhateja
67f5341ffe 8248830: C2: Optimize Rotate API on x86
Improved existing scalar rotate operations, added support for vector rotate operations using new AVX512 instructions.

Reviewed-by: vlivanov, kvn
2020-08-09 02:03:09 +05:30
Alexander Matveev
1159a67509 8248905: [macos] symbolic links not properly resolved
Reviewed-by: herrick, asemenyuk
2020-08-07 19:04:45 -07:00
Vladimir Kozlov
9ec75c9079 8250233: -XX:+CITime triggers guarantee(events != NULL) in jvmci.cpp:173
Add missing EnableJVMCI flag check. Refactoring compiler print statistic code.

Reviewed-by: thartmann
2020-08-04 13:16:45 -07:00
duke
d95ea12a06 Automatic merge of client:master into master 2020-08-04 19:28:59 +00:00
Phil Race
913a12b7be 8250894: Provide a configure option to build and run against the platform libharfbuzz
Reviewed-by: erikj
2020-08-04 12:20:37 -07:00
Calvin Cheung
c935976db5 8249586: Test runtime/cds/appcds/DirClasspathTest.java will fail if run twice
Add the StandardCopyOption.REPLACE_EXISTING option when calling Files.copy().

Reviewed-by: iklam
2020-08-04 19:17:31 +00:00
Mandy Chung
41a8bfdc49 8250219: Proxy::newProxyInstance spec should specify the behavior if a given proxy interface is hidden
Reviewed-by: alanb
2020-08-04 10:36:02 -07:00
Mandy Chung
4de9999ecc 8022795: Method.isVarargs of dynamic proxy generated method to match the proxy interface method
Reviewed-by: rriggs, darcy
2020-08-04 10:26:39 -07:00
Kim Barrett
37fb43c89e 8250652: Add logical operations on types
Add stand-ins for C++17 logical operations on types.

Reviewed-by: eosterlund, tschatzl
2020-08-04 04:19:23 -04:00
Yasumasa Suenaga
52ac1c355e 8250930: [TESTBUG] Some forceEarlyReturn00* tests failed due to compiler optimization
Reviewed-by: cjplummer, dholmes
2020-08-04 15:28:27 +09:00
Mikael Vidstedt
06d0c923f1 8250899: Backout JDK-8249628 from jdk/jdk
Reviewed-by: erikj
2020-08-03 22:10:31 -07:00
Mikael Vidstedt
512946734d Merge 2020-08-03 22:08:37 -07:00
Mikael Vidstedt
8f1bc47a89 Merge 2020-08-03 21:56:35 -07:00
Mikhailo Seledtsov
a9268c7cc0 8250986: Problem list docker/TestMemoryAwareness.java and docker/TestDockerMemoryMetrics.java for linux-5.4.0-1019-oracle
Problem listed the tests

Reviewed-by: dholmes
2020-08-03 18:58:53 -07:00
Chris Plummer
92b4f568f6 8250750: JDK-8247515 fix for OSX pc_to_symbol() lookup fails with some symbols
8249150: SA core file tests sometimes time out on OSX with "java.io.IOException: App waiting timeout"

Reviewed-by: sspitsyn, amenkov
2020-08-03 17:38:22 -07:00
Chris Plummer
fb600ad773 8250750: JDK-8247515 fix for OSX pc_to_symbol() lookup fails with some symbols
Reviewed-by: sspitsyn, kevinw
2020-08-03 16:11:41 -07:00
Alexey Ushakov
18c3a1eaae 8250809: [Lanai] Netbeans crashes with fix of JDK-8249659 - also - R… 2020-08-03 18:45:08 +00:00
Rajan Halade
3b5c80a702 8243320: Add SSL root certificates to Oracle Root CA program
Reviewed-by: mullan
2020-08-03 11:35:24 -07:00
Albert Mingkun Yang
a9647c5185 8250628: ZGC: fixup_partial_loads was removed, but still are referenced
Reviewed-by: eosterlund, kbarrett, lkorinth
2020-08-03 14:01:00 +02:00
duke
a406428fe8 Automatic merge of client:master into master 2020-08-03 12:00:51 +00:00
Jayathirth D V
5382177581 8243674: Remove language tag length limit for iTXt chunk in PNGImageReader
Reviewed-by: prr, serb
2020-08-03 17:27:05 +05:30
Ajit Ghaisas
9cf06e4092 8233226: Implement XOR Mode rendering option 2020-08-03 09:47:55 +00:00
Christian Hagedorn
0a4ddac117 8249605: C2: assert(no_dead_loop) failed: dead loop detected
Fixed dead loop detection in PhiNode::Ideal() to additionally account for dead MergeMemNodes

Reviewed-by: kvn, thartmann
2020-08-03 09:21:45 +02:00
duke
bd424852bd Automatic merge of client:master into master 2020-08-03 06:34:12 +00:00
Yasumasa Suenaga
889b463d2b 8249215: JFrame::setVisible crashed with -Dfile.encoding=UTF-8 on Japanese Windows
Reviewed-by: prr, serb
2020-08-03 15:29:48 +09:00
Monica Beckwith
5a8c995a37 8250824: AArch64: follow up for JDK-8248414
The original change missed to update an assert.

Co-authored-by: Ludovic Henry <luhenry@microsoft.com>
Co-authored-by: Bernhard Urban-Forster <beurba@microsoft.com>
Reviewed-by: dholmes
2020-08-03 00:16:49 -04:00
Aleksey Shipilev
995c35c81c 8250844: Make sure {type,obj}ArrayOopDesc accessors check the bounds
Reviewed-by: rrich, coleenp
2020-08-02 16:58:14 +02:00
Thomas Stuefe
f951fa8b3a 8250911: [windows] os::pd_map_memory() error detection broken
Reviewed-by: iklam, kbarrett
2020-08-02 09:54:33 +02:00
duke
5880ed7c11 Automatic merge of client:master into master 2020-08-02 05:15:15 +00:00
Prasanta Sadhukhan
694387943c Merge 2020-08-02 10:34:21 +05:30
Robert Field
eaade7b5f7 8249566: jshell tool: retained modes from JDK-13 or prior cause confusing messages to be generated for records
Reviewed-by: jlahoda
2020-08-01 14:18:06 -07:00
duke
9effb06c24 Automatic merge of client:master into master 2020-08-01 12:30:20 +00:00
Prasanta Sadhukhan
9e2a80fe9d Merge 2020-08-01 17:54:03 +05:30
Chihiro Ito
866c67c3bc 8250818: idea.sh script doesn't work on WSL 1 and 2
Reviewed-by: erikj
2020-08-01 20:25:02 +09:00
denis.konoplev
b9e0d7cdb1 8247564: Lanai - SwingSet2 - Motif L&F - UI controls border is incorrectly drawn with uiScale=1.0
Reviewed-by: aghaisas
2020-07-31 12:21:29 +00:00
denis.konoplev
b01b4ed2d9 8244402: Lanai - Motif L&F - Non selected Radio button is barely rendered on non-retina display
Reviewed-by: aghaisas
2020-07-31 12:06:15 +00:00
denis.konoplev
7954d97230 8248831: Lanai : SwingSet2Demo Input dialog is not proper for MetalLookAndFeel with default non-retina display
Reviewed-by: aghaisas
2020-07-31 11:54:31 +00:00
Jie Fu
044a3c519b 8250825: C2 crashes with assert(field != __null) failed: missing field
Reviewed-by: kvn, thartmann
2020-07-31 17:10:46 +08:00
Xin Liu
911e038572 8249809: avoid calling DirectiveSet::clone(this) in compilecommand_compatibility_init
Add DirectiveSet smart pointer to isolate cloning

Reviewed-by: simonis, thartmann
2020-07-31 11:35:25 -07:00
Joe Wang
309917ce65 8250638: Address reliance on default constructors in java.xml
Reviewed-by: darcy, lancea
2020-07-31 18:25:12 +00:00
Patrick Concannon
e2294c1ced 8250889: Disable testing SendReceiveMaxSize with preferIPv4Stack=true on the old impl until JDK-8250886 is fixed
The `test java/net/DatagramSocket/SendReceiveMaxSize` is currently failing when run with `-Djdk.net.usePlainDatagramSocketImpl` and `-Djava.net.preferIPv4Stack=true`. This fix removes these run settings from the test until a more permanent solution can be found.

Reviewed-by: dfuchs
2020-07-31 18:59:27 +01:00
Vicente Romero
2622e560b2 8250629: do not allow C-style array declaration in record components
Reviewed-by: jlahoda
2020-07-31 12:13:52 -04:00
Naoto Sato
314ce0bba0 8233048: WeekFields.ISO is not a singleton
Reviewed-by: joehw, rriggs, scolebourne
2020-07-31 09:09:53 -07:00
Vicente Romero
eaf32de573 8250741: an annotation interface may not be declared as a local interface
Reviewed-by: jlahoda
2020-07-31 12:05:55 -04:00
Patrick Concannon
07dbd94b3c 8242885: PlainDatagramSocketImpl doesn’t allow for the sending of IPv6 datagrams on macOS with sizes between 65508-65527 bytes
This fix changes the current max size for IPv6 datagrams on macOS from it's current size of 65507, which is the IPv4 limit, to 65527, the actual limit for IPv6 on macOS

Reviewed-by: alanb, dfuchs, vtewari
2020-07-31 12:42:32 +01:00
Patrick Concannon
dd8931d54d 8246164: SendDatagramToBadAddress.java and ChangingAddress.java should be changed to explicitly require the new DatagramSocket implementation
This fix updates these tests to explicitly run with `-Djdk.net.usePlainDatagramSocketImpl=false` to avoid false failures when running all tests with a global jtreg -Djdk.net.usePlainDatagramSocketImpl switch.

Reviewed-by: vtewari
2020-07-31 12:12:49 +01:00
Hannes Wallnöfer
285a279a8c 8241518: Member signature parameter span contains closing but not opening parens
Reviewed-by: prappo
2020-07-31 12:09:59 +02:00
duke
21b06954b7 Automatic merge of client:master into master 2020-07-31 08:01:17 +00:00
Pankaj Bansal
954e32d27b 8233635: [TESTBUG] ProgressMonitorEscapeKeyPress.java fails on macos
Reviewed-by: psadhukhan
2020-07-31 13:25:15 +05:30
Richard Reingruber
cc53f8a628 8249293: Unsafe stackwalk in VM_GetOrSetLocal::doit_prologue()
Reviewed-by: sspitsyn, dholmes
2020-07-31 09:07:29 +02:00
Kim Barrett
19df711dc9 8251850: Refactor ResourceMark and DeoptResourceMark for better code sharing
Move saved state to ResourceArea, merge most of marks into shared helper.

Reviewed-by: stuefe, iklam, tschatzl, xliu, vlivanov
2020-08-25 22:17:04 -04:00
Vladimir Kozlov
9f421d031b 8252331: JDK-8252058 is causing failures in Tier1
Added Graal changes which were missing in 8252058 push.

Reviewed-by: dcubed
2020-08-25 15:00:37 -07:00
Yudi Zheng
2815830965 8252058: [JVMCI] Rework setting is_method_handle_invoke flag in jvmciCodeInstaller
Reviewed-by: kvn, dlong
2020-08-25 22:23:08 +02:00
Roger Riggs
2c3738563e 8251203: Fix "no comment" warnings in java.base/java.lang and java/io
Reviewed-by: dfuchs, lancea, mchung, naoto
2020-08-25 10:20:14 -04:00
Jie Fu
5b186304ba 8251155: HostIdentifier fails to canonicalize hostnames starting with digits
Reviewed-by: sspitsyn, redestad
2020-08-05 15:07:25 +08:00
Andy Herrick
5bdf05590f 8251988: jpackage --runtime-image fails on mac when using JDK11 based runtime
Reviewed-by: asemenyuk, almatvee, prr
2020-08-25 07:54:59 -04:00
Vipin Sharma
bb354b9dd1 8251542: Several small Javadoc errors in java.base
Fixing wrong exception type in throws clause and wrong return type description

Reviewed-by: darcy, dfuchs, mullan, mchung, rriggs
2020-08-25 09:27:36 +01:00
Jose Ziviani
c3296c4698 8248190: Enable Power10 system and implement new byte-reverse instructions
Reviewed-by: mdoerr, stuefe
2020-08-25 09:01:54 +09:00
Lin Zang
7d0afd2b26 8252101: Add description of expected behavior of using "live" and "all" options together for jmap
Update description

Reviewed-by: dcubed, sspitsyn, phh
2020-08-24 13:48:17 -07:00
Lin Zang
8bb092be76 8251848: JMap.histo() and JMap.dump() should parse sub-arguments similarly
Update JMap histo/dump parsing code

Reviewed-by: sspitsyn, phh
2020-08-24 13:47:33 -07:00
Igor Ignatyev
77f82b3298 8252186: remove FileInstaller action from vmTestbase/jit/graph tests
Reviewed-by: kvn
2020-08-24 13:23:34 -07:00
Attila Szegedi
83a7a649a2 8252124: Restore Dynalink tests
Reviewed-by: sundar
2020-08-23 14:58:59 +02:00
Ioi Lam
1d65cbd155 8252056: Move DumpRegion/ReadClosure/WriteClosure to archiveUtils.hpp
Reviewed-by: ccheung, minqi
2020-08-22 17:09:41 -07:00
Yumin Qi
3a78fa5adb 8249096: Clean up code for DumpLoadedClassList
Clean up code for DumpLoadedClassList output code, centralize in InstanceKlass.

Reviewed-by: iklam, dcubed
2020-08-21 22:23:12 -07:00
Igor Ignatyev
e4cc944428 6501010: test/java/io/File/GetXSpace.java fails on Windows
Reviewed-by: bpb
2020-07-30 19:39:44 -07:00
duke
cb7bd4b0fb Automatic merge of client:master into master 2020-07-31 01:13:10 +00:00
Koichi Sakata
61db079ef1 8250863: Build error with GCC 10 in NetworkInterface.c and k_standard.c
Reviewed-by: aph, ysuenaga
2020-07-31 09:15:57 +09:00
Sergey Bylokhov
d2a9c11d6b 8250755: Better cleanup for jdk/test/javax/imageio/plugins/shared/CanWriteSequence.java
Reviewed-by: jdv
2020-07-31 00:19:42 +01:00
Brian Burkhalter
31795ff972 8249772: (ch) Improve sun/nio/ch/TestMaxCachedBufferSize.java
Reviewed-by: alanb
2020-07-30 15:06:29 -07:00
Ajit Ghaisas
fe28c1d4b1 8250843: [Lanai] Back out changes done in JDK-8250778 2020-07-30 19:05:31 +00:00
Hannes Wallnöfer
5f10fe3baa 8250779: Anchor is ignored when reloading a page in Chrome
Reviewed-by: prappo
2020-07-30 16:53:56 +02:00
Coleen Phillimore
5709133f80 8249837: Avoid direct or implicit Thread::current() calls when we already have a current thread variable
Add current thread OR remove unneeded HandleMark

Reviewed-by: kvn, dholmes
2020-07-30 10:41:31 -04:00
Bernhard Urban
73bcb5c2c1 8248816: C1: Fix signature mismatch of LIRGenerator::strengh_reduce_multiply
Co-authored-by: Monica Beckwith <monica.beckwith@microsoft.com>
Co-authored-by: Ludovic Henry <luhenry@microsoft.com>
Reviewed-by: aph
2020-07-30 15:05:22 +02:00
David Holmes
03663eb45d 8251460: Fix the biased-locking code in ObjectSynchronizer::FastHashCode
Reviewed-by: coleenp, dcubed, pchilanomate
2020-08-13 00:20:42 -04:00
Mikael Vidstedt
733dde1645 Added tag jdk-16+11 for changeset 5c18d696c7ce 2020-08-12 20:23:40 -07:00
Coleen Phillimore
acc99a4a94 8251489: universe.cpp includes too many headers
Reviewed-by: lfoltan, stuefe
2020-08-12 12:37:16 -04:00
Alexey Semenyuk
17d32adccf 8232621: L10n issues with msi installers
Reviewed-by: herrick, almatvee
2020-08-12 11:38:30 -04:00
Alexander Scherbatiy
380dbb2c22 8241053: Hotspot runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java test fails on Alpine Linux with debug build
Reviewed-by: dholmes, stuefe, dsamersoff
2020-08-12 15:01:12 +03:00
Coleen Phillimore
973a3dc5d0 8251336: OopHandle release can not be called in a safepoint
Release OopStorage oops for threadObj for exiting threads outside the service lock region that is marked as safe for safepoint.

Reviewed-by: zgu, dholmes, kbarrett
2020-08-12 07:54:17 -04:00
Conor Cleary
74112916e6 8246707: (sc) SocketChannel.read/write throws AsynchronousCloseException on closed channel
This fix addresses an issue where an AsynchronousCloseException was being thrown instead of a ChannelClosedException when SocketChannel.write() is called on a closed SocketChannel.

Reviewed-by: alanb, chegar, dfuchs
2020-08-12 12:32:54 +01:00
Roman Kennke
19abdabf1a 8251451: Shenandoah: Remark ObjectSynchronizer roots with I-U
Reviewed-by: shade
2020-08-12 13:19:44 +02:00
Aleksei Efimov
429914b3b6 8251189: com/sun/jndi/ldap/LdapDnsProviderTest.java failed due to timeout
Reviewed-by: dfuchs, vtewari
2020-08-12 12:01:52 +01:00
Aleksei Efimov
b92ab434bc 8250772: Test com/sun/jndi/ldap/NamingExceptionMessageTest.java fails intermittently with javax.naming.ServiceUnavailableException
Reviewed-by: dfuchs
2020-08-12 11:45:18 +01:00
Christian Hagedorn
778a985cb8 8249603: C1: assert(has_error == false) failed: register allocation invalid
Added bailout in combine_spilled_intervals() to avoid an overlap between two intervals

Reviewed-by: kvn, thartmann
2020-08-12 08:45:44 +02:00
Ioi Lam
bb52380f07 8249276: CDS archived objects must have "neutral" markwords
Reviewed-by: coleenp, dholmes
2020-08-11 22:05:56 -07:00
Vladimir Kozlov
57f9c6180d 8251306: compiler/aot/cli/jaotc/IgnoreErrorsTest.java timed out on MacOS
Icrease test timout to 6 min

Reviewed-by: iignatyev
2020-08-11 19:44:40 -07:00
David Holmes
d5a602f8d0 8251383: Disable Event::log from linux_mprotect when processing the assertion poison page
Reviewed-by: stuefe, dcubed
2020-08-11 20:05:58 -04:00
Clive Verghese
7b3dbfd920 8251268: Move PhaseChaitin definitions from live.cpp to chaitin.cpp
Move PhaseChaitin verify_base_ptrs() and verify() from live.cpp to chaitin.cpp

Reviewed-by: chagedorn, kvn
2020-08-11 15:32:55 -07:00
Lance Andersen
6fb7cfc182 8251205: Add missing javadoc comments to ZipConstants.java
Reviewed-by: naoto, rriggs
2020-08-11 15:41:47 -04:00
Zhengyu Gu
e27e41c899 8251359: Shenandoah: filter null oops before calling enqueue/SATB barrier
Reviewed-by: shade
2020-08-11 14:41:52 -04:00
Ajit Ghaisas
a057120da3 8250778: [Lanai] Primitives rendered with metal on non-retina monitor are different as compared to OpenGL 2020-07-30 06:56:25 +00:00
Alexey Ushakov
a5c3460875 8249659: [Lanai] Crash while running RenderPerfTest with metal pipeli… 2020-07-29 12:17:05 +00:00
duke
74618f7a28 Automatic merge of client:master into master 2020-07-29 12:04:13 +00:00
Prasanta Sadhukhan
f38fb70374 8146451: javax/swing/JComponent/4337267/bug4337267.java failed on Windows
Reviewed-by: serb
2020-07-29 17:29:45 +05:30
duke
0fa3c6a1a7 Automatic merge of client:master into master 2020-07-28 06:42:09 +00:00
Prasanta Sadhukhan
7a904f3451 8169959: javax/swing/JTable/6263446/bug6263446.java: Table should be editing
Reviewed-by: serb
2020-07-28 12:07:20 +05:30
duke
b74b49287b Automatic merge of client:master into master 2020-07-28 06:35:13 +00:00
Prasanta Sadhukhan
08469dbd44 8246742: ServiceUI.printDialog does not support properties dialog
Reviewed-by: prr, jdv
2020-07-28 12:00:55 +05:30
Evgeny Nikitin
9c05f763db 8067651: LevelTransitionTest.java, fix trivial methods levels logic
Make test method really trivial, adjust trivial logic, make logic independent of background compilation.

Reviewed-by: iignatyev, thartmann, kvn
2020-07-27 21:17:44 +02:00
Raffaello Giulietti
68c479d257 8245036: DataInputStream.readFully(byte[], int, int) does not throw expected IndexOutOfBoundsExceptions
Reviewed-by: bpb
2020-08-07 12:58:40 -07:00
Patrick Concannon
61108f2409 8250886: java/net/DatagramSocket/SendReceiveMaxSize.java fails in timeout
SO_RCVBUF was previously set to match the SO_SNDBUF, however the kernel value for SO_RCVBUF is much larger. This mismatch caused the test to fail, and the fix removes this issue.

Reviewed-by: alanb, dfuchs
2020-08-07 20:39:10 +01:00
Thomas Schatzl
e05a51a009 8248401: Refactor/unify RMI gc support functionality
Move recent timestamp of most recent whole heap liveness analysis into CollectedHeap, removing the duplicates in all collectors

Reviewed-by: kbarrett, ayang, stefank
2020-08-07 19:23:53 +02:00
Vladimir Kozlov
ea873c5ea2 8251260: two MD5 tests fail "RuntimeException: Unexpected count of intrinsic"
Do not run intrinsics/sha/sanity tests with AOTed java.base

Reviewed-by: vlivanov
2020-08-07 10:16:19 -07:00
Andy Herrick
6f3d6865e8 8251184: File association without description causes exception
Reviewed-by: asemenyuk, almatvee
2020-08-07 11:42:42 -04:00
Daniel Fuchs
18fdf05076 8229822: ThrowingPushPromises tests sometimes fail due to EOF
SocketTube is fixed to cater for errors caused by pausing/resuming events on an asynchronously closed connection, from within the selector's manager thread. Http2Connection and Stream are fixed to prevent sending a DataFrame on a stream after Reset has been sent.

Reviewed-by: chegar
2020-08-07 16:16:45 +01:00
Daniel Fuchs
1b6f67134b 8249786: java/net/httpclient/websocket/PendingPingTextClose.java fails very infrequently
TransportImpl is modified to make sure the CLOSED state is recorded before the channel is closed. The tests are modified to enable their retry mechanism on windows, similar to what was done previously for macOS.

Reviewed-by: prappo, chegar
2020-08-07 15:09:19 +01:00
Coleen Phillimore
21b99411de 8244997: Convert the JavaThread::_threadObj oop to use OopStorage
Move the oop and handle releasing it in the service thread.  Remove Universe::oops_do from callers.

Co-authored-by: Erik Osterlund <erik.osterlund@oracle.com>
Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com>
Reviewed-by: dholmes, zgu, eosterlund, cjplummer
2020-08-07 07:53:26 -04:00
Markus Grönlund
b6d88a9023 8251179: Word tearing problem with _last_sweep
Reviewed-by: coleenp, dholmes, kbarrett
2020-08-07 11:52:09 +02:00
Dong Bo
853ad083f3 8165404: AArch64: Implement SHA512 accelerator/intrinsic
Reviewed-by: aph
2020-08-07 12:35:30 +08:00
Mikael Vidstedt
8703ff443a Added tag jdk-16+10 for changeset b01985b4f88f 2020-08-06 20:56:46 -07:00
Gabriel Reid
642343eb67 8250928: JFR: Improve hash algorithm for stack traces
Reviewed-by: egahlin
2020-08-07 04:21:57 +02:00
Leo Jiang
68c08afede 8250665: Wrong translation for the month name of May in ar_JO,LB,SY
Reviewed-by: naoto
2020-08-07 01:48:31 +00:00
Brian Burkhalter
2ddf1a1e35 Merge 2020-08-06 18:27:33 -07:00
Brian Burkhalter
8835dcb3ac 8251272: Typo in java.util.Formatter: "Numberic" should be "Numeric"
Reviewed-by: bchristi, naoto, jlaskey
2020-08-06 18:23:21 -07:00
Chris Plummer
19d757e310 8251121: six SA tests leave core files behind on macOS
Reviewed-by: dholmes, dcubed
2020-08-06 18:21:21 -07:00
David Holmes
813322264f 8250606: Remove unnecessary assertions in ObjectSynchronizer FastHashcode and inflate
Reviewed-by: dcubed, coleenp
2020-08-06 21:03:18 -04:00
Alex Menkov
9d4ccfbe5d 8249550: jdb should use loopback address when not using remote agent
Reviewed-by: cjplummer, sspitsyn
2020-08-06 15:59:47 -07:00
Leonid Mesnik
ff87ee097e 8161684: [testconf] Add VerifyOops' testing into compiler tiers
Reviewed-by: kvn
2020-08-06 13:29:15 -07:00
Chris Plummer
e7bad41a32 8248879: SA core file support on OSX has some bugs trying to locate the jvm libraries
Reviewed-by: sspitsyn, amenkov
2020-08-06 13:14:15 -07:00
Lois Foltan
d38172c84d 8247938: Change various JVM enums like LinkInfo::AccessCheck and Klass::DefaultsLookupMode to enum class
Use C++11 scoped enumeration declarations for several different Klass and LinkInfo enumerations.

Reviewed-by: coleenp, hseigel, kbarrett
2020-08-06 18:13:56 +00:00
Joe Darcy
c3464101c8 8249273: Documentation of BigInteger(String) constructor does not mention leading plus
Reviewed-by: bpb
2020-08-06 09:58:57 -07:00
Chihiro Ito
d70a42a510 8250912: Recording#copy() doesn't copy the flush interval
Reviewed-by: jbachorik
2020-08-06 23:47:55 +09:00
Zhengyu Gu
a6d931b27f 8251192: Shenandoah: Shenandoah build failed after JDK-8235573
Reviewed-by: stuefe, ysuenaga, adityam
2020-08-06 08:30:37 -04:00
Joe Darcy
8c4b228755 8250660: Clarify that WildcardType and AnnotatedWildcardType bounds methods return one
Reviewed-by: mchung, dholmes
2020-08-05 23:02:22 -07:00
Mikael Vidstedt
087dd7dfd0 Added tag jdk-16+9 for changeset c075a286cc7d 2020-08-05 19:05:05 -07:00
Igor Ignatyev
1e5d70b3d5 8251126: nsk.share.GoldChecker should read golden file from ${test.src}
Reviewed-by: dholmes
2020-08-05 16:39:38 -07:00
Igor Ignatyev
e635c5f1cf 8251132: make main classes public in vmTestbase/jit tests
Reviewed-by: kvn
2020-08-05 16:39:08 -07:00
Brian Burkhalter
6d6fd5faf0 8235792: LineNumberReader.getLineNumber() behavior is inconsistent with respect to EOF
Reviewed-by: alanb, darcy, rriggs
2020-08-05 11:40:07 -07:00
Ludovic Henry
cde65ccc84 8250902: Implement MD5 Intrinsics on x86
Reviewed-by: kvn, vdeshpande, ascarpino
2020-08-05 11:32:15 -07:00
duke
1969c3448d Automatic merge of client:master into master 2020-07-26 09:26:03 +00:00
Prasanta Sadhukhan
83e8d6a494 Merge 2020-07-26 14:46:36 +05:30
Joe Darcy
0d8db7a7af 8250583: Address reliance on default constructors in java.management
Reviewed-by: alanb
2020-07-25 12:49:09 -07:00
duke
c8292d3f15 Automatic merge of client:master into master 2020-07-25 07:25:10 +00:00
Prasanta Sadhukhan
49591370e1 Merge 2020-07-25 12:48:29 +05:30
Doug Simon
9a822e7e6c 8250548: libgraal can deadlock in -Xcomp mode
Reviewed-by: never, kvn
2020-07-25 08:41:51 +02:00
Aleksei Voitylov
95a0895f61 8248239: jpackage adds some arguments twice in case it is re-executed by JLI
Reviewed-by: herrick, almatvee
2020-07-24 19:54:01 -04:00
Joe Darcy
7addad25b6 8250578: Address reliance on default constructors in javax.sql
Reviewed-by: lancea
2020-07-25 09:46:08 -07:00
Joe Darcy
086c3bdd3d 8250244: Address reliance on default constructors in java.net
Reviewed-by: alanb, vtewari
2020-07-25 09:42:45 -07:00
Coleen Phillimore
850faa827b 8250519: [REDO] Move mirror oops from Universe into OopStorage
Redo the patch but add a null pointer check where one belongs.

Reviewed-by: dcubed, iklam, dholmes
2020-07-25 10:36:19 -04:00
Hai-May Chao
c6817d9881 8247960: jarsigner says "signer errors" for some normal warnings when -strict is set
8250586: jarsigner refactoring in displayMessagesAndResult() method

Reviewed-by: weijun
2020-07-25 16:40:10 +08:00
Alexander Matveev
01d9d3aaf1 8248248: [macos] EmptyFolderPackageTest.java fails EmptyFolderPackageTest-dmg-setup.scpt exited with 134 code
Reviewed-by: herrick, asemenyuk
2020-07-24 16:46:18 -07:00
Joe Darcy
7d98c22d37 8250246: Address reliance on default constructors in security libs
Reviewed-by: mullan
2020-07-24 13:49:38 -07:00
Harold Seigel
6dc6400a38 8250557: Rename vmTestbase/nsk shared timeout handler package to Terminator.java
Rename the class and fix the tests that use it.

Reviewed-by: dcubed
2020-07-24 18:44:27 +00:00
Yumin Qi
60bc0e1582 8249624: update appcds/sharedStrings/IncompatibleOptions test in view of 8081416 closed as WNF
With CDS can archive with compressed oops off, the result of the test gives correct information.

Reviewed-by: iklam, dholmes
2020-07-24 10:29:27 -07:00
Roger Riggs
7a4efdf1ec 8249217: Unexpected StackOverflowError in "process reaper" thread still happens
Reviewed-by: martin, plevart, dholmes
2020-07-24 11:00:50 -04:00
Coleen Phillimore
f9e530de24 Merge 2020-07-24 10:51:38 -04:00
Vicente Romero
73f3a6b948 8243057: compilation of annotated static record fields fails with NPE
Reviewed-by: jlahoda
2020-07-24 10:34:18 -04:00
Coleen Phillimore
f5520acde1 8250516: [BACKOUT] Move mirror oops from Universe into OopStorage
Reviewed-by: dholmes, tschatzl
2020-07-24 10:34:11 -04:00
Boris Ulasevich
925e9ac4d6 8249189: AARCH64: more L2I conversions can be skipped
Reviewed-by: aph
2020-07-24 09:07:10 -04:00
Harold Seigel
69eff78a8d 8222582: [TESTBUG] AbstractMethodErrorTest.java fails with "did not test both cases (interpreted and compiled)."
Exclude the test from running with Graal

Reviewed-by: dholmes, coleenp
2020-07-24 12:40:41 +00:00
Coleen Phillimore
4f32b8d075 8249938: Move mirror oops from Universe into OopStorage
Save and restore mirror oops to temporary array for CDS, and move them to OopStorage once restored.

Reviewed-by: iklam, dholmes
2020-07-24 08:32:27 -04:00
Boris Ulasevich
36eaf0011d 8248870: AARCH64: I2L/L2I conversions can be skipped for masked positive values
Reviewed-by: aph
2020-07-24 08:21:11 -04:00
Michael McMahon
d1cc002d96 Merge 2020-07-24 12:49:33 +01:00
Coleen Phillimore
c45b7bf5e4 8249822: SymbolPropertyTable creates an extra OopHandle per entry
Add an assert to OopHandle assigment operator to catch leaking OopHandles, and fix code accordingly.

Reviewed-by: sspitsyn, eosterlund, dholmes
2020-07-24 07:45:38 -04:00
Ajit Ghaisas
2122e5be4f 8240221: XOR mode rendering option does not work with Texture paint and Gradient Paint 2020-07-24 11:09:34 +00:00
Rahul Yadav
2ac547fa25 8245306: Update sun.security.ssl.SSLLogger to use Immutable DateTimeFormatter
The fix updates sun.security.ssl.SSLLogger to use DateTimeFormatter to make it virtual thread friendly

Reviewed-by: alanb, jnimeh
2020-07-24 12:07:59 +01:00
Kim Barrett
88d110b4a8 8249945: Improve ARRAY_SIZE()
Make ARRAY_SIZE type-safe.

Reviewed-by: tschatzl, lfoltan, dholmes
2020-07-24 05:07:37 -04:00
Monica Beckwith
40c1013ca6 8248668: AArch64: Avoid MIN/MAX macros when using MSVC
MSVC employs min/max as macros

Co-authored-by: Ludovic Henry <luhenry@microsoft.com>
Reviewed-by: tschatzl, kbarrett
2020-07-24 11:16:08 +02:00
Cesar Soares Lucas
eb448c2cf9 8249225: Move definition of PADDING_ELEM_NUM
Reviewed-by: tschatzl, kbarrett
2020-07-24 11:16:05 +02:00
Nick Gasson
edea0cf63f 8249781: AArch64: AOT compiled code crashes if C2 allocates r27
Reviewed-by: aph
2020-07-24 11:28:28 +08:00
Kim Barrett
64e30cf6b9 8249944: Move and improve the AllStatic class
Move AllStatic to it's own standalone file, and use C++11 deleted functions

Reviewed-by: dholmes, stuefe
2020-07-24 04:43:08 -04:00
Kim Barrett
974a943bc6 8247908: Replace IsRegisteredEnum with std::is_enum
Reviewed-by: tschatzl, dholmes
2020-07-24 04:29:34 -04:00
Joe Darcy
4217fd195e 8250240: Address use of default constructors in the java.util.concurrent
Reviewed-by: martin, lancea
2020-07-23 22:50:12 -07:00
David Holmes
2ee839a77b 8194309: JNI handle allocation failure not reported correctly
Reviewed-by: kbarrett, coleenp
2020-07-23 21:46:39 -04:00
Stuart Monteith
9875dddddd 8246373: AArch64: Refactor register spilling code in ZGC barriers
Tidy up code spilling registers, reduce in some cases.

Reviewed-by: aph, eosterlund
2020-07-24 09:00:40 +08:00
Joe Darcy
21d0b3f048 8250237: Address use of default constructors in the javax.script package
Reviewed-by: lancea, psandoz
2020-07-23 15:13:08 -07:00
Daniel D. Daugherty
ea28491041 8250236: ProblemList java/lang/invoke/lambda/LambdaFileEncodingSerialization.java on linux-x64
Reviewed-by: rriggs
2020-07-23 16:36:44 -04:00
Daniel Fuchs
6dc4ef7af1 8249812: java/net/DatagramSocket/PortUnreachable.java still fails intermittently with SocketTimeoutException
Fixed the test to reenable its retry logic

Reviewed-by: alanb
2020-07-23 20:25:41 +01:00
Thomas Schatzl
f12f0bf59c 8249192: MonitorInfo stores raw oops across safepoints
Change raw oops in MonitorInfo to Handles and update Resource/HandleMarks.

Reviewed-by: sspitsyn, dholmes, coleenp, dcubed
2020-07-23 21:10:52 +02:00
Joe Darcy
8b13aa24e8 8250221: Address use of default constructors in java.logging
Reviewed-by: lancea
2020-07-23 11:26:23 -07:00
Robert Field
f9327b3708 8249197: JShell: variable declaration with unicode type name gets garbled result
8249199: JShell: Consistent representation of unicode

Reviewed-by: jlahoda
2020-07-23 10:37:06 -07:00
Calvin Cheung
28f3f21fd6 8249630: unused is_static_archive parameter in SystemDictionaryShared::write_dictionary
Reviewed-by: minqi, dholmes
2020-07-23 16:52:08 +00:00
Aleksei Voitylov
78cac844c8 8247592: refactor test/jdk/tools/launcher/Test7029048.java
Reviewed-by: mchung
2020-07-23 09:43:55 -07:00
Naoto Sato
3629cd2661 8248655: Support supplementary characters in String case insensitive operations
8248434: some newly added locale cannot parse uppercased date string

Reviewed-by: jlaskey, joehw, rriggs, bchristi
2020-07-23 08:46:31 -07:00
Aleksey Shipilev
1a163bce48 8249953: Shenandoah: gc/shenandoah/mxbeans tests should account for corner cases
Reviewed-by: rkennke
2020-07-23 12:46:24 +02:00
Doug Simon
c8c4efa7cf 8249888: failure to create a libgraal JavaVM should result in a VM crash
Reviewed-by: never, kvn
2020-07-23 11:47:20 +02:00
Alexander Scherbatiy
b7b6c80016 8249612: Remove unused ISNANF and ISNAND from jdk_util_md.h
Reviewed-by: darcy
2020-07-23 11:39:56 +03:00
duke
3682655fa0 Automatic merge of client:master into master 2020-07-22 14:55:07 +00:00
Bernhard Urban-Forster
88d59e59f5 8248666: AArch64: Use THREAD_LOCAL instead of __thread
__thread is gcc-ism, instead rely on compiler independent macro.

Reviewed-by: dholmes
2020-07-22 15:03:50 +02:00
David Holmes
eaf4be06ba 8249940: Remove unnecessary includes of jni_util.h in native tests
Reviewed-by: iignatyev, mchung
2020-07-23 00:47:02 -04:00
Yasumasa Suenaga
2aea8cfda2 8249875: GCC 10 warnings -Wtype-limits with JFR code
Reviewed-by: mgronlun
2020-07-23 12:19:59 +09:00
Mikael Vidstedt
c21dc22dfd Merge 2020-07-22 19:45:45 -07:00
Mikael Vidstedt
45904370a8 Added tag jdk-16+7 for changeset c3a4a7ea7c30 2020-07-22 19:20:42 -07:00
Alexander Matveev
369d0527da 8245311: [macos] misc package tests failed due to "execution error: Finder got an error: AppleEvent timed out."
Reviewed-by: herrick, asemenyuk
2020-07-22 14:19:01 -07:00
Bob Vandette
2af788b883 8249880: JVMCI calling register_nmethod without CodeCache lock
Reviewed-by: eosterlund, kvn, never
2020-07-22 17:59:33 +00:00
Roman Kennke
9afc2f65c1 8249884: Shenandoah: Call report_num_dead() from ShParallelWeakRootsCleaningTask destructor
Reviewed-by: zgu
2020-07-22 17:08:01 +02:00
Coleen Phillimore
0ab11c2409 8249768: Move static oops and NullPointerException oops from Universe into OopStorage
Make NPE oops an objArrayOop.

Reviewed-by: dholmes, eosterlund
2020-07-22 10:32:44 -04:00
Raffaello Giulietti
fd2ca0b9b8 8222187: java.util.Base64.Decoder stream adds unexpected null bytes at the end
Reviewed-by: lancea, rriggs
2020-07-22 10:01:03 -04:00
Roman Kennke
1a1367b701 8249877: Shenandoah: Report number of dead weak oops during STW weak roots
Reviewed-by: zgu
2020-07-22 15:16:57 +02:00
Christian Hagedorn
15c059f0aa 8247743: Segmentation fault in debug builds due to stack overflow in find_recur with deep graphs
Replace the recursive algorithm of Node::find() by an iterative one to avoid a stack overflow crash with deep graphs.

Reviewed-by: kvn, thartmann
2020-07-22 10:31:37 +02:00
Christian Hagedorn
436cd605a6 8248467: C2: compiler/intrinsics/object/TestClone fails with -XX:+VerifyGraphEdges
Fix assert by taking MemBarNodes into account whose precedence edge can be NULL.

Reviewed-by: kvn, thartmann
2020-07-22 10:28:34 +02:00
duke
bbef2df66d Automatic merge of client:master into master 2020-07-22 06:45:11 +00:00
David Holmes
7891649b57 8249650: Optimize JNIHandle::make_local thread variable usage
Reviewed-by: kbarrett, dcubed, kvn, coleenp, sspitsyn
2020-07-22 01:27:08 -04:00
Kim Barrett
3bca569234 8246032: Implementation of JEP 347: Enable C++14 Language Features
Update build configuration to use C++14

Reviewed-by: jlaskey, mdoerr, ihse, erikj
2020-07-22 00:13:53 -04:00
duke
d80efd8ad9 Automatic merge of client:master into master 2020-07-21 21:30:21 +00:00
duke
a361daf0b1 Automatic merge of client:master into master 2020-07-21 20:22:12 +00:00
Bernhard Urban-Forster
214aef51ee 8248671: AArch64: Remove unused variables
Remove unused variables in the AArch64 backend. Detected by compiling with MSVC, which warns about them.

Reviewed-by: aph, dholmes
2020-07-21 10:32:52 -04:00
duke
e5edd0c32e Automatic merge of client:master into master 2020-07-20 15:21:10 +00:00
duke
597016b5ad Automatic merge of client:master into master 2020-07-19 18:11:09 +00:00
Alexey Ushakov
091d6a5f8f 8247556: Lanai : J2DDemo - ImageOps demo - Few options are not workin… 2020-07-18 16:40:36 +00:00
duke
a2fcc2aba9 Automatic merge of client:master into master 2020-07-18 06:45:31 +00:00
duke
0485b4e34b Automatic merge of client:master into master 2020-07-18 06:43:31 +00:00
duke
7c5db51dcd Automatic merge of client:master into master 2020-07-17 17:09:08 +00:00
Prasanta Sadhukhan
a0d86b77e6 8247831: Clamp texture height to maxTextureSize(16384) 2020-07-17 06:43:36 +00:00
duke
01159e7339 Automatic merge of client:master into master 2020-07-15 23:22:30 +00:00
duke
ea9ce2f7d7 Automatic merge of client:master into master 2020-07-15 15:08:35 +00:00
duke
42535d03f3 Automatic merge of client:master into master 2020-07-15 06:11:32 +00:00
Jayathirth D V
1314319b00 8249174: Fix improper glyph cache initialization logic for text rende… 2020-07-10 06:46:11 +00:00
duke
33bf12529e Automatic merge of client:master into master 2020-07-09 07:32:58 +00:00
Jayathirth D V
683da66f10 8243953: Optimize encoder creation/deletion logic for LCD text rendering 2020-07-06 09:28:26 +00:00
duke
3088310c88 Automatic merge of client:master into master 2020-07-03 18:41:29 +00:00
duke
60f307fd1d Automatic merge of client:master into master 2020-07-03 13:36:37 +00:00
duke
8f9de8ff7f Automatic merge of client:master into master 2020-07-03 04:08:49 +00:00
duke
314f2fd5f4 Automatic merge of client:master into master 2020-07-02 17:03:54 +00:00
duke
5bb93deef2 Automatic merge of client:master into master 2020-07-01 03:49:19 +00:00
Ajit Ghaisas
51172c40fe 8248301: Lanai - Change MTLStorageMode of MTLSurfaceData texture (render backbuffer) to private 2020-06-25 09:24:22 +00:00
duke
ebaa2c3c14 Automatic merge of client:master into master 2020-06-25 07:23:07 +00:00
duke
948a7ff99c Automatic merge of client:master into master 2020-06-25 01:41:06 +00:00
duke
2431174483 Automatic merge of client:master into master 2020-06-22 23:40:11 +00:00
duke
fc34f9094f Automatic merge of client:master into master 2020-06-22 07:14:06 +00:00
duke
6605af4cfc Automatic merge of client:master into master 2020-06-22 07:00:03 +00:00
Severin Gehwolf
a812cd299c 8247863: Unreachable code in OperatingSystemImpl.getTotalSwapSpaceSize()
After 8231111 we have -1 for missing metrics, thus the fix of 8236617 is obsolete

Reviewed-by: mbaesken
2020-06-19 10:40:04 +02:00
Ludovic Henry
6eebdca862 8250810: Push missing parts of JDK-8248817
Push changes from JDK-8248817 that were accidentally excluded from the commit.

Reviewed-by: kbarrett, dholmes
2020-07-30 02:47:00 -04:00
Jie Fu
fa26bb0d9d 8250745: assert(eval_map.contains(n)) failed: absent
Reviewed-by: vlivanov, kvn
2020-07-29 11:38:28 +08:00
Mikael Vidstedt
e3272713c7 Added tag jdk-16+8 for changeset 0a73d6f3aab4 2020-07-29 18:31:44 -07:00
Ludovic Henry
3ca8fb7188 8248682: AArch64: Use ATTRIBUTE_ALIGNED helper
Reviewed-by: kbarrett, tschatzl, dholmes
2020-07-29 20:28:11 -04:00
Ludovic Henry
a294e092f0 8248817: Windows: Improving common cross-platform code
Reviewed-by: kbarrett, dholmes
2020-07-29 20:25:39 -04:00
Igor Ignatyev
d376f608c4 8250797: remove CompileReason::Reason_CTW
Reviewed-by: kvn, epavlova
2020-07-29 16:52:23 -07:00
Alexandre Iline
a808295619 8250743: Switch to JCov build which supports byte code version 60
Reviewed-by: erikj
2020-07-29 16:12:10 -07:00
Eric Caspole
5bc5c86f26 8249663: LogCompilation cannot process log from o.r.scala.dotty.JmhDotty
Fix stale site and uncommon trap processing in LogParser

Reviewed-by: vlivanov, kvn
2020-07-29 15:41:37 -04:00
Naoto Sato
53032c587f 8247546: Pattern matching does not skip correctly over supplementary characters
Reviewed-by: joehw
2020-07-29 09:49:43 -07:00
Rajan Halade
8885a83d73 8243321: Add Entrust root CA - G4 to Oracle Root CA program
Reviewed-by: mullan
2020-07-29 09:31:38 -07:00
Huang Wang
c4d0058b19 8250609: C2 crash in IfNode::fold_compares
Reviewed-by: kvn, chagedorn
2020-07-28 10:38:04 +08:00
Severin Gehwolf
f59ac21a98 8250627: Use -XX:+/-UseContainerSupport for enabling/disabling Java container metrics
Reviewed-by: aph, dholmes, bobv
2020-07-24 19:57:06 +02:00
Richard Reingruber
d742a467b1 8250610: SafepointMechanism::disarm_if_needed() is declared but not used
Reviewed-by: shade, dholmes
2020-07-29 14:11:46 +02:00
Jan Lahoda
6aafff1513 8249261: AssertionError in StructuralStuckChecker
Reviewed-by: mcimadamore
2020-07-29 11:34:25 +02:00
Jan Lahoda
f747f1c95a 8248641: Trees.getScope returns incorrect results for code inside a rule case
Ensuring rule cases are copied correctly by TreeCopier.

Reviewed-by: vromero
2020-07-29 11:34:24 +02:00
Rahul Yadav
5a6f74152e 8250602: Update sun/security/ssl/SSLLogger/LoggerDateFormatterTest.java to handle TimeZones
This fix updates the test LoggerDateFormatterTest.java to be able to handle different TimeZones

Reviewed-by: alanb, dfuchs, xuelei
2020-07-29 10:26:39 +01:00
Ludovic Henry
430cc5c84f 8248657: Windows: strengthening in ThreadCritical regarding memory model
Reviewed-by: dholmes, kbarrett, aph, stuefe
2020-07-29 10:38:28 +02:00
Aleksey Shipilev
43f3262467 8250612: jvmciCompilerToVM.cpp declares jio_printf with "void" return type, should be "int"
Reviewed-by: thartmann, kvn
2020-07-29 09:48:08 +02:00
Andrei Pangin
8dc8b55602 8249719: MethodHandle performance suffers from bad ResolvedMethodTable hash function
Reviewed-by: simonis, stuefe, coleenp
2020-07-24 15:33:38 +03:00
Mikael Vidstedt
b519a2cdd8 Merge 2020-07-28 22:37:23 -07:00
Chris Plummer
788edb6960 8250742: ProblemList serviceability/sa/ClhsdbPstack.java #id0 and #id1 for ZGC
Reviewed-by: sspitsyn
2020-07-28 16:41:07 -07:00
Joe Wang
fe3b44abfb 8249643: Clarify DOM documentation
Reviewed-by: lancea
2020-07-28 23:29:33 +00:00
Joe Darcy
ba56f01e26 8250580: Address reliance on default constructors in java.rmi
Reviewed-by: smarks
2020-07-28 16:26:28 -07:00
Igor Ignatyev
90cfe209ff 8250739: remove Compile::Generate_*_Graph methods declarations
Reviewed-by: kvn
2020-07-28 15:31:10 -07:00
Igor Ignatyev
51ccb1965d 8250738: C2Compiler::is_intrinsic_supported(methodHandle&, bool) shouldn't be virtual
Reviewed-by: xliu, kvn
2020-07-28 15:31:09 -07:00
Harold Seigel
94ab177a51 8250562: Clean up weird comment in vmTestbase class Terminator.java
Delete the weird comment.

Reviewed-by: lfoltan
2020-07-28 20:14:01 +00:00
Chris Plummer
59322f865d 8248882: SA PMap and PStack support on OSX works with core files. Enable them
Reviewed-by: sspitsyn, amenkov
2020-07-28 12:04:58 -07:00
Chris Plummer
75cb54ec9f 8247515: OSX pc_to_symbol() lookup does not work with core files
Reviewed-by: sspitsyn, kevinw
2020-07-28 09:52:07 -07:00
Joe Darcy
34cf684fe6 8249219: Update --release 15 symbol information for JDK 15 build 33
Reviewed-by: jlahoda
2020-07-28 09:25:23 -07:00
Joe Darcy
d129fd67ec 8250640: Address reliance on default constructors in jdk.jdi
Reviewed-by: alanb
2020-07-28 09:21:04 -07:00
Christian Hagedorn
e6e5096e36 8249602: C2: assert(cnt == _outcnt) failed: no insertions allowed
Use DUIterator instead of DUIterator_Fast due to legit insertions.

Reviewed-by: kvn, thartmann
2020-07-28 16:05:30 +02:00
Coleen Phillimore
695a7852f1 8250589: Move Universe::_reference_pending_list into OopHandle
Use synchronization to reference the _reference_pending_list with OopHandle

Reviewed-by: shade, kbarrett, dholmes, eosterlund
2020-07-28 08:10:43 -04:00
Coleen Phillimore
c993ee4b9c 8250042: Clean up methodOop and method_oop names from the code
Reviewed-by: dholmes, sspitsyn, cjplummer, chagedorn
2020-07-28 07:33:51 -04:00
Nick Gasson
790c6cc195 8237483: AArch64 C1 OopMap inserted twice fatal error
Reviewed-by: aph
2020-07-28 16:50:32 +08:00
Aleksey Shipilev
212a39be42 8250605: Linux x86_32 builds fail after JDK-8249821
Reviewed-by: erikj, prr
2020-07-28 09:05:36 +02:00
Mikael Vidstedt
74bd95bcc1 Merge 2020-07-27 22:26:00 -07:00
Kim Barrett
e2b632ebaf 8247976: Update HotSpot Style Guide for C++14 adoption
Update and move style guide from wiki to jdk repo.

Reviewed-by: jrose, stefank, dholmes, mikael, stuefe, kvn
2020-07-27 22:19:33 -04:00
Jamil Nimeh
047949d2a1 8247630: Use two key share entries
Reviewed-by: xuelei
2020-07-27 18:20:57 -07:00
Doug Simon
1256e2bcc3 8250556: revert JVMCI part of JDK-8230395
Reviewed-by: never, dholmes
2020-07-27 22:59:27 +02:00
Daniil Titov
cf0f63f151 8216324: GetClassMethods is confused by the presence of default methods in super interfaces
Reviewed-by: sspitsyn, amenkov
2020-07-27 11:34:19 -07:00
Joe Darcy
d7e99e607f 8250213: Address use of default constructors in com.sun.source.util
Reviewed-by: jjg
2020-07-27 11:07:30 -07:00
Patric Hedlin
1d93ce2b05 8247766: [aarch64] guarantee(val < (1U << nbits)) failed: Field too big for insn
Reviewed-by: neliasso, aph
2020-07-27 10:56:51 +02:00
Martin Balao
3749a30c50 8250582: Revert Principal Name type to NT-UNKNOWN when requesting TGS Kerberos tickets
Reviewed-by: weijun
2020-07-25 01:02:51 -03:00
Vicente Romero
bd00604ea1 8249829: javac is issuing an incorrect static access error
Reviewed-by: jlahoda
2020-07-27 10:12:30 -04:00
Albert Yang
6a91c5161a 8242036: G1 HeapRegionRemSet::_n_coarse_entries could be a bool
Reviewed-by: kbarrett, eosterlund, tschatzl, lkorinth
2020-07-27 12:59:32 +02:00
Christian Hagedorn
c567877ecb 8248552: C2 crashes with SIGFPE due to division by zero
Bail out in PhaseIdealLoop:split_thru_phi when trying to split a Div or ModNode iv phi whose zero check was removed but could potentially still be zero based on type information.

Reviewed-by: kvn, thartmann
2020-07-27 11:03:17 +02:00
Yasumasa Suenaga
d178203283 8248362: JVMTI frame operations should use Thread-Local Handshake
Reviewed-by: sspitsyn, dholmes, dcubed
2020-07-27 15:49:53 +09:00
David Holmes
ef313f7710 8247296: Optimize JVM_GetDeclaringClass
Co-authored-by: Christoph Dreis <christoph.dreis@freenet.de>
Reviewed-by: shade, minqi
2020-07-26 20:29:42 -04:00
Ioi Lam
858e37a0cf 8249087: Always initialize _body[0..1] in Symbol constructor
Reviewed-by: dholmes, lfoltan
2020-07-24 13:56:45 -07:00
Prasanta Sadhukhan
2947a7c344 8247772: Lanai: Several jtreg tests fails with assertion validateText… 2020-06-17 16:46:51 +00:00
Prasanta Sadhukhan
e16e7f0b61 8242950: Files which can't be selected has different color with metal… 2020-06-15 12:52:35 +00:00
Ajit Ghaisas
955a58a59b 8247464: Memory Leak in MTLBlitLoops_CopyArea() method 2020-06-12 07:36:28 +00:00
Jayathirth D V
12b63f53e8 8247304: Use separate MTLCommandQueue for final blit and MTLDrawable … 2020-06-10 09:38:07 +00:00
duke
5645835acd Automatic merge of client:master into master 2020-06-10 07:24:46 +00:00
duke
4116ed6213 Automatic merge of client:master into master 2020-06-09 11:44:22 +00:00
duke
676af46996 Automatic merge of client:master into master 2020-06-08 14:00:15 +00:00
duke
a876ec7d5b Automatic merge of client:master into master 2020-06-05 23:43:16 +00:00
Alexey Ushakov
8fae5e00b5 8246495: Lanai: update AA clip info on GPU via compute shader 2020-06-04 11:08:14 +00:00
duke
4ac8803c5d Automatic merge of client:master into master 2020-06-03 16:26:16 +00:00
Alexey Ushakov
961a913a5a 8246454: Lanai: Create RenderPerf tests for rectangular and shape clips 2020-06-03 14:48:17 +00:00
Prasanta Sadhukhan
c9e8f24ae1 8238703: system_profiler command not found 2020-06-03 12:45:09 +00:00
Alexey Ushakov
c723f0966a 8242952: fixed MTLBlitLoops::replaceTextureRegion (add correct offset…
Co-authored-by: Artem Bochkarev <abochkarev@openjdk.org>
Co-authored-by: add Artem Bochkarev <abochkarev@openjdk.org>
2020-06-02 17:55:46 +00:00
Alexey Ushakov
a403550ceb 8242354: support for bufImgOps (RescaleOp, LookupOp, ConvolveOp)
Co-authored-by: Artem Bochkarev <abochkarev@openjdk.org>
2020-06-02 17:27:31 +00:00
Alexey Ushakov
0c519db955 8246331: Lanai: do not update AA clip info in nonAA mode 2020-06-02 16:56:05 +00:00
duke
413525fb9d Automatic merge of client:master into master 2020-06-02 16:36:17 +00:00
duke
ccf8d55371 Automatic merge of client:master into master 2020-06-01 17:40:10 +00:00
Jayathirth D V
a7d93863a1 8246239: Revert JDK-8244193 as it causes performance regression 2020-06-01 09:01:38 +00:00
duke
168dd4fd9c Automatic merge of client:master into master 2020-05-30 05:13:04 +00:00
duke
40d3b75fc6 Automatic merge of client:master into master 2020-05-29 20:13:39 +00:00
duke
258fc0be9d Automatic merge of client:master into master 2020-05-29 05:14:13 +00:00
duke
6f7f9a0c84 Automatic merge of client:master into master 2020-05-28 09:04:02 +00:00
duke
f2d5dcf256 Automatic merge of client:master into master 2020-05-28 05:57:03 +00:00
duke
fbd6b2b6b9 Automatic merge of client:master into master 2020-05-27 12:38:19 +00:00
duke
e3088fedfc Automatic merge of client:master into master 2020-05-27 12:30:58 +00:00
duke
8b8b0b1953 Automatic merge of client:master into master 2020-05-27 12:10:02 +00:00
Alexey Ushakov
37cfa9f0fd 8245693: Lanai: [_MTLCommandEncoder dealloc]:70: failed assertion `Co… 2020-05-27 10:41:24 +00:00
duke
5a69bfbe9b Automatic merge of client:master into master 2020-05-27 03:41:58 +00:00
duke
ddbe37caec Automatic merge of client:master into master 2020-05-23 08:04:01 +00:00
duke
009ccc3828 Automatic merge of client:master into master 2020-05-23 07:57:00 +00:00
duke
d3b8b8b6f1 Automatic merge of client:master into master 2020-05-22 06:04:58 +00:00
duke
929c1ba66c Automatic merge of client:master into master 2020-05-21 06:35:58 +00:00
duke
830f96afe2 Automatic merge of client:master into master 2020-05-21 05:47:00 +00:00
duke
30d07796d6 Automatic merge of client:master into master 2020-05-21 05:37:04 +00:00
duke
cdc54cbc15 Automatic merge of client:master into master 2020-05-20 16:06:12 +00:00
duke
fa761007e0 Automatic merge of client:master into master 2020-05-20 09:38:02 +00:00
duke
b9452e95cf Automatic merge of client:master into master 2020-05-19 00:21:59 +00:00
duke
bec6212151 Automatic merge of client:master into master 2020-05-18 18:43:02 +00:00
duke
1ab93cb993 Automatic merge of client:master into master 2020-05-18 10:23:58 +00:00
duke
5c212fc881 Automatic merge of client:master into master 2020-05-18 05:52:59 +00:00
Ajit Ghaisas
1773b20de2 8243009: SwingSet2 scrolling doesn't repaint properly on Catalina 2020-05-14 10:15:13 +00:00
duke
bd03d4d220 Automatic merge of client:master into master 2020-05-13 14:26:51 +00:00
duke
88a1f69fb5 Automatic merge of client:master into master 2020-05-13 14:18:03 +00:00
duke
de6cd3a80b Automatic merge of client:master into master 2020-05-09 04:26:30 +00:00
duke
8927d5c2f7 Automatic merge of client:master into master 2020-05-08 06:17:29 +00:00
duke
7b6d7af13f Automatic merge of client:master into master 2020-05-08 04:18:56 +00:00
duke
03b75851a3 Automatic merge of client:master into master 2020-05-08 04:16:49 +00:00
Alexey Ushakov
167a33c011 8242338: Shape clip with AA not working in J2DDemo 2020-05-07 23:25:33 +00:00
Artem Bochkarev
c76eeefa8e 8243545: don't use clip rect in texture-mode (in IsoBlit) 2020-05-07 21:45:30 +00:00
duke
161711cb2f Automatic merge of client:master into master 2020-05-07 17:03:48 +00:00
duke
de2abf17d6 Automatic merge of client:master into master 2020-05-06 08:35:51 +00:00
duke
b8f0b5fc66 Automatic merge of client:master into master 2020-05-06 08:31:23 +00:00
duke
5a37b5225a Automatic merge of client:master into master 2020-05-04 18:36:20 +00:00
duke
a3691b07ef Automatic merge of client:master into master 2020-05-04 03:42:11 +00:00
duke
38811d3a0e Automatic merge of client:master into master 2020-05-04 03:33:23 +00:00
duke
04523d9d80 Automatic merge of client:master into master 2020-05-02 04:41:49 +00:00
duke
0002a91517 Automatic merge of client:master into master 2020-05-01 21:43:02 +00:00
duke
5f36a43220 Automatic merge of client:master into master 2020-05-01 00:24:27 +00:00
duke
6698ac4ded Automatic merge of client:master into master 2020-04-30 17:49:06 +00:00
duke
ef98db1d0d Automatic merge of client:master into master 2020-04-30 14:38:17 +00:00
Jayathirth D V
f643afdb22 8244193: Remove nextDrawableCount and lock RQ only during the blit op… 2020-04-30 13:53:32 +00:00
duke
be4bea9585 Automatic merge of client:master into master 2020-04-30 07:15:31 +00:00
duke
20f6e79c6d Automatic merge of client:master into master 2020-04-30 07:12:26 +00:00
duke
d22b543058 Automatic merge of client:master into master 2020-04-29 08:35:35 +00:00
duke
341cf3716a Automatic merge of client:master into master 2020-04-28 19:32:26 +00:00
Alexey Ushakov
7c59839250 8243508: Update alpha blending and compositing functions 2020-04-27 22:25:31 +00:00
duke
923bd0bb87 Automatic merge of client:master into master 2020-04-27 21:23:57 +00:00
duke
9d847b543a Automatic merge of client:master into master 2020-04-27 10:32:36 +00:00
duke
e54446332d Automatic merge of client:master into master 2020-04-27 05:11:43 +00:00
duke
ac569a56a0 Automatic merge of client:master into master 2020-04-24 11:52:19 +00:00
Jayathirth D V
89705e4cd8 8243538: Use glyphCacheLCD for LCD text rendering 2020-04-24 08:47:32 +00:00
Kevin Rushforth
07e9fbf764 8243505: SRC_OVER alpha composite mode doesn't render correctly 2020-04-24 01:43:10 +00:00
duke
e9d7168fc7 Automatic merge of client:master into master 2020-04-23 17:48:02 +00:00
Artem Bochkarev
7cc7448622 8242354: implemented MaskBlit 2020-04-23 12:22:07 +00:00
duke
b6f2fd6c44 Automatic merge of client:master into master 2020-04-22 08:34:08 +00:00
duke
bc4283413d Automatic merge of client:master into master 2020-04-22 06:49:26 +00:00
duke
92f27e94d7 Automatic merge of client:master into master 2020-04-22 00:05:52 +00:00
Jayathirth D V
4ffc9752bc 8243253: Disable incomplete cached text rendering for LCD 2020-04-21 11:51:02 +00:00
duke
b5c1be0c30 Automatic merge of client:master into master 2020-04-20 22:22:11 +00:00
duke
fd4cf1d519 Automatic merge of client:master into master 2020-04-20 20:53:28 +00:00
duke
130560f769 Automatic merge of client:master into master 2020-04-20 18:34:19 +00:00
duke
fd85e5fbd1 Automatic merge of client:master into master 2020-04-20 16:42:21 +00:00
Ajit Ghaisas
d991baed46 8243158: Lanai - Interpolation constants should be mapped from AffineTransformOp 2020-04-20 11:44:40 +00:00
Jayathirth D V
79f176b4a1 8243160: Update AddToGlyphCache to handle LCD text rendering 2020-04-20 11:33:22 +00:00
Jayathirth D V
61fdc8a95a 8243159: Disable unused glyph cache code in LCD rendering 2020-04-20 10:53:52 +00:00
Jayathirth D V
ec0ca2bc72 8243131: DisableMaskCache in MTLMaskFill to maintain proper state 2020-04-20 05:45:36 +00:00
duke
137168f694 Automatic merge of client:master into master 2020-04-17 06:02:55 +00:00
duke
ce891e9756 Automatic merge of client:master into master 2020-04-17 05:44:49 +00:00
duke
3eb5cfb91a Automatic merge of client:master into master 2020-04-16 17:23:24 +00:00
Alexey Ushakov
ee7fee1d07 8242653: Lanai: SRC_OVER with extra alpha does not work for VI 2020-04-16 10:14:01 +00:00
duke
616100a6c4 Automatic merge of client:master into master 2020-04-15 07:13:21 +00:00
duke
63f81c9587 Automatic merge of client:master into master 2020-04-14 08:15:34 +00:00
duke
1c0fe72535 Automatic merge of client:master into master 2020-04-13 12:16:17 +00:00
duke
45534e2389 Automatic merge of client:master into master 2020-04-11 05:10:28 +00:00
duke
469c179c9a Automatic merge of client:master into master 2020-04-10 06:30:24 +00:00
Artem Bochkarev
5cae755f21 8233309: implement image rendering options 2020-04-09 13:53:45 +00:00
Alexey Ushakov
8d90ece185 8233305: Implement rendering to volatile image 2020-04-09 12:33:55 +00:00
Alexey Ushakov
35aa6e1810 8233305: Implement rendering to volatile image 2020-04-09 11:30:50 +00:00
Prasanta Sadhukhan
aeb0b443d1 8242444: LCD Text Rendering characters other than 1st are not rendere… 2020-04-09 10:07:49 +00:00
duke
e945ccef4b Automatic merge of client:master into master 2020-04-09 00:01:14 +00:00
duke
c7ab913154 Automatic merge of client:master into master 2020-04-08 20:23:14 +00:00
duke
639f384353 Automatic merge of client:master into master 2020-04-08 17:55:17 +00:00
duke
e00df2c2d3 Automatic merge of client:master into master 2020-04-08 11:02:32 +00:00
duke
4ae50c4519 Automatic merge of client:master into master 2020-04-08 09:40:32 +00:00
duke
0772c1933b Automatic merge of client:master into master 2020-04-08 09:08:30 +00:00
duke
15d9b35741 Automatic merge of client:master into master 2020-04-08 08:47:32 +00:00
Kevin Rushforth
5574cca908 8242185: Lanai: JDK built on macOS 10.15 fails to run on macOS 10.13
Specify metal version 2.0 when compiling shaders
2020-04-07 17:10:18 +00:00
duke
3fcc3f71d9 Automatic merge of client:master into master 2020-04-07 04:27:32 +00:00
duke
76e7b41c53 Automatic merge of client:master into master 2020-04-07 03:22:29 +00:00
duke
7d657e8c94 Automatic merge of client:master into master 2020-04-06 19:05:32 +00:00
duke
0de241433d Automatic merge of client:master into master 2020-04-03 22:05:27 +00:00
Prasanta Sadhukhan
fd95090fa2 8242079: Update RenderPerf LCD Test to ensure LCD code path is used 2020-04-03 09:05:13 +00:00
Jayathirth D V
9cb40a9bc7 8242035: Combine drawPrimitive calls in text drawing flush
Co-authored-by: Ajit Ghaisas <ajit.ghaisas@oracle.com>
2020-04-02 12:00:25 +00:00
duke
97c7a63ab6 Automatic merge of client:master into master 2020-04-01 03:00:25 +00:00
duke
623aa48c4f Automatic merge of client:master into master 2020-04-01 02:50:27 +00:00
duke
83bbb3941e Automatic merge of client:master into master 2020-03-31 17:06:37 +00:00
Phil Race
cae4b9cc37 Merge 2020-03-31 17:04:42 +00:00
Alexey Ushakov
9226e84501 8241594: Lanai: javax/swing/JFileChooser/8013442: SIGSEGV at AMDMTLBr… 2020-03-26 17:42:15 +00:00
Ajit Ghaisas
3da068b282 8238223: Lanai - JPopupMenu/7154841 - no mouse events on the popup menu 2020-03-26 15:14:38 +00:00
Alexey Ushakov
45fea40dbd JDK-8241422: Regression in RenderPerfTest after JDK-8238535 2020-03-24 13:46:02 +00:00
Jayathirth D V
e5d516d182 8241490: Add large text performance tests in RenderPerfTest 2020-03-24 10:46:23 +00:00
Alexey Ushakov
db88ce172a JDK-8241156: Lanai: JPEG Image does not render 2020-03-20 14:03:41 +00:00
Alexey Ushakov
4a9a1708b3 JDK-8241143 Lanai: LinearGradient does not work in AA mode 2020-03-18 12:19:59 +00:00
Alexey Ushakov
43bbd51b72 JDK-8238535: Shape Clip does not work with AA rendering 2020-03-17 17:02:50 +00:00
Alexey Ushakov
c02799eede JDK-8240996: Lanai: rendering artifacts with external GPU 2020-03-13 10:07:41 +00:00
Alexey Ushakov
6ff6db02e7 JDK-8240573: Texture paint does not work with AA rendering 2020-03-12 20:18:02 +00:00
Prasanta Sadhukhan
032aeb34e6 JDK-8240926: Do not prevent metal initialisation even if metal suppor… 2020-03-12 06:59:05 +00:00
Prasanta Sadhukhan
8b636c6a87 8240796: Infinite loop in Diagnostic message code 2020-03-10 10:32:02 +00:00
Prasanta Sadhukhan
26d9a0794c Metal support diagnostics message 2020-03-09 11:53:36 +00:00
Ajit Ghaisas
7744fb099e 8238674: WindowOwnedByEmbeddedFrameTest: sun.java2d.opengl.CGLLayer cannot be cast to sun.java2d.metal.MTLLayer 2020-03-09 09:27:47 +00:00
Prasanta Sadhukhan
f66a1f1263 8233314: LCD Text rendering implementation with glyph cache 2020-03-04 10:50:14 +00:00
Kevin Rushforth
bc73e009cc 8240328: Update .jcheck/conf for lanai 2020-03-03 19:05:51 +00:00
Prasanta Sadhukhan
ff5966de7f 8233312: LCD text rendering implementation without glyph cache
First character of a string is rendered without artifact. Subsequent characters are rendered but not in same contrast as first chatacter.
2020-03-02 16:08:47 +05:30
Jayathirth D V
6ab1ed5817 Merge 2020-03-02 09:26:25 +05:30
Alexey Ushakov
075e1321e3 8240234: Improve performance of bulk MTLRenderer_FillAAParallelogram ops 2020-02-28 19:47:31 +03:00
Ajit Ghaisas
6a57e1fd9c 8233226: Implement XOR Mode rendering option
XOR Mode rendering support for primitive rendering and text rendering.
2020-02-28 15:59:05 +05:30
Alexey Ushakov
2e6bdc171a 8240176: Lanai: MTLPaint copyFrom - incorrect color handling 2020-02-27 15:44:44 +03:00
Jayathirth D V
72cac62f89 8239858: Initial implementation of caching for LCD text 2020-02-24 17:29:53 +05:30
Prasanta Sadhukhan
98743762dd 8233312: LCD text rendering implementation without glyph cache
First character of a string is rendered.
2020-02-24 13:59:01 +05:30
Jayathirth D V
f0445c24e8 Merge 2020-02-21 11:00:23 +05:30
Jayathirth D V
d0b2ad3e82 8239546: Update Vertexcache and GlyphCache flush limits 2020-02-20 16:08:28 +05:30
Jayathirth D V
32a1a537f0 8239220: Update text cache management to handle lot of unique glyphs 2020-02-17 17:32:53 +05:30
Prasanta Sadhukhan
5199fb702d 8233312: LCD text rendering implementation without glyph cache
Incremental implementation of LCD text.
2020-02-17 15:56:03 +05:30
Prasanta Sadhukhan
3bd02981db 8238744: JCK interactive test doesn't show instructions
Made JCK instruction frame go via grayscale code path as LCD text rendering is not fully done yet.
2020-02-11 16:10:59 +05:30
Jayathirth D V
8a1132d3a2 Merge 2020-02-07 10:39:23 +05:30
Prasanta Sadhukhan
3174bd2c75 8233312: LCD Text Rendering implementation without glyph cache
Initial draft implementation of LCD text without glyph cache.
2020-02-06 14:39:05 +05:30
Ajit Ghaisas
6e24ac5e09 8233231: Implement PaintType : Texture Paint
Modified shader to support all transformations of texture paint anchor rectangle.
2020-02-05 15:23:56 +05:30
Ajit Ghaisas
6d8ae023f2 8238465: [Lanai] Fix build errors on non-mac platforms 2020-02-04 15:31:58 +05:30
Ajit Ghaisas
c8002d297a 8233231: Implement PaintType : Texture Paint
This is basic untransformed texture paint support.
2020-02-03 22:54:17 +05:30
Jayathirth D V
3b48643a82 Merge 2020-01-31 13:39:17 +05:30
Alexey Ushakov
07ac868b77 8238165: Lanai: crashes at [libobjc.A.dylib+0x601d] objc_msgSend+0x1d
Fixed incorrect deallocation of native resources connected with MTLSurfaceData. Applied OGL fix logic (8146238)
2020-01-29 21:32:10 +03:00
Kevin Rushforth
a2d1099854 8234813: MTLRenderer_FillAAParallelogram is not implemented
Fix build failure
2020-01-23 10:32:13 -08:00
Alexey Ushakov
96a52e96de 8234813: MTLRenderer_FillAAParallelogram is not implemented
Added _Nonnull annotation
2020-01-23 20:07:34 +03:00
Alexey Ushakov
57e1ab737d 8234813: MTLRenderer_FillAAParallelogram is not implemented
Use multisampling rendering for AA parallelogram rendering
2020-01-23 17:24:18 +03:00
Alexey Ushakov
7bc2660967 8237458: J2Ddemo test becomes unresponsive after launching
Fixed memory leak in texture pool and restored changeset 09b8eb38bbfa
8236137 (avoid texture reallocations inside vertex-cache)
2020-01-22 22:52:18 +03:00
Jayathirth D V
c4ef423d8e 8237608: Initial implementation of Grayscale with cache text rendering 2020-01-22 11:09:37 +05:30
Alexey Ushakov
269e7e98e6 8237458: J2Ddemo test becomes unresponsive after launching
Backed out changeset 09b8eb38bbfa
8236137 (avoid texture reallocations inside vertex-cache)
2020-01-20 16:54:42 +03:00
Jayathirth D V
136f957e05 Merge 2020-01-14 15:32:41 +05:30
Ajit Ghaisas
364be79d47 8236616: Polyline drawing is incorrect 2020-01-03 16:13:00 +05:30
Artem Bochkarev
2ad73d2e67 8236137: avoid texture reallocations inside vertex-cache 2019-12-25 02:25:33 +03:00
Artem Bochkarev
a941e59035 8236104: introduce EncoderManager, split MTLContext into several classes
EncoderManager:
1. checks destination texture changes (creates new encoder when dest changes)
2. changes states of encoder only when cached state doesn't equal required states

Also:
- extract Composite, Transform, Clip and Paint entities from MTLContext (shaders and buffers are set in MTLPaint.setPipelineState)
- reimplemented MTLPipelineStatesStorage (simplified), add several optimizations (don't use stringWithFormat, fast state search)
- fix texture shaders
- fixed various composite problems
- optimizations
2019-12-25 02:21:28 +03:00
Artem Bochkarev
c4baadb3c9 8233710: support all params for native blit loops
with:
1. code cleanup (remove unnecessary code)
2. fix clip-rect usage
3. add debug under define
4. minor optimizations
2019-12-25 01:50:00 +03:00
Ajit Ghaisas
e2d1e4c804 8233233 : Implement Shape Clip 2019-12-19 14:38:40 +05:30
Jayathirth D V
dee4009a97 8235176: Add local glyph state management and remove global references 2019-12-02 14:20:32 +05:30
Jayathirth D V
e682c5129a Merge 2019-11-27 13:34:58 +05:30
Jayathirth D V
cdcb094b65 8233190: Use multi commandbuffer and draw back buffer in QueueFlusher 2019-11-26 16:35:19 +05:30
Artem Bochkarev
537653bd49 8234506: implement cleaning logic for textures pool
* use Last-Recent-Used strategy
* also optimized search of item
* also add command buffer wrapper (that manages binded per-frame resources)
2019-11-20 14:41:12 +03:00
Artem Bochkarev
4fd7c3c449 8234352: fixed memory leaks (for textures)
also remove unnecessary code that has no sense (given from initial GL impl)
2019-11-18 21:22:51 +03:00
Alexey Ushakov
2ec02181fa 8233879 : Improve performance of MTLVertexCache
Improved performance by avoiding creation of MTLBuffer objects for passing vertices
2019-11-09 18:58:48 +03:00
Artem Bochkarev
14e6b1244c 8233840: implemented MTLBlitLoops_CopyArea 2019-11-08 13:06:44 +03:00
Artem Bochkarev
24bff4e701 8233711: support alpha-composite modes (through multipliers of MTLRenderPipelineColorAttachmentDescriptor) 2019-11-08 12:07:14 +03:00
Artem Bochkarev
18b550e872 8233714: support 32bpp raster formats (for SwToTexture blit)
* use swizzle when available (otherwise perform raster conversion on cpu)
* supported flag SurfaceData.isOpaue
* fixed memory management for TexturesPool
2019-11-07 12:24:48 +03:00
Magnus Ihse Bursie
fab846163c 8233034: configure needs to provide path to Xcode metal build tools
Reviewed-by: prr
2019-11-04 12:14:45 -08:00
Phil Race
03aa3101a1 Backout 8233039 due to build breakage 2019-11-04 11:39:32 -08:00
Artem Bochkarev
c8b91c2d3f 8233039: support different raster formats (for SwToTexture blit)
* supported flag SurfaceData.isOpaue
* added implementation for missing composite rules (some combinations of parameters and extra-alpha can't be supported with CAD-multipliers, need to reimplement via shaders)
2019-11-01 17:25:07 +03:00
Artem Bochkarev
5b3c412357 8233039: minor code cleanup
minor simplification for MTLContext.createRenderEncoder, fixed logging utils
2019-11-01 17:23:42 +03:00
Kevin Rushforth
95b69fe529 8232918: Unguarded use of displaySyncEnabled causes build to fail
Wrap displaySyncEnabled in @available check to avoid warning
2019-10-23 12:04:35 -07:00
Jayathirth D V
535fff0dac Merge 2019-10-11 18:14:10 +05:30
Jayathirth D V
bbfac12c68 8232164: Lock renderqueue for least amount of time by making CAMetalLayer asynchronous
Reviewed-by: aghaisas
2019-10-11 15:20:54 +05:30
Alexey Ushakov
1768149951 8230958: AA Geometry rendering is not supported in metal
Fixed severe memory leaks that caused J2Demo hangs in AA mode
2019-10-03 00:38:17 +03:00
Ajit Ghaisas
49ca894f15 8231614: Avoid passing of redundant vertex 'z' data to vertex shader 2019-09-30 14:18:02 +05:30
Alexey Ushakov
0f76adc28d Fixed out of bounds access to transform matrix 2019-09-26 17:51:40 +03:00
Alexey Ushakov
cfc96d96f7 8230958: AA Geometry rendering is not supported in metal
Replaced mallocs with local arrays
2019-09-15 17:22:08 +03:00
Jayathirth D V
4921d927e0 Merge 2019-09-26 12:26:28 +05:30
Jayathirth D V
61aeca21c1 8231215: Add missed change for JDK-8231056
Reviewed-by: aghaisas
2019-09-19 11:30:46 +05:30
Jayathirth D V
fda678bef9 8231056: Refactor code to remove repetative logic in MTLLayer
Reviewed-by: aghaisas
2019-09-19 10:58:49 +05:30
Ajit Ghaisas
aba2c30d1e 8231178 : testImgBubbles of RenderPerfTest reports less FPS when run with Metal
Reviewed-by : jdv
2019-09-18 15:25:25 +05:30
Ajit Ghaisas
3ecd356574 8231175 : Fix J2DDemo sanity breakage caused due to initial commit of 8230958 2019-09-18 14:50:04 +05:30
Alexey Ushakov
762853fe8f 8230958: AA Geometry rendering is not supported in metal
Supported flat color fills in AA rendering mode
2019-09-13 21:17:07 +03:00
Alexey Ushakov
f879fa4e34 8230958: AA Geometry rendering is not supported in metal
Implemented MTLMaskFill_MaskFill operation
2019-09-13 15:38:18 +03:00
Ajit Ghaisas
6c8022b1ee 8230837: MTLRenderer_DrawParallelogram method - can be optimized by combining 4 drawPrimitives calls
Reviewed-by: jdv
2019-09-12 15:10:50 +05:30
Alexey Ushakov
d691007acc 8230859: fillOval with stroke width < 1 does not render
Implemented missing primitive
2019-09-11 17:47:02 +03:00
Jayathirth D V
9f250e53c8 8230849: Remove scheduleBlitAllModifiedLayers code after setNeedsDisplay
Reviewed-by: aghaisas
2019-09-11 17:37:53 +05:30
Alexey Ushakov
7cba2b956a 8230810: JFrame has incorrect insets with metal pipeline enabled
Adjusted metal rendering to use correct insets in JFrame
2019-09-10 18:21:35 +03:00
Jayathirth D V
c4ee724176 8230793: Remove CALayerDelegate usage for metal
Reviewed-by: aghaisas
2019-09-10 15:21:59 +05:30
Jayathirth D V
393e924d2d 8230789: Call setNeedsDisplay when we are drawing child layers recursively
Reviewed-by: aghaisas
2019-09-10 12:15:30 +05:30
Alexey Ushakov
fcba1675a7 8230657: Create fine grained render perf test for metal pipeline
Converted gradle JUnit test to plain java for ant and gnumake

To run the tests:
cd src/demo/share/java2d/RenderPerfTest

ant run
or
java -jar dist/RenderPerfTest.jar
or
java -jar dist/RenderPerfTest.jar testWhiteTextBubblesGray
2019-09-06 16:06:07 +03:00
Jayathirth D V
493e7d102a 8228576: Use setNeedsDisplay to start blitting in Appkit thread in Metal
Co-authored-by: Ajit Ghaisas <ajit.ghaisas@oracle.com>
Reviewed-by: aghaisas
2019-09-06 16:09:19 +05:30
Alexey Ushakov
54f1e4ec23 8230657: Create fine grained render perf test for metal pipeline
To run the tests:
cd src/demo/share/java2d/RenderPerfTest

sh gradlew test -i
or
sh gradlew test --tests *testWiredBoxBubbles* -i
2019-09-05 17:35:46 +03:00
Alexey Ushakov
a59e9ab2ac 8230647: Provide metal shaders library for all build targets 2019-09-05 13:15:38 +03:00
Ajit Ghaisas
6bd87cb96f 8230641: MTLRenderer_FillSpans method needs to be optimized by reducing total number of drawPrimitives calls
Reviewed-by: jdv
2019-09-05 15:28:54 +05:30
Jayathirth D V
7a448bc74d 8230287: Use single render encoder per destination for metal 2019-08-28 17:23:11 +05:30
Alexey Ushakov
b5cc29da48 Added support for Xcode 10 2019-08-23 22:51:17 +03:00
Jayathirth D V
d98d18b297 8230042: Fix metal shader generation path
Reviewed-by: aghaisas
2019-08-22 19:52:56 +05:30
Jayathirth D V
1441538b23 8229915: Migrate the metal changes from sandbox to lanai repository
Co-authored-by: Alexey Ushakov <alexey.ushakov@jetbrains.com>
Co-authored-by: Ajit Ghaisas <ajit.ghaisas@oracle.com>
Reviewed-by: aghaisas
2019-08-22 17:57:55 +05:30
117 changed files with 20602 additions and 94 deletions

View File

@@ -1,13 +1,32 @@
;
; Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
;
; This code is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License version 2 only, as
; published by the Free Software Foundation.
;
; This code is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; version 2 for more details (a copy is included in the LICENSE file that
; accompanied this code).
;
; You should have received a copy of the GNU General Public License version
; 2 along with this work; if not, write to the Free Software Foundation,
; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
;
; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
; or visit www.oracle.com if you need additional information or have any
; questions.
;
[general]
project=jdk
project=lanai
jbs=JDK
[checks]
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
[repository]
tags=(?:jdk-(?:[1-9]([0-9]*)(?:\.(?:0|[1-9][0-9]*)){0,4})(?:\+(?:(?:[0-9]+))|(?:-ga)))|(?:jdk[4-9](?:u\d{1,3})?-(?:(?:b\d{2,3})|(?:ga)))|(?:hs\d\d(?:\.\d{1,2})?-b\d\d)
branches=
error=author,whitespace,executable
[census]
version=0
@@ -15,19 +34,3 @@ domain=openjdk.org
[checks "whitespace"]
files=.*\.cpp|.*\.hpp|.*\.c|.*\.h|.*\.java|.*\.cc|.*\.hh|.*\.m|.*\.mm
[checks "merge"]
message=Merge
[checks "reviewers"]
reviewers=1
ignore=duke
[checks "committer"]
role=committer
[checks "issues"]
pattern=^([124-8][0-9]{6}): (\S.*)$
[checks "problemlists"]
dirs=test/jdk|test/langtools|test/lib-test|test/hotspot/jtreg|test/jaxp

View File

@@ -0,0 +1,10 @@
# jetbrains/runtime:jbr15env
FROM centos:7
RUN yum -y install centos-release-scl
RUN yum -y install devtoolset-8
RUN yum -y install zip bzip2 unzip tar wget make autoconf automake libtool alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel freetype-devel file which libXtst-devel libXt-devel libXrender-devel alsa-lib-devel fontconfig-devel libXrandr-devel libXi-devel git
# Install Java 11
RUN wget https://download.java.net/java/GA/jdk13.0.1/cec27d702aa74d5a8630c65ae61e4305/9/GPL/openjdk-13.0.1_linux-x64_bin.tar.gz \
-O - | tar xz -C /
ENV JAVA_HOME /jbrsdk
ENV PATH $JAVA_HOME/bin:/opt/rh/devtoolset-8/root/usr/bin:$PATH

View File

@@ -0,0 +1,135 @@
apply plugin: 'java'
import org.gradle.internal.os.OperatingSystem
repositories {
mavenCentral()
}
def test_jvm = {
if (project.hasProperty('jbsdkhome')) {
file(jbsdkhome + (OperatingSystem.current().isWindows()?"/bin/java.exe" : "/bin/java")).absolutePath
} else {
if (OperatingSystem.current().isMacOsX()) {
file('../../../build/macosx-x86_64-normal-server-release/images/jdk-bundle/jdk-11.0.4.jdk/Contents/Home/bin/java').absolutePath
} else if (OperatingSystem.current().isLinux()) {
file('../../../build/linux-x86_64-normal-server-release/images/jdk/bin/java').absolutePath
} else {
file('../../../build/windows-x86_64-normal-server-release/images/jdk/bin/java.exe').absolutePath
}
}
}
dependencies {
testCompile('junit:junit:4.12'){
exclude group: 'org.hamcrest'
}
testCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'net.java.dev.jna:jna:4.4.0'
testCompile 'com.twelvemonkeys.imageio:imageio-tiff:3.3.2'
testCompile 'org.apache.commons:commons-lang3:3.0'
}
def jdk_modules = ["java.base", "java.logging", "java.prefs",
"java.se.ee", "java.sql", "java.datatransfer",
"java.management", "java.rmi", "java.security.jgss",
"java.sql.rowset", "java.desktop", "java.management.rmi",
"java.scripting", "java.security.sasl", "java.transaction",
"java.instrument", "java.naming", "java.se",
"java.smartcardio", "java.xml.crypto"]
def jdk_class_dirs = []
jdk_modules.collect(jdk_class_dirs) {
new File("../../../src/" + it + "/share/classes")
}
if (OperatingSystem.current().isMacOsX())
jdk_modules.collect(jdk_class_dirs) {
"../../../src/" + it + "/macosx/classes"
}
else if (OperatingSystem.current().isLinux()) {
jdk_modules.collect(jdk_class_dirs) {
"../../../src/" + it + "/solaris/classes"
}
jdk_modules.collect(jdk_class_dirs) {
"../../../src/" + it + "/unix/classes"
}
} else
jdk_modules.collect(jdk_class_dirs) {
"../../../src/" + it + "/windows/classes"
}
sourceSets.main.java.srcDirs = jdk_class_dirs
sourceSets {
test {
java {
srcDir "../../../test/jdk/jbu"
}
}
}
test.dependsOn.clear()
test.dependsOn tasks.compileTestJava
test {
systemProperty "jb.java2d.metal", "true"
systemProperty "testdata", file('../../../test/jdk/jbu/testdata').absolutePath
// Generate golden images for DroidFontTest and MixedTextTest
// systemProperty "gentestdata", ""
// Enable Java2D logging (https://confluence.jetbrains.com/display/JRE/Java2D+Rendering+Logging)
// systemProperty "sun.java2d.trace", "log"
// systemProperty "sun.java2d.trace", "log,pimpl"
outputs.upToDateWhen { false }
executable = test_jvm()
// Enable async/dtrace profiler
jvmArgs "-XX:+PreserveFramePointer"
// Enable native J2D logging (only in debug build)
// Can be turned on for J2D by adding "#define DEBUG 1" into jdk/src/share/native/sun/java2d/Trace.h
// environment 'J2D_TRACE_LEVEL', '4'
}
def buildDir = project.buildscript.sourceFile.parentFile.parentFile.parentFile.parentFile
def make_cmd = "make"
if (OperatingSystem.current().isWindows()) {
def cyg_make_cmd = new File("c:/cygwin64/bin/make.exe")
if (cyg_make_cmd.exists()) make_cmd = cyg_make_cmd.absolutePath
}
def test_run = false
task make_images {
doLast {
if (!test_run) {
def pb = new ProcessBuilder().command(make_cmd.toString(), "-C", buildDir.absolutePath, "images")
def proc = pb.redirectErrorStream(true).start()
proc.inputStream.eachLine { println it }
assert proc.waitFor() == 0
}
}
}
task make_clean {
doLast {
def pb = new ProcessBuilder().command(make_cmd.toString(), "-C", buildDir.absolutePath, "clean")
def proc = pb.redirectErrorStream(true).start()
proc.inputStream.eachLine { println it }
assert proc.waitFor() == 0
}
}
task run_test {
doLast {
test_run = true
}
}
tasks.cleanTest.dependsOn tasks.run_test
classes.dependsOn.clear()
classes.dependsOn tasks.make_images
tasks.cleanClasses.dependsOn tasks.make_clean

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Thu Dec 06 20:31:44 MSK 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip

172
jb/project/java-gradle/gradlew vendored Executable file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/linux/scripts
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -0,0 +1,77 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-boot-jdk=amazon-corretto-11.0.5.10.1-linux-aarch64 \
--with-import-modules=./modular-sdk \
--enable-cds=yes || exit $?
make clean CONF=linux-aarch64-normal-server-release || exit $?
make images CONF=linux-aarch64-normal-server-release test-image || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-aarch64-b${build_number}
BASE_DIR=build/linux-aarch64-normal-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar \
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
gzip $JBSDK.tar || exit $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-aarch64-b$build_number
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.aarch64
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list.aarch64 | sed s/" "//g | sed s/,$//g) \
--output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
echo Creating $JBR.tar.gz ...
tar -pcf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
gzip $JBR.tar || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-aarch64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?

View File

@@ -0,0 +1,139 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
function create_jbr {
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
*)
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
JBR=$JBR_BASE_NAME-linux-x64-b$build_number
echo Running jlink....
$JSDK/bin/jlink \
--module-path $JSDK/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output $BASE_DIR/$JBR_BUNDLE
if [[ "$bundle_type" == *jcef* ]]; then
cp -R $BASE_DIR/$JBR_BUNDLE $BASE_DIR/jbr
cp -R jcef_linux_x64/* $BASE_DIR/$JBR_BUNDLE/lib || exit $?
fi
grep -v "^JAVA_VERSION" $JSDK/release | grep -v "^MODULES" >> $BASE_DIR/$JBR_BUNDLE/release
echo Creating $JBR.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
tar -pcf $JBR.tar -C $BASE_DIR jbr || exit $?
gzip $JBR.tar || exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
}
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
;;
esac
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-boot-jdk=$BOOT_JDK \
--enable-cds=yes || exit $?
else
JBR_BUNDLE=jbr_${bundle_type}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=./modular-sdk \
--with-boot-jdk=$BOOT_JDK \
--enable-cds=yes || exit $?
fi
make images CONF=linux-x86_64-server-release || exit $?
JSDK=build/linux-x86_64-server-release/images/jdk
JBSDK=$JBRSDK_BASE_NAME-linux-x64-b$build_number
echo Fixing permissions
chmod -R a+r $JSDK
BASE_DIR=build/linux-x86_64-server-release/images
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
if [[ "$bundle_type" == *jcef* ]]; then
cp -R jcef_linux_x64/* $BASE_DIR/$JBRSDK_BUNDLE/lib || exit $?
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar --exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR $JBRSDK_BUNDLE || exit $?
gzip $JBSDK.tar || exit $?
fi
create_jbr ${bundle_type}
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make test-image || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x64-b$build_number
echo Creating $JBSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?
fi

View File

@@ -0,0 +1,72 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=fastdebug \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-import-modules=./modular-sdk \
--enable-cds=yes || exit $?
make clean CONF=linux-x86_64-normal-server-fastdebug || exit $?
make images CONF=linux-x86_64-normal-server-fastdebug || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-x64-fastdebug-b${build_number}
BASE_DIR=build/linux-x86_64-normal-server-fastdebug/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
cp -R jcef_linux_x64/* $BASE_DIR/$JBRSDK_BUNDLE/lib || exit $?
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar \
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
gzip $JBSDK.tar || exit $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-x64-fastdebug-b$build_number
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list | sed s/" "//g | sed s/,$//g) \
--output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
cp -R jcef_linux_x64/* $BASE_DIR/$JBR_BUNDLE/lib || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
echo Creating $JBR.tar.gz ...
tar -czf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
gzip $JBR.tar || exit $?

View File

@@ -0,0 +1,73 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
linux32 bash configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-boot-jdk=/jbrsdk-11.0.5-b1 \
--enable-cds=yes || exit $?
make clean CONF=linux-x86-normal-server-release || exit $?
make images CONF=linux-x86-normal-server-release test-image || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-x86-b${build_number}
BASE_DIR=build/linux-x86-normal-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar --exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man -C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
gzip $JBSDK.tar || exit $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-x86-b$build_number
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list.x86 | sed s/" "//g | sed s/,$//g) --output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
echo Creating $JBR.tar.gz ...
tar -pcf $JBR.tar -C $BASE_DIR $JBR_BUNDLE || exit $?
gzip $JBR.tar || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x86-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' --exclude='test/hotspot/gtest' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,9 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/mac/scripts
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -0,0 +1,148 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
function create_jbr {
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
*)
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
JRE_CONTENTS=${BASE_DIR}/${JBR_BUNDLE}/Contents
JRE_HOME=${JRE_CONTENTS}/Home
if [ -d "${JRE_CONTENTS}" ]; then
rm -rf ${JRE_CONTENTS}
fi
mkdir -p ${JRE_CONTENTS}
JBR=${JBR_BASE_NAME}-osx-x64-b${build_number}
${BASE_DIR}/$JBRSDK_BUNDLE/Contents/Home/bin/jlink \
--module-path ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output ${JRE_HOME} || exit $?
grep -v "^JAVA_VERSION" ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release | grep -v "^MODULES" >> ${JRE_HOME}/release
cp -R ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/MacOS ${JRE_CONTENTS}
cp ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Info.plist ${JRE_CONTENTS}
if [[ "${bundle_type}" == *jcef* ]]; then
rm -rf ${JRE_CONTENTS}/Frameworks || exit $?
rm -rf ${JRE_CONTENTS}/Helpers || exit $?
cp -a jcef_mac/Frameworks ${JRE_CONTENTS} || exit $?
cp -a jcef_mac/Helpers ${JRE_CONTENTS} || exit $?
fi
echo Creating ${JBR}.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
COPYFILE_DISABLE=1 tar -pczf ${JBR}.tar.gz --exclude='*.dSYM' --exclude='man' -C ${BASE_DIR} jbr || exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
;;
esac
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-boot-jdk=`/usr/libexec/java_home -v $BOOT_JDK` \
--enable-cds=yes || exit $?
else
JBR_BUNDLE=jbr_${bundle_type}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=./modular-sdk \
--with-boot-jdk=`/usr/libexec/java_home -v $BOOT_JDK` \
--enable-cds=yes || exit $?
fi
make images CONF=macosx-x86_64-server-release || exit $?
JSDK=build/macosx-x86_64-server-release/images/jdk-bundle
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-b${build_number}
BASE_DIR=jre
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR
mkdir $BASE_DIR || exit $?
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
cp -a $JSDK/jdk-$JBSDK_VERSION_WITH_DOTS.jdk $BASE_DIR/$JBRSDK_BUNDLE || exit $?
if [[ "$bundle_type" == *jcef* ]]; then
cp -a jcef_mac/Frameworks $BASE_DIR/$JBRSDK_BUNDLE/Contents/ || exit $?
cp -a jcef_mac/Helpers $BASE_DIR/$JBRSDK_BUNDLE/Contents/ || exit $?
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
echo Creating $JBSDK.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBSDK.tar.gz -C $BASE_DIR \
--exclude='._*' --exclude='.DS_Store' --exclude='*~' \
--exclude='Home/demo' --exclude='Home/man' --exclude='Home/sample' \
$JBRSDK_BUNDLE || exit $?
fi
create_jbr "${bundle_type}" || exit $?
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make test-image || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-osx-test-x64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBRSDK_TEST.tar.gz -C build/macosx-x86_64-server-release/images \
--exclude='test/jdk/demos' test || exit $?
fi

View File

@@ -0,0 +1,83 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=fastdebug \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-import-modules=./modular-sdk \
--with-boot-jdk=`/usr/libexec/java_home -v 11` \
--enable-cds=yes || exit $?
make clean CONF=macosx-x86_64-normal-server-fastdebug || exit $?
make images CONF=macosx-x86_64-normal-server-fastdebug || exit $?
JSDK=build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-fastdebug-b${build_number}
BASE_DIR=jre
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR
mkdir $BASE_DIR || exit $?
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
cp -a $JSDK/jdk-$JBSDK_VERSION_WITH_DOTS.jdk $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
cp -a jcef_mac/Frameworks $BASE_DIR/$JBRSDK_BUNDLE/Contents/
cp -a jcef_mac/Helpers $BASE_DIR/$JBRSDK_BUNDLE/Contents
COPYFILE_DISABLE=1 \
tar -pczf ${JBSDK}.tar.gz -C ${BASE_DIR} \
--exclude='._*' --exclude='.DS_Store' --exclude='*~' \
--exclude='Home/demo' --exclude='Home/man' --exclude='Home/sample' \
${JBRSDK_BUNDLE} || exit $?
JBR_BUNDLE=jbr
JRE_CONTENTS=$BASE_DIR/$JBR_BUNDLE/Contents
JRE_HOME=$JRE_CONTENTS/Home
JBR_BASE_NAME=jbr-$JBSDK_VERSION
mkdir -p $JRE_CONTENTS
if [ -d "$JRE_HOME" ]; then
rm -rf $JRE_HOME
fi
JBR=${JBR_BASE_NAME}-osx-x64-fastdebug-b${build_number}
$BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/bin/jlink \
--module-path $BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list | sed s/" "//g) --output $JRE_HOME || exit $?
grep -v "^JAVA_VERSION" $BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/release | grep -v "^MODULES" >> $JRE_HOME/release
cp -R $BASE_DIR/$JBRSDK_BUNDLE/Contents/MacOS $JRE_CONTENTS
cp $BASE_DIR/$JBRSDK_BUNDLE/Contents/Info.plist $JRE_CONTENTS
cp -a jcef_mac/Frameworks ${JRE_CONTENTS} || exit $?
cp -a jcef_mac/Helpers ${JRE_CONTENTS} || exit $?
echo Creating $JBR.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBR.tar.gz --exclude='*.dSYM' --exclude='man' -C $BASE_DIR $JBR_BUNDLE || exit $?

View File

@@ -0,0 +1,120 @@
#!/bin/bash
APP_DIRECTORY=$1
APPL_USER=$2
APPL_PASSWORD=$3
APP_NAME=$4
BUNDLE_ID=$5
FAKE_ROOT="${6:-fake-root}"
if [[ -z "$APP_DIRECTORY" ]] || [[ -z "$APPL_USER" ]] || [[ -z "$APPL_PASSWORD" ]]; then
echo "Usage: $0 AppDirectory Username Password"
exit 1
fi
if [[ ! -d "$APP_DIRECTORY" ]]; then
echo "AppDirectory '$APP_DIRECTORY' does not exist or not a directory"
exit 1
fi
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
function publish-log() {
id=$1
file=$2
curl -T "$file" "$ARTIFACTORY_URL/$id" || true
}
function altool-upload() {
# Since altool uses same file for upload token we have to trick it into using different folders for token file location
# Also it copies zip into TMPDIR so we override it too, to simplify cleanup
OLD_HOME="$HOME"
export HOME="$FAKE_ROOT/home"
export TMPDIR="$FAKE_ROOT/tmp"
mkdir -p "$HOME"
mkdir -p "$TMPDIR"
export _JAVA_OPTIONS="-Duser.home=$HOME -Djava.io.tmpdir=$TMPDIR"
# Reduce amount of downloads, cache transporter libraries
shared_itmstransporter="$OLD_HOME/shared-itmstransporter"
if [[ -f "$shared_itmstransporter" ]]; then
cp -r "$shared_itmstransporter" "$HOME/.itmstransporter"
fi
# For some reason altool prints everything to stderr, not stdout
set +e
xcrun altool --notarize-app \
--username "$APPL_USER" --password "$APPL_PASSWORD" \
--primary-bundle-id "$BUNDLE_ID" \
--asc-provider JetBrainssro --file "$1" 2>&1 | tee "altool.init.out"
unset TMPDIR
export HOME="$OLD_HOME"
set -e
}
#immediately exit script with an error if a command fails
set -euo pipefail
file="$APP_NAME.zip"
log "Zipping $file..."
rm -rf "$file"
ditto -c -k --sequesterRsrc --keepParent "$APP_DIRECTORY/Contents" "$file"
log "Notarizing $file..."
rm -rf "altool.init.out" "altool.check.out"
altool-upload "$file"
rm -rf "$file"
notarization_info="$(grep -e "RequestUUID" "altool.init.out" | grep -oE '([0-9a-f-]{36})')"
if [ -z "$notarization_info" ]; then
log "Faile to read RequestUUID from altool.init.out"
exit 10
fi
PATH="$PATH:/usr/local/bin/"
log "Notarization request sent, awaiting response"
spent=0
while true; do
# For some reason altool prints everything to stderr, not stdout
xcrun altool --username "$APPL_USER" --notarization-info "$notarization_info" --password "$APPL_PASSWORD" >"altool.check.out" 2>&1 || true
status="$(grep -oe 'Status: .*' "altool.check.out" | cut -c 9- || true)"
log "Current status: $status"
if [ "$status" = "invalid" ]; then
log "Notarization failed"
ec=1
elif [ "$status" = "success" ]; then
log "Notarization succeeded"
ec=0
else
if [ "$status" != "in progress" ]; then
log "Unknown notarization status, waiting more, altool output:"
cat "altool.check.out"
fi
if [[ $spent -gt 60 ]]; then
log "Waiting time out (apx 60 minutes)"
ec=2
break
fi
sleep 60
((spent += 1))
continue
fi
developer_log="developer_log.json"
log "Fetching $developer_log"
# TODO: Replace cut with trim or something better
url="$(grep -oe 'LogFileURL: .*' "altool.check.out" | cut -c 13-)"
wget "$url" -O "$developer_log" && cat "$developer_log" || true
if [ $ec != 0 ]; then
log "Publishing $developer_log"
publish-log "$notarization_info" "$developer_log"
fi
break
done
cat "altool.check.out"
rm -rf "altool.init.out" "altool.check.out"
exit $ec

View File

@@ -0,0 +1,93 @@
#!/bin/bash
APP_DIRECTORY=$1
JB_CERT=$2
if [[ -z "$APP_DIRECTORY" ]] || [[ -z "$JB_CERT" ]]; then
echo "Usage: $0 AppDirectory CertificateID"
exit 1
fi
if [[ ! -d "$APP_DIRECTORY" ]]; then
echo "AppDirectory '$APP_DIRECTORY' does not exist or not a directory"
exit 1
fi
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
#immediately exit script with an error if a command fails
set -euo pipefail
# Cleanup files left from previous sign attempt (if any)
find "$APP_DIRECTORY" -name '*.cstemp' -exec rm '{}' \;
log "Signing libraries and executables..."
# -perm +111 searches for executables
for f in \
"Contents/Home/bin" \
"Contents/Home/lib"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
fi
done
log "Signing libraries in jars in $PWD"
# todo: add set -euo pipefail; into the inner sh -c
# `-e` prevents `grep -q && printf` loginc
# with `-o pipefail` there's no input for 'while' loop
find "$APP_DIRECTORY" -name '*.jar' \
-exec sh -c "set -u; unzip -l \"\$0\" | grep -q -e '\.dylib\$' -e '\.jnilib\$' -e '\.so\$' -e '^jattach\$' && printf \"\$0\0\" " {} \; |
while IFS= read -r -d $'\0' file; do
log "Processing libraries in $file"
rm -rf jarfolder jar.jar
mkdir jarfolder
filename="${file##*/}"
log "Filename: $filename"
cp "$file" jarfolder && (cd jarfolder && jar xf "$filename" && rm "$filename")
find jarfolder \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -name "jattach" \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
(cd jarfolder; zip -q -r -o ../jar.jar .)
mv jar.jar "$file"
done
rm -rf jarfolder jar.jar
log "Signing other files..."
for f in \
"Contents/MacOS"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
fi
done
#log "Signing executable..."
#codesign --timestamp \
# -v -s "$JB_CERT" --options=runtime \
# --force \
# --entitlements entitlements.xml "$APP_DIRECTORY/Contents/MacOS/idea"
log "Signing whole app..."
codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--force \
--entitlements entitlements.xml "$APP_DIRECTORY"
log "Verifying java is not broken"
find "$APP_DIRECTORY" \
-type f -name 'java' -perm +111 -exec {} -version \;

View File

@@ -0,0 +1,145 @@
#!/bin/bash
#immediately exit script with an error if a command fails
set -euo pipefail
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
export COPYFILE_DISABLE=true
INPUT_FILE=$1
EXPLODED=$2.exploded
BACKUP_JMODS=$2.backup
USERNAME=$3
PASSWORD=$4
CODESIGN_STRING=$5
NOTARIZE=$6
BUNDLE_ID=$7
cd "$(dirname "$0")"
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
log "Deleting $EXPLODED ..."
if test -d "$EXPLODED"; then
find "$EXPLODED" -mindepth 1 -maxdepth 1 -exec chmod -R u+wx '{}' \;
fi
rm -rf "$EXPLODED"
mkdir "$EXPLODED"
rm -rf "$BACKUP_JMODS"
mkdir "$BACKUP_JMODS"
log "Unzipping $INPUT_FILE to $EXPLODED ..."
tar -xzvf "$INPUT_FILE" --directory $EXPLODED
rm "$INPUT_FILE"
BUILD_NAME="$(ls "$EXPLODED")"
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/jmods; then
mv $EXPLODED/$BUILD_NAME/Contents/Home/jmods $BACKUP_JMODS
fi
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks; then
mv $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks $BACKUP_JMODS
fi
if test -f $EXPLODED/$BUILD_NAME/Contents/MacOS/libjli.dylib; then
mv $EXPLODED/$BUILD_NAME/Contents/MacOS/libjli.dylib $BACKUP_JMODS
fi
#log "$INPUT_FILE unzipped and removed"
log "$INPUT_FILE extracted and removed"
APPLICATION_PATH="$EXPLODED/$BUILD_NAME"
find "$APPLICATION_PATH/Contents/Home/bin" \
-maxdepth 1 -type f -name '*.jnilib' -print0 |
while IFS= read -r -d $'\0' file; do
if [ -f "$file" ]; then
log "Linking $file"
b="$(basename "$file" .jnilib)"
ln -sf "$b.jnilib" "$(dirname "$file")/$b.dylib"
fi
done
find "$APPLICATION_PATH/Contents/" \
-maxdepth 1 -type f -name '*.txt' -print0 |
while IFS= read -r -d $'\0' file; do
if [ -f "$file" ]; then
log "Moving $file"
mv "$file" "$APPLICATION_PATH/Contents/Resources"
fi
done
non_plist=$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist' | wc -l)
if [[ $non_plist -gt 0 ]]; then
log "Only Info.plist file is allowed in Contents directory but found $non_plist file(s):"
log "$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist')"
exit 1
fi
log "Unlocking keychain..."
# Make sure *.p12 is imported into local KeyChain
security unlock-keychain -p "$PASSWORD" "/Users/$USERNAME/Library/Keychains/login.keychain"
attempt=1
limit=3
set +e
while [[ $attempt -le $limit ]]; do
log "Signing (attempt $attempt) $APPLICATION_PATH ..."
./sign.sh "$APPLICATION_PATH" "$CODESIGN_STRING"
ec=$?
if [[ $ec -ne 0 ]]; then
((attempt += 1))
if [ $attempt -eq $limit ]; then
set -e
fi
log "Signing failed, wait for 30 sec and try to sign again"
sleep 30
else
log "Signing done"
codesign -v "$APPLICATION_PATH" -vvvvv
log "Check sign done"
((attempt += limit))
fi
done
set -e
if [ "$NOTARIZE" = "yes" ]; then
log "Notarizing..."
# shellcheck disable=SC1090
source "$HOME/.notarize_token"
APP_NAME=$(echo ${INPUT_FILE} | awk -F"." '{ print $1 }')
# Since notarization tool uses same file for upload token we have to trick it into using different folders, hence fake root
# Also it leaves copy of zip file in TMPDIR, so notarize.sh overrides it and uses FAKE_ROOT as location for temp TMPDIR
FAKE_ROOT="$(pwd)/fake-root"
mkdir -p "$FAKE_ROOT"
echo "Notarization will use fake root: $FAKE_ROOT"
./notarize.sh "$APPLICATION_PATH" "$APPLE_USERNAME" "$APPLE_PASSWORD" "$APP_NAME" "$BUNDLE_ID" "$FAKE_ROOT"
rm -rf "$FAKE_ROOT"
set +e
log "Stapling..."
xcrun stapler staple "$APPLICATION_PATH"
else
log "Notarization disabled"
log "Stapling disabled"
fi
log "Zipping $BUILD_NAME to $INPUT_FILE ..."
(
#cd "$EXPLODED"
#ditto -c -k --sequesterRsrc --keepParent "$BUILD_NAME" "../$INPUT_FILE"
if test ! -z $(ls $BACKUP_JMODS/libjli.dylib); then
mv $BACKUP_JMODS/libjli.dylib $EXPLODED/$BUILD_NAME/Contents/MacOS
fi
if test -d $BACKUP_JMODS/jmods; then
mv $BACKUP_JMODS/jmods $EXPLODED/$BUILD_NAME/Contents/Home
fi
if test -d $BACKUP_JMODS/Frameworks; then
mv $BACKUP_JMODS/Frameworks $EXPLODED/$BUILD_NAME/Contents/Home
fi
COPYFILE_DISABLE=1 tar -pczf $INPUT_FILE --exclude='*.dSYM' --exclude='man' -C $EXPLODED $BUILD_NAME
log "Finished zipping"
)
rm -rf "$EXPLODED"
log "Done"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/windows/scripts
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -0,0 +1,119 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
function create_jbr {
case "$1" in
"${bundle_type}_lw")
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef" | "jfx_jcef")
cat modules.list > modules_tmp.list
;;
*)
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${JBR_BUNDLE}
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output ${JBR_BUNDLE} || exit $?
if [[ "${bundle_type}" == *jcef* ]]
then
cp -R jcef_win_x64/* ${JBR_BUNDLE}/bin
fi
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WORK_DIR=$(pwd)
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
echo "Excluding jcef modules"
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
echo "Excluding jfx modules"
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
;;
esac
PATH="/usr/local/bin:/usr/bin:${PATH}"
if [ -z "$bundle_type" ]; then
bash ./configure \
--disable-warnings-as-errors \
--with-target-bits=64 \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
else
bash ./configure \
--disable-warnings-as-errors \
--with-target-bits=64 \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=${WORK_DIR}/modular-sdk \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make LOG=info images CONF=windows-x86_64-server-release test-image || exit 1
else
make LOG=info images CONF=windows-x86_64-server-release || exit 1
fi
JSDK=build/windows-x86_64-server-release/images/jdk
if [[ "$bundle_type" == "*jcef*" || -z "$bundle_type" ]]; then
JBSDK=${JBRSDK_BASE_NAME}-windows-x64-b${build_number}
fi
BASE_DIR=build/windows-x86_64-server-release/images
JBRSDK_BUNDLE=jbrsdk
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || exit 1
if [[ "$bundle_type" == "*jcef*" ]]; then
cp -R jcef_win_x64/* ${JBRSDK_BUNDLE}/bin
fi
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
create_jbr ${bundle_type}
#JBR_BUNDLE=jbr_${bundle_type}_lw
#create_jbr ${bundle_type}_lw

View File

@@ -0,0 +1,57 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WORK_DIR=$(pwd)
PATH="/usr/local/bin:/usr/bin:${PATH}"
./configure \
--disable-warnings-as-errors \
--disable-debug-symbols \
--with-target-bits=32 \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-toolchain-version=2015 \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
make clean CONF=windows-x86-normal-server-release || exit 1
make LOG=info images CONF=windows-x86-normal-server-release test-image || exit 1
JBSDK=${JBRSDK_BASE_NAME}-windows-x86-b${build_number}
BASE_DIR=build/windows-x86-normal-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || exit 1
JBR_BUNDLE=jbr
rm -rf ${JBR_BUNDLE}
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list.x86 | sed s/" "//g) --output ${JBR_BUNDLE} || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release

View File

@@ -0,0 +1,79 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
function pack_jbr {
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef" | "")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && exit 1
;;
esac
JBR=$JBR_BASE_NAME-windows-x64-b$build_number
echo Creating $JBR.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR jbr || exit 1
#rm -rf ${BASE_DIR}/${JBR_BUNDLE}
}
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
JBR_BASE_NAME=jbr-$JBSDK_VERSION
IMAGES_DIR=build/windows-x86_64-server-release/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x64-b$build_number
BASE_DIR=.
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
JBRSDK_BUNDLE=jbrsdk
echo Creating $JBSDK.tar.gz ...
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || exit 1
fi
JBR_BUNDLE=jbr_${bundle_type}
pack_jbr $bundle_type
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
JBRSDK_TEST=$JBRSDK_BASE_NAME-windows-test-x64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
/usr/bin/tar -czf $JBRSDK_TEST.tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || exit 1
fi

View File

@@ -0,0 +1,45 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
JBR_BASE_NAME=jbr-$JBSDK_VERSION
IMAGES_DIR=build/windows-x86-normal-server-release/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x86-b$build_number
BASE_DIR=.
JBRSDK_BUNDLE=jbrsdk
echo Creating $JBSDK.tar.gz ...
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || exit 1
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
JBR=$JBR_BASE_NAME-windows-x86-b$build_number
echo Creating $JBR.tar.gz ...
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR ${JBR_BUNDLE} || exit 1
JBRSDK_TEST=$JBRSDK_BASE_NAME-windows-test-x86-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
/usr/bin/tar -czf $JBRSDK_TEST.tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || exit 1

View File

@@ -563,6 +563,8 @@ CXXFILT:=@CXXFILT@
LIPO:=@LIPO@
INSTALL_NAME_TOOL:=@INSTALL_NAME_TOOL@
METAL := @METAL@
METALLIB := @METALLIB@
# Options to linker to specify a mapfile.
# (Note absence of := assignment, because we do not want to evaluate the macro body here)

View File

@@ -776,6 +776,32 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_EXTRA],
UTIL_FIXUP_EXECUTABLE(OTOOL)
UTIL_REQUIRE_PROGS(INSTALL_NAME_TOOL, install_name_tool)
UTIL_FIXUP_EXECUTABLE(INSTALL_NAME_TOOL)
UTIL_PATH_PROGS(METAL, metal)
if test "x$METAL" = x; then
AC_MSG_CHECKING([if metal can be run using xcrun])
METAL="xcrun -sdk macosx metal"
test_metal=`$METAL --version 2>&1`
if test $? -ne 0; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([XCode tool 'metal' neither found in path nor with xcrun])
else
AC_MSG_RESULT([yes, will be using '$METAL'])
fi
fi
UTIL_PATH_PROGS(METALLIB, metallib)
if test "x$METALLIB" = x; then
AC_MSG_CHECKING([if metallib can be run using xcrun])
METALLIB="xcrun -sdk macosx metallib"
test_metallib=`$METALLIB --version 2>&1`
if test $? -ne 0; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([XCode tool 'metallib' neither found in path nor with xcrun])
else
AC_MSG_RESULT([yes, will be using '$METALLIB'])
fi
fi
fi
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then

View File

@@ -24,6 +24,7 @@
#
include LibCommon.gmk
include Execute.gmk
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, modules/java.desktop/Lib.gmk))

View File

@@ -160,6 +160,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT, \
LIBS_macosx := -lmlib_image \
-framework Cocoa \
-framework OpenGL \
-framework Metal \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework ApplicationServices \
@@ -764,6 +765,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
-framework Foundation \
-framework Security \
-framework Cocoa \
-framework Metal \
-framework JavaNativeFoundation
else ifeq ($(call isTargetOs, windows), true)
LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
@@ -824,6 +826,7 @@ ifeq ($(call isTargetOs, macosx), true)
libawt_lwawt/awt \
libawt_lwawt/font \
libawt_lwawt/java2d/opengl \
libawt_lwawt/java2d/metal \
include \
common/awt/debug \
common/java2d/opengl \
@@ -859,6 +862,7 @@ ifeq ($(call isTargetOs, macosx), true)
-framework AudioToolbox \
-framework Carbon \
-framework Cocoa \
-framework Metal \
-framework Security \
-framework ExceptionHandling \
-framework JavaNativeFoundation \
@@ -882,6 +886,28 @@ endif
################################################################################
ifeq ($(call isTargetOs, macosx), true)
SHADERS_SRC := $(TOPDIR)/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal
SHADERS_SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/native/java.desktop/libosxui
SHADERS_AIR := $(SHADERS_SUPPORT_DIR)/shaders.air
SHADERS_LIB := $(INSTALL_LIBRARIES_HERE)/shaders.metallib
$(eval $(call SetupExecute, metal_shaders, \
INFO := Running metal on $(notdir $(SHADERS_SRC)) (for libosxui.dylib), \
DEPS := $(SHADERS_SRC), \
OUTPUT_FILE := $(SHADERS_AIR), \
SUPPORT_DIR := $(SHADERS_SUPPORT_DIR), \
COMMAND := $(METAL) -c -std=osx-metal2.0 -o $(SHADERS_AIR) $(SHADERS_SRC), \
))
$(eval $(call SetupExecute, metallib_shaders, \
INFO := Running metallib on $(notdir $(SHADERS_AIR)) (for libosxui.dylib), \
DEPS := $(SHADERS_AIR), \
OUTPUT_FILE := $(SHADERS_LIB), \
SUPPORT_DIR := $(SHADERS_SUPPORT_DIR), \
COMMAND := $(METALLIB) -o $(SHADERS_LIB) $(SHADERS_AIR), \
))
TARGETS += $(SHADERS_LIB)
$(eval $(call SetupJdkLibrary, BUILD_LIBOSXUI, \
NAME := osxui, \
@@ -897,6 +923,7 @@ ifeq ($(call isTargetOs, macosx), true)
-L$(INSTALL_LIBRARIES_HERE), \
LIBS := -lawt -losxapp -lawt_lwawt \
-framework Cocoa \
-framework Metal \
-framework Carbon \
-framework ApplicationServices \
-framework JavaNativeFoundation \
@@ -905,6 +932,7 @@ ifeq ($(call isTargetOs, macosx), true)
))
TARGETS += $(BUILD_LIBOSXUI)
$(BUILD_LIBOSXUI): $(SHADERS_LIB)
$(BUILD_LIBOSXUI): $(BUILD_LIBAWT)

53
modules.list Normal file
View File

@@ -0,0 +1,53 @@
java.base,
java.compiler,
java.datatransfer,
java.desktop,
java.instrument,
java.logging,
java.management,
java.management.rmi,
java.naming,
java.net.http,
java.prefs,
java.rmi,
java.scripting,
java.se,
java.security.jgss,
java.security.sasl,
java.smartcardio,
java.sql,
java.sql.rowset,
java.transaction.xa,
java.xml,
java.xml.crypto,
jdk.accessibility,
jdk.aot,
jdk.charsets,
jdk.compiler,
jdk.crypto.cryptoki,
jdk.crypto.ec,
jdk.dynalink,
jdk.httpserver,
jdk.internal.ed,
jdk.internal.le,
jdk.internal.vm.ci,
jdk.internal.vm.compiler,
jdk.internal.vm.compiler.management,
jdk.jdi,
jdk.jdwp.agent,
jdk.jfr,
jdk.jsobject,
jdk.localedata,
jdk.management,
jdk.management.agent,
jdk.management.jfr,
jdk.naming.dns,
jdk.naming.rmi,
jdk.net,
jdk.sctp,
jdk.security.auth,
jdk.security.jgss,
jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent

View File

@@ -0,0 +1,86 @@
#
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# - Neither the name of Oracle nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
SOURCEPATH=src
CLASSES=build
DIST=dist
RESOURCES=resources
RENDERPERF_CLASSES = $(CLASSES)/renderperf/RenderPerfTest.class
RENDERPERFLCD_CLASSES = $(CLASSES)/renderperf/RenderPerfLCDTest.class
RENDERPERF_SOURCES = $(SOURCEPATH)/renderperf/RenderPerfTest.java
RENDERPERFLCD_SOURCES = $(SOURCEPATH)/renderperf/RenderPerfLCDTest.java
RENDERPERF_RESOURCES = $(CLASSES)/renderperf/images/duke.png
all: mkdirs $(DIST)/RenderPerfTest.jar $(DIST)/RenderPerfLCDTest.jar
run: mkdirs $(DIST)/RenderPerfTest.jar
java -jar $(DIST)/RenderPerfTest.jar
$(DIST)/RenderPerfTest.jar: \
$(RENDERPERF_CLASSES) $(RENDERPERF_RESOURCES) \
$(CLASSES)/renderperf.manifest
jar cvmf $(CLASSES)/renderperf.manifest $(DIST)/RenderPerfTest.jar -C $(CLASSES) .
$(DIST)/RenderPerfLCDTest.jar: \
$(RENDERPERFLCD_CLASSES) $(RENDERPERFLCD_RESOURCES) \
$(CLASSES)/renderperflcd.manifest
jar cvmf $(CLASSES)/renderperflcd.manifest $(DIST)/RenderPerfLCDTest.jar -C $(CLASSES) .
$(CLASSES)/renderperf/images/%: $(RESOURCES)/renderperf/images/%
cp -r $< $@
$(CLASSES)/renderperf.manifest:
echo "Main-Class: renderperf.RenderPerfTest" > $@
$(CLASSES)/renderperflcd.manifest:
echo "Main-Class: renderperf.RenderPerfLCDTest" > $@
$(DIST):
mkdir $(DIST)
$(CLASSES):
mkdir $(CLASSES)
mkdir -p $(CLASSES)/renderperf/images
mkdirs: $(DIST) $(CLASSES)
$(RENDERPERF_CLASSES): $(RENDERPERF_SOURCES)
javac -g:none -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
$(RENDERPERFLCD_CLASSES): $(RENDERPERFLCD_SOURCES)
javac -g:none -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
clean:
rm -rf $(CLASSES)
rm -rf $(DIST)

View File

@@ -0,0 +1,34 @@
-----------------------------------------------------------------------
Introduction
-----------------------------------------------------------------------
RenderPerfTest is a set of on-screen rendering microbenchmarks to
analyze the performance of Java2D graphical primitives rendering
-----------------------------------------------------------------------
How To Compile
-----------------------------------------------------------------------
#> cd RenderPerfTest
The benchmark can be compiled by using either ant:
#> ant
or gnumake (assuming there's 'javac' in the path):
#> gnumake
The jar files will be generated into RenderPerfTest/dist directory.
-----------------------------------------------------------------------
How To Run RenderPerfTest
-----------------------------------------------------------------------
Run all tests
#> ant run
or
#> java -jar dist/RenderPerfTest.jar
Run particular test cases
#> java -jar dist/RenderPerfTest.jar testWhiteTextBubblesGray ...

View File

@@ -0,0 +1,94 @@
<!--
Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<project name="RenderPerfTest" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<property name="resources" location="resources"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac includeantruntime="false" debug="off" srcdir="${src}" destdir="${build}"/>
</target>
<target name="run" depends="dist"
description="run RenderPerfTest" >
<java jar="${dist}/RenderPerfTest.jar"
fork="true"
>
</java>
</target>
<target name="resources" depends="init"
description="copy resources into build dir" >
<!-- Copy the resource files from ${resources} into ${build}/ -->
<mkdir dir="${dist}"/>
<mkdir dir="${dist}/renderperf"/>
<mkdir dir="${build}/renderperf/images"/>
<copy todir="${build}/renderperf/images">
<fileset dir="resources/renderperf/images" />
</copy>
</target>
<target name="dist" depends="compile, resources"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}"/>
<!-- Put everything in ${build} into the J2DBench.jar file -->
<jar jarfile="${dist}/RenderPerfTest.jar" basedir="${build}">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="renderperf.RenderPerfTest"/>
</manifest>
</jar>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,367 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package renderperf;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class RenderPerfLCDTest {
private static HashSet<String> ignoredTests = new HashSet<>();
private final static int N = 1000;
private final static float WIDTH = 800;
private final static float HEIGHT = 800;
private final static float R = 25;
private final static int BW = 50;
private final static int BH = 50;
private final static int COUNT = 300;
private final static int DELAY = 10;
private final static int RESOLUTION = 5;
private final static int COLOR_TOLERANCE = 10;
private final static int MAX_MEASURE_TIME = 5000;
interface Configurable {
void configure(Graphics2D g2d);
}
interface Renderable {
void setup(Graphics2D g2d);
void render(Graphics2D g2d);
void update();
}
static class Particles {
private float[] bx;
private float[] by;
private float[] vx;
private float[] vy;
private float r;
private int n;
private float x0;
private float y0;
private float width;
private float height;
Particles(int n, float r, float x0, float y0, float width, float height) {
bx = new float[n];
by = new float[n];
vx = new float[n];
vy = new float[n];
this.n = n;
this.r = r;
this.x0 = x0;
this.y0 = y0;
this.width = width;
this.height = height;
for (int i = 0; i < n; i++) {
bx[i] = (float) (x0 + r + 0.1 + Math.random() * (width - 2 * r - 0.2 - x0));
by[i] = (float) (y0 + r + 0.1 + Math.random() * (height - 2 * r - 0.2 - y0));
vx[i] = 0.1f * (float) (Math.random() * 2 * r - r);
vy[i] = 0.1f * (float) (Math.random() * 2 * r - r);
}
}
void render(Graphics2D g2d, ParticleRenderer renderer) {
for (int i = 0; i < n; i++) {
renderer.render(g2d, i, bx, by, vx, vy);
}
}
void update() {
for (int i = 0; i < n; i++) {
bx[i] += vx[i];
if (bx[i] + r > width || bx[i] - r < x0) vx[i] = -vx[i];
by[i] += vy[i];
if (by[i] + r > height || by[i] - r < y0) vy[i] = -vy[i];
}
}
}
ParticleRenderable createPR(ParticleRenderer renderer) {
return new ParticleRenderable(renderer);
}
static class ParticleRenderable implements Renderable {
ParticleRenderer renderer;
Configurable configure;
ParticleRenderable(ParticleRenderer renderer, Configurable configure) {
this.renderer = renderer;
this.configure = configure;
}
ParticleRenderable(ParticleRenderer renderer) {
this(renderer, null);
}
@Override
public void setup(Graphics2D g2d) {
if (configure != null) configure.configure(g2d);
}
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, renderer);
}
@Override
public void update() {
balls.update();
}
public ParticleRenderable configure(Configurable configure) {
this.configure = configure;
return this;
}
}
interface ParticleRenderer {
void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy);
}
static class WhiteTextParticleRenderer implements ParticleRenderer {
float r;
WhiteTextParticleRenderer(float r) {
this.r = r;
}
void setPaint(Graphics2D g2d, int id) {
g2d.setColor(Color.WHITE);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
setPaint(g2d, id);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] - r));
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)y[id]);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] + r));
}
}
static class TextParticleRenderer extends WhiteTextParticleRenderer {
Color[] colors;
float r;
TextParticleRenderer(int n, float r) {
super(r);
colors = new Color[n];
this.r = r;
for (int i = 0; i < n; i++) {
colors[i] = new Color((float) Math.random(),
(float) Math.random(), (float) Math.random());
}
}
void setPaint(Graphics2D g2d, int id) {
g2d.setColor(colors[id % colors.length]);
}
}
static class PerfMeter {
private String name;
private int frame = 0;
private JPanel panel;
private long time;
private double execTime = 0;
private Color expColor = Color.RED;
AtomicBoolean waiting = new AtomicBoolean(false);
private double fps;
PerfMeter(String name) {
this.name = name;
}
PerfMeter exec(final Renderable renderable) throws Exception {
final CountDownLatch latch = new CountDownLatch(COUNT);
final CountDownLatch latchFrame = new CountDownLatch(1);
final long endTime = System.currentTimeMillis() + MAX_MEASURE_TIME;
final Frame f = new Frame();
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchFrame.countDown();
}
});
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panel = new JPanel()
{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
time = System.nanoTime();
Graphics2D g2d = (Graphics2D) g.create();
renderable.setup(g2d);
renderable.render(g2d);
g2d.setColor(expColor);
g.fillRect(0, 0, BW, BH);
}
};
panel.setPreferredSize(new Dimension((int)(WIDTH + BW), (int)(HEIGHT + BH)));
panel.setBackground(Color.BLACK);
f.add(panel);
//f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
Robot robot = new Robot();
Timer timer = new Timer(DELAY, e -> {
if (waiting.compareAndSet(false, true)) {
Color c = robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BW / 2);
if (isAlmostEqual(c, Color.BLUE)) {
expColor = Color.RED;
} else {
expColor = Color.BLUE;
}
renderable.update();
panel.getParent().repaint();
} else {
while (!isAlmostEqual(
robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
expColor))
{
try {
Thread.sleep(RESOLUTION);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
time = System.nanoTime() - time;
execTime += time;
frame++;
waiting.set(false);
}
if (System.currentTimeMillis() < endTime) {
latch.countDown();
} else {
while(latch.getCount() > 0) latch.countDown();
}
});
timer.start();
latch.await();
SwingUtilities.invokeAndWait(() -> {
timer.stop();
f.setVisible(false);
f.dispose();
});
latchFrame.await();
if (execTime != 0 && frame != 0) {
fps = 1e9 / (execTime / frame);
} else {
fps = 0;
}
return this;
}
private void report() {
System.err.println(name + " : " + String.format("%.2f FPS", fps));
}
private boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
}
}
private static final Particles balls = new Particles(N, R, BW, BH, WIDTH, HEIGHT);
private static final ParticleRenderer textRenderer = new TextParticleRenderer(N, R);
private static final Configurable TextLCD = (Graphics2D g2d) ->
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
public void testTextBubblesLCD() throws Exception {
(new PerfMeter("TextLCD")).exec(createPR(textRenderer).configure(TextLCD)).report();
}
public static void main(String[] args)
throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
{
RenderPerfLCDTest test = new RenderPerfLCDTest();
if (args.length > 0) {
for (String testCase : args) {
Method m = RenderPerfLCDTest.class.getDeclaredMethod(testCase);
m.invoke(test);
}
} else {
Method[] methods = RenderPerfLCDTest.class.getDeclaredMethods();
for (Method m : methods) {
if (m.getName().startsWith("test") && !ignoredTests.contains(m.getName())) {
m.invoke(test);
}
}
}
}
}

View File

@@ -0,0 +1,860 @@
/*
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package renderperf;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class RenderPerfTest {
private static HashSet<String> ignoredTests = new HashSet<>();
static {
ignoredTests.add("testWhiteTextBubblesNoAA");
ignoredTests.add("testWhiteTextBubblesLCD");
ignoredTests.add("testWhiteTextBubblesGray");
ignoredTests.add("testLinGradOvalRotBubblesAA");
ignoredTests.add("testWiredBoxBubblesAA");
ignoredTests.add("testLinesAA");
}
private final static int N = 1000;
private final static float WIDTH = 800;
private final static float HEIGHT = 800;
private final static float R = 25;
private final static int BW = 50;
private final static int BH = 50;
private final static int COUNT = 300;
private final static int DELAY = 10;
private final static int RESOLUTION = 5;
private final static int COLOR_TOLERANCE = 10;
private final static int MAX_MEASURE_TIME = 5000;
interface Configurable {
void configure(Graphics2D g2d);
}
interface Renderable {
void setup(Graphics2D g2d);
void render(Graphics2D g2d);
void update();
}
static class Particles {
private float[] bx;
private float[] by;
private float[] vx;
private float[] vy;
private float r;
private int n;
private float x0;
private float y0;
private float width;
private float height;
Particles(int n, float r, float x0, float y0, float width, float height) {
bx = new float[n];
by = new float[n];
vx = new float[n];
vy = new float[n];
this.n = n;
this.r = r;
this.x0 = x0;
this.y0 = y0;
this.width = width;
this.height = height;
for (int i = 0; i < n; i++) {
bx[i] = (float) (x0 + r + 0.1 + Math.random() * (width - 2 * r - 0.2 - x0));
by[i] = (float) (y0 + r + 0.1 + Math.random() * (height - 2 * r - 0.2 - y0));
vx[i] = 0.1f * (float) (Math.random() * 2 * r - r);
vy[i] = 0.1f * (float) (Math.random() * 2 * r - r);
}
}
void render(Graphics2D g2d, ParticleRenderer renderer) {
for (int i = 0; i < n; i++) {
renderer.render(g2d, i, bx, by, vx, vy);
}
}
void update() {
for (int i = 0; i < n; i++) {
bx[i] += vx[i];
if (bx[i] + r > width || bx[i] - r < x0) vx[i] = -vx[i];
by[i] += vy[i];
if (by[i] + r > height || by[i] - r < y0) vy[i] = -vy[i];
}
}
}
ParticleRenderable createPR(ParticleRenderer renderer) {
return new ParticleRenderable(renderer);
}
static class ParticleRenderable implements Renderable {
ParticleRenderer renderer;
Configurable configure;
ParticleRenderable(ParticleRenderer renderer, Configurable configure) {
this.renderer = renderer;
this.configure = configure;
}
ParticleRenderable(ParticleRenderer renderer) {
this(renderer, null);
}
@Override
public void setup(Graphics2D g2d) {
if (configure != null) configure.configure(g2d);
}
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, renderer);
}
@Override
public void update() {
balls.update();
}
public ParticleRenderable configure(Configurable configure) {
this.configure = configure;
return this;
}
}
interface ParticleRenderer {
void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy);
}
static class FlatParticleRenderer implements ParticleRenderer {
Color[] colors;
float r;
FlatParticleRenderer(int n, float r) {
colors = new Color[n];
this.r = r;
for (int i = 0; i < n; i++) {
colors[i] = new Color((float) Math.random(),
(float) Math.random(), (float) Math.random());
}
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
g2d.fillOval((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
}
}
static class ClipFlatParticleRenderer extends FlatParticleRenderer {
ClipFlatParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
if ((id % 10) == 0) {
g2d.setColor(colors[id % colors.length]);
g2d.setClip(new Ellipse2D.Double((int) (x[id] - r), (int) (y[id] - r), (int) (2 * r), (int) (2 * r)));
g2d.fillRect((int) (x[id] - 2 * r), (int) (y[id] - 2 * r), (int) (4 * r), (int) (4 * r));
}
}
}
static class WhiteTextParticleRenderer implements ParticleRenderer {
float r;
WhiteTextParticleRenderer(float r) {
this.r = r;
}
void setPaint(Graphics2D g2d, int id) {
g2d.setColor(Color.WHITE);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
setPaint(g2d, id);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] - r));
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)y[id]);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] + r));
}
}
static class TextParticleRenderer extends WhiteTextParticleRenderer {
Color[] colors;
float r;
TextParticleRenderer(int n, float r) {
super(r);
colors = new Color[n];
this.r = r;
for (int i = 0; i < n; i++) {
colors[i] = new Color((float) Math.random(),
(float) Math.random(), (float) Math.random());
}
}
void setPaint(Graphics2D g2d, int id) {
g2d.setColor(colors[id % colors.length]);
}
}
static class LargeTextParticleRenderer extends TextParticleRenderer {
LargeTextParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
setPaint(g2d, id);
Font font = new Font("LucidaGrande", Font.PLAIN, 32);
g2d.setFont(font);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] - r));
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)y[id]);
g2d.drawString("The quick brown fox jumps over the lazy dog",
(int)(x[id] - r), (int)(y[id] + r));
}
}
static class FlatOvalRotParticleRenderer extends FlatParticleRenderer {
FlatOvalRotParticleRenderer(int n, float r) {
super(n, r);
}
void setPaint(Graphics2D g2d, int id) {
g2d.setColor(colors[id % colors.length]);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
setPaint(g2d, id);
if (Math.abs(vx[id] + vy[id]) > 0.001) {
AffineTransform t = (AffineTransform) g2d.getTransform().clone();
double l = vx[id] / Math.sqrt(vx[id] * vx[id] + vy[id] * vy[id]);
if (vy[id] < 0) {
l = -l;
}
g2d.translate(x[id], y[id]);
g2d.rotate(Math.acos(l));
g2d.fillOval(-(int)r, (int)(-0.5*r), (int) (2 * r), (int)r);
g2d.setTransform(t);
} else {
g2d.fillOval((int)(x[id] - r), (int)(y[id] - 0.5*r),
(int) (2 * r), (int) r);
}
}
}
static class LinGradOvalRotParticleRenderer extends FlatOvalRotParticleRenderer {
LinGradOvalRotParticleRenderer(int n, float r) {
super(n, r);
}
@Override
void setPaint(Graphics2D g2d, int id) {
Point2D start = new Point2D.Double(- r, - 0.5*r);
Point2D end = new Point2D.Double( 2 * r, r);
float[] dist = {0.0f, 1.0f};
Color[] cls = {colors[id %colors.length], colors[(colors.length - id) %colors.length]};
LinearGradientPaint p =
new LinearGradientPaint(start, end, dist, cls);
g2d.setPaint(p);
}
}
static class LinGrad3OvalRotParticleRenderer extends FlatOvalRotParticleRenderer {
LinGrad3OvalRotParticleRenderer(int n, float r) {
super(n, r);
}
@Override
void setPaint(Graphics2D g2d, int id) {
Point2D start = new Point2D.Double(- r, - 0.5*r);
Point2D end = new Point2D.Double( 2 * r, r);
float[] dist = {0.0f, 0.5f, 1.0f};
Color[] cls = {
colors[id %colors.length],
colors[(colors.length - id) %colors.length],
colors[(id*5) %colors.length]};
LinearGradientPaint p =
new LinearGradientPaint(start, end, dist, cls);
g2d.setPaint(p);
}
}
static class RadGrad3OvalRotParticleRenderer extends FlatOvalRotParticleRenderer {
RadGrad3OvalRotParticleRenderer(int n, float r) {
super(n, r);
}
@Override
void setPaint(Graphics2D g2d, int id) {
Point2D start = new Point2D.Double();
float[] dist = {0.0f, 0.5f, 1.0f};
Color[] cls = {
colors[id %colors.length],
colors[(colors.length - id) %colors.length],
colors[(id*5) %colors.length]};
RadialGradientPaint p =
new RadialGradientPaint(start, r, dist, cls);
g2d.setPaint(p);
}
}
static class FlatBoxParticleRenderer extends FlatParticleRenderer {
FlatBoxParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
g2d.fillRect((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
}
}
static class ClipFlatBoxParticleRenderer extends FlatParticleRenderer {
ClipFlatBoxParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
if ((id % 10) == 0) {
g2d.setColor(colors[id % colors.length]);
g2d.setClip((int) (x[id] - r), (int) (y[id] - r), (int) (2 * r), (int) (2 * r));
g2d.fillRect((int) (x[id] - 2 * r), (int) (y[id] - 2 * r), (int) (4 * r), (int) (4 * r));
}
}
}
static class ImgParticleRenderer extends FlatParticleRenderer {
BufferedImage dukeImg;
ImgParticleRenderer(int n, float r) {
super(n, r);
try {
dukeImg = ImageIO.read(
Objects.requireNonNull(
RenderPerfTest.class.getClassLoader().getResourceAsStream(
"renderperf/images/duke.png")));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
g2d.drawImage(dukeImg, (int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r), null);
}
}
static class FlatBoxRotParticleRenderer extends FlatParticleRenderer {
FlatBoxRotParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
if (Math.abs(vx[id] + vy[id]) > 0.001) {
AffineTransform t = (AffineTransform) g2d.getTransform().clone();
double l = vx[id] / Math.sqrt(vx[id] * vx[id] + vy[id] * vy[id]);
if (vy[id] < 0) {
l = -l;
}
g2d.translate(x[id], y[id]);
g2d.rotate(Math.acos(l));
g2d.fillRect(-(int)r, -(int)r, (int) (2 * r), (int) (2 * r));
g2d.setTransform(t);
} else {
g2d.fillRect((int)(x[id] - r), (int)(y[id] - r),
(int) (2 * r), (int) (2 * r));
}
}
}
static class WiredParticleRenderer extends FlatParticleRenderer {
WiredParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
g2d.drawOval((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
}
}
static class WiredBoxParticleRenderer extends FlatParticleRenderer {
WiredBoxParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
g2d.setColor(colors[id % colors.length]);
g2d.drawRect((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
}
}
static class SegParticleRenderer extends FlatParticleRenderer {
SegParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
double v = Math.sqrt(vx[id]*vx[id]+vy[id]*vy[id]);
float nvx = (float) (vx[id]/v);
float nvy = (float) (vy[id]/v);
g2d.setColor(colors[id % colors.length]);
g2d.drawLine((int)(x[id] - r*nvx), (int)(y[id] - r*nvy),
(int)(x[id] + 2*r*nvx), (int)(y[id] + 2*r*nvy));
}
}
static class WiredQuadParticleRenderer extends FlatParticleRenderer {
WiredQuadParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
if (id > 2 && (id % 3) == 0) {
g2d.setColor(colors[id % colors.length]);
g2d.draw(new QuadCurve2D.Float(x[id-3], y[id-3], x[id-2], y[id-2], x[id-1], y[id-1]));
}
}
}
static class FlatQuadParticleRenderer extends FlatParticleRenderer {
FlatQuadParticleRenderer(int n, float r) {
super(n, r);
}
@Override
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
if (id > 2 && (id % 3) == 0) {
g2d.setColor(colors[id % colors.length]);
g2d.fill(new QuadCurve2D.Float(x[id-3], y[id-3], x[id-2], y[id-2], x[id-1], y[id-1]));
}
}
}
static class PerfMeter {
private String name;
private int frame = 0;
private JPanel panel;
private long time;
private double execTime = 0;
private Color expColor = Color.RED;
AtomicBoolean waiting = new AtomicBoolean(false);
private double fps;
PerfMeter(String name) {
this.name = name;
}
PerfMeter exec(final Renderable renderable) throws Exception {
final CountDownLatch latch = new CountDownLatch(COUNT);
final CountDownLatch latchFrame = new CountDownLatch(1);
final long endTime = System.currentTimeMillis() + MAX_MEASURE_TIME;
final JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchFrame.countDown();
}
});
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panel = new JPanel()
{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
time = System.nanoTime();
Graphics2D g2d = (Graphics2D) g.create();
renderable.setup(g2d);
renderable.render(g2d);
g2d.setColor(expColor);
g.fillRect(0, 0, BW, BH);
}
};
panel.setPreferredSize(new Dimension((int)(WIDTH + BW), (int)(HEIGHT + BH)));
panel.setBackground(Color.BLACK);
f.add(panel);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
Robot robot = new Robot();
Timer timer = new Timer(DELAY, e -> {
if (waiting.compareAndSet(false, true)) {
Color c = robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BW / 2);
if (isAlmostEqual(c, Color.BLUE)) {
expColor = Color.RED;
} else {
expColor = Color.BLUE;
}
renderable.update();
panel.getParent().repaint();
} else {
while (!isAlmostEqual(
robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
expColor))
{
try {
Thread.sleep(RESOLUTION);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
time = System.nanoTime() - time;
execTime += time;
frame++;
waiting.set(false);
}
if (System.currentTimeMillis() < endTime) {
latch.countDown();
} else {
while(latch.getCount() > 0) latch.countDown();
}
});
timer.start();
latch.await();
SwingUtilities.invokeAndWait(() -> {
timer.stop();
f.setVisible(false);
f.dispose();
});
latchFrame.await();
if (execTime != 0 && frame != 0) {
fps = 1e9 / (execTime / frame);
} else {
fps = 0;
}
return this;
}
private void report() {
System.err.println(name + " : " + String.format("%.2f FPS", fps));
}
private boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
}
}
private static final Particles balls = new Particles(N, R, BW, BH, WIDTH, HEIGHT);
private static final ParticleRenderer flatRenderer = new FlatParticleRenderer(N, R);
private static final ParticleRenderer clipFlatRenderer = new ClipFlatParticleRenderer(N, R);
private static final ParticleRenderer flatOvalRotRenderer = new FlatOvalRotParticleRenderer(N, R);
private static final ParticleRenderer flatBoxRenderer = new FlatBoxParticleRenderer(N, R);
private static final ParticleRenderer clipFlatBoxParticleRenderer = new ClipFlatBoxParticleRenderer(N, R);
private static final ParticleRenderer flatBoxRotRenderer = new FlatBoxRotParticleRenderer(N, R);
private static final ParticleRenderer linGradOvalRotRenderer = new LinGradOvalRotParticleRenderer(N, R);
private static final ParticleRenderer linGrad3OvalRotRenderer = new LinGrad3OvalRotParticleRenderer(N, R);
private static final ParticleRenderer radGrad3OvalRotRenderer = new RadGrad3OvalRotParticleRenderer(N, R);
private static final ParticleRenderer wiredRenderer = new WiredParticleRenderer(N, R);
private static final ParticleRenderer wiredBoxRenderer = new WiredBoxParticleRenderer(N, R);
private static final ParticleRenderer segRenderer = new SegParticleRenderer(N, R);
private static final ParticleRenderer flatQuadRenderer = new FlatQuadParticleRenderer(N, R);
private static final ParticleRenderer wiredQuadRenderer = new WiredQuadParticleRenderer(N, R);
private static final ParticleRenderer imgRenderer = new ImgParticleRenderer(N, R);
private static final ParticleRenderer textRenderer = new TextParticleRenderer(N, R);
private static final ParticleRenderer largeTextRenderer = new LargeTextParticleRenderer(N, R);
private static final ParticleRenderer whiteTextRenderer = new WhiteTextParticleRenderer(R);
private static final Configurable AA = (Graphics2D g2d) ->
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
private static final Configurable TextLCD = (Graphics2D g2d) ->
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
private static final Configurable TextAA = (Graphics2D g2d) ->
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
public void testFlatBubbles() throws Exception {
(new PerfMeter("FlatOval")).exec(createPR(flatRenderer)).report();
}
public void testFlatBubblesAA() throws Exception {
(new PerfMeter("FlatOvalAA")).exec(createPR(flatRenderer).configure(AA)).report();
}
public void testClipFlatBubbles() throws Exception {
(new PerfMeter("ClipFlatOval")).exec(createPR(clipFlatRenderer)).report();
}
public void testClipFlatBubblesAA() throws Exception {
(new PerfMeter("ClipFlatOvalAA")).exec(createPR(clipFlatRenderer).configure(AA)).report();
}
public void testFlatBoxBubbles() throws Exception {
(new PerfMeter("FlatBox")).exec(createPR(flatBoxRenderer)).report();
}
public void testFlatBoxBubblesAA() throws Exception {
(new PerfMeter("FlatBoxAA")).exec(createPR(flatBoxRenderer).configure(AA)).report();
}
public void testClipFlatBoxBubbles() throws Exception {
(new PerfMeter("ClipFlatBox")).exec(createPR(clipFlatBoxParticleRenderer)).report();
}
public void testClipFlatBoxBubblesAA() throws Exception {
(new PerfMeter("ClipFlatBoxAA")).exec(createPR(clipFlatBoxParticleRenderer).configure(AA)).report();
}
public void testImgBubbles() throws Exception {
(new PerfMeter("Image")).exec(createPR(imgRenderer)).report();
}
public void testImgBubblesAA() throws Exception {
(new PerfMeter("ImageAA")).exec(createPR(imgRenderer).configure(AA)).report();
}
public void testFlatBoxRotBubbles() throws Exception {
(new PerfMeter("RotatedBox")).exec(createPR(flatBoxRotRenderer)).report();
}
public void testFlatBoxRotBubblesAA() throws Exception {
(new PerfMeter("RotatedBoxAA")).exec(createPR(flatBoxRotRenderer).configure(AA)).report();
}
public void testFlatOvalRotBubbles() throws Exception {
(new PerfMeter("RotatedOval")).exec(createPR(flatOvalRotRenderer)).report();
}
public void testFlatOvalRotBubblesAA() throws Exception {
(new PerfMeter("RotatedOvalAA")).exec(createPR(flatOvalRotRenderer).configure(AA)).report();
}
public void testLinGrad3OvalRotBubbles() throws Exception {
(new PerfMeter("LinGrad3RotatedOval")).exec(createPR(linGrad3OvalRotRenderer)).report();
}
public void testLinGrad3OvalRotBubblesAA() throws Exception {
(new PerfMeter("LinGrad3RotatedOvalAA")).exec(createPR(linGrad3OvalRotRenderer).configure(AA)).report();
}
public void testRadGrad3OvalRotBubbles() throws Exception {
(new PerfMeter("RadGrad3RotatedOval")).exec(createPR(radGrad3OvalRotRenderer)).report();
}
public void testRadGrad3OvalRotBubblesAA() throws Exception {
(new PerfMeter("RadGrad3RotatedOvalAA")).exec(createPR(radGrad3OvalRotRenderer).configure(AA)).report();
}
public void testLinGradOvalRotBubbles() throws Exception {
(new PerfMeter("LinGradRotatedOval")).exec(createPR(linGradOvalRotRenderer)).report();
}
public void testLinGradOvalRotBubblesAA() throws Exception {
(new PerfMeter("LinGradRotatedOvalAA")).exec(createPR(linGradOvalRotRenderer).configure(AA)).report();
}
public void testWiredBubbles() throws Exception {
(new PerfMeter("WiredBubbles")).exec(createPR(wiredRenderer)).report();
}
public void testWiredBubblesAA() throws Exception {
(new PerfMeter("WiredBubblesAA")).exec(createPR(wiredRenderer).configure(AA)).report();
}
public void testWiredBoxBubbles() throws Exception {
(new PerfMeter("WiredBox")).exec(createPR(wiredBoxRenderer)).report();
}
public void testWiredBoxBubblesAA() throws Exception {
(new PerfMeter("WiredBoxAA")).exec(createPR(wiredBoxRenderer).configure(AA)).report();
}
public void testLines() throws Exception {
(new PerfMeter("Lines")).exec(createPR(segRenderer)).report();
}
public void testLinesAA() throws Exception {
(new PerfMeter("LinesAA")).exec(createPR(segRenderer).configure(AA)).report();
}
public void testFlatQuad() throws Exception {
(new PerfMeter("FlatQuad")).exec(createPR(flatQuadRenderer)).report();
}
public void testFlatQuadAA() throws Exception {
(new PerfMeter("FlatQuadAA")).exec(createPR(flatQuadRenderer).configure(AA)).report();
}
public void testWiredQuad() throws Exception {
(new PerfMeter("WiredQuad")).exec(createPR(wiredQuadRenderer)).report();
}
public void testWiredQuadAA() throws Exception {
(new PerfMeter("WiredQuadAA")).exec(createPR(wiredQuadRenderer).configure(AA)).report();
}
public void testTextBubblesNoAA() throws Exception {
(new PerfMeter("TextNoAA")).exec(createPR(textRenderer)).report();
}
public void testTextBubblesLCD() throws Exception {
(new PerfMeter("TextLCD")).exec(createPR(textRenderer).configure(TextLCD)).report();
}
public void testTextBubblesGray() throws Exception {
(new PerfMeter("TextGray")).exec(createPR(textRenderer).configure(TextAA)).report();
}
public void testLargeTextBubblesNoAA() throws Exception {
(new PerfMeter("LargeTextNoAA")).exec(createPR(largeTextRenderer)).report();
}
public void testLargeTextBubblesLCD() throws Exception {
(new PerfMeter("LargeTextLCD")).exec(createPR(largeTextRenderer).configure(TextLCD)).report();
}
public void testLargeTextBubblesGray() throws Exception {
(new PerfMeter("LargeTextGray")).exec(createPR(largeTextRenderer).configure(TextAA)).report();
}
public void testWhiteTextBubblesNoAA() throws Exception {
(new PerfMeter("WhiteTextNoAA")).exec(createPR(whiteTextRenderer)).report();
}
public void testWhiteTextBubblesLCD() throws Exception {
(new PerfMeter("WhiteTextLCD")).exec(createPR(whiteTextRenderer).configure(TextLCD)).report();
}
public void testWhiteTextBubblesGray() throws Exception {
(new PerfMeter("WhiteTextGray")).exec(createPR(whiteTextRenderer).configure(TextAA)).report();
}
public static void main(String[] args)
throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
{
RenderPerfTest test = new RenderPerfTest();
if (args.length > 0) {
for (String testCase : args) {
Method m = RenderPerfTest.class.getDeclaredMethod(testCase);
m.invoke(test);
}
} else {
Method[] methods = RenderPerfTest.class.getDeclaredMethods();
for (Method m : methods) {
if (m.getName().startsWith("test") && !ignoredTests.contains(m.getName())) {
m.invoke(test);
}
}
}
}
}

View File

@@ -34,6 +34,7 @@ import java.awt.image.ColorModel;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWGraphicsConfig;
import sun.lwawt.macosx.CFRetainedResource;
public abstract class CGraphicsConfig extends GraphicsConfiguration
implements LWGraphicsConfig {
@@ -80,7 +81,7 @@ public abstract class CGraphicsConfig extends GraphicsConfiguration
* Creates a new SurfaceData that will be associated with the given
* CGLLayer.
*/
public abstract SurfaceData createSurfaceData(CGLLayer layer);
public abstract SurfaceData createSurfaceData(CFRetainedResource layer);
@Override
public final boolean isTranslucencyCapable() {

View File

@@ -37,6 +37,8 @@ import java.awt.peer.WindowPeer;
import java.util.Objects;
import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLGraphicsConfig;
import sun.java2d.opengl.CGLGraphicsConfig;
import static java.awt.peer.ComponentPeer.SET_BOUNDS;
@@ -63,7 +65,9 @@ public final class CGraphicsDevice extends GraphicsDevice
public CGraphicsDevice(final int displayID) {
this.displayID = displayID;
config = CGLGraphicsConfig.getConfig(this);
config = MacOSFlags.isMetalEnabled() ?
MTLGraphicsConfig.getConfig(this, displayID, 0) :
CGLGraphicsConfig.getConfig(this);
// initializes default device state, might be redundant step since we
// call "displayChanged()" later anyway, but we do not want to leave the
// device in an inconsistent state after construction

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@ package sun.java2d;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLVolatileSurfaceManager;
import sun.java2d.opengl.CGLVolatileSurfaceManager;
/**
@@ -49,6 +51,7 @@ public class MacosxSurfaceManagerFactory extends SurfaceManagerFactory {
public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
Object context)
{
return new CGLVolatileSurfaceManager(vImg, context);
return MacOSFlags.isMetalEnabled() ? new MTLVolatileSurfaceManager(vImg, context) :
new CGLVolatileSurfaceManager(vImg, context);
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.macos;
import java.security.PrivilegedAction;
public class MacOSFlags {
/**
* Description of command-line flags. All flags with [true|false]
* values
* metalEnabled: usage: "-Dsun.java2d.metal=[true|false]"
*/
private static boolean metalEnabled;
static {
initJavaFlags();
initNativeFlags();
}
private static native boolean initNativeFlags();
private static boolean getBooleanProp(String p, boolean defaultVal) {
String propString = System.getProperty(p);
boolean returnVal = defaultVal;
if (propString != null) {
if (propString.equals("true") ||
propString.equals("t") ||
propString.equals("True") ||
propString.equals("T") ||
propString.equals("")) // having the prop name alone
{ // is equivalent to true
returnVal = true;
} else if (propString.equals("false") ||
propString.equals("f") ||
propString.equals("False") ||
propString.equals("F"))
{
returnVal = false;
}
}
return returnVal;
}
private static boolean getPropertySet(String p) {
String propString = System.getProperty(p);
return (propString != null) ? true : false;
}
private static void initJavaFlags() {
java.security.AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> {
metalEnabled = getBooleanProp("sun.java2d.metal", false);
return null;
});
}
public static boolean isMetalEnabled() {
return metalEnabled;
}
}

View File

@@ -0,0 +1,951 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SurfaceData;
import sun.java2d.loops.*;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.RenderQueue;
import sun.java2d.pipe.hw.AccelSurface;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.lang.annotation.Native;
import java.lang.ref.WeakReference;
import static sun.java2d.pipe.BufferedOpCodes.BLIT;
import static sun.java2d.pipe.BufferedOpCodes.SURFACE_TO_SW_BLIT;
final class MTLBlitLoops {
static void register() {
Blit blitIntArgbPreToSurface =
new MTLSwToSurfaceBlit(SurfaceType.IntArgbPre,
MTLSurfaceData.PF_INT_ARGB_PRE);
Blit blitIntArgbPreToTexture =
new MTLSwToTextureBlit(SurfaceType.IntArgbPre,
MTLSurfaceData.PF_INT_ARGB_PRE);
TransformBlit transformBlitIntArgbPreToSurface =
new MTLSwToSurfaceTransform(SurfaceType.IntArgbPre,
MTLSurfaceData.PF_INT_ARGB_PRE);
MTLSurfaceToSwBlit blitSurfaceToIntArgbPre =
new MTLSurfaceToSwBlit(SurfaceType.IntArgbPre,
MTLSurfaceData.PF_INT_ARGB_PRE);
GraphicsPrimitive[] primitives = {
// surface->surface ops
new MTLSurfaceToSurfaceBlit(),
new MTLSurfaceToSurfaceScale(),
new MTLSurfaceToSurfaceTransform(),
// render-to-texture surface->surface ops
new MTLRTTSurfaceToSurfaceBlit(),
new MTLRTTSurfaceToSurfaceScale(),
new MTLRTTSurfaceToSurfaceTransform(),
// surface->sw ops
new MTLSurfaceToSwBlit(SurfaceType.IntArgb,
MTLSurfaceData.PF_INT_ARGB),
blitSurfaceToIntArgbPre,
// sw->surface ops
blitIntArgbPreToSurface,
new MTLSwToSurfaceBlit(SurfaceType.IntRgb,
MTLSurfaceData.PF_INT_RGB),
new MTLSwToSurfaceBlit(SurfaceType.IntRgbx,
MTLSurfaceData.PF_INT_RGBX),
new MTLSwToSurfaceBlit(SurfaceType.IntBgr,
MTLSurfaceData.PF_INT_BGR),
new MTLSwToSurfaceBlit(SurfaceType.IntBgrx,
MTLSurfaceData.PF_INT_BGRX),
// TODO: Provide native implementation
// It may not be effective/possible. For example, there is no direct
// support in Metal for SurfaceType.ThreeByteBgr
// new MTLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,
// MTLSurfaceData.PF_3BYTE_BGR),
// new MTLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
// MTLSurfaceData.PF_USHORT_565_RGB),
// new MTLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
// MTLSurfaceData.PF_USHORT_555_RGB),
// new MTLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,
// MTLSurfaceData.PF_USHORT_555_RGBX),
// new MTLSwToSurfaceBlit(SurfaceType.ByteGray,
// MTLSurfaceData.PF_BYTE_GRAY),
// new MTLSwToSurfaceBlit(SurfaceType.UshortGray,
// MTLSurfaceData.PF_USHORT_GRAY),
new MTLGeneralBlit(MTLSurfaceData.MTLSurface,
CompositeType.AnyAlpha,
blitIntArgbPreToSurface),
new MTLAnyCompositeBlit(MTLSurfaceData.MTLSurface,
blitSurfaceToIntArgbPre,
blitSurfaceToIntArgbPre,
blitIntArgbPreToSurface),
new MTLAnyCompositeBlit(SurfaceType.Any,
null,
blitSurfaceToIntArgbPre,
blitIntArgbPreToSurface),
new MTLSwToSurfaceScale(SurfaceType.IntRgb,
MTLSurfaceData.PF_INT_RGB),
new MTLSwToSurfaceScale(SurfaceType.IntRgbx,
MTLSurfaceData.PF_INT_RGBX),
new MTLSwToSurfaceScale(SurfaceType.IntBgr,
MTLSurfaceData.PF_INT_BGR),
new MTLSwToSurfaceScale(SurfaceType.IntBgrx,
MTLSurfaceData.PF_INT_BGRX),
// TODO: Provide native implementation
// new MTLSwToSurfaceScale(SurfaceType.ThreeByteBgr,
// MTLSurfaceData.PF_3BYTE_BGR),
// new MTLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
// MTLSurfaceData.PF_USHORT_565_RGB),
// new MTLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
// MTLSurfaceData.PF_USHORT_555_RGB),
// new MTLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,
// MTLSurfaceData.PF_USHORT_555_RGBX),
// new MTLSwToSurfaceScale(SurfaceType.ByteGray,
// MTLSurfaceData.PF_BYTE_GRAY),
// new MTLSwToSurfaceScale(SurfaceType.UshortGray,
// MTLSurfaceData.PF_USHORT_GRAY),
new MTLSwToSurfaceScale(SurfaceType.IntArgbPre,
MTLSurfaceData.PF_INT_ARGB_PRE),
new MTLSwToSurfaceTransform(SurfaceType.IntRgb,
MTLSurfaceData.PF_INT_RGB),
new MTLSwToSurfaceTransform(SurfaceType.IntRgbx,
MTLSurfaceData.PF_INT_RGBX),
new MTLSwToSurfaceTransform(SurfaceType.IntBgr,
MTLSurfaceData.PF_INT_BGR),
new MTLSwToSurfaceTransform(SurfaceType.IntBgrx,
MTLSurfaceData.PF_INT_BGRX),
// TODO: Provide native implementation
// new MTLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
// MTLSurfaceData.PF_3BYTE_BGR),
// new MTLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
// MTLSurfaceData.PF_USHORT_565_RGB),
// new MTLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
// MTLSurfaceData.PF_USHORT_555_RGB),
// new MTLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,
// MTLSurfaceData.PF_USHORT_555_RGBX),
// new MTLSwToSurfaceTransform(SurfaceType.ByteGray,
// MTLSurfaceData.PF_BYTE_GRAY),
// new MTLSwToSurfaceTransform(SurfaceType.UshortGray,
// MTLSurfaceData.PF_USHORT_GRAY),
transformBlitIntArgbPreToSurface,
new MTLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
// texture->surface ops
new MTLTextureToSurfaceBlit(),
new MTLTextureToSurfaceScale(),
new MTLTextureToSurfaceTransform(),
// sw->texture ops
blitIntArgbPreToTexture,
new MTLSwToTextureBlit(SurfaceType.IntRgb,
MTLSurfaceData.PF_INT_RGB),
new MTLSwToTextureBlit(SurfaceType.IntRgbx,
MTLSurfaceData.PF_INT_RGBX),
new MTLSwToTextureBlit(SurfaceType.IntBgr,
MTLSurfaceData.PF_INT_BGR),
new MTLSwToTextureBlit(SurfaceType.IntBgrx,
MTLSurfaceData.PF_INT_BGRX),
// TODO: Provide native implementation
// new MTLSwToTextureBlit(SurfaceType.ThreeByteBgr,
// MTLSurfaceData.PF_3BYTE_BGR),
// new MTLSwToTextureBlit(SurfaceType.Ushort565Rgb,
// MTLSurfaceData.PF_USHORT_565_RGB),
// new MTLSwToTextureBlit(SurfaceType.Ushort555Rgb,
// MTLSurfaceData.PF_USHORT_555_RGB),
// new MTLSwToTextureBlit(SurfaceType.Ushort555Rgbx,
// MTLSurfaceData.PF_USHORT_555_RGBX),
// new MTLSwToTextureBlit(SurfaceType.ByteGray,
// MTLSurfaceData.PF_BYTE_GRAY),
// new MTLSwToTextureBlit(SurfaceType.UshortGray,
// MTLSurfaceData.PF_USHORT_GRAY),
new MTLGeneralBlit(MTLSurfaceData.MTLTexture,
CompositeType.SrcNoEa,
blitIntArgbPreToTexture),
};
GraphicsPrimitiveMgr.register(primitives);
}
/**
* The following offsets are used to pack the parameters in
* createPackedParams(). (They are also used at the native level when
* unpacking the params.)
*/
@Native private static final int OFFSET_SRCTYPE = 16;
@Native private static final int OFFSET_HINT = 8;
@Native private static final int OFFSET_TEXTURE = 3;
@Native private static final int OFFSET_RTT = 2;
@Native private static final int OFFSET_XFORM = 1;
@Native private static final int OFFSET_ISOBLIT = 0;
/**
* Packs the given parameters into a single int value in order to save
* space on the rendering queue.
*/
private static int createPackedParams(boolean isoblit, boolean texture,
boolean rtt, boolean xform,
int hint, int srctype)
{
return
((srctype << OFFSET_SRCTYPE) |
(hint << OFFSET_HINT ) |
((texture ? 1 : 0) << OFFSET_TEXTURE) |
((rtt ? 1 : 0) << OFFSET_RTT ) |
((xform ? 1 : 0) << OFFSET_XFORM ) |
((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
}
/**
* Enqueues a BLIT operation with the given parameters. Note that the
* RenderQueue lock must be held before calling this method.
*/
private static void enqueueBlit(RenderQueue rq,
SurfaceData src, SurfaceData dst,
int packedParams,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2)
{
// assert rq.lock.isHeldByCurrentThread();
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(72, 24);
buf.putInt(BLIT);
buf.putInt(packedParams);
buf.putInt(sx1).putInt(sy1);
buf.putInt(sx2).putInt(sy2);
buf.putDouble(dx1).putDouble(dy1);
buf.putDouble(dx2).putDouble(dy2);
buf.putLong(src.getNativeOps());
buf.putLong(dst.getNativeOps());
}
static void Blit(SurfaceData srcData, SurfaceData dstData,
Composite comp, Region clip,
AffineTransform xform, int hint,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2,
int srctype, boolean texture)
{
int ctxflags = 0;
if (srcData.getTransparency() == Transparency.OPAQUE) {
ctxflags |= MTLContext.SRC_IS_OPAQUE;
}
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// make sure the RenderQueue keeps a hard reference to the
// source (sysmem) SurfaceData to prevent it from being
// disposed while the operation is processed on the QFT
rq.addReference(srcData);
MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
if (texture) {
// make sure we have a current context before uploading
// the sysmem data to the texture object
MTLGraphicsConfig gc = oglDst.getMTLGraphicsConfig();
MTLContext.setScratchSurface(gc);
} else {
MTLContext.validateContext(oglDst, oglDst,
clip, comp, xform, null, null,
ctxflags);
}
int packedParams = createPackedParams(false, texture,
false /*unused*/, xform != null,
hint, srctype);
enqueueBlit(rq, srcData, dstData,
packedParams,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2);
// always flush immediately, since we (currently) have no means
// of tracking changes to the system memory surface
rq.flushNow();
} finally {
rq.unlock();
}
}
/**
* Note: The srcImg and biop parameters are only used when invoked
* from the MTLBufImgOps.renderImageWithOp() method; in all other cases,
* this method can be called with null values for those two parameters,
* and they will be effectively ignored.
*/
static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
BufferedImage srcImg, BufferedImageOp biop,
Composite comp, Region clip,
AffineTransform xform, int hint,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2,
boolean texture)
{
int ctxflags = 0;
if (srcData.getTransparency() == Transparency.OPAQUE) {
ctxflags |= MTLContext.SRC_IS_OPAQUE;
}
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
MTLSurfaceData oglSrc = (MTLSurfaceData)srcData;
MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
int srctype = oglSrc.getType();
boolean rtt;
MTLSurfaceData srcCtxData;
if (srctype == MTLSurfaceData.TEXTURE) {
// the source is a regular texture object; we substitute
// the destination surface for the purposes of making a
// context current
rtt = false;
srcCtxData = oglDst;
} else {
// the source is a pbuffer, backbuffer, or render-to-texture
// surface; we set rtt to true to differentiate this kind
// of surface from a regular texture object
rtt = true;
if (srctype == AccelSurface.RT_TEXTURE) {
srcCtxData = oglDst;
} else {
srcCtxData = oglSrc;
}
}
MTLContext.validateContext(srcCtxData, oglDst,
clip, comp, xform, null, null,
ctxflags);
if (biop != null) {
MTLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);
}
int packedParams = createPackedParams(true, texture,
false /*unused*/, xform != null,
hint, 0 /*unused*/);
enqueueBlit(rq, srcData, dstData,
packedParams,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2);
if (biop != null) {
MTLBufImgOps.disableBufImgOp(rq, biop);
}
if (rtt && oglDst.isOnScreen()) {
// we only have to flush immediately when copying from a
// (non-texture) surface to the screen; otherwise Swing apps
// might appear unresponsive until the auto-flush completes
rq.flushNow();
}
} finally {
rq.unlock();
}
}
}
class MTLSurfaceToSurfaceBlit extends Blit {
MTLSurfaceToSurfaceBlit() {
super(MTLSurfaceData.MTLSurface,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
false);
}
}
class MTLSurfaceToSurfaceScale extends ScaledBlit {
MTLSurfaceToSurfaceScale() {
super(MTLSurfaceData.MTLSurface,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Scale(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2,
false);
}
}
class MTLSurfaceToSurfaceTransform extends TransformBlit {
MTLSurfaceToSurfaceTransform() {
super(MTLSurfaceData.MTLSurface,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint,
int sx, int sy, int dx, int dy,
int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, at, hint,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
false);
}
}
class MTLRTTSurfaceToSurfaceBlit extends Blit {
MTLRTTSurfaceToSurfaceBlit() {
super(MTLSurfaceData.MTLSurfaceRTT,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
true);
}
}
class MTLRTTSurfaceToSurfaceScale extends ScaledBlit {
MTLRTTSurfaceToSurfaceScale() {
super(MTLSurfaceData.MTLSurfaceRTT,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Scale(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2,
true);
}
}
class MTLRTTSurfaceToSurfaceTransform extends TransformBlit {
MTLRTTSurfaceToSurfaceTransform() {
super(MTLSurfaceData.MTLSurfaceRTT,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, at, hint,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
true);
}
}
final class MTLSurfaceToSwBlit extends Blit {
private final int typeval;
private WeakReference<SurfaceData> srcTmp;
// destination will actually be ArgbPre or Argb
MTLSurfaceToSwBlit(final SurfaceType dstType, final int typeval) {
super(MTLSurfaceData.MTLSurface,
CompositeType.SrcNoEa,
dstType);
this.typeval = typeval;
}
private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
int w, int h) {
SurfaceData cachedSrc = null;
if (srcTmp != null) {
// use cached intermediate surface, if available
cachedSrc = srcTmp.get();
}
// We can convert argb_pre data from MTL surface in two places:
// - During MTL surface -> SW blit
// - During SW -> SW blit
// The first one is faster when we use opaque MTL surface, because in
// this case we simply skip conversion and use color components as is.
// Because of this we align intermediate buffer type with type of
// destination not source.
final int type = typeval == MTLSurfaceData.PF_INT_ARGB_PRE ?
BufferedImage.TYPE_INT_ARGB_PRE :
BufferedImage.TYPE_INT_ARGB;
src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);
// copy intermediate SW to destination SW using complex clip
final Blit performop = Blit.getFromCache(src.getSurfaceType(),
CompositeType.SrcNoEa,
dst.getSurfaceType());
performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
if (src != cachedSrc) {
// cache the intermediate surface
srcTmp = new WeakReference<>(src);
}
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
int w, int h)
{
if (clip != null) {
clip = clip.getIntersectionXYWH(dx, dy, w, h);
// At the end this method will flush the RenderQueue, we should exit
// from it as soon as possible.
if (clip.isEmpty()) {
return;
}
sx += clip.getLoX() - dx;
sy += clip.getLoY() - dy;
dx = clip.getLoX();
dy = clip.getLoY();
w = clip.getWidth();
h = clip.getHeight();
if (!clip.isRectangular()) {
complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
return;
}
}
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// make sure the RenderQueue keeps a hard reference to the
// destination (sysmem) SurfaceData to prevent it from being
// disposed while the operation is processed on the QFT
rq.addReference(dst);
RenderBuffer buf = rq.getBuffer();
MTLContext.validateContext((MTLSurfaceData)src);
rq.ensureCapacityAndAlignment(48, 32);
buf.putInt(SURFACE_TO_SW_BLIT);
buf.putInt(sx).putInt(sy);
buf.putInt(dx).putInt(dy);
buf.putInt(w).putInt(h);
buf.putInt(typeval);
buf.putLong(src.getNativeOps());
buf.putLong(dst.getNativeOps());
// always flush immediately
rq.flushNow();
} finally {
rq.unlock();
}
}
}
class MTLSwToSurfaceBlit extends Blit {
private int typeval;
MTLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
super(srcType,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
this.typeval = typeval;
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.Blit(src, dst,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
typeval, false);
}
}
class MTLSwToSurfaceScale extends ScaledBlit {
private int typeval;
MTLSwToSurfaceScale(SurfaceType srcType, int typeval) {
super(srcType,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
this.typeval = typeval;
}
public void Scale(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2)
{
MTLBlitLoops.Blit(src, dst,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2,
typeval, false);
}
}
class MTLSwToSurfaceTransform extends TransformBlit {
private int typeval;
MTLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
super(srcType,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
this.typeval = typeval;
}
public void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.Blit(src, dst,
comp, clip, at, hint,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
typeval, false);
}
}
class MTLSwToTextureBlit extends Blit {
private int typeval;
MTLSwToTextureBlit(SurfaceType srcType, int typeval) {
super(srcType,
CompositeType.SrcNoEa,
MTLSurfaceData.MTLTexture);
this.typeval = typeval;
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.Blit(src, dst,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
typeval, true);
}
}
class MTLTextureToSurfaceBlit extends Blit {
MTLTextureToSurfaceBlit() {
super(MTLSurfaceData.MTLTexture,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
true);
}
}
class MTLTextureToSurfaceScale extends ScaledBlit {
MTLTextureToSurfaceScale() {
super(MTLSurfaceData.MTLTexture,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Scale(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx1, int sy1,
int sx2, int sy2,
double dx1, double dy1,
double dx2, double dy2)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, null,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2,
true);
}
}
class MTLTextureToSurfaceTransform extends TransformBlit {
MTLTextureToSurfaceTransform() {
super(MTLSurfaceData.MTLTexture,
CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
}
public void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint,
int sx, int sy, int dx, int dy,
int w, int h)
{
MTLBlitLoops.IsoBlit(src, dst,
null, null,
comp, clip, at, hint,
sx, sy, sx+w, sy+h,
dx, dy, dx+w, dy+h,
true);
}
}
/**
* This general Blit implementation converts any source surface to an
* intermediate IntArgbPre surface, and then uses the more specific
* IntArgbPre->MTLSurface/Texture loop to get the intermediate
* (premultiplied) surface down to OpenGL using simple blit.
*/
class MTLGeneralBlit extends Blit {
private final Blit performop;
private WeakReference<SurfaceData> srcTmp;
MTLGeneralBlit(SurfaceType dstType,
CompositeType compType,
Blit performop)
{
super(SurfaceType.Any, compType, dstType);
this.performop = performop;
}
public synchronized void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
int w, int h)
{
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
CompositeType.SrcNoEa,
SurfaceType.IntArgbPre);
SurfaceData cachedSrc = null;
if (srcTmp != null) {
// use cached intermediate surface, if available
cachedSrc = srcTmp.get();
}
// convert source to IntArgbPre
src = convertFrom(convertsrc, src, sx, sy, w, h,
cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
// copy IntArgbPre intermediate surface to OpenGL surface
performop.Blit(src, dst, comp, clip,
0, 0, dx, dy, w, h);
if (src != cachedSrc) {
// cache the intermediate surface
srcTmp = new WeakReference<>(src);
}
}
}
/**
* This general TransformedBlit implementation converts any source surface to an
* intermediate IntArgbPre surface, and then uses the more specific
* IntArgbPre->MTLSurface/Texture loop to get the intermediate
* (premultiplied) surface down to OpenGL using simple transformBlit.
*/
final class MTLGeneralTransformedBlit extends TransformBlit {
private final TransformBlit performop;
private WeakReference<SurfaceData> srcTmp;
MTLGeneralTransformedBlit(final TransformBlit performop) {
super(SurfaceType.Any, CompositeType.AnyAlpha,
MTLSurfaceData.MTLSurface);
this.performop = performop;
}
@Override
public synchronized void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint, int srcx,
int srcy, int dstx, int dsty, int width,
int height){
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
CompositeType.SrcNoEa,
SurfaceType.IntArgbPre);
// use cached intermediate surface, if available
final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
// convert source to IntArgbPre
src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
BufferedImage.TYPE_INT_ARGB_PRE);
// transform IntArgbPre intermediate surface to OpenGL surface
performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
width, height);
if (src != cachedSrc) {
// cache the intermediate surface
srcTmp = new WeakReference<>(src);
}
}
}
/**
* This general MTLAnyCompositeBlit implementation can convert any source/target
* surface to an intermediate surface using convertsrc/convertdst loops, applies
* necessary composite operation, and then uses convertresult loop to get the
* intermediate surface down to OpenGL.
*/
final class MTLAnyCompositeBlit extends Blit {
private WeakReference<SurfaceData> dstTmp;
private WeakReference<SurfaceData> srcTmp;
private final Blit convertsrc;
private final Blit convertdst;
private final Blit convertresult;
MTLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,
Blit convertresult) {
super(srctype, CompositeType.Any, MTLSurfaceData.MTLSurface);
this.convertsrc = convertsrc;
this.convertdst = convertdst;
this.convertresult = convertresult;
}
public synchronized void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy,
int w, int h)
{
if (convertsrc != null) {
SurfaceData cachedSrc = null;
if (srcTmp != null) {
// use cached intermediate surface, if available
cachedSrc = srcTmp.get();
}
// convert source to IntArgbPre
src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc,
BufferedImage.TYPE_INT_ARGB_PRE);
if (src != cachedSrc) {
// cache the intermediate surface
srcTmp = new WeakReference<>(src);
}
}
SurfaceData cachedDst = null;
if (dstTmp != null) {
// use cached intermediate surface, if available
cachedDst = dstTmp.get();
}
// convert destination to IntArgbPre
SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
Region bufferClip =
clip == null ? null : clip.getTranslatedRegion(-dx, -dy);
Blit performop = Blit.getFromCache(src.getSurfaceType(),
CompositeType.Any, dstBuffer.getSurfaceType());
performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);
if (dstBuffer != cachedDst) {
// cache the intermediate surface
dstTmp = new WeakReference<>(dstBuffer);
}
// now blit the buffer back to the destination
convertresult.Blit(dstBuffer, dst, AlphaComposite.Src, clip, 0, 0, dx,
dy, w, h);
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.CompositeType;
import sun.java2d.pipe.BufferedBufImgOps;
import java.awt.image.*;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
class MTLBufImgOps extends BufferedBufImgOps {
/**
* This method is called from MTLDrawImage.transformImage() only. It
* validates the provided BufferedImageOp to determine whether the op
* is one that can be accelerated by the MTL pipeline. If the operation
* cannot be completed for any reason, this method returns false;
* otherwise, the given BufferedImage is rendered to the destination
* using the provided BufferedImageOp and this method returns true.
*/
static boolean renderImageWithOp(SunGraphics2D sg, BufferedImage img,
BufferedImageOp biop, int x, int y)
{
// Validate the provided BufferedImage (make sure it is one that
// is supported, and that its properties are acceleratable)
if (biop instanceof ConvolveOp) {
if (!isConvolveOpValid((ConvolveOp)biop)) {
return false;
}
} else if (biop instanceof RescaleOp) {
if (!isRescaleOpValid((RescaleOp)biop, img)) {
return false;
}
} else if (biop instanceof LookupOp) {
if (!isLookupOpValid((LookupOp)biop, img)) {
return false;
}
} else {
// No acceleration for other BufferedImageOps (yet)
return false;
}
SurfaceData dstData = sg.surfaceData;
if (!(dstData instanceof MTLSurfaceData) ||
(sg.interpolationType == AffineTransformOp.TYPE_BICUBIC) ||
(sg.compositeState > SunGraphics2D.COMP_ALPHA))
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof MTLSurfaceData)) {
// REMIND: this hack tries to ensure that we have a cached texture
srcData =
dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof MTLSurfaceData)) {
return false;
}
}
// Verify that the source surface is actually a texture and
// that the operation is supported
MTLSurfaceData mtlSrc = (MTLSurfaceData)srcData;
MTLGraphicsConfig gc = mtlSrc.getMTLGraphicsConfig();
if (mtlSrc.getType() != MTLSurfaceData.TEXTURE ||
!gc.isCapPresent(CAPS_EXT_BIOP_SHADER))
{
return false;
}
int sw = img.getWidth();
int sh = img.getHeight();
MTLBlitLoops.IsoBlit(srcData, dstData,
img, biop,
sg.composite, sg.getCompClip(),
sg.transform, sg.interpolationType,
0, 0, sw, sh,
x, y, x+sw, y+sh,
true);
return true;
}
}

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.pipe.BufferedContext;
import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.RenderQueue;
import sun.java2d.pipe.hw.ContextCapabilities;
import java.lang.annotation.Native;
import static sun.java2d.pipe.BufferedOpCodes.*;
/**
* Note that the RenderQueue lock must be acquired before calling any of
* the methods in this class.
*/
final class MTLContext extends BufferedContext {
public MTLContext(RenderQueue rq) {
super(rq);
}
/**
* Convenience method that delegates to setScratchSurface() below.
*/
static void setScratchSurface(MTLGraphicsConfig gc) {
setScratchSurface(gc.getNativeConfigInfo());
}
/**
* Makes the given GraphicsConfig's context current to its associated
* "scratch surface". Each GraphicsConfig maintains a native context
* (MTLDevice) as well as a native pbuffer
* known as the "scratch surface". By making the context current to the
* scratch surface, we are assured that we have a current context for
* the relevant GraphicsConfig, and can therefore perform operations
* depending on the capabilities of that GraphicsConfig.
* This method should be used for operations with an MTL texture
* as the destination surface (e.g. a sw->texture blit loop), or in those
* situations where we may not otherwise have a current context (e.g.
* when disposing a texture-based surface).
*/
public static void setScratchSurface(long pConfigInfo) {
// assert MTLRenderQueue.getInstance().lock.isHeldByCurrentThread();
// invalidate the current context
currentContext = null;
// set the scratch context
MTLRenderQueue rq = MTLRenderQueue.getInstance();
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(SET_SCRATCH_SURFACE);
buf.putLong(pConfigInfo);
}
/**
* Invalidates the currentContext field to ensure that we properly
* revalidate the MTLContext (make it current, etc.) next time through
* the validate() method. This is typically invoked from methods
* that affect the current context state (e.g. disposing a context or
* surface).
*/
public static void invalidateCurrentContext() {
// assert MTLRenderQueue.getInstance().lock.isHeldByCurrentThread();
// invalidate the current Java-level context so that we
// revalidate everything the next time around
if (currentContext != null) {
currentContext.invalidateContext();
currentContext = null;
}
// invalidate the context reference at the native level, and
// then flush the queue so that we have no pending operations
// dependent on the current context
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.ensureCapacity(4);
rq.getBuffer().putInt(INVALIDATE_CONTEXT);
rq.flushNow();
}
/**
* Returns a string representing adapter id (vendor, renderer, version).
* Must be called on the rendering thread.
*
* @return an id string for the adapter
*/
public static final native String getMTLIdString();
public static class MTLContextCaps extends ContextCapabilities {
/**
* This cap will only be set if the fbobject system property has been
* enabled and we are able to create an FBO with depth buffer.
*/
@Native
public static final int CAPS_EXT_FBOBJECT =
(CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE);
/** Indicates that the context is doublebuffered. */
@Native
public static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0);
/**
* This cap will only be set if the lcdshader system property has been
* enabled and the hardware supports the minimum number of texture units
*/
@Native
static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1);
/**
* This cap will only be set if the biopshader system property has been
* enabled and the hardware meets our minimum requirements.
*/
@Native
public static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2);
/**
* This cap will only be set if the gradshader system property has been
* enabled and the hardware meets our minimum requirements.
*/
@Native
static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3);
/** Indicates the presence of the GL_ARB_texture_rectangle extension. */
@Native
static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4);
/** Indicates the presence of the GL_NV_texture_barrier extension. */
@Native
static final int CAPS_EXT_TEXBARRIER = (FIRST_PRIVATE_CAP << 5);
public MTLContextCaps(int caps, String adapterId) {
super(caps, adapterId);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(super.toString());
if ((caps & CAPS_EXT_FBOBJECT) != 0) {
sb.append("CAPS_EXT_FBOBJECT|");
}
if ((caps & CAPS_DOUBLEBUFFERED) != 0) {
sb.append("CAPS_DOUBLEBUFFERED|");
}
if ((caps & CAPS_EXT_LCD_SHADER) != 0) {
sb.append("CAPS_EXT_LCD_SHADER|");
}
if ((caps & CAPS_EXT_BIOP_SHADER) != 0) {
sb.append("CAPS_BIOP_SHADER|");
}
if ((caps & CAPS_EXT_GRAD_SHADER) != 0) {
sb.append("CAPS_EXT_GRAD_SHADER|");
}
if ((caps & CAPS_EXT_TEXRECT) != 0) {
sb.append("CAPS_EXT_TEXRECT|");
}
if ((caps & CAPS_EXT_TEXBARRIER) != 0) {
sb.append("CAPS_EXT_TEXBARRIER|");
}
return sb.toString();
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.TransformBlit;
import sun.java2d.pipe.DrawImage;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
public class MTLDrawImage extends DrawImage {
@Override
protected void renderImageXform(SunGraphics2D sg, Image img,
AffineTransform tx, int interpType,
int sx1, int sy1, int sx2, int sy2,
Color bgColor)
{
// punt to the MediaLib-based transformImage() in the superclass if:
// - bicubic interpolation is specified
// - a background color is specified and will be used
// - the source surface is neither a texture nor render-to-texture
// surface, and a non-default interpolation hint is specified
// (we can only control the filtering for texture->surface
// copies)
// REMIND: we should tweak the sw->texture->surface
// transform case to handle filtering appropriately
// (see 4841762)...
// - an appropriate TransformBlit primitive could not be found
if (interpType != AffineTransformOp.TYPE_BICUBIC) {
SurfaceData dstData = sg.surfaceData;
SurfaceData srcData =
dstData.getSourceSurfaceData(img,
SunGraphics2D.TRANSFORM_GENERIC,
sg.imageComp,
bgColor);
if (srcData != null &&
!isBgOperation(srcData, bgColor) &&
(srcData.getSurfaceType() == MTLSurfaceData.MTLTexture ||
srcData.getSurfaceType() == MTLSurfaceData.MTLSurfaceRTT ||
interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR))
{
SurfaceType srcType = srcData.getSurfaceType();
SurfaceType dstType = dstData.getSurfaceType();
TransformBlit blit = TransformBlit.getFromCache(srcType,
sg.imageComp,
dstType);
if (blit != null) {
blit.Transform(srcData, dstData,
sg.composite, sg.getCompClip(),
tx, interpType,
sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
return;
}
}
}
super.renderImageXform(sg, img, tx, interpType,
sx1, sy1, sx2, sy2, bgColor);
}
@Override
public void transformImage(SunGraphics2D sg, BufferedImage img,
BufferedImageOp op, int x, int y)
{
if (op != null) {
if (op instanceof AffineTransformOp) {
AffineTransformOp atop = (AffineTransformOp) op;
transformImage(sg, img, x, y,
atop.getTransform(),
atop.getInterpolationType());
return;
} else {
if (MTLBufImgOps.renderImageWithOp(sg, img, op, x, y)) {
return;
}
}
img = op.filter(img, null);
}
copyImage(sg, img, x, y, null);
}
}

View File

@@ -0,0 +1,406 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.awt.CGraphicsConfig;
import sun.awt.CGraphicsDevice;
import sun.awt.image.OffScreenImage;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.SurfaceManager;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
import sun.java2d.Surface;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.hw.AccelGraphicsConfig;
import sun.java2d.pipe.hw.AccelSurface;
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
import sun.java2d.pipe.hw.ContextCapabilities;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.macosx.CFRetainedResource;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_GRAD_SHADER;
import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
import static sun.java2d.pipe.hw.AccelSurface.RT_TEXTURE;
import static sun.java2d.pipe.hw.ContextCapabilities.*;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
public final class MTLGraphicsConfig extends CGraphicsConfig
implements AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
{
//private static final int kOpenGLSwapInterval =
// RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
private static final int kOpenGLSwapInterval = 0; // TODO
private static boolean mtlAvailable;
private static ImageCapabilities imageCaps = new MTLImageCaps();
private static final String mtlShadersLib = AccessController.doPrivileged(
(PrivilegedAction<String>) () ->
System.getProperty("java.home", "") + File.separator +
"lib" + File.separator + "shaders.metallib");
private int pixfmt;
private BufferCapabilities bufferCaps;
private long pConfigInfo;
private ContextCapabilities mtlCaps;
private final MTLContext context;
private final Object disposerReferent = new Object();
private final int maxTextureSize;
private static native boolean initMTL();
private static native long getMTLConfigInfo(int displayID, String mtlShadersLib);
/**
* Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
* called under OGLRQ lock, because this method change current context.
*
* @return GL_MAX_TEXTURE_SIZE
*/
private static native int nativeGetMaxTextureSize();
static {
mtlAvailable = initMTL();
}
private MTLGraphicsConfig(CGraphicsDevice device, int pixfmt,
long configInfo, int maxTextureSize,
ContextCapabilities mtlCaps) {
super(device);
this.pixfmt = pixfmt;
this.pConfigInfo = configInfo;
this.mtlCaps = mtlCaps;
this.maxTextureSize = maxTextureSize;
context = new MTLContext(MTLRenderQueue.getInstance());
// add a record to the Disposer so that we destroy the native
// MTLGraphicsConfigInfo data when this object goes away
Disposer.addRecord(disposerReferent,
new MTLGCDisposerRecord(pConfigInfo));
}
@Override
public Object getProxyKey() {
return this;
}
public SurfaceData createManagedSurface(int w, int h, int transparency) {
return MTLSurfaceData.createData(this, w, h,
getColorModel(transparency),
null,
MTLSurfaceData.TEXTURE);
}
public static MTLGraphicsConfig getConfig(CGraphicsDevice device,
int displayID, int pixfmt)
{
if (!mtlAvailable) {
return null;
}
long cfginfo = 0;
int textureSize = 0;
final String[] ids = new String[1];
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// getCGLConfigInfo() creates and destroys temporary
// surfaces/contexts, so we should first invalidate the current
// Java-level context and flush the queue...
MTLContext.invalidateCurrentContext();
cfginfo = getMTLConfigInfo(displayID, mtlShadersLib);
if (cfginfo != 0L) {
textureSize = nativeGetMaxTextureSize();
// 7160609: GL still fails to create a square texture of this
// size. Half should be safe enough.
// Explicitly not support a texture more than 2^14, see 8010999.
textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
MTLContext.setScratchSurface(cfginfo);
rq.flushAndInvokeNow(() -> {
ids[0] = MTLContext.getMTLIdString();
});
}
} finally {
rq.unlock();
}
if (cfginfo == 0) {
return null;
}
ContextCapabilities caps = new MTLContext.MTLContextCaps(
CAPS_PS30 | CAPS_PS20 | CAPS_RT_PLAIN_ALPHA |
CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE |
CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 | CAPS_TEXNONSQUARE |
CAPS_EXT_BIOP_SHADER | CAPS_EXT_GRAD_SHADER,
ids[0]);
return new MTLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
}
/**
* Returns true if the provided capability bit is present for this config.
* See MTLContext.java for a list of supported capabilities.
*/
public boolean isCapPresent(int cap) {
return ((mtlCaps.getCaps() & cap) != 0);
}
public long getNativeConfigInfo() {
return pConfigInfo;
}
/**
* {@inheritDoc}
*
* @see sun.java2d.pipe.hw.BufferedContextProvider#getContext
*/
@Override
public MTLContext getContext() {
return context;
}
@Override
public BufferedImage createCompatibleImage(int width, int height) {
ColorModel model = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
WritableRaster
raster = model.createCompatibleWritableRaster(width, height);
return new BufferedImage(model, raster, model.isAlphaPremultiplied(),
null);
}
@Override
public ColorModel getColorModel(int transparency) {
switch (transparency) {
case Transparency.OPAQUE:
// REMIND: once the ColorModel spec is changed, this should be
// an opaque premultiplied DCM...
return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
case Transparency.BITMASK:
return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
case Transparency.TRANSLUCENT:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
return new DirectColorModel(cs, 32,
0xff0000, 0xff00, 0xff, 0xff000000,
true, DataBuffer.TYPE_INT);
default:
return null;
}
}
public boolean isDoubleBuffered() {
return true;
}
private static class MTLGCDisposerRecord implements DisposerRecord {
private long pCfgInfo;
public MTLGCDisposerRecord(long pCfgInfo) {
this.pCfgInfo = pCfgInfo;
}
public void dispose() {
if (pCfgInfo != 0) {
MTLRenderQueue.disposeGraphicsConfig(pCfgInfo);
pCfgInfo = 0;
}
}
}
// TODO: CGraphicsConfig doesn't implement displayChanged() yet
//@Override
public synchronized void displayChanged() {
//super.displayChanged();
// the context could hold a reference to a MTLSurfaceData, which in
// turn has a reference back to this MTLGraphicsConfig, so in order
// for this instance to be disposed we need to break the connection
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
MTLContext.invalidateCurrentContext();
} finally {
rq.unlock();
}
}
@Override
public String toString() {
return ("MTLGraphicsConfig[" + getDevice().getIDstring() +
",pixfmt="+pixfmt+"]");
}
@Override
public SurfaceData createSurfaceData(CFRetainedResource layer) {
return MTLSurfaceData.createData((MTLLayer) layer);
}
@Override
public Image createAcceleratedImage(Component target,
int width, int height)
{
ColorModel model = getColorModel(Transparency.OPAQUE);
WritableRaster wr = model.createCompatibleWritableRaster(width, height);
return new OffScreenImage(target, model, wr,
model.isAlphaPremultiplied());
}
@Override
public void assertOperationSupported(final int numBuffers,
final BufferCapabilities caps)
throws AWTException {
// Assume this method is never called with numBuffers != 2, as 0 is
// unsupported, and 1 corresponds to a SingleBufferStrategy which
// doesn't depend on the peer. Screen is considered as a separate
// "buffer".
if (numBuffers != 2) {
throw new AWTException("Only double buffering is supported");
}
final BufferCapabilities configCaps = getBufferCapabilities();
if (!configCaps.isPageFlipping()) {
throw new AWTException("Page flipping is not supported");
}
if (caps.getFlipContents() == BufferCapabilities.FlipContents.PRIOR) {
throw new AWTException("FlipContents.PRIOR is not supported");
}
}
@Override
public Image createBackBuffer(final LWComponentPeer<?, ?> peer) {
final Rectangle r = peer.getBounds();
// It is possible for the component to have size 0x0, adjust it to
// be at least 1x1 to avoid IAE
final int w = Math.max(1, r.width);
final int h = Math.max(1, r.height);
final int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT
: Transparency.OPAQUE;
return new SunVolatileImage(this, w, h, transparency, null);
}
@Override
public void destroyBackBuffer(final Image backBuffer) {
if (backBuffer != null) {
backBuffer.flush();
}
}
@Override
public void flip(final LWComponentPeer<?, ?> peer, final Image backBuffer,
final int x1, final int y1, final int x2, final int y2,
final BufferCapabilities.FlipContents flipAction) {
final Graphics g = peer.getGraphics();
try {
g.drawImage(backBuffer, x1, y1, x2, y2, x1, y1, x2, y2, null);
} finally {
g.dispose();
}
if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
final Graphics2D bg = (Graphics2D) backBuffer.getGraphics();
try {
bg.setBackground(peer.getBackground());
bg.clearRect(0, 0, backBuffer.getWidth(null),
backBuffer.getHeight(null));
} finally {
bg.dispose();
}
}
}
private static class MTLBufferCaps extends BufferCapabilities {
public MTLBufferCaps(boolean dblBuf) {
super(imageCaps, imageCaps,
dblBuf ? FlipContents.UNDEFINED : null);
}
}
@Override
public BufferCapabilities getBufferCapabilities() {
if (bufferCaps == null) {
bufferCaps = new MTLBufferCaps(isDoubleBuffered());
}
return bufferCaps;
}
private static class MTLImageCaps extends ImageCapabilities {
private MTLImageCaps() {
super(true);
}
public boolean isTrueVolatile() {
return true;
}
}
@Override
public ImageCapabilities getImageCapabilities() {
return imageCaps;
}
@Override
public VolatileImage createCompatibleVolatileImage(int width, int height,
int transparency,
int type) {
if (type != RT_TEXTURE && type != TEXTURE) {
return null;
}
SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
transparency, type);
Surface sd = vi.getDestSurface();
if (!(sd instanceof AccelSurface) ||
((AccelSurface)sd).getType() != type)
{
vi.flush();
vi = null;
}
return vi;
}
/**
* {@inheritDoc}
*
* @see sun.java2d.pipe.hw.AccelGraphicsConfig#getContextCapabilities
*/
@Override
public ContextCapabilities getContextCapabilities() {
return mtlCaps;
}
@Override
public int getMaxTextureWidth() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
getBounds().width);
}
@Override
public int getMaxTextureHeight() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
getBounds().height);
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.NullSurfaceData;
import sun.java2d.SurfaceData;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.macosx.CFRetainedResource;
import java.awt.*;
public class MTLLayer extends CFRetainedResource {
private native long nativeCreateLayer();
private static native void nativeSetScale(long layerPtr, double scale);
private static native void nativeSetInsets(long layerPtr, int top, int left);
private static native void validate(long layerPtr, MTLSurfaceData cglsd);
private static native void blitTexture(long layerPtr);
private LWWindowPeer peer;
private int scale = 1;
private SurfaceData surfaceData; // represents intermediate buffer (texture)
public MTLLayer(LWWindowPeer peer) {
super(0, true);
setPtr(nativeCreateLayer());
this.peer = peer;
}
public long getPointer() {
return ptr;
}
public Rectangle getBounds() {
return peer.getBounds();
}
public GraphicsConfiguration getGraphicsConfiguration() {
return peer.getGraphicsConfiguration();
}
public boolean isOpaque() {
return !peer.isTranslucent();
}
public int getTransparency() {
return isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT;
}
public Object getDestination() {
return peer.getTarget();
}
public SurfaceData replaceSurfaceData() {
if (getBounds().isEmpty()) {
surfaceData = NullSurfaceData.theInstance;
return surfaceData;
}
// the layer redirects all painting to the buffer's graphics
// and blits the buffer to the layer surface (in drawInCGLContext callback)
MTLGraphicsConfig gc = (MTLGraphicsConfig)getGraphicsConfiguration();
surfaceData = gc.createSurfaceData(this);
setScale(gc.getDevice().getScaleFactor());
Insets insets = peer.getInsets();
execute(ptr -> nativeSetInsets(ptr, insets.top, insets.left));
// the layer holds a reference to the buffer, which in
// turn has a reference back to this layer
if (surfaceData instanceof MTLSurfaceData) {
validate((MTLSurfaceData)surfaceData);
}
return surfaceData;
}
public SurfaceData getSurfaceData() {
return surfaceData;
}
public void validate(final MTLSurfaceData cglsd) {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
execute(ptr -> validate(ptr, cglsd));
} finally {
rq.unlock();
}
}
@Override
public void dispose() {
// break the connection between the layer and the buffer
validate(null);
SurfaceData oldData = surfaceData;
surfaceData = NullSurfaceData.theInstance;;
if (oldData != null) {
oldData.flush();
}
super.dispose();
}
private void setScale(final int _scale) {
if (scale != _scale) {
scale = _scale;
execute(ptr -> nativeSetScale(ptr, scale));
}
}
// ----------------------------------------------------------------------
// NATIVE CALLBACKS
// ----------------------------------------------------------------------
private void drawInMTLContext() {
// tell the flusher thread not to update the intermediate buffer
// until we are done blitting from it
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
execute(ptr -> blitTexture(ptr));
} finally {
rq.unlock();
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SurfaceData;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.GraphicsPrimitiveMgr;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.BufferedMaskBlit;
import sun.java2d.pipe.Region;
import java.awt.*;
import static sun.java2d.loops.CompositeType.SrcNoEa;
import static sun.java2d.loops.CompositeType.SrcOver;
import static sun.java2d.loops.SurfaceType.*;
class MTLMaskBlit extends BufferedMaskBlit {
static void register() {
GraphicsPrimitive[] primitives = {
new MTLMaskBlit(IntArgb, SrcOver),
new MTLMaskBlit(IntArgbPre, SrcOver),
new MTLMaskBlit(IntRgb, SrcOver),
new MTLMaskBlit(IntRgb, SrcNoEa),
new MTLMaskBlit(IntBgr, SrcOver),
new MTLMaskBlit(IntBgr, SrcNoEa),
};
GraphicsPrimitiveMgr.register(primitives);
}
private MTLMaskBlit(SurfaceType srcType,
CompositeType compType)
{
super(MTLRenderQueue.getInstance(),
srcType, compType, MTLSurfaceData.MTLSurface);
}
@Override
protected void validateContext(SurfaceData dstData,
Composite comp, Region clip)
{
MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
MTLContext.validateContext(oglDst, oglDst,
clip, comp, null, null, null,
MTLContext.NO_CONTEXT_FLAGS);
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.GraphicsPrimitiveMgr;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.BufferedMaskFill;
import java.awt.*;
import static sun.java2d.loops.CompositeType.SrcNoEa;
import static sun.java2d.loops.CompositeType.SrcOver;
import static sun.java2d.loops.SurfaceType.*;
class MTLMaskFill extends BufferedMaskFill {
static void register() {
GraphicsPrimitive[] primitives = {
new MTLMaskFill(AnyColor, SrcOver),
new MTLMaskFill(OpaqueColor, SrcNoEa),
new MTLMaskFill(GradientPaint, SrcOver),
new MTLMaskFill(OpaqueGradientPaint, SrcNoEa),
new MTLMaskFill(LinearGradientPaint, SrcOver),
new MTLMaskFill(OpaqueLinearGradientPaint, SrcNoEa),
new MTLMaskFill(RadialGradientPaint, SrcOver),
new MTLMaskFill(OpaqueRadialGradientPaint, SrcNoEa),
new MTLMaskFill(TexturePaint, SrcOver),
new MTLMaskFill(OpaqueTexturePaint, SrcNoEa),
};
GraphicsPrimitiveMgr.register(primitives);
}
protected MTLMaskFill(SurfaceType srcType, CompositeType compType) {
super(MTLRenderQueue.getInstance(),
srcType, compType, MTLSurfaceData.MTLSurface);
}
@Override
protected native void maskFill(int x, int y, int w, int h,
int maskoff, int maskscan, int masklen,
byte[] mask);
@Override
protected void validateContext(SunGraphics2D sg2d,
Composite comp, int ctxflags)
{
MTLSurfaceData dstData;
try {
dstData = (MTLSurfaceData) sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " +
sg2d.surfaceData);
}
MTLContext.validateContext(dstData, dstData,
sg2d.getCompClip(), comp,
null, sg2d.paint, sg2d, ctxflags);
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.CompositeType;
import java.awt.*;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_GRAD_SHADER;
import static sun.java2d.pipe.BufferedPaints.MULTI_MAX_FRACTIONS;
abstract class MTLPaints {
/**
* Holds all registered implementations, using the corresponding
* SunGraphics2D.PAINT_* constant as the hash key.
*/
private static Map<Integer, MTLPaints> impls =
new HashMap<Integer, MTLPaints>(4, 1.0f);
static {
impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient());
impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient());
impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient());
impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture());
}
/**
* Attempts to locate an implementation corresponding to the paint state
* of the provided SunGraphics2D object. If no implementation can be
* found, or if the paint cannot be accelerated under the conditions
* of the SunGraphics2D, this method returns false; otherwise, returns
* true.
*/
static boolean isValid(SunGraphics2D sg2d) {
MTLPaints impl = impls.get(sg2d.paintState);
return (impl != null && impl.isPaintValid(sg2d));
}
/**
* Returns true if this implementation is able to accelerate the
* Paint object associated with, and under the conditions of, the
* provided SunGraphics2D instance; otherwise returns false.
*/
abstract boolean isPaintValid(SunGraphics2D sg2d);
/************************* GradientPaint support ****************************/
private static class Gradient extends MTLPaints {
private Gradient() {}
/**
* There are no restrictions for accelerating GradientPaint, so
* this method always returns true.
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
return true;
}
}
/************************** TexturePaint support ****************************/
private static class Texture extends MTLPaints {
private Texture() {}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated MTLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
MTLSurfaceData dstData = (MTLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof MTLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof MTLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
MTLSurfaceData oglData = (MTLSurfaceData)srcData;
if (oglData.getType() != MTLSurfaceData.TEXTURE) {
return false;
}
return true;
}
}
/****************** Shared MultipleGradientPaint support ********************/
private abstract static class MultiGradient extends MTLPaints {
protected MultiGradient() {}
/**
* Returns true if the given MultipleGradientPaint instance can be
* used by the accelerated MTLPaints.MultiGradient implementation.
* A MultipleGradientPaint is considered valid if the following
* conditions are met:
* - the number of gradient "stops" is <= MAX_FRACTIONS
* - the destination has support for fragment shaders
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint;
// REMIND: ugh, this creates garbage; would be nicer if
// we had a MultipleGradientPaint.getNumStops() method...
if (paint.getFractions().length > MULTI_MAX_FRACTIONS) {
return false;
}
MTLSurfaceData dstData = (MTLSurfaceData)sg2d.surfaceData;
MTLGraphicsConfig gc = dstData.getMTLGraphicsConfig();
if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) {
return false;
}
return true;
}
}
/********************** LinearGradientPaint support *************************/
private static class LinearGradient extends MultiGradient {
private LinearGradient() {}
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;
if (paint.getFractions().length == 2 &&
paint.getCycleMethod() != CycleMethod.REPEAT &&
paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
{
// we can delegate to the optimized two-color gradient
// codepath, which does not require fragment shader support
return true;
}
return super.isPaintValid(sg2d);
}
}
/********************** RadialGradientPaint support *************************/
private static class RadialGradient extends MultiGradient {
private RadialGradient() {}
}
}

View File

@@ -0,0 +1,254 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.awt.util.ThreadGroupUtils;
import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.RenderQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
import static sun.java2d.pipe.BufferedOpCodes.DISPOSE_CONFIG;
import static sun.java2d.pipe.BufferedOpCodes.SYNC;
/**
* OGL-specific implementation of RenderQueue. This class provides a
* single (daemon) thread that is responsible for periodically flushing
* the queue, thus ensuring that only one thread communicates with the native
* OpenGL libraries for the entire process.
*/
public class MTLRenderQueue extends RenderQueue {
private static MTLRenderQueue theInstance;
private final QueueFlusher flusher;
private MTLRenderQueue() {
/*
* The thread must be a member of a thread group
* which will not get GCed before VM exit.
*/
flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new);
}
/**
* Returns the single MTLRenderQueue instance. If it has not yet been
* initialized, this method will first construct the single instance
* before returning it.
*/
public static synchronized MTLRenderQueue getInstance() {
if (theInstance == null) {
theInstance = new MTLRenderQueue();
}
return theInstance;
}
/**
* Flushes the single MTLRenderQueue instance synchronously. If an
* MTLRenderQueue has not yet been instantiated, this method is a no-op.
* This method is useful in the case of Toolkit.sync(), in which we want
* to flush the OGL pipeline, but only if the OGL pipeline is currently
* enabled. Since this class has few external dependencies, callers need
* not be concerned that calling this method will trigger initialization
* of the OGL pipeline and related classes.
*/
public static void sync() {
if (theInstance != null) {
theInstance.lock();
try {
theInstance.ensureCapacity(4);
theInstance.getBuffer().putInt(SYNC);
theInstance.flushNow();
} finally {
theInstance.unlock();
}
}
}
/**
* Disposes the native memory associated with the given native
* graphics config info pointer on the single queue flushing thread.
*/
public static void disposeGraphicsConfig(long pConfigInfo) {
MTLRenderQueue rq = getInstance();
rq.lock();
try {
// make sure we make the context associated with the given
// GraphicsConfig current before disposing the native resources
MTLContext.setScratchSurface(pConfigInfo);
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(DISPOSE_CONFIG);
buf.putLong(pConfigInfo);
// this call is expected to complete synchronously, so flush now
rq.flushNow();
} finally {
rq.unlock();
}
}
/**
* Returns true if the current thread is the OGL QueueFlusher thread.
*/
public static boolean isQueueFlusherThread() {
return (Thread.currentThread() == getInstance().flusher.thread);
}
@Override
public void flushNow() {
// assert lock.isHeldByCurrentThread();
try {
flusher.flushNow();
} catch (Exception e) {
System.err.println("exception in flushNow:");
e.printStackTrace();
}
}
public void flushAndInvokeNow(Runnable r) {
// assert lock.isHeldByCurrentThread();
try {
flusher.flushAndInvokeNow(r);
} catch (Exception e) {
System.err.println("exception in flushAndInvokeNow:");
e.printStackTrace();
}
}
private native void flushBuffer(long buf, int limit);
private void flushBuffer() {
// assert lock.isHeldByCurrentThread();
int limit = buf.position();
if (limit > 0) {
// process the queue
flushBuffer(buf.getAddress(), limit);
}
// reset the buffer position
buf.clear();
// clear the set of references, since we no longer need them
refSet.clear();
}
private class QueueFlusher implements Runnable {
private boolean needsFlush;
private Runnable task;
private Error error;
private final Thread thread;
public QueueFlusher() {
String name = "Java2D Queue Flusher";
thread = new Thread(ThreadGroupUtils.getRootThreadGroup(),
this, name, 0, false);
thread.setDaemon(true);
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
}
public synchronized void flushNow() {
// wake up the flusher
needsFlush = true;
notify();
// wait for flush to complete
while (needsFlush) {
try {
wait();
} catch (InterruptedException e) {
}
}
// re-throw any error that may have occurred during the flush
if (error != null) {
throw error;
}
}
public synchronized void flushAndInvokeNow(Runnable task) {
this.task = task;
flushNow();
}
public synchronized void run() {
boolean timedOut = false;
while (true) {
while (!needsFlush) {
try {
timedOut = false;
/*
* Wait until we're woken up with a flushNow() call,
* or the timeout period elapses (so that we can
* flush the queue periodically).
*/
wait(100);
/*
* We will automatically flush the queue if the
* following conditions apply:
* - the wait() timed out
* - we can lock the queue (without blocking)
* - there is something in the queue to flush
* Otherwise, just continue (we'll flush eventually).
*/
if (!needsFlush && (timedOut = tryLock())) {
if (buf.position() > 0) {
needsFlush = true;
} else {
unlock();
}
}
} catch (InterruptedException e) {
}
}
try {
// reset the throwable state
error = null;
// flush the buffer now
flushBuffer();
// if there's a task, invoke that now as well
if (task != null) {
task.run();
}
} catch (Error e) {
error = e;
} catch (Exception x) {
System.err.println("exception in QueueFlusher:");
x.printStackTrace();
} finally {
if (timedOut) {
unlock();
}
task = null;
// allow the waiting thread to continue
needsFlush = false;
notify();
}
}
}
}
}

View File

@@ -0,0 +1,223 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.pipe.BufferedRenderPipe;
import sun.java2d.pipe.ParallelogramPipe;
import sun.java2d.pipe.RenderQueue;
import sun.java2d.pipe.SpanIterator;
import java.awt.*;
import java.awt.geom.Path2D;
import static sun.java2d.pipe.BufferedOpCodes.COPY_AREA;
class MTLRenderer extends BufferedRenderPipe {
MTLRenderer(RenderQueue rq) {
super(rq);
}
@Override
protected void validateContext(SunGraphics2D sg2d) {
int ctxflags =
sg2d.paint.getTransparency() == Transparency.OPAQUE ?
MTLContext.SRC_IS_OPAQUE : MTLContext.NO_CONTEXT_FLAGS;
MTLSurfaceData dstData;
try {
dstData = (MTLSurfaceData)sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
MTLContext.validateContext(dstData, dstData,
sg2d.getCompClip(), sg2d.composite,
null, sg2d.paint, sg2d, ctxflags);
}
@Override
protected void validateContextAA(SunGraphics2D sg2d) {
int ctxflags = MTLContext.NO_CONTEXT_FLAGS;
MTLSurfaceData dstData;
try {
dstData = (MTLSurfaceData)sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
MTLContext.validateContext(dstData, dstData,
sg2d.getCompClip(), sg2d.composite,
null, sg2d.paint, sg2d, ctxflags);
}
void copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
{
rq.lock();
try {
int ctxflags =
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE ?
MTLContext.SRC_IS_OPAQUE : MTLContext.NO_CONTEXT_FLAGS;
MTLSurfaceData dstData;
try {
dstData = (MTLSurfaceData)sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
MTLContext.validateContext(dstData, dstData,
sg2d.getCompClip(), sg2d.composite,
null, null, null, ctxflags);
rq.ensureCapacity(28);
buf.putInt(COPY_AREA);
buf.putInt(x).putInt(y).putInt(w).putInt(h);
buf.putInt(dx).putInt(dy);
} finally {
rq.unlock();
}
}
@Override
protected native void drawPoly(int[] xPoints, int[] yPoints,
int nPoints, boolean isClosed,
int transX, int transY);
MTLRenderer traceWrap() {
return new Tracer(this);
}
private class Tracer extends MTLRenderer {
private MTLRenderer mtlr;
Tracer(MTLRenderer mtlr) {
super(mtlr.rq);
this.mtlr = mtlr;
}
public ParallelogramPipe getAAParallelogramPipe() {
final ParallelogramPipe realpipe = mtlr.getAAParallelogramPipe();
return new ParallelogramPipe() {
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("MTLFillAAParallelogram");
realpipe.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
GraphicsPrimitive.tracePrimitive("MTLDrawAAParallelogram");
realpipe.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2,
lw1, lw2);
}
};
}
protected void validateContext(SunGraphics2D sg2d) {
mtlr.validateContext(sg2d);
}
public void drawLine(SunGraphics2D sg2d,
int x1, int y1, int x2, int y2)
{
GraphicsPrimitive.tracePrimitive("MTLDrawLine");
mtlr.drawLine(sg2d, x1, y1, x2, y2);
}
public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
GraphicsPrimitive.tracePrimitive("MTLDrawRect");
mtlr.drawRect(sg2d, x, y, w, h);
}
protected void drawPoly(SunGraphics2D sg2d,
int[] xPoints, int[] yPoints,
int nPoints, boolean isClosed)
{
GraphicsPrimitive.tracePrimitive("MTLDrawPoly");
mtlr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
}
public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
GraphicsPrimitive.tracePrimitive("MTLFillRect");
mtlr.fillRect(sg2d, x, y, w, h);
}
protected void drawPath(SunGraphics2D sg2d,
Path2D.Float p2df, int transx, int transy)
{
GraphicsPrimitive.tracePrimitive("MTLDrawPath");
mtlr.drawPath(sg2d, p2df, transx, transy);
}
protected void fillPath(SunGraphics2D sg2d,
Path2D.Float p2df, int transx, int transy)
{
GraphicsPrimitive.tracePrimitive("MTLFillPath");
mtlr.fillPath(sg2d, p2df, transx, transy);
}
protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
int transx, int transy)
{
GraphicsPrimitive.tracePrimitive("MTLFillSpans");
mtlr.fillSpans(sg2d, si, transx, transy);
}
public void fillParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
GraphicsPrimitive.tracePrimitive("MTLFillParallelogram");
mtlr.fillParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg2d,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
GraphicsPrimitive.tracePrimitive("MTLDrawParallelogram");
mtlr.drawParallelogram(sg2d,
ux1, uy1, ux2, uy2,
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
}
public void copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
{
GraphicsPrimitive.tracePrimitive("MTLCopyArea");
mtlr.copyArea(sg2d, x, y, w, h, dx, dy);
}
}
}

View File

@@ -0,0 +1,695 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.awt.SunHints;
import sun.awt.image.PixelConverter;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.MaskFill;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.ParallelogramPipe;
import sun.java2d.pipe.PixelToParallelogramConverter;
import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.TextPipe;
import sun.java2d.pipe.hw.AccelSurface;
import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_LCD_SHADER;
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_TEXRECT;
import static sun.java2d.pipe.BufferedOpCodes.*;
import static sun.java2d.pipe.hw.ContextCapabilities.*;
public abstract class MTLSurfaceData extends SurfaceData
implements AccelSurface {
/**
* Pixel formats
*/
public static final int PF_INT_ARGB = 0;
public static final int PF_INT_ARGB_PRE = 1;
public static final int PF_INT_RGB = 2;
public static final int PF_INT_RGBX = 3;
public static final int PF_INT_BGR = 4;
public static final int PF_INT_BGRX = 5;
public static final int PF_USHORT_565_RGB = 6;
public static final int PF_USHORT_555_RGB = 7;
public static final int PF_USHORT_555_RGBX = 8;
public static final int PF_BYTE_GRAY = 9;
public static final int PF_USHORT_GRAY = 10;
public static final int PF_3BYTE_BGR = 11;
/**
* SurfaceTypes
*/
private static final String DESC_MTL_SURFACE = "MTL Surface";
private static final String DESC_MTL_SURFACE_RTT =
"MTL Surface (render-to-texture)";
private static final String DESC_MTL_TEXTURE = "MTL Texture";
static final SurfaceType MTLSurface =
SurfaceType.Any.deriveSubType(DESC_MTL_SURFACE,
PixelConverter.ArgbPre.instance);
static final SurfaceType MTLSurfaceRTT =
MTLSurface.deriveSubType(DESC_MTL_SURFACE_RTT);
static final SurfaceType MTLTexture =
SurfaceType.Any.deriveSubType(DESC_MTL_TEXTURE);
protected static MTLRenderer mtlRenderPipe;
protected static PixelToParallelogramConverter mtlTxRenderPipe;
protected static ParallelogramPipe mtlAAPgramPipe;
protected static MTLTextRenderer mtlTextPipe;
protected static MTLDrawImage mtlImagePipe;
/** This will be true if the fbobject system property has been enabled. */
private static boolean isFBObjectEnabled;
/** This will be true if the lcdshader system property has been enabled.*/
private static boolean isLCDShaderEnabled;
/** This will be true if the biopshader system property has been enabled.*/
private static boolean isBIOpShaderEnabled;
/** This will be true if the gradshader system property has been enabled.*/
private static boolean isGradShaderEnabled;
static {
if (!GraphicsEnvironment.isHeadless()) {
// fbobject currently enabled by default; use "false" to disable
String fbo = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java2d.metal.fbobject"));
isFBObjectEnabled = !"false".equals(fbo);
// lcdshader currently enabled by default; use "false" to disable
String lcd = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java2d.metal.lcdshader"));
isLCDShaderEnabled = !"false".equals(lcd);
// biopshader currently enabled by default; use "false" to disable
String biop = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java2d.metal.biopshader"));
isBIOpShaderEnabled = !"false".equals(biop);
// gradshader currently enabled by default; use "false" to disable
String grad = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java2d.metal.gradshader"));
isGradShaderEnabled = !"false".equals(grad);
MTLRenderQueue rq = MTLRenderQueue.getInstance();
mtlImagePipe = new MTLDrawImage();
mtlTextPipe = new MTLTextRenderer(rq);
mtlRenderPipe = new MTLRenderer(rq);
if (GraphicsPrimitive.tracingEnabled()) {
mtlTextPipe = mtlTextPipe.traceWrap();
//The wrapped mtlRenderPipe will wrap the AA pipe as well...
//mtlAAPgramPipe = mtlRenderPipe.traceWrap();
}
mtlAAPgramPipe = mtlRenderPipe.getAAParallelogramPipe();
mtlTxRenderPipe =
new PixelToParallelogramConverter(mtlRenderPipe,
mtlRenderPipe,
1.0, 0.25, true);
MTLBlitLoops.register();
MTLMaskFill.register();
MTLMaskBlit.register();
}
}
protected final int scale;
protected final int width;
protected final int height;
protected int type;
private MTLGraphicsConfig graphicsConfig;
// these fields are set from the native code when the surface is
// initialized
private int nativeWidth;
private int nativeHeight;
/**
* Returns the appropriate SurfaceType corresponding to the given OpenGL
* surface type constant (e.g. TEXTURE -> MTLTexture).
*/
private static SurfaceType getCustomSurfaceType(int oglType) {
switch (oglType) {
case TEXTURE:
return MTLTexture;
case RT_TEXTURE:
return MTLSurfaceRTT;
default:
return MTLSurface;
}
}
static void swapBuffers(long window) {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(SWAP_BUFFERS);
buf.putLong(window);
rq.flushNow();
} finally {
rq.unlock();
}
}
private native void initOps(MTLGraphicsConfig gc, long pConfigInfo, long pPeerData, long layerPtr,
int xoff, int yoff, boolean isOpaque);
private MTLSurfaceData(MTLLayer layer, MTLGraphicsConfig gc,
ColorModel cm, int type, int width, int height)
{
super(getCustomSurfaceType(type), cm);
this.graphicsConfig = gc;
this.type = type;
setBlitProxyKey(gc.getProxyKey());
// TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
this.width = width * scale;
this.height = height * scale;
long pConfigInfo = gc.getNativeConfigInfo();
long layerPtr = 0L;
boolean isOpaque = true;
if (layer != null) {
layerPtr = layer.getPointer();
isOpaque = layer.isOpaque();
}
initOps(gc, pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
}
@Override //SurfaceData
public GraphicsConfiguration getDeviceConfiguration() {
return graphicsConfig;
}
/**
* Creates a SurfaceData object representing the intermediate buffer
* between the Java2D flusher thread and the AppKit thread.
*/
public static MTLLayerSurfaceData createData(MTLLayer layer) {
MTLGraphicsConfig gc = (MTLGraphicsConfig)layer.getGraphicsConfiguration();
Rectangle r = layer.getBounds();
return new MTLLayerSurfaceData(layer, gc, r.width, r.height);
}
/**
* Creates a SurfaceData object representing an off-screen buffer (either a
* FBO or Texture).
*/
public static MTLOffScreenSurfaceData createData(MTLGraphicsConfig gc,
int width, int height, ColorModel cm, Image image, int type) {
return new MTLOffScreenSurfaceData(gc, width, height, image, cm,
type);
}
@Override
public double getDefaultScaleX() {
return scale;
}
@Override
public double getDefaultScaleY() {
return scale;
}
@Override
public Rectangle getBounds() {
return new Rectangle(width, height);
}
protected native void clearWindow();
protected native boolean initTexture(long pData, boolean isOpaque, int width, int height);
protected native boolean initRTexture(long pData, boolean isOpaque, int width, int height);
protected native boolean initFlipBackbuffer(long pData);
@Override
public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
return MTLSurfaceDataProxy.createProxy(srcData, graphicsConfig);
}
/**
* Note: This should only be called from the QFT under the AWT lock.
* This method is kept separate from the initSurface() method below just
* to keep the code a bit cleaner.
*/
private void initSurfaceNow(int width, int height) {
boolean isOpaque = (getTransparency() == Transparency.OPAQUE);
boolean success = false;
switch (type) {
case TEXTURE:
success = initTexture(getNativeOps(), isOpaque, width, height);
break;
case RT_TEXTURE:
success = initRTexture(getNativeOps(), isOpaque, width, height);
break;
case FLIP_BACKBUFFER:
success = initFlipBackbuffer(getNativeOps());
break;
default:
break;
}
if (!success) {
throw new OutOfMemoryError("can't create offscreen surface");
}
}
/**
* Initializes the appropriate OpenGL offscreen surface based on the value
* of the type parameter. If the surface creation fails for any reason,
* an OutOfMemoryError will be thrown.
*/
protected void initSurface(final int width, final int height) {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
switch (type) {
case TEXTURE:
case RT_TEXTURE:
// need to make sure the context is current before
// creating the texture or fbobject
MTLContext.setScratchSurface(graphicsConfig);
break;
default:
break;
}
rq.flushAndInvokeNow(new Runnable() {
public void run() {
initSurfaceNow(width, height);
}
});
} finally {
rq.unlock();
}
}
/**
* Returns the MTLContext for the GraphicsConfig associated with this
* surface.
*/
public final MTLContext getContext() {
return graphicsConfig.getContext();
}
/**
* Returns the MTLGraphicsConfig associated with this surface.
*/
final MTLGraphicsConfig getMTLGraphicsConfig() {
return graphicsConfig;
}
/**
* Returns one of the surface type constants defined above.
*/
public final int getType() {
return type;
}
/**
* For now, we can only render LCD text if:
* - the fragment shader extension is available, and
* - the source color is opaque, and
* - blending is SrcOverNoEa or disabled
* - and the destination is opaque
*
* Eventually, we could enhance the native OGL text rendering code
* and remove the above restrictions, but that would require significantly
* more code just to support a few uncommon cases.
*/
public boolean canRenderLCDText(SunGraphics2D sg2d) {
return
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE &&
sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR &&
(sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY ||
(sg2d.compositeState <= SunGraphics2D.COMP_ALPHA && canHandleComposite(sg2d.composite)));
}
private boolean canHandleComposite(Composite c) {
if (c instanceof AlphaComposite) {
AlphaComposite ac = (AlphaComposite)c;
return ac.getRule() == AlphaComposite.SRC_OVER && ac.getAlpha() >= 1f;
}
return false;
}
public void validatePipe(SunGraphics2D sg2d) {
TextPipe textpipe;
boolean validated = false;
// MTLTextRenderer handles both AA and non-AA text, but
// only works with the following modes:
// (Note: For LCD text we only enter this code path if
// canRenderLCDText() has already validated that the mode is
// CompositeType.SrcNoEa (opaque color), which will be subsumed
// by the CompositeType.SrcNoEa (any color) test below.)
if (/* CompositeType.SrcNoEa (any color) */
(sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) ||
/* CompositeType.SrcOver (any color) */
(sg2d.compositeState == SunGraphics2D.COMP_ALPHA &&
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
(((AlphaComposite)sg2d.composite).getRule() ==
AlphaComposite.SRC_OVER)) ||
/* CompositeType.Xor (any color) */
(sg2d.compositeState == SunGraphics2D.COMP_XOR &&
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR))
{
textpipe = mtlTextPipe;
} else {
// do this to initialize textpipe correctly; we will attempt
// to override the non-text pipes below
super.validatePipe(sg2d);
textpipe = sg2d.textpipe;
validated = true;
}
PixelToParallelogramConverter txPipe = null;
MTLRenderer nonTxPipe = null;
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) {
txPipe = mtlTxRenderPipe;
nonTxPipe = mtlRenderPipe;
}
} else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
if (MTLPaints.isValid(sg2d)) {
txPipe = mtlTxRenderPipe;
nonTxPipe = mtlRenderPipe;
}
// custom paints handled by super.validatePipe() below
}
} else {
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
if (graphicsConfig.isCapPresent(CAPS_PS30) &&
(sg2d.imageComp == CompositeType.SrcOverNoEa ||
sg2d.imageComp == CompositeType.SrcOver))
{
if (!validated) {
super.validatePipe(sg2d);
validated = true;
}
PixelToParallelogramConverter aaConverter =
new PixelToParallelogramConverter(sg2d.shapepipe,
mtlAAPgramPipe,
1.0/8.0, 0.499,
false);
sg2d.drawpipe = aaConverter;
sg2d.fillpipe = aaConverter;
sg2d.shapepipe = aaConverter;
} else if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
// install the solid pipes when AA and XOR are both enabled
txPipe = mtlTxRenderPipe;
nonTxPipe = mtlRenderPipe;
}
}
// other cases handled by super.validatePipe() below
}
if (txPipe != null) {
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
sg2d.drawpipe = txPipe;
sg2d.fillpipe = txPipe;
} else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
sg2d.drawpipe = txPipe;
sg2d.fillpipe = nonTxPipe;
} else {
sg2d.drawpipe = nonTxPipe;
sg2d.fillpipe = nonTxPipe;
}
// Note that we use the transforming pipe here because it
// will examine the shape and possibly perform an optimized
// operation if it can be simplified. The simplifications
// will be valid for all STROKE and TRANSFORM types.
sg2d.shapepipe = txPipe;
} else {
if (!validated) {
super.validatePipe(sg2d);
}
}
// install the text pipe based on our earlier decision
sg2d.textpipe = textpipe;
// always override the image pipe with the specialized OGL pipe
sg2d.imagepipe = mtlImagePipe;
}
@Override
protected MaskFill getMaskFill(SunGraphics2D sg2d) {
if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) {
/*
* We can only accelerate non-Color MaskFill operations if
* all of the following conditions hold true:
* - there is an implementation for the given paintState
* - the current Paint can be accelerated for this destination
* - multitexturing is available (since we need to modulate
* the alpha mask texture with the paint texture)
*
* In all other cases, we return null, in which case the
* validation code will choose a more general software-based loop.
*/
if (!MTLPaints.isValid(sg2d) ||
!graphicsConfig.isCapPresent(CAPS_MULTITEXTURE))
{
return null;
}
}
return super.getMaskFill(sg2d);
}
public void flush() {
invalidate();
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// make sure we have a current context before
// disposing the native resources (e.g. texture object)
MTLContext.setScratchSurface(graphicsConfig);
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(FLUSH_SURFACE);
buf.putLong(getNativeOps());
// this call is expected to complete synchronously, so flush now
rq.flushNow();
} finally {
rq.unlock();
}
}
/**
* Returns true if the surface is an on-screen window surface or
* a FBO texture attached to an on-screen CALayer.
*
* Needed by Mac OS X port.
*/
public boolean isOnScreen() {
return getType() == WINDOW;
}
private native long getMTLTexturePointer(long pData);
/**
* Returns native resource of specified {@code resType} associated with
* this surface.
*
* Specifically, for {@code MTLSurfaceData} this method returns the
* the following:
* <pre>
* TEXTURE - texture id
* </pre>
*
* Note: the resource returned by this method is only valid on the rendering
* thread.
*
* @return native resource of specified type or 0L if
* such resource doesn't exist or can not be retrieved.
* @see AccelSurface#getNativeResource
*/
public long getNativeResource(int resType) {
if (resType == TEXTURE) {
return getMTLTexturePointer(getNativeOps());
}
return 0L;
}
public Raster getRaster(int x, int y, int w, int h) {
throw new InternalError("not implemented yet");
}
@Override
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
int dx, int dy) {
if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
return false;
}
mtlRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
return true;
}
public Rectangle getNativeBounds() {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
return new Rectangle(nativeWidth, nativeHeight);
} finally {
rq.unlock();
}
}
/**
* A surface which implements an intermediate buffer between
* the Java2D flusher thread and the AppKit thread.
*
* This surface serves as a buffer attached to a MTLLayer and
* the layer redirects all painting to the buffer's graphics.
*/
public static class MTLLayerSurfaceData extends MTLSurfaceData {
private final MTLLayer layer;
private MTLLayerSurfaceData(MTLLayer layer, MTLGraphicsConfig gc,
int width, int height) {
super(layer, gc, gc.getColorModel(), RT_TEXTURE, width, height);
this.layer = layer;
initSurface(this.width, this.height);
}
@Override
public SurfaceData getReplacement() {
return layer.getSurfaceData();
}
@Override
public boolean isOnScreen() {
return true;
}
@Override
public Object getDestination() {
return layer.getDestination();
}
@Override
public int getTransparency() {
return layer.getTransparency();
}
@Override
public void invalidate() {
super.invalidate();
clearWindow();
}
}
/**
* SurfaceData object representing an off-screen buffer (either a FBO or
* Texture).
+ */
public static class MTLOffScreenSurfaceData extends MTLSurfaceData {
private final Image offscreenImage;
public MTLOffScreenSurfaceData(MTLGraphicsConfig gc, int width,
int height, Image image,
ColorModel cm, int type) {
super(null, gc, cm, type, width, height);
offscreenImage = image;
initSurface(this.width, this.height);
}
@Override
public SurfaceData getReplacement() {
return restoreContents(offscreenImage);
}
/**
* Returns destination Image associated with this SurfaceData.
*/
@Override
public Object getDestination() {
return offscreenImage;
}
}
// additional cleanup
private static native void destroyCGLContext(long ctx);
public static void destroyOGLContext(long ctx) {
if (ctx != 0L) {
destroyCGLContext(ctx);
}
}
/**
* Disposes the native resources associated with the given MTLSurfaceData
* (referenced by the pData parameter). This method is invoked from
* the native Dispose() method from the Disposer thread when the
* Java-level MTLSurfaceData object is about to go away.
*/
public static void dispose(long pData, MTLGraphicsConfig gc) {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// make sure we have a current context before
// disposing the native resources (e.g. texture object)
MTLContext.setScratchSurface(gc);
RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4);
buf.putInt(DISPOSE_SURFACE);
buf.putLong(pData);
// this call is expected to complete synchronously, so flush now
rq.flushNow();
} finally {
rq.unlock();
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SurfaceData;
import sun.java2d.SurfaceDataProxy;
import sun.java2d.loops.CompositeType;
import java.awt.*;
/**
* The proxy class contains the logic for when to replace a
* SurfaceData with a cached OGL Texture and the code to create
* the accelerated surfaces.
*/
public class MTLSurfaceDataProxy extends SurfaceDataProxy {
public static SurfaceDataProxy createProxy(SurfaceData srcData,
MTLGraphicsConfig dstConfig)
{
if (srcData instanceof MTLSurfaceData) {
// srcData must be a VolatileImage which either matches
// our pixel format or not - either way we do not cache it...
return UNCACHED;
}
return new MTLSurfaceDataProxy(dstConfig, srcData.getTransparency());
}
MTLGraphicsConfig oglgc;
int transparency;
public MTLSurfaceDataProxy(MTLGraphicsConfig oglgc, int transparency) {
this.oglgc = oglgc;
this.transparency = transparency;
}
@Override
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData,
int w, int h)
{
if (cachedData == null) {
try {
cachedData = oglgc.createManagedSurface(w, h, transparency);
} catch (OutOfMemoryError er) {
return null;
}
}
return cachedData;
}
@Override
public boolean isSupportedOperation(SurfaceData srcData,
int txtype,
CompositeType comp,
Color bgColor)
{
return comp.isDerivedFrom(CompositeType.AnyAlpha) &&
(bgColor == null || transparency == Transparency.OPAQUE);
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.font.GlyphList;
import sun.java2d.SunGraphics2D;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.pipe.BufferedTextPipe;
import sun.java2d.pipe.RenderQueue;
import java.awt.*;
class MTLTextRenderer extends BufferedTextPipe {
MTLTextRenderer(RenderQueue rq) {
super(rq);
}
@Override
protected native void drawGlyphList(int numGlyphs, boolean usePositions,
boolean subPixPos, boolean rgbOrder,
int lcdContrast,
float glOrigX, float glOrigY,
long[] images, float[] positions);
@Override
protected void validateContext(SunGraphics2D sg2d, Composite comp) {
// assert rq.lock.isHeldByCurrentThread();
MTLSurfaceData oglDst = (MTLSurfaceData)sg2d.surfaceData;
MTLContext.validateContext(oglDst, oglDst,
sg2d.getCompClip(), comp,
null, sg2d.paint, sg2d,
MTLContext.NO_CONTEXT_FLAGS);
}
MTLTextRenderer traceWrap() {
return new Tracer(this);
}
private static class Tracer extends MTLTextRenderer {
Tracer(MTLTextRenderer mtltr) {
super(mtltr.rq);
}
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
GraphicsPrimitive.tracePrimitive("MTLDrawGlyphs");
super.drawGlyphList(sg2d, gl);
}
}
}

View File

@@ -0,0 +1,278 @@
/*
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.Region;
import java.awt.*;
/**
* This class contains a number of static utility methods that may be
* called (via reflection) by a third-party library in order
* to interoperate with the metal-based Java 2D pipeline.
*
*/
class MTLUtilities {
/**
* These OGL-specific surface type constants are the same as those
* defined in the MTLSurfaceData class and are duplicated here so that
* clients of this API can access them more easily via reflection.
*/
public static final int UNDEFINED = MTLSurfaceData.UNDEFINED;
public static final int WINDOW = MTLSurfaceData.WINDOW;
public static final int TEXTURE = MTLSurfaceData.TEXTURE;
public static final int FLIP_BACKBUFFER = MTLSurfaceData.FLIP_BACKBUFFER;
public static final int RT_TEXTURE = MTLSurfaceData.RT_TEXTURE;
private MTLUtilities() {
}
/**
* Returns true if the current thread is the OGL QueueFlusher thread.
*/
public static boolean isQueueFlusherThread() {
return MTLRenderQueue.isQueueFlusherThread();
}
/**
* Invokes the given Runnable on the MTL QueueFlusher thread with the
* MTL context corresponding to the given Graphics object made
* current. It is legal for MTL code executed in the given
* Runnable to change the current MTL context; it will be reset
* once the Runnable completes. No guarantees are made as to the
* state of the MTL context of the Graphics object; for
*
* In order to avoid deadlock, it is important that the given Runnable
* does not attempt to acquire the AWT lock, as that will be handled
* automatically as part of the {@code rq.flushAndInvokeNow()} step.
*
* @param g the Graphics object for the corresponding destination surface;
* if null, the step making a context current to the destination surface
* will be skipped
* @param r the action to be performed on the QFT; cannot be null
* @return true if the operation completed successfully, or false if
* there was any problem making a context current to the surface
* associated with the given Graphics object
*/
public static boolean invokeWithMTLContextCurrent(Graphics g, Runnable r) {
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
if (g != null) {
if (!(g instanceof SunGraphics2D)) {
return false;
}
SurfaceData sData = ((SunGraphics2D)g).surfaceData;
if (!(sData instanceof MTLSurfaceData)) {
return false;
}
// make a context current to the destination surface
MTLContext.validateContext((MTLSurfaceData)sData);
}
// invoke the given runnable on the QFT
rq.flushAndInvokeNow(r);
// invalidate the current context so that the next time we render
// with Java 2D, the context state will be completely revalidated
MTLContext.invalidateCurrentContext();
} finally {
rq.unlock();
}
return true;
}
/**
* Invokes the given Runnable on the MTL QueueFlusher thread with the
* "shared" MTL context (corresponding to the given
* GraphicsConfiguration object) made current. This method is typically
* used when the Runnable needs a current context to complete its
* operation, but does not require that the context be made current to
* a particular surface. For example, an application may call this
* method so that the given Runnable can query the OpenGL capabilities
* of the given GraphicsConfiguration, without making a context current
* to a dummy surface (or similar hacky techniques).
*
* In order to avoid deadlock, it is important that the given Runnable
* does not attempt to acquire the AWT lock, as that will be handled
* automatically as part of the {@code rq.flushAndInvokeNow()} step.
*
* @param config the GraphicsConfiguration object whose "shared"
* context will be made current during this operation; if this value is
* null or if MTL is not enabled for the GraphicsConfiguration, this
* method will return false
* @param r the action to be performed on the QFT; cannot be null
* @return true if the operation completed successfully, or false if
* there was any problem making the shared context current
*/
public static boolean
invokeWithMTLSharedContextCurrent(GraphicsConfiguration config,
Runnable r)
{
if (!(config instanceof MTLGraphicsConfig)) {
return false;
}
MTLRenderQueue rq = MTLRenderQueue.getInstance();
rq.lock();
try {
// make the "shared" context current for the given GraphicsConfig
MTLContext.setScratchSurface((MTLGraphicsConfig)config);
// invoke the given runnable on the QFT
rq.flushAndInvokeNow(r);
// invalidate the current context so that the next time we render
// with Java 2D, the context state will be completely revalidated
MTLContext.invalidateCurrentContext();
} finally {
rq.unlock();
}
return true;
}
/**
* Returns the Rectangle describing the MTL viewport on the
* Java 2D surface associated with the given Graphics object and
* component width and height. When a third-party library is
* performing MTL rendering directly into the visible region of
* the associated surface, this viewport helps the application
* position the MTL output correctly on that surface.
*
* Note that the x/y values in the returned Rectangle object represent
* the lower-left corner of the viewport region, relative to the
* lower-left corner of the given surface.
*
* @param g the Graphics object for the corresponding destination surface;
* cannot be null
* @param componentWidth width of the component to be painted
* @param componentHeight height of the component to be painted
* @return a Rectangle describing the MTL viewport for the given
* destination surface and component dimensions, or null if the given
* Graphics object is invalid
*/
public static Rectangle getMTLViewport(Graphics g,
int componentWidth,
int componentHeight)
{
if (!(g instanceof SunGraphics2D)) {
return null;
}
SunGraphics2D sg2d = (SunGraphics2D)g;
SurfaceData sData = sg2d.surfaceData;
// this is the upper-left origin of the region to be painted,
// relative to the upper-left origin of the surface
// (in Java2D coordinates)
int x0 = sg2d.transX;
int y0 = sg2d.transY;
// this is the lower-left origin of the region to be painted,
// relative to the lower-left origin of the surface
// (in OpenGL coordinates)
Rectangle surfaceBounds = sData.getBounds();
int x1 = x0;
int y1 = surfaceBounds.height - (y0 + componentHeight);
return new Rectangle(x1, y1, componentWidth, componentHeight);
}
/**
* Returns the Rectangle describing the MTL scissor box on the
* Java 2D surface associated with the given Graphics object. When a
* third-party library is performing MTL rendering directly
* into the visible region of the associated surface, this scissor box
* must be set to avoid drawing over existing rendering results.
*
* Note that the x/y values in the returned Rectangle object represent
* the lower-left corner of the scissor region, relative to the
* lower-left corner of the given surface.
*
* @param g the Graphics object for the corresponding destination surface;
* cannot be null
* @return a Rectangle describing the MTL scissor box for the given
* Graphics object and corresponding destination surface, or null if the
* given Graphics object is invalid or the clip region is non-rectangular
*/
public static Rectangle getOGLScissorBox(Graphics g) {
if (!(g instanceof SunGraphics2D)) {
return null;
}
SunGraphics2D sg2d = (SunGraphics2D)g;
SurfaceData sData = sg2d.surfaceData;
Region r = sg2d.getCompClip();
if (!r.isRectangular()) {
// caller probably doesn't know how to handle shape clip
// appropriately, so just return null (Swing currently never
// sets a shape clip, but that could change in the future)
return null;
}
// this is the upper-left origin of the scissor box relative to the
// upper-left origin of the surface (in Java 2D coordinates)
int x0 = r.getLoX();
int y0 = r.getLoY();
// this is the width and height of the scissor region
int w = r.getWidth();
int h = r.getHeight();
// this is the lower-left origin of the scissor box relative to the
// lower-left origin of the surface (in OpenGL coordinates)
Rectangle surfaceBounds = sData.getBounds();
int x1 = x0;
int y1 = surfaceBounds.height - (y0 + h);
return new Rectangle(x1, y1, w, h);
}
/**
* Returns an Object identifier for the Java 2D surface associated with
* the given Graphics object. This identifier may be used to determine
* whether the surface has changed since the last invocation of this
* operation, and thereby whether the MTL state corresponding to the
* old surface must be destroyed and recreated.
*
* @param g the Graphics object for the corresponding destination surface;
* cannot be null
* @return an identifier for the surface associated with the given
* Graphics object, or null if the given Graphics object is invalid
*/
public static Object getMTLSurfaceIdentifier(Graphics g) {
if (!(g instanceof SunGraphics2D)) {
return null;
}
return ((SunGraphics2D)g).surfaceData;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.metal;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.OGLSurfaceData;
import java.awt.*;
import java.awt.image.ColorModel;
import static java.awt.BufferCapabilities.FlipContents.COPIED;
public class MTLVolatileSurfaceManager extends VolatileSurfaceManager {
private final boolean accelerationEnabled;
public MTLVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
super(vImg, context);
/*
* We will attempt to accelerate this image only under the
* following conditions:
* - the image is not bitmask AND the GraphicsConfig supports the FBO
* extension
*/
int transparency = vImg.getTransparency();
MTLGraphicsConfig gc = (MTLGraphicsConfig) vImg.getGraphicsConfig();
accelerationEnabled = true;
//gc.isCapPresent(CAPS_EXT_FBOBJECT)
//&& transparency != Transparency.BITMASK;
}
protected boolean isAccelerationEnabled() {
return accelerationEnabled;
}
/**
* Create a FBO-based SurfaceData object (or init the backbuffer
* of an existing window if this is a double buffered GraphicsConfig)
*/
protected SurfaceData initAcceleratedSurface() {
try {
MTLGraphicsConfig gc =
(MTLGraphicsConfig)vImg.getGraphicsConfig();
ColorModel cm = gc.getColorModel(vImg.getTransparency());
int type = vImg.getForcedAccelSurfaceType();
// if acceleration type is forced (type != UNDEFINED) then
// use the forced type, otherwise choose RT_TEXTURE
if (type == OGLSurfaceData.UNDEFINED) {
type = OGLSurfaceData.FBOBJECT;
}
return MTLSurfaceData.createData(gc,
vImg.getWidth(),
vImg.getHeight(),
cm, vImg, type);
} catch (NullPointerException | OutOfMemoryError ignored) {
return null;
}
}
@Override
protected boolean isConfigValid(GraphicsConfiguration gc) {
return ((gc == null) || (gc == vImg.getGraphicsConfig()));
}
@Override
public void initContents() {
if (vImg.getForcedAccelSurfaceType() != OGLSurfaceData.TEXTURE) {
super.initContents();
}
}
}

View File

@@ -55,6 +55,7 @@ import sun.java2d.pipe.hw.AccelSurface;
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
import sun.java2d.pipe.hw.ContextCapabilities;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.macosx.CFRetainedResource;
import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_DOUBLEBUFFERED;
import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_EXT_FBOBJECT;
@@ -62,7 +63,7 @@ import static sun.java2d.opengl.OGLSurfaceData.FBOBJECT;
import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
public final class CGLGraphicsConfig extends CGraphicsConfig
implements OGLGraphicsConfig
implements OGLGraphicsConfig
{
private static boolean cglAvailable;
private static ImageCapabilities imageCaps = new CGLImageCaps();
@@ -101,7 +102,7 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
// add a record to the Disposer so that we destroy the native
// CGLGraphicsConfigInfo data when this object goes away
Disposer.addRecord(disposerReferent,
new CGLGCDisposerRecord(pConfigInfo));
new CGLGCDisposerRecord(pConfigInfo));
}
@Override
@@ -112,9 +113,9 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
@Override
public SurfaceData createManagedSurface(int w, int h, int transparency) {
return CGLSurfaceData.createData(this, w, h,
getColorModel(transparency),
null,
OGLSurfaceData.TEXTURE);
getColorModel(transparency),
null,
OGLSurfaceData.TEXTURE);
}
public static CGLGraphicsConfig getConfig(CGraphicsDevice device)
@@ -184,27 +185,27 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
public BufferedImage createCompatibleImage(int width, int height) {
ColorModel model = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
WritableRaster
raster = model.createCompatibleWritableRaster(width, height);
raster = model.createCompatibleWritableRaster(width, height);
return new BufferedImage(model, raster, model.isAlphaPremultiplied(),
null);
null);
}
@Override
public ColorModel getColorModel(int transparency) {
switch (transparency) {
case Transparency.OPAQUE:
// REMIND: once the ColorModel spec is changed, this should be
// an opaque premultiplied DCM...
return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
case Transparency.BITMASK:
return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
case Transparency.TRANSLUCENT:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
return new DirectColorModel(cs, 32,
0xff0000, 0xff00, 0xff, 0xff000000,
true, DataBuffer.TYPE_INT);
default:
return null;
case Transparency.OPAQUE:
// REMIND: once the ColorModel spec is changed, this should be
// an opaque premultiplied DCM...
return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
case Transparency.BITMASK:
return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
case Transparency.TRANSLUCENT:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
return new DirectColorModel(cs, 32,
0xff0000, 0xff00, 0xff, 0xff000000,
true, DataBuffer.TYPE_INT);
default:
return null;
}
}
@@ -248,8 +249,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
}
@Override
public SurfaceData createSurfaceData(CGLLayer layer) {
return CGLSurfaceData.createData(layer);
public SurfaceData createSurfaceData(CFRetainedResource layer) {
return CGLSurfaceData.createData((CGLLayer) layer);
}
@Override
@@ -259,7 +260,7 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
ColorModel model = getColorModel(Transparency.OPAQUE);
WritableRaster wr = model.createCompatibleWritableRaster(width, height);
return new OffScreenImage(target, model, wr,
model.isAlphaPremultiplied());
model.isAlphaPremultiplied());
}
@Override
@@ -290,7 +291,7 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
final int w = Math.max(1, r.width);
final int h = Math.max(1, r.height);
final int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT
: Transparency.OPAQUE;
: Transparency.OPAQUE;
return new SunVolatileImage(this, w, h, transparency, null);
}
@@ -316,7 +317,7 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
try {
bg.setBackground(peer.getBackground());
bg.clearRect(0, 0, backBuffer.getWidth(null),
backBuffer.getHeight(null));
backBuffer.getHeight(null));
} finally {
bg.dispose();
}
@@ -326,7 +327,7 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
private static class CGLBufferCaps extends BufferCapabilities {
public CGLBufferCaps(boolean dblBuf) {
super(imageCaps, imageCaps,
dblBuf ? FlipContents.UNDEFINED : null);
dblBuf ? FlipContents.UNDEFINED : null);
}
}
@@ -362,10 +363,10 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
return null;
}
SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
transparency, type);
transparency, type);
Surface sd = vi.getDestSurface();
if (!(sd instanceof AccelSurface) ||
((AccelSurface)sd).getType() != type)
((AccelSurface)sd).getType() != type)
{
vi.flush();
vi = null;
@@ -382,12 +383,12 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
@Override
public int getMaxTextureWidth() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
getBounds().width);
getBounds().width);
}
@Override
public int getMaxTextureHeight() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
getBounds().height);
getBounds().height);
}
}

View File

@@ -74,8 +74,11 @@ import sun.awt.SunToolkit;
import sun.awt.event.IgnorePaintEvent;
import sun.awt.image.SunVolatileImage;
import sun.java2d.SunGraphics2D;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLRenderQueue;
import sun.java2d.opengl.OGLRenderQueue;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.RenderQueue;
import sun.util.logging.PlatformLogger;
public abstract class LWComponentPeer<T extends Component, D extends JComponent>
@@ -1414,7 +1417,8 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
protected static final void flushOnscreenGraphics(){
final OGLRenderQueue rq = OGLRenderQueue.getInstance();
RenderQueue rq = MacOSFlags.isMetalEnabled() ?
MTLRenderQueue.getInstance() : OGLRenderQueue.getInstance();
rq.lock();
try {
rq.flushNow();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,11 +29,15 @@ import java.awt.*;
import java.awt.event.FocusEvent;
import sun.java2d.SurfaceData;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLLayer;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformWindow;
import sun.lwawt.macosx.CFRetainedResource;
import sun.util.logging.PlatformLogger;
/*
* Provides a lightweight implementation of the EmbeddedFrame.
*/
@@ -42,7 +46,7 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
private static final PlatformLogger focusLogger = PlatformLogger.getLogger(
"sun.lwawt.macosx.focus.CPlatformEmbeddedFrame");
private CGLLayer windowLayer;
private CFRetainedResource windowLayer;
private LWWindowPeer peer;
private CEmbeddedFrame target;
@@ -52,7 +56,11 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override // PlatformWindow
public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
this.peer = peer;
this.windowLayer = new CGLLayer(peer);
if (MacOSFlags.isMetalEnabled()) {
this.windowLayer = new MTLLayer(peer);
} else {
this.windowLayer = new CGLLayer(peer);
}
this.target = (CEmbeddedFrame)target;
}
@@ -63,12 +71,20 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override
public long getLayerPtr() {
return windowLayer.getPointer();
if (MacOSFlags.isMetalEnabled()) {
return ((MTLLayer)windowLayer).getPointer();
} else {
return ((CGLLayer)windowLayer).getPointer();
}
}
@Override
public void dispose() {
windowLayer.dispose();
if (MacOSFlags.isMetalEnabled()) {
((MTLLayer)windowLayer).dispose();
} else {
((CGLLayer)windowLayer).dispose();
}
}
@Override
@@ -99,12 +115,20 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override
public SurfaceData getScreenSurface() {
return windowLayer.getSurfaceData();
if (MacOSFlags.isMetalEnabled()) {
return ((MTLLayer)windowLayer).getSurfaceData();
} else {
return ((CGLLayer)windowLayer).getSurfaceData();
}
}
@Override
public SurfaceData replaceSurfaceData() {
return windowLayer.replaceSurfaceData();
if (MacOSFlags.isMetalEnabled()) {
return ((MTLLayer)windowLayer).replaceSurfaceData();
} else {
return ((CGLLayer)windowLayer).replaceSurfaceData();
}
}
@Override

View File

@@ -35,9 +35,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import sun.awt.CGraphicsEnvironment;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLLayer;
import sun.lwawt.LWWindowPeer;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer;
public class CPlatformView extends CFRetainedResource {
private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr);
@@ -48,7 +51,7 @@ public class CPlatformView extends CFRetainedResource {
private LWWindowPeer peer;
private SurfaceData surfaceData;
private CGLLayer windowLayer;
private CFRetainedResource windowLayer;
private CPlatformResponder responder;
public CPlatformView() {
@@ -58,7 +61,7 @@ public class CPlatformView extends CFRetainedResource {
public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
initializeBase(peer, responder);
this.windowLayer = createCGLayer();
this.windowLayer = MacOSFlags.isMetalEnabled()? createMTLLayer() : createCGLayer();
setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr()));
}
@@ -66,6 +69,11 @@ public class CPlatformView extends CFRetainedResource {
return new CGLLayer(peer);
}
public MTLLayer createMTLLayer() {
return new MTLLayer(peer);
}
protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) {
this.peer = peer;
this.responder = responder;
@@ -96,7 +104,10 @@ public class CPlatformView extends CFRetainedResource {
// PAINTING METHODS
// ----------------------------------------------------------------------
public SurfaceData replaceSurfaceData() {
surfaceData = windowLayer.replaceSurfaceData();
surfaceData = (MacOSFlags.isMetalEnabled()) ?
((MTLLayer)windowLayer).replaceSurfaceData() :
((CGLLayer)windowLayer).replaceSurfaceData()
;
return surfaceData;
}
@@ -111,7 +122,9 @@ public class CPlatformView extends CFRetainedResource {
}
public long getWindowLayerPtr() {
return windowLayer.getPointer();
return MacOSFlags.isMetalEnabled() ?
((MTLLayer)windowLayer).getPointer() :
((CGLLayer)windowLayer).getPointer();
}
public void setAutoResizable(boolean toResize) {
@@ -176,18 +189,18 @@ public class CPlatformView extends CFRetainedResource {
if (event.getType() == CocoaConstants.NSScrollWheel) {
responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(),
event.getScrollDeltaX(), event.getScrollDeltaY(),
event.getScrollPhase());
event.getScrollDeltaX(), event.getScrollDeltaY(),
event.getScrollPhase());
} else {
responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
event.getClickCount(), x, y,
absX, absY);
event.getClickCount(), x, y,
absX, absY);
}
}
private void deliverKeyEvent(NSEvent event) {
responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(),
event.getCharactersIgnoringModifiers(), event.getKeyCode(), true, false);
event.getCharactersIgnoringModifiers(), event.getKeyCode(), true, false);
}
/**

View File

@@ -29,6 +29,7 @@ import sun.awt.AWTAccessor;
import sun.awt.IconInfo;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.metal.MTLLayer;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformEventNotifier;
@@ -222,8 +223,8 @@ public final class CWarningWindow extends CPlatformWindow
owner.execute(ownerPtr -> {
execute(ptr -> {
CWrapper.NSWindow.orderWindow(ptr,
CWrapper.NSWindow.NSWindowAbove,
ownerPtr);
CWrapper.NSWindow.NSWindowAbove,
ownerPtr);
});
});
@@ -300,6 +301,23 @@ public final class CWarningWindow extends CPlatformWindow
}
};
}
public MTLLayer createMTLLayer() {
return new MTLLayer(null) {
public Rectangle getBounds() {
return CWarningWindow.this.getBounds();
}
public GraphicsConfiguration getGraphicsConfiguration() {
LWWindowPeer peer = ownerPeer.get();
return peer.getGraphicsConfiguration();
}
public boolean isOpaque() {
return false;
}
};
}
};
}
@@ -349,7 +367,7 @@ public final class CWarningWindow extends CPlatformWindow
currentSize = newSize;
IconInfo ico = getSecurityIconInfo(currentSize, 0);
AWTAccessor.getWindowAccessor().setSecurityWarningSize(
ownerWindow, ico.getWidth(), ico.getHeight());
ownerWindow, ico.getWidth(), ico.getHeight());
}
}
}
@@ -361,7 +379,7 @@ public final class CWarningWindow extends CPlatformWindow
}
return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window,
ownerWindow.getFont());
ownerWindow.getFont());
}

View File

@@ -109,6 +109,8 @@ import sun.awt.SunToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.dnd.SunDragSourceContextPeer;
import sun.awt.util.ThreadGroupUtils;
import sun.java2d.macos.MacOSFlags;
import sun.java2d.metal.MTLRenderQueue;
import sun.java2d.opengl.OGLRenderQueue;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.LWCursorManager;
@@ -496,7 +498,11 @@ public final class LWCToolkit extends LWToolkit {
@Override
public void sync() {
// flush the OGL pipeline (this is a no-op if OGL is not enabled)
OGLRenderQueue.sync();
if (MacOSFlags.isMetalEnabled()) {
MTLRenderQueue.sync();
} else {
OGLRenderQueue.sync();
}
// setNeedsDisplay() selector was sent to the appropriate CALayer so now
// we have to flush the native selectors queue.
flushNativeSelectors();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <QuartzCore/CATransaction.h>
#import <QuartzCore/CAMetalLayer.h>
@implementation AWTSurfaceLayers
@@ -67,10 +68,11 @@
}
}
// Updates back buffer size of the layer if it's an OpenGL layer
// including all OpenGL sublayers
// Updates back buffer size of the layer if it's an OpenGL/Metal layer
// including all OpenGL/Metal sublayers
+ (void) repaintLayersRecursively:(CALayer*)aLayer {
if ([aLayer isKindOfClass:[CAOpenGLLayer class]]) {
if ([aLayer isKindOfClass:[CAOpenGLLayer class]] ||
[aLayer isKindOfClass:[CAMetalLayer class]]) {
[aLayer setNeedsDisplay];
}
for(CALayer *child in aLayer.sublayers) {
@@ -92,7 +94,7 @@
/*
* Class: sun_lwawt_macosx_CPlatformComponent
* Method: nativeCreateLayer
* Method: nativeCreateComponent
* Signature: ()J
*/
JNIEXPORT jlong JNICALL

View File

@@ -37,6 +37,8 @@
#import <Carbon/Carbon.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
jboolean metalEnabled = JNI_FALSE;
@interface AWTView()
@property (retain) CDropTarget *_dropTarget;
@property (retain) CDragSource *_dragSource;
@@ -52,6 +54,8 @@
//#define IM_DEBUG TRUE
//#define EXTRA_DEBUG
#define METAL_DEBUG
static BOOL shouldUsePressAndHold() {
static int shouldUsePressAndHold = -1;
if (shouldUsePressAndHold != -1) return shouldUsePressAndHold;
@@ -66,6 +70,7 @@ static BOOL shouldUsePressAndHold() {
@synthesize cglLayer;
@synthesize mouseIsOver;
// Note: Must be called on main (AppKit) thread only
- (id) initWithRect: (NSRect) rect
platformView: (jobject) cPlatformView
@@ -1499,3 +1504,19 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeIsViewUnder
return underMouse;
}
jboolean GetStaticBoolean(JNIEnv *env, jclass fClass, const char *fieldName)
{
jfieldID fieldID = (*env)->GetStaticFieldID(env, fClass, fieldName, "Z");
return (*env)->GetStaticBooleanField(env, fClass, fieldID);
}
JNIEXPORT void JNICALL
Java_sun_java2d_macos_MacOSFlags_initNativeFlags(JNIEnv *env,
jclass flagsClass)
{
metalEnabled = GetStaticBoolean(env, flagsClass, "metalEnabled");
#ifdef METAL_DEBUG
fprintf(stderr, "metalEnabled=%d\n", metalEnabled);
#endif
}

View File

@@ -1171,6 +1171,8 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
extern jboolean metalEnabled;
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetNSWindowInsets

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef COMMON_H
#define COMMON_H
#include <simd/SIMD.h>
#define PGRAM_VERTEX_COUNT 6
#define QUAD_VERTEX_COUNT 4
#define GRAD_MAX_FRACTIONS 12
enum GradCycleMethod {
GradNoCycle = 0,
GradReflect = 1,
GradRepeat = 2
};
enum VertexAttributes {
VertexAttributePosition = 0,
VertexAttributeTexPos = 1
};
enum BufferIndex {
MeshVertexBuffer = 0,
FrameUniformBuffer = 1,
MatrixBuffer = 2
};
struct FrameUniforms {
vector_float4 color;
};
struct TransformMatrix {
matrix_float4x4 transformMatrix;
};
struct GradFrameUniforms {
vector_float3 params;
vector_float4 color1;
vector_float4 color2;
int isCyclic;
};
struct LinGradFrameUniforms {
vector_float3 params;
float fract[GRAD_MAX_FRACTIONS];
vector_float4 color[GRAD_MAX_FRACTIONS];
int numFracts;
int cycleMethod;
};
struct RadGradFrameUniforms {
float fract[GRAD_MAX_FRACTIONS];
vector_float4 color[GRAD_MAX_FRACTIONS];
int numFracts;
int cycleMethod;
vector_float3 m0;
vector_float3 m1;
vector_float3 precalc;
};
struct Vertex {
float position[2];
};
struct TxtVertex {
float position[2];
float txtpos[2];
};
// These values are mapped from AffineTransformOp
#define INTERPOLATION_NEAREST_NEIGHBOR 1
#define INTERPOLATION_BILINEAR 2
// #define INTERPOLATION_BICUBIC 3
// NOTE: Metal samplers doesn't supports bicubic interpolation
// see table 2.7 from https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
// (probably we need to implement separate fragment shader with bicubic interpolation)
struct TxtFrameUniforms {
vector_float4 color;
int mode; // NOTE: consider to use bit fields
int isSrcOpaque;
int isDstOpaque;
float extraAlpha;
};
struct TxtFrameOpRescaleUniforms {
vector_float4 color;
float extraAlpha;
int isSrcOpaque;
int isNonPremult;
vector_float4 normScaleFactors;
vector_float4 normOffsets;
};
struct TxtFrameOpConvolveUniforms {
float extraAlpha;
int isSrcOpaque;
vector_float4 imgEdge;
int kernelSize;
int isEdgeZeroFill;
};
struct TxtFrameOpLookupUniforms {
float extraAlpha;
int isSrcOpaque;
vector_float4 offset;
int isUseSrcAlpha;
int isNonPremult;
};
struct AnchorData
{
vector_float3 xParams;
vector_float3 yParams;
};
struct LCDFrameUniforms {
vector_float3 src_adj;
vector_float3 gamma;
vector_float3 invgamma;
};
#endif

View File

@@ -0,0 +1,742 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <simd/simd.h>
#include <metal_stdlib>
#include "common.h"
using namespace metal;
struct VertexInput {
float2 position [[attribute(VertexAttributePosition)]];
};
struct TxtVertexInput {
float2 position [[attribute(VertexAttributePosition)]];
float2 texCoords [[attribute(VertexAttributeTexPos)]];
};
struct ColShaderInOut {
float4 position [[position]];
half4 color;
};
struct StencilShaderInOut {
float4 position [[position]];
char color;
};
struct TxtShaderInOut {
float4 position [[position]];
float2 texCoords;
float2 tpCoords;
};
struct LCDShaderInOut {
float4 position [[position]];
float2 orig_pos;
float2 texCoords;
};
struct GradShaderInOut {
float4 position [[position]];
float2 texCoords;
};
struct ColShaderInOut_XOR {
float4 position [[position]];
float2 orig_pos;
half4 color;
};
struct TxtShaderInOut_XOR {
float4 position [[position]];
float2 orig_pos;
float2 texCoords;
float2 tpCoords;
};
vertex ColShaderInOut vert_col(VertexInput in [[stage_in]],
constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
ColShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a);
return out;
}
vertex StencilShaderInOut vert_stencil(VertexInput in [[stage_in]],
constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
StencilShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix * pos4;
out.color = 0xFF;
return out;
}
vertex GradShaderInOut vert_grad(VertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
GradShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
return out;
}
vertex TxtShaderInOut vert_txt(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
TxtShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.texCoords = in.texCoords;
return out;
}
vertex LCDShaderInOut vert_txt_lcd(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
LCDShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.orig_pos = in.position;
out.texCoords = in.texCoords;
return out;
}
vertex TxtShaderInOut vert_txt_tp(TxtVertexInput in [[stage_in]], constant AnchorData& anchorData [[buffer(FrameUniformBuffer)]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]])
{
TxtShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix * pos4;
// Compute texture coordinates here w.r.t. anchor rect of texture paint
out.tpCoords.x = (anchorData.xParams[0] * in.position.x) +
(anchorData.xParams[1] * in.position.y) +
(anchorData.xParams[2] * out.position.w);
out.tpCoords.y = (anchorData.yParams[0] * in.position.x) +
(anchorData.yParams[1] * in.position.y) +
(anchorData.yParams[2] * out.position.w);
out.texCoords = in.texCoords;
return out;
}
vertex GradShaderInOut vert_txt_grad(TxtVertexInput in [[stage_in]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
GradShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.texCoords = in.texCoords;
return out;
}
fragment half4 frag_col(ColShaderInOut in [[stage_in]]) {
return in.color;
}
fragment unsigned int frag_stencil(StencilShaderInOut in [[stage_in]]) {
return in.color;
}
// NOTE:
// 1. consider to make shaders without IF-conditions
// 2. we can pass interpolation mode via uniforms and select corresponding sampler in shader
// but it can cause performance problems (something like getTextureSampler(hint) will be invoked
// for every pixel)
fragment half4 frag_txt(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]],
constant TxtFrameUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
float srcA = uniforms.isSrcOpaque ? 1 : pixelColor.a;
if (uniforms.mode) {
float4 c = mix(pixelColor, uniforms.color, srcA);
return half4(c.r, c.g, c.b , c.a);
}
return half4(pixelColor.r,
pixelColor.g,
pixelColor.b, srcA*uniforms.extraAlpha);
}
fragment half4 frag_txt_tp(TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]],
texture2d<float, access::sample> paintTexture [[texture(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 renderColor = renderTexture.sample(textureSampler, vert.texCoords);
float4 paintColor = paintTexture.sample(textureSampler, vert.tpCoords);
return half4(paintColor.r*renderColor.a,
paintColor.g*renderColor.a,
paintColor.b*renderColor.a,
renderColor.a);
}
fragment half4 frag_txt_grad(GradShaderInOut in [[stage_in]],
constant GradFrameUniforms& uniforms [[buffer(0)]],
texture2d<float, access::sample> renderTexture [[texture(0)]])
{
constexpr sampler textureSampler (address::repeat, mag_filter::nearest,
min_filter::nearest);
float4 renderColor = renderTexture.sample(textureSampler, in.texCoords);
float3 v = float3(in.position.x, in.position.y, 1);
float a = (dot(v,uniforms.params)-0.25)*2.0;
int fa = floor(a);
if (uniforms.isCyclic) {
if (fa%2) {
a = 1.0 + fa - a;
} else {
a = a - fa;
}
}
float4 c = mix(uniforms.color1, uniforms.color2, a);
return half4(c.r*renderColor.a,
c.g*renderColor.a,
c.b*renderColor.a,
c.a*renderColor.a);
}
fragment half4 frag_txt_lin_grad(GradShaderInOut in [[stage_in]],
constant LinGradFrameUniforms& uniforms [[buffer(0)]],
texture2d<float, access::sample> renderTexture [[texture(0)]])
{
constexpr sampler textureSampler (address::repeat, mag_filter::nearest,
min_filter::nearest);
float4 renderColor = renderTexture.sample(textureSampler, in.texCoords);
float3 v = float3(in.position.x, in.position.y, 1);
float a = dot(v,uniforms.params);
float lf = 1.0/(uniforms.numFracts - 1);
if (uniforms.cycleMethod > GradNoCycle) {
int fa = floor(a);
a = a - fa;
if (uniforms.cycleMethod == GradReflect && fa%2) {
a = 1.0 - a;
}
}
int n = floor(a/lf);
if (uniforms.cycleMethod > GradNoCycle) {
n = ((n % uniforms.numFracts) + uniforms.numFracts) % uniforms.numFracts;
} else {
if (n < 0) n = 0;
if (n > uniforms.numFracts - 2) n = uniforms.numFracts - 2;
}
a = (a - n*lf)/lf;
float4 c = mix(uniforms.color[n], uniforms.color[n + 1], a);
return half4(c.r*renderColor.a,
c.g*renderColor.a,
c.b*renderColor.a,
c.a*renderColor.a);
}
fragment half4 frag_txt_rad_grad(GradShaderInOut in [[stage_in]],
constant RadGradFrameUniforms& uniforms [[buffer(0)]],
texture2d<float, access::sample> renderTexture [[texture(0)]])
{
constexpr sampler textureSampler (address::repeat, mag_filter::nearest,
min_filter::nearest);
float4 renderColor = renderTexture.sample(textureSampler, in.texCoords);
float3 fragCoord = float3(in.position.x+0.5, in.position.y-0.5, 1);
float x = dot(fragCoord, uniforms.m0);
float y = dot(fragCoord, uniforms.m1);
float xfx = x - uniforms.precalc.x;
float a = (uniforms.precalc.x*xfx + sqrt(xfx*xfx + y*y*uniforms.precalc.y))*uniforms.precalc.z;
float lf = 1.0/(uniforms.numFracts - 1);
if (uniforms.cycleMethod > GradNoCycle) {
int fa = floor(a);
a = a - fa;
if (uniforms.cycleMethod == GradReflect && fa%2) {
a = 1.0 - a;
}
}
int n = floor(a/lf);
if (uniforms.cycleMethod > GradNoCycle) {
n = ((n % uniforms.numFracts) + uniforms.numFracts) % uniforms.numFracts;
} else {
if (n < 0) n = 0;
if (n > uniforms.numFracts - 2) n = uniforms.numFracts - 2;
}
a = (a - n*lf)/lf;
float4 c = mix(uniforms.color[n], uniforms.color[n + 1], a);
return half4(c.r*renderColor.a,
c.g*renderColor.a,
c.b*renderColor.a,
c.a*renderColor.a);
}
fragment half4 aa_frag_txt(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]],
texture2d<float, access::sample> stencilTexture [[texture(1)]],
constant TxtFrameUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
if (!is_null_texture(stencilTexture)) {
float4 stencil = stencilTexture.sample(textureSampler, vert.texCoords);
if (stencil.r == 0.0) {
discard_fragment();
}
}
return half4(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a);
}
fragment half4 frag_txt_op_rescale(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
constant TxtFrameOpRescaleUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 srcColor = srcTex.sample(textureSampler, vert.texCoords);
const float srcA = uniforms.isSrcOpaque ? 1 : srcColor.a;
// TODO: check uniforms.isNonPremult and pre-multiply if necessary
return half4(srcColor.r*uniforms.normScaleFactors.r + uniforms.normOffsets.r,
srcColor.g*uniforms.normScaleFactors.g + uniforms.normOffsets.g,
srcColor.b*uniforms.normScaleFactors.b + uniforms.normOffsets.b, srcA*uniforms.extraAlpha);
// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
//" %s" // (placeholder for un-premult code: srcColor.rgb /= srcColor.a;)
//" vec4 result = (srcColor * scaleFactors) + offsets;" // rescale source value
//" %s" // (placeholder for re-premult code: result.rgb *= result.a;)
//" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}
fragment half4 frag_txt_op_convolve(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
constant TxtFrameOpConvolveUniforms& uniforms [[buffer(1)]],
const device float * kernelVals [[buffer(2)]],
sampler textureSampler [[sampler(0)]]
) {
float4 sum = float4(0, 0, 0, 0);
if (vert.texCoords[0] < uniforms.imgEdge[0]
|| vert.texCoords[1] < uniforms.imgEdge[1]
|| vert.texCoords[0] > uniforms.imgEdge[2]
|| vert.texCoords[1] > uniforms.imgEdge[3]
) {
if (!uniforms.isEdgeZeroFill) {
sum = srcTex.sample(textureSampler, vert.texCoords);
}
}
for (int i = 0; i < uniforms.kernelSize; i++) {
float3 kern = float3(kernelVals[i*3], kernelVals[i*3 + 1], kernelVals[i*3 + 2]);
float2 pos = float2(vert.texCoords.x + kern.x, vert.texCoords.y + kern.y);
float4 pixCol = srcTex.sample(textureSampler, pos);
sum.r += kern.z * pixCol.r;
sum.g += kern.z * pixCol.g;
sum.b += kern.z * pixCol.b;
sum.a += kern.z * pixCol.a;
}
const float srcA = uniforms.isSrcOpaque ? 1 : sum.a;
return half4(sum.r, sum.g, sum.b, srcA*uniforms.extraAlpha);
// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" if (any(lessThan(gl_TexCoord[0].st, imgEdge.xy)) ||"
//" any(greaterThan(gl_TexCoord[0].st, imgEdge.zw)))"
//" {"
//" %s" // (placeholder for edge condition code)
//" } else {"
//" sum = vec4(0.0);"
//" for (i = 0; i < MAX_KERNEL_SIZE; i++) {"
//" sum +="
//" kernelVals[i].z *"
//" texture%s(baseImage,"
//" gl_TexCoord[0].st + kernelVals[i].xy);"
//" }"
//" }"
//""
//" gl_FragColor = sum * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}
fragment half4 frag_txt_op_lookup(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> srcTex [[texture(0)]],
texture2d<float, access::sample> lookupTex [[texture(1)]],
constant TxtFrameOpLookupUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]]
) {
float4 srcColor = srcTex.sample(textureSampler, vert.texCoords);
float4 srcIndex = srcColor - uniforms.offset;
const float2 posR = float2(srcIndex.r, 0.125);
const float2 posG = float2(srcIndex.g, 0.375);
const float2 posB = float2(srcIndex.b, 0.625);
float4 lookupR = lookupTex.sample(textureSampler, posR);
float4 lookupG = lookupTex.sample(textureSampler, posG);
float4 lookupB = lookupTex.sample(textureSampler, posB);
const float srcA = uniforms.isSrcOpaque ? 1 : srcColor.a;
const float a = uniforms.isUseSrcAlpha ? srcA : lookupTex.sample(textureSampler, float2(srcIndex.a, 0.875)).a;
// TODO: check uniforms.isNonPremult and pre-multiply if necessary
return half4(lookupR.a, lookupG.a, lookupB.a, a*uniforms.extraAlpha);
// NOTE: GL-shader multiplies result with glColor (in order to apply extra alpha), probably it's better to do the
// same here.
//
// GL-shader impl:
//" vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
//" %s" // (placeholder for un-premult code)
//" vec4 srcIndex = srcColor - offset;" // subtract offset from original index
//
// // use source value as input to lookup table (note that
// // "v" texcoords are hardcoded to hit texel centers of
// // each row/band in texture)
//" vec4 result;"
//" result.r = texture2D(lookupTable, vec2(srcIndex.r, 0.125)).r;"
//" result.g = texture2D(lookupTable, vec2(srcIndex.g, 0.375)).r;"
//" result.b = texture2D(lookupTable, vec2(srcIndex.b, 0.625)).r;"
//" %s" // (placeholder for alpha store code)
//" %s" // (placeholder for re-premult code)
//" gl_FragColor = result * gl_Color;" // modulate with gl_Color in order to apply extra alpha
}
fragment half4 frag_grad(GradShaderInOut in [[stage_in]],
constant GradFrameUniforms& uniforms [[buffer(0)]]) {
float3 v = float3(in.position.x, in.position.y, 1);
float a = (dot(v,uniforms.params)-0.25)*2.0;
int fa = floor(a);
if (uniforms.isCyclic) {
if (fa%2) {
a = 1.0 + fa - a;
} else {
a = a - fa;
}
}
float4 c = mix(uniforms.color1, uniforms.color2, a);
return half4(c);
}
// LinGradFrameUniforms
fragment half4 frag_lin_grad(GradShaderInOut in [[stage_in]],
constant LinGradFrameUniforms& uniforms [[buffer(0)]]) {
float3 v = float3(in.position.x, in.position.y, 1);
float a = dot(v,uniforms.params);
float lf = 1.0/(uniforms.numFracts - 1);
if (uniforms.cycleMethod > GradNoCycle) {
int fa = floor(a);
a = a - fa;
if (uniforms.cycleMethod == GradReflect && fa%2) {
a = 1.0 - a;
}
}
int n = floor(a/lf);
if (uniforms.cycleMethod > GradNoCycle) {
n = ((n % uniforms.numFracts) + uniforms.numFracts) % uniforms.numFracts;
} else {
if (n < 0) n = 0;
if (n > uniforms.numFracts - 2) n = uniforms.numFracts - 2;
}
a = (a - n*lf)/lf;
float4 c = mix(uniforms.color[n], uniforms.color[n + 1], a);
return half4(c);
}
fragment half4 frag_rad_grad(GradShaderInOut in [[stage_in]],
constant RadGradFrameUniforms& uniforms [[buffer(0)]]) {
float3 fragCoord = float3(in.position.x+0.5, in.position.y-0.5, 1);
float x = dot(fragCoord, uniforms.m0);
float y = dot(fragCoord, uniforms.m1);
float xfx = x - uniforms.precalc.x;
float a = (uniforms.precalc.x*xfx + sqrt(xfx*xfx + y*y*uniforms.precalc.y))*uniforms.precalc.z;
float lf = 1.0/(uniforms.numFracts - 1);
if (uniforms.cycleMethod > GradNoCycle) {
int fa = floor(a);
a = a - fa;
if (uniforms.cycleMethod == GradReflect && fa%2) {
a = 1.0 - a;
}
}
int n = floor(a/lf);
if (uniforms.cycleMethod > GradNoCycle) {
n = ((n % uniforms.numFracts) + uniforms.numFracts) % uniforms.numFracts;
} else {
if (n < 0) n = 0;
if (n > uniforms.numFracts - 2) n = uniforms.numFracts - 2;
}
a = (a - n*lf)/lf;
float4 c = mix(uniforms.color[n], uniforms.color[n + 1], a);
return half4(c);
}
vertex TxtShaderInOut vert_tp(VertexInput in [[stage_in]],
constant AnchorData& anchorData [[buffer(FrameUniformBuffer)]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]])
{
TxtShaderInOut out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix * pos4;
// Compute texture coordinates here w.r.t. anchor rect of texture paint
out.texCoords.x = (anchorData.xParams[0] * in.position.x) +
(anchorData.xParams[1] * in.position.y) +
(anchorData.xParams[2] * out.position.w);
out.texCoords.y = (anchorData.yParams[0] * in.position.x) +
(anchorData.yParams[1] * in.position.y) +
(anchorData.yParams[2] * out.position.w);
return out;
}
fragment half4 frag_tp(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]])
{
constexpr sampler textureSampler (address::repeat,
mag_filter::nearest,
min_filter::nearest);
float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
return half4(pixelColor.r, pixelColor.g, pixelColor.b, 1.0);
// This implementation defaults alpha to 1.0 as if source is opaque
//TODO : implement alpha component value if source is transparent
}
/* The variables involved in the equation can be expressed as follows:
*
* Cs = Color component of the source (foreground color) [0.0, 1.0]
* Cd = Color component of the destination (background color) [0.0, 1.0]
* Cr = Color component to be written to the destination [0.0, 1.0]
* Ag = Glyph alpha (aka intensity or coverage) [0.0, 1.0]
* Ga = Gamma adjustment in the range [1.0, 2.5]
* (^ means raised to the power)
*
* And here is the theoretical equation approximated by this shader:
*
* Cr = (Ag*(Cs^Ga) + (1-Ag)*(Cd^Ga)) ^ (1/Ga)
*/
fragment float4 lcd_color(
LCDShaderInOut vert [[stage_in]],
texture2d<float, access::sample> glyphTexture [[texture(0)]],
texture2d<float, access::sample> dstTexture [[texture(1)]],
constant LCDFrameUniforms& uniforms [[buffer(1)]])
{
float3 src_adj = uniforms.src_adj;
float3 gamma = uniforms.gamma;
float3 invgamma = uniforms.invgamma;
constexpr sampler glyphTextureSampler (address::repeat,
mag_filter::nearest,
min_filter::nearest);
// load the RGB value from the glyph image at the current texcoord
float3 glyph_clr = float3(glyphTexture.sample(glyphTextureSampler, vert.texCoords));
if (glyph_clr.r == 0.0f && glyph_clr.g == 0.0f && glyph_clr.b == 0.0f) {
// zero coverage, so skip this fragment
discard_fragment();
}
// load the RGB value from the corresponding destination pixel
uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)};
float4 dst_clr = dstTexture.read(texCoord);
// gamma adjust the dest color
float3 dst_adj = pow(dst_clr.rgb, gamma);
// linearly interpolate the three color values
float3 result = mix(dst_adj, src_adj, glyph_clr);
// gamma re-adjust the resulting color (alpha is always set to 1.0)
return float4(pow(result.rgb, invgamma), 1.0);
}
// Compute shader to transfer clipping data to the texture used for manual clipping in
// aa_frag_txt shader
kernel void stencil2tex(const device uchar *imageBuffer [[buffer(0)]],
device uchar4 *outputBuffer [[buffer(1)]],
uint gid [[thread_position_in_grid]])
{
uchar p = imageBuffer[gid];
outputBuffer[gid] = uchar4(p, p, p, p);
}
// ----------------------------------------------------------------------------
// Shaders for rendering in XOR Mode
// ----------------------------------------------------------------------------
vertex ColShaderInOut_XOR vert_col_xorMode(VertexInput in [[stage_in]],
constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]])
{
ColShaderInOut_XOR out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.orig_pos = in.position;
out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a);
return out;
}
fragment half4 frag_col_xorMode(ColShaderInOut_XOR in [[stage_in]],
texture2d<float, access::read> renderTexture [[texture(0)]])
{
uint2 texCoord = {(unsigned int)(in.orig_pos.x), (unsigned int)(in.orig_pos.y)};
float4 pixelColor = renderTexture.read(texCoord);
half4 color = in.color;
half4 c;
c.r = float( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(color.r * 255.0)) / 255.0f;
c.g = float( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(color.g * 255.0)) / 255.0f;
c.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(color.b * 255.0)) / 255.0f;
c.a = 1.0;
return c;
}
vertex TxtShaderInOut_XOR vert_txt_xorMode(
TxtVertexInput in [[stage_in]],
constant TransformMatrix& transform [[buffer(MatrixBuffer)]])
{
TxtShaderInOut_XOR out;
float4 pos4 = float4(in.position, 0.0, 1.0);
out.position = transform.transformMatrix*pos4;
out.orig_pos = in.position;
out.texCoords = in.texCoords;
return out;
}
fragment half4 frag_txt_xorMode(
TxtShaderInOut_XOR vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]],
texture2d<float, access::read> backgroundTexture [[texture(1)]],
constant TxtFrameUniforms& uniforms [[buffer(1)]],
sampler textureSampler [[sampler(0)]])
{
uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)};
float4 bgColor = backgroundTexture.read(texCoord);
float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
float srcA = uniforms.isSrcOpaque ? 1 : pixelColor.a;
float4 c;
if (uniforms.mode) {
c = mix(pixelColor, uniforms.color, srcA);
} else {
c = float4(pixelColor.r,
pixelColor.g,
pixelColor.b, srcA*uniforms.extraAlpha);
}
half4 ret;
ret.r = half( (unsigned char)(c.r * 255.0) ^ (unsigned char)(bgColor.r * 255.0)) / 255.0f;
ret.g = half( (unsigned char)(c.g * 255.0) ^ (unsigned char)(bgColor.g * 255.0)) / 255.0f;
ret.b = half( (unsigned char)(c.b * 255.0) ^ (unsigned char)(bgColor.b * 255.0)) / 255.0f;
ret.a = c.a + (1.0 - c.a) * bgColor.a;
return ret;
}
/*
// --------------------------------------------------------------------------------------
Currently, gradient paint and texture paint XOR mode rendering has been implemented
through tile based rendering (similar to OGL) that uses MTLBlitLoops_SurfaceToSwBlit method for
getting framebuffer tiles and render using a different render pipe (not MTLRenderer)
In metal, we can avoid tile based rendering and use below shaders.
NOTE: These two shaders are incomplete and need some tweak.
// --------------------------------------------------------------------------------------
fragment half4 frag_grad_xorMode(GradShaderInOut_XOR in [[stage_in]],
texture2d<float, access::read> renderTexture [[texture(0)]],
constant GradFrameUniforms& uniforms [[buffer(0)]]) {
uint2 texCoord = {(unsigned int)(in.orig_pos.x), (unsigned int)(in.orig_pos.y)};
float4 pixelColor = renderTexture.read(texCoord);
float3 v = float3(in.position.x, in.position.y, 1);
float a = (dot(v,uniforms.params)-0.25)*2.0;
float4 c = mix(uniforms.color1, uniforms.color2, a);
half4 ret;
ret.r = float( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(c.r * 255.0)) / 255.0f;
ret.g = float( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(c.g * 255.0)) / 255.0f;
ret.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(c.b * 255.0)) / 255.0f;
return half4(ret);
}
fragment half4 frag_tp_xorMode(
TxtShaderInOut vert [[stage_in]],
texture2d<float, access::sample> renderTexture [[texture(0)]],
texture2d<float, access::read> backgroundTexture [[texture(1)]],
constant int& xorColor[[buffer(0)]])
{
uint2 texCoord = {(unsigned int)(vert.orig_pos.x), (unsigned int)(vert.orig_pos.y)};
float4 bgColor = backgroundTexture.read(texCoord);
constexpr sampler textureSampler (address::repeat,
mag_filter::nearest,
min_filter::nearest);
float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
pixelColor.r = float( (unsigned char)(pixelColor.r * 255.0) ^ ((xorColor >> 16) & 0xFF) ) / 255.0f;
pixelColor.g = float( (unsigned char)(pixelColor.g * 255.0) ^ ((xorColor >> 8) & 0xFF)) / 255.0f;
pixelColor.b = float( (unsigned char)(pixelColor.b * 255.0) ^ (xorColor & 0xFF)) / 255.0f;
pixelColor.a = 1.0;
half4 ret;
ret.r = half( (unsigned char)(pixelColor.r * 255.0) ^ (unsigned char)(bgColor.r * 255.0)) / 255.0f;
ret.g = half( (unsigned char)(pixelColor.g * 255.0) ^ (unsigned char)(bgColor.g * 255.0)) / 255.0f;
ret.b = half( (unsigned char)(pixelColor.b * 255.0) ^ (unsigned char)(bgColor.b * 255.0)) / 255.0f;
ret.a = 1.0;
return ret;
// This implementation defaults alpha to 1.0 as if source is opaque
//TODO : implement alpha component value if source is transparent
}
*/

View File

@@ -0,0 +1,67 @@
#ifndef EncoderManager_h_Included
#define EncoderManager_h_Included
#import <Metal/Metal.h>
#include "RenderOptions.h"
@class MTLContex;
/**
* The EncoderManager class used to obtain MTLRenderCommandEncoder (or MTLBlitCommandEncoder) corresponding
* to the current state of MTLContext.
*
* Due to performance issues (creation of MTLRenderCommandEncoder isn't cheap), each getXXXEncoder invocation
* updates properties of common (cached) encoder and returns this encoder.
*
* Base method getEncoder does the following:
* 1. Checks whether common encoder must be closed and recreated (some of encoder properties is 'persistent',
* for example destination, stencil, or any other property of MTLRenderPassDescriptor)
* 2. Updates 'mutable' properties encoder: pipelineState (with corresponding buffers), clip, transform, e.t.c. To avoid
* unnecessary calls of [encoder setXXX] this manager compares requested state with cached one.
* */
@interface EncoderManager : NSObject
- (id _Nonnull)init;
- (void)dealloc;
- (void)setContext:(MTLContex * _Nonnull)mtlc;
// returns encoder that renders/fills geometry with current paint and composite
- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps;
- (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps;
- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest
isDstOpaque:(bool)isOpaque;
// returns encoder that renders/fills geometry with current composite and with given texture
// (user must call [encoder setFragmentTexture] before any rendering)
- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps
isSrcOpaque:(bool)isSrcOpaque;
- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque;
- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque
interpolation:(int)interpolation;
- (id<MTLRenderCommandEncoder> _Nonnull)getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque
interpolation:(int)interpolation
isAA:(jboolean)isAA;
// Base method to obtain any MTLRenderCommandEncoder
- (id<MTLRenderCommandEncoder> _Nonnull) getEncoder:(id<MTLTexture> _Nonnull)dest
isDestOpaque:(jboolean)isDestOpaque
renderOptions:(const RenderOptions * _Nonnull)renderOptions;
- (id<MTLBlitCommandEncoder> _Nonnull)createBlitEncoder;
- (void)endEncoder;
@end
#endif // EncoderManager_h_Included

View File

@@ -0,0 +1,437 @@
#include "EncoderManager.h"
#include "MTLContext.h"
#include "sun_java2d_SunGraphics2D.h"
#import "common.h"
// NOTE: uncomment to disable comparing cached encoder states with requested (for debugging)
// #define ALWAYS_UPDATE_ENCODER_STATES
const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE };
// Internal utility class that represents the set of 'mutable' encoder properties
@interface EncoderStates : NSObject
@property (readonly) MTLClip * clip;
- (id)init;
- (void)dealloc;
- (void)reset:(id<MTLTexture>)destination
isDstOpaque:(jboolean)isDstOpaque
isDstPremultiplied:(jboolean)isDstPremultiplied
isAA:(jboolean)isAA;
- (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
context:(MTLContext *)mtlc
renderOptions:(const RenderOptions *)renderOptions
forceUpdate:(jboolean)forceUpdate;
@property (assign) jboolean aa;
@property (retain) MTLPaint* paint;
@end
@implementation EncoderStates {
MTLPipelineStatesStorage * _pipelineStateStorage;
id<MTLDevice> _device;
// Persistent encoder properties
id<MTLTexture> _destination;
SurfaceRasterFlags _dstFlags;
jboolean _isAA;
//
// Cached 'mutable' states of encoder
//
// Composite rule and source raster flags (it affects the CAD-multipliers (of pipelineState))
MTLComposite * _composite;
SurfaceRasterFlags _srcFlags;
// Paint mode (it affects shaders (of pipelineState) and corresponding buffers)
MTLPaint * _paint;
// If true, indicates that encoder is used for texture drawing (user must do [encoder setFragmentTexture:] before drawing)
jboolean _isTexture;
int _interpolationMode;
// Clip rect or stencil
MTLClip * _clip;
// Transform (affects transformation inside vertex shader)
MTLTransform * _transform;
}
@synthesize aa = _isAA;
@synthesize paint = _paint;
- (id)init {
self = [super init];
if (self) {
_destination = nil;
_composite = [[MTLComposite alloc] init];
_paint = [[MTLPaint alloc] init];
_transform = [[MTLTransform alloc] init];
_clip = [[MTLClip alloc] init];
}
return self;
}
- (void)dealloc {
[_composite release];
[_paint release];
[_transform release];
[super dealloc];
}
- (void)setContext:(MTLContext * _Nonnull)mtlc {
self->_pipelineStateStorage = mtlc.pipelineStateStorage;
self->_device = mtlc.device;
}
- (void)reset:(id<MTLTexture>)destination
isDstOpaque:(jboolean)isDstOpaque
isDstPremultiplied:(jboolean)isDstPremultiplied
isAA:(jboolean)isAA {
_destination = destination;
_dstFlags.isOpaque = isDstOpaque;
_dstFlags.isPremultiplied = isDstPremultiplied;
_isAA = isAA;
// NOTE: probably it's better to invalidate/reset all cached states now
}
- (void)updateEncoder:(id<MTLRenderCommandEncoder>)encoder
context:(MTLContext *)mtlc
renderOptions:(const RenderOptions *)renderOptions
forceUpdate:(jboolean)forceUpdate
{
// 1. Process special case for stencil mask generation
if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) {
// use separate pipeline state for stencil generation
if (forceUpdate || (_clip.stencilMaskGenerationInProgress != JNI_TRUE)) {
[_clip copyFrom:mtlc.clip];
[_clip setMaskGenerationPipelineState:encoder
destWidth:_destination.width
destHeight:_destination.height
pipelineStateStorage:_pipelineStateStorage];
}
[self updateTransform:encoder transform:mtlc.transform forceUpdate:forceUpdate];
return;
}
// 2. Otherwise update all 'mutable' properties of encoder
[self updatePipelineState:encoder
context:mtlc
renderOptions:renderOptions
forceUpdate:forceUpdate];
[self updateTransform:encoder transform:mtlc.transform forceUpdate:forceUpdate];
[self updateClip:encoder clip:mtlc.clip forceUpdate:forceUpdate];
}
//
// Internal methods that update states when necessary (compare with cached states)
//
// Updates pipelineState (and corresponding buffers) with use of paint+composite+flags
- (void)updatePipelineState:(id<MTLRenderCommandEncoder>)encoder
context:(MTLContext *)mtlc
renderOptions:(const RenderOptions *)renderOptions
forceUpdate:(jboolean)forceUpdate
{
if (!forceUpdate
&& [_paint isEqual:mtlc.paint]
&& [_composite isEqual:mtlc.composite]
&& (_isTexture == renderOptions->isTexture && (!renderOptions->isTexture || _interpolationMode == renderOptions->interpolation)) // interpolation is used only in texture mode
&& _isAA == renderOptions->isAA
&& _srcFlags.isOpaque == renderOptions->srcFlags.isOpaque && _srcFlags.isPremultiplied == renderOptions->srcFlags.isPremultiplied)
return;
self.paint = mtlc.paint;
[_composite copyFrom:mtlc.composite];
_isTexture = renderOptions->isTexture;
_interpolationMode = renderOptions->interpolation;
_isAA = renderOptions->isAA;
_srcFlags = renderOptions->srcFlags;
if ((jint)[mtlc.composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR) {
[mtlc.paint setXorModePipelineState:encoder
context:mtlc
renderOptions:renderOptions
pipelineStateStorage:_pipelineStateStorage];
} else {
[mtlc.paint setPipelineState:encoder
context:mtlc
renderOptions:renderOptions
pipelineStateStorage:_pipelineStateStorage];
}
}
- (void) updateClip:(id<MTLRenderCommandEncoder>)encoder clip:(MTLClip *)clip forceUpdate:(jboolean)forceUpdate
{
if (clip.stencilMaskGenerationInProgress == JNI_TRUE) {
// don't set setScissorOrStencil when generateion in progress
return;
}
if (!forceUpdate && [_clip isEqual:clip])
return;
[_clip copyFrom:clip];
[_clip setScissorOrStencil:encoder
destWidth:_destination.width
destHeight:_destination.height
device:_device];
}
- (void)updateTransform:(id <MTLRenderCommandEncoder>)encoder
transform:(MTLTransform *)transform
forceUpdate:(jboolean)forceUpdate
{
if (!forceUpdate
&& [_transform isEqual:transform])
return;
[_transform copyFrom:transform];
[_transform setVertexMatrix:encoder
destWidth:_destination.width
destHeight:_destination.height];
}
@end
@implementation EncoderManager {
MTLContext * _mtlc; // used to obtain CommandBufferWrapper and Composite/Paint/Transform
id<MTLRenderCommandEncoder> _encoder;
// 'Persistent' properties of encoder
id<MTLTexture> _destination;
id<MTLTexture> _aaDestination;
BOOL _useStencil;
// 'Mutable' states of encoder
EncoderStates * _encoderStates;
}
- (id _Nonnull)init {
self = [super init];
if (self) {
_encoder = nil;
_destination = nil;
_aaDestination = nil;
_useStencil = NO;
_encoderStates = [[EncoderStates alloc] init];
}
return self;
}
- (void)dealloc {
[_encoderStates release];
[super dealloc];
}
- (void)setContext:(MTLContex * _Nonnull)mtlc {
self->_mtlc = mtlc;
[self->_encoderStates setContext:mtlc];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getRenderEncoder:(const BMTLSDOps * _Nonnull)dstOps
{
return [self getRenderEncoder:dstOps->pTexture isDstOpaque:dstOps->isOpaque];
}
- (id<MTLRenderCommandEncoder> _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps {
id<MTLTexture> dstTxt = dstOps->pTexture;
RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}};
return [self getEncoder:dstTxt renderOptions:&roptions];
}
- (id<MTLRenderCommandEncoder> _Nonnull)getRenderEncoder:(id<MTLTexture> _Nonnull)dest
isDstOpaque:(bool)isOpaque
{
RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {isOpaque, JNI_TRUE}};
return [self getEncoder:dest renderOptions:&roptions];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(const BMTLSDOps * _Nonnull)dstOps
isSrcOpaque:(bool)isSrcOpaque
{
return [self getTextureEncoder:dstOps->pTexture
isSrcOpaque:isSrcOpaque
isDstOpaque:dstOps->isOpaque
interpolation:INTERPOLATION_NEAREST_NEIGHBOR];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque
{
return [self getTextureEncoder:dest
isSrcOpaque:isSrcOpaque
isDstOpaque:isDstOpaque
interpolation:INTERPOLATION_NEAREST_NEIGHBOR
isAA:JNI_FALSE];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque
interpolation:(int)interpolation
isAA:(jboolean)isAA
{
RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}};
return [self getEncoder:dest renderOptions:&roptions];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getTextureEncoder:(id<MTLTexture> _Nonnull)dest
isSrcOpaque:(bool)isSrcOpaque
isDstOpaque:(bool)isDstOpaque
interpolation:(int)interpolation
{
return [self getTextureEncoder:dest isSrcOpaque:isSrcOpaque isDstOpaque:isDstOpaque interpolation:interpolation isAA:JNI_FALSE];
}
- (id<MTLRenderCommandEncoder> _Nonnull) getEncoder:(id <MTLTexture> _Nonnull)dest
renderOptions:(const RenderOptions * _Nonnull)renderOptions
{
//
// 1. check whether it's necessary to call endEncoder
//
jboolean needEnd = JNI_FALSE;
if (_encoder != nil) {
if (_destination != dest || renderOptions->isAA != _encoderStates.aa) {
J2dTraceLn2(J2D_TRACE_VERBOSE,
"end common encoder because of dest change: %p -> %p",
_destination, dest);
needEnd = JNI_TRUE;
} else if ((_useStencil == NO) != ([_mtlc.clip isShape] == NO)) {
// 1. When mode changes RECT -> SHAPE we must recreate encoder with
// stencilAttachment (todo: consider the case when current encoder already
// has stencil)
//
// 2. When mode changes SHAPE -> RECT it seems that we can use the same
// encoder with disabled stencil test, but [encoder
// setDepthStencilState:nil] causes crash, so we have to recreate encoder
// in such case
J2dTraceLn2(J2D_TRACE_VERBOSE,
"end common encoder because toggle stencil: %d -> %d",
(int)_useStencil, (int)[_mtlc.clip isShape]);
needEnd = JNI_TRUE;
}
}
if (needEnd)
[self endEncoder];
//
// 2. recreate encoder if necessary
//
jboolean forceUpdate = JNI_FALSE;
#ifdef ALWAYS_UPDATE_ENCODER_STATES
forceUpdate = JNI_TRUE;
#endif // ALWAYS_UPDATE_ENCODER_STATES
if (_encoder == nil) {
_destination = dest;
_useStencil = [_mtlc.clip isShape];
forceUpdate = JNI_TRUE;
MTLCommandBufferWrapper *cbw = [_mtlc getCommandBufferWrapper];
MTLRenderPassDescriptor *rpd =
[MTLRenderPassDescriptor renderPassDescriptor];
MTLRenderPassColorAttachmentDescriptor *ca = rpd.colorAttachments[0];
if (renderOptions->isAA && !renderOptions->isTexture) {
MTLTexturePoolItem *tiBuf = [_mtlc.texturePool getTexture:dest.width
height:dest.height
format:MTLPixelFormatBGRA8Unorm];
[cbw registerPooledTexture:tiBuf];
[tiBuf release];
_aaDestination = tiBuf.texture;
MTLTexturePoolItem *ti = [_mtlc.texturePool getTexture:dest.width
height:dest.height
format:_aaDestination.pixelFormat
isMultiSample:YES];
[cbw registerPooledTexture:ti];
[ti release];
ca.texture = ti.texture;
ca.resolveTexture = _aaDestination;
ca.clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 0.0f);
ca.loadAction = MTLLoadActionClear;
ca.storeAction = MTLStoreActionMultisampleResolve;
} else {
ca.texture = dest;
ca.loadAction = MTLLoadActionLoad;
ca.storeAction = MTLStoreActionStore;
}
if (_useStencil && !renderOptions->isAA) {
// If you enable stencil testing or stencil writing, the
// MTLRenderPassDescriptor must include a stencil attachment.
rpd.stencilAttachment.loadAction = MTLLoadActionLoad;
rpd.stencilAttachment.storeAction = MTLStoreActionStore;
rpd.stencilAttachment.texture = _mtlc.clip.stencilTextureRef;
}
// J2dTraceLn1(J2D_TRACE_VERBOSE, "created render encoder to draw on
// tex=%p", dest);
_encoder = [[cbw getCommandBuffer] renderCommandEncoderWithDescriptor:rpd];
[_encoderStates reset:dest
isDstOpaque:renderOptions->dstFlags.isOpaque
isDstPremultiplied:YES
isAA:renderOptions->isAA];
}
//
// 3. update encoder states
//
[_encoderStates updateEncoder:_encoder
context:_mtlc
renderOptions:renderOptions
forceUpdate:forceUpdate];
return _encoder;
}
- (id<MTLBlitCommandEncoder> _Nonnull) createBlitEncoder {
[self endEncoder];
return [[[_mtlc getCommandBufferWrapper] getCommandBuffer] blitCommandEncoder];
}
- (void) endEncoder {
if (_encoder != nil) {
[_encoder endEncoding];
_encoder = nil;
if (_aaDestination != nil) {
id<MTLTexture> aaDest = _aaDestination;
_aaDestination = nil;
NSUInteger _w = _destination.width;
NSUInteger _h = _destination.height;
_encoder = [self getTextureEncoder:_destination
isSrcOpaque:JNI_FALSE
isDstOpaque:JNI_TRUE
interpolation:INTERPOLATION_NEAREST_NEIGHBOR
isAA:JNI_TRUE];
[_encoder setFragmentTexture:_mtlc.clip.stencilAADataRef atIndex: 1];
struct TxtVertex quadTxVerticesBuffer[] = {
{{0, 0}, {0, 0}},
{{0,_h}, {0, 1}},
{{_w, 0},{1, 0}},
{{0, _h},{0, 1}},
{{_w, _h}, {1, 1}},
{{_w, 0}, {1, 0}}
};
[_encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer];
[_encoder setFragmentTexture:aaDest atIndex: 0];
[_encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
[_encoder endEncoding];
}
_encoder = nil;
_destination = nil;
}
}
@end

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLBlitLoops_h_Included
#define MTLBlitLoops_h_Included
#include "sun_java2d_metal_MTLBlitLoops.h"
#include "MTLSurfaceDataBase.h"
#include "MTLContext.h"
#define OFFSET_SRCTYPE sun_java2d_metal_MTLBlitLoops_OFFSET_SRCTYPE
#define OFFSET_HINT sun_java2d_metal_MTLBlitLoops_OFFSET_HINT
#define OFFSET_TEXTURE sun_java2d_metal_MTLBlitLoops_OFFSET_TEXTURE
#define OFFSET_RTT sun_java2d_metal_MTLBlitLoops_OFFSET_RTT
#define OFFSET_XFORM sun_java2d_metal_MTLBlitLoops_OFFSET_XFORM
#define OFFSET_ISOBLIT sun_java2d_metal_MTLBlitLoops_OFFSET_ISOBLIT
void MTLBlitLoops_IsoBlit(JNIEnv *env,
MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
jboolean xform, jint hint,
jboolean texture,
jint sx1, jint sy1,
jint sx2, jint sy2,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2);
void MTLBlitLoops_Blit(JNIEnv *env,
MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
jboolean xform, jint hint,
jint srctype, jboolean texture,
jint sx1, jint sy1,
jint sx2, jint sy2,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2);
void MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc,
jlong pSrcOps, jlong pDstOps, jint dsttype,
jint srcx, jint srcy,
jint dstx, jint dsty,
jint width, jint height);
void MTLBlitLoops_CopyArea(JNIEnv *env,
MTLContext *mtlc, BMTLSDOps *dstOps,
jint x, jint y,
jint width, jint height,
jint dx, jint dy);
void MTLBlitTex2Tex(MTLContext *mtlc, id<MTLTexture> src, id<MTLTexture> dest);
void drawTex2Tex(MTLContext *mtlc,
id<MTLTexture> src, id<MTLTexture> dst,
jboolean isSrcOpaque, jboolean isDstOpaque, jint hint,
jint sx1, jint sy1, jint sx2, jint sy2,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2);
#endif /* MTLBlitLoops_h_Included */

View File

@@ -0,0 +1,872 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include <jni.h>
#include <jlong.h>
#include "SurfaceData.h"
#include "MTLBlitLoops.h"
#include "MTLRenderQueue.h"
#include "MTLSurfaceData.h"
#include "MTLUtils.h"
#include "GraphicsPrimitiveMgr.h"
#include <stdlib.h> // malloc
#include <string.h> // memcpy
#include "IntArgbPre.h"
#import <Accelerate/Accelerate.h>
#ifdef DEBUG
#define TRACE_ISOBLIT
#define TRACE_BLIT
#endif //DEBUG
//#define DEBUG_ISOBLIT
//#define DEBUG_BLIT
typedef struct {
MTLPixelFormat format;
jboolean hasAlpha;
jboolean isPremult;
const uint8_t * permuteMap;
} MTLRasterFormatInfo;
// 0 denotes the alpha channel, 1 the red channel, 2 the green channel, and 3 the blue channel.
const uint8_t permuteMap_rgbx[4] = { 1, 2, 3, 0 };
const uint8_t permuteMap_bgrx[4] = { 3, 2, 1, 0 };
static uint8_t revertPerm(const uint8_t * perm, uint8_t pos) {
for (int c = 0; c < 4; ++c) {
if (perm[c] == pos)
return c;
}
return -1;
}
#define uint2swizzle(channel) (channel == 0 ? MTLTextureSwizzleAlpha : (channel == 1 ? MTLTextureSwizzleRed : (channel == 2 ? MTLTextureSwizzleGreen : (channel == 3 ? MTLTextureSwizzleBlue : MTLTextureSwizzleZero))))
/**
* This table contains the "pixel formats" for all system memory surfaces
* that Metal is capable of handling, indexed by the "PF_" constants defined
* in MTLLSurfaceData.java. These pixel formats contain information that is
* passed to Metal when copying from a system memory ("Sw") surface to
* an Metal surface
*/
MTLRasterFormatInfo RasterFormatInfos[] = {
{ MTLPixelFormatBGRA8Unorm, 1, 0, NULL }, /* 0 - IntArgb */ // Argb (in java notation)
{ MTLPixelFormatBGRA8Unorm, 1, 1, NULL }, /* 1 - IntArgbPre */
{ MTLPixelFormatBGRA8Unorm, 0, 1, NULL }, /* 2 - IntRgb */ // xrgb
{ MTLPixelFormatBGRA8Unorm, 0, 1, permuteMap_rgbx }, /* 3 - IntRgbx */
{ MTLPixelFormatRGBA8Unorm, 0, 1, NULL }, /* 4 - IntBgr */ // xbgr
{ MTLPixelFormatBGRA8Unorm, 0, 1, permuteMap_bgrx }, /* 5 - IntBgrx */
// TODO: support 2-byte formats
// { GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
// 2, 0, 1, }, /* 7 - Ushort555Rgb */
// { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
// 2, 0, 1, }, /* 8 - Ushort555Rgbx*/
// { GL_LUMINANCE, GL_UNSIGNED_BYTE,
// 1, 0, 1, }, /* 9 - ByteGray */
// { GL_LUMINANCE, GL_UNSIGNED_SHORT,
// 2, 0, 1, }, /*10 - UshortGray */
// { GL_BGR, GL_UNSIGNED_BYTE,
// 1, 0, 1, }, /*11 - ThreeByteBgr */
};
extern void J2dTraceImpl(int level, jboolean cr, const char *string, ...);
void fillTxQuad(
struct TxtVertex * txQuadVerts,
jint sx1, jint sy1, jint sx2, jint sy2, jint sw, jint sh,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dw, jdouble dh
) {
const float nsx1 = sx1/(float)sw;
const float nsy1 = sy1/(float)sh;
const float nsx2 = sx2/(float)sw;
const float nsy2 = sy2/(float)sh;
txQuadVerts[0].position[0] = dx1;
txQuadVerts[0].position[1] = dy1;
txQuadVerts[0].txtpos[0] = nsx1;
txQuadVerts[0].txtpos[1] = nsy1;
txQuadVerts[1].position[0] = dx2;
txQuadVerts[1].position[1] = dy1;
txQuadVerts[1].txtpos[0] = nsx2;
txQuadVerts[1].txtpos[1] = nsy1;
txQuadVerts[2].position[0] = dx2;
txQuadVerts[2].position[1] = dy2;
txQuadVerts[2].txtpos[0] = nsx2;
txQuadVerts[2].txtpos[1] = nsy2;
txQuadVerts[3].position[0] = dx2;
txQuadVerts[3].position[1] = dy2;
txQuadVerts[3].txtpos[0] = nsx2;
txQuadVerts[3].txtpos[1] = nsy2;
txQuadVerts[4].position[0] = dx1;
txQuadVerts[4].position[1] = dy2;
txQuadVerts[4].txtpos[0] = nsx1;
txQuadVerts[4].txtpos[1] = nsy2;
txQuadVerts[5].position[0] = dx1;
txQuadVerts[5].position[1] = dy1;
txQuadVerts[5].txtpos[0] = nsx1;
txQuadVerts[5].txtpos[1] = nsy1;
}
//#define TRACE_drawTex2Tex
void drawTex2Tex(MTLContext *mtlc,
id<MTLTexture> src, id<MTLTexture> dst,
jboolean isSrcOpaque, jboolean isDstOpaque, jint hint,
jint sx1, jint sy1, jint sx2, jint sy2,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
{
#ifdef TRACE_drawTex2Tex
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "drawTex2Tex: src tex=%p, dst tex=%p", src, dst);
J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " sw=%d sh=%d dw=%d dh=%d", src.width, src.height, dst.width, dst.height);
J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d", sx1, sy1, sx2, sy2);
J2dRlsTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2);
#endif //TRACE_drawTex2Tex
id<MTLRenderCommandEncoder> encoder = [mtlc.encoderManager getTextureEncoder:dst
isSrcOpaque:isSrcOpaque
isDstOpaque:isDstOpaque
interpolation:hint
];
struct TxtVertex quadTxVerticesBuffer[6];
fillTxQuad(quadTxVerticesBuffer, sx1, sy1, sx2, sy2, src.width, src.height, dx1, dy1, dx2, dy2, dst.width, dst.height);
[encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer];
[encoder setFragmentTexture:src atIndex: 0];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
}
static
id<MTLTexture> replaceTextureRegion(MTLContext *mtlc, id<MTLTexture> dest, const SurfaceDataRasInfo * srcInfo, const MTLRasterFormatInfo * rfi, int dx1, int dy1, int dx2, int dy2) {
const int dw = dx2 - dx1;
const int dh = dy2 - dy1;
const void * raster = srcInfo->rasBase;
raster += srcInfo->bounds.y1*srcInfo->scanStride + srcInfo->bounds.x1*srcInfo->pixelStride;
id<MTLTexture> result = nil;
if (rfi->permuteMap != NULL) {
#if defined(__MAC_10_15) && __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_15
if (@available(macOS 10.15, *)) {
@autoreleasepool {
const uint8_t swzRed = revertPerm(rfi->permuteMap, 1);
const uint8_t swzGreen = revertPerm(rfi->permuteMap, 2);
const uint8_t swzBlue = revertPerm(rfi->permuteMap, 3);
const uint8_t swzAlpha = revertPerm(rfi->permuteMap, 0);
MTLTextureSwizzleChannels swizzle = MTLTextureSwizzleChannelsMake(
uint2swizzle(swzRed),
uint2swizzle(swzGreen),
uint2swizzle(swzBlue),
rfi->hasAlpha ? uint2swizzle(swzAlpha) : MTLTextureSwizzleOne
);
result = [dest
newTextureViewWithPixelFormat:MTLPixelFormatBGRA8Unorm
textureType:MTLTextureType2D
levels:NSMakeRange(0, 1) slices:NSMakeRange(0, 1)
swizzle:swizzle];
J2dTraceLn5(J2D_TRACE_VERBOSE, "replaceTextureRegion [use swizzle for pooled]: %d, %d, %d, %d, hasA=%d",
swizzle.red, swizzle.green, swizzle.blue, swizzle.alpha, rfi->hasAlpha);
}
} else
#endif // __MAC_10_15 && __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_15
{
// perform raster conversion
// invoked only from rq-thread, so use static buffers
// but it's better to use thread-local buffers (or special buffer manager)
const int destRasterSize = dw*dh*4;
static int bufferSize = 0;
static void * buffer = NULL;
if (buffer == NULL || bufferSize < destRasterSize) {
bufferSize = destRasterSize;
buffer = realloc(buffer, bufferSize);
}
if (buffer == NULL) {
J2dTraceLn1(J2D_TRACE_ERROR, "replaceTextureRegion: can't alloc buffer for raster conversion, size=%d", bufferSize);
bufferSize = 0;
return nil;
}
vImage_Buffer srcBuf;
srcBuf.height = dh;
srcBuf.width = dw;
srcBuf.rowBytes = srcInfo->scanStride;
srcBuf.data = raster;
vImage_Buffer destBuf;
destBuf.height = dh;
destBuf.width = dw;
destBuf.rowBytes = dw*4;
destBuf.data = buffer;
vImagePermuteChannels_ARGB8888(&srcBuf, &destBuf, rfi->permuteMap, kvImageNoFlags);
raster = buffer;
J2dTraceLn5(J2D_TRACE_VERBOSE, "replaceTextureRegion [use conversion]: %d, %d, %d, %d, hasA=%d",
rfi->permuteMap[0], rfi->permuteMap[1], rfi->permuteMap[2], rfi->permuteMap[3], rfi->hasAlpha);
}
}
MTLRegion region = MTLRegionMake2D(dx1, dy1, dw, dh);
if (result != nil)
dest = result;
@autoreleasepool {
id <MTLBlitCommandEncoder> blitEncoder = [mtlc.encoderManager createBlitEncoder];
J2dTraceLn4(J2D_TRACE_VERBOSE, "replaceTextureRegion src (dw, dh) : [%d, %d] dest (dx1, dy1) =[%d, %d]",
dw, dh, dx1, dy1);
id <MTLBuffer> buff = [[mtlc.device newBufferWithBytes:raster length:srcInfo->scanStride * dh options:MTLResourceStorageModeManaged] autorelease];
[blitEncoder copyFromBuffer:buff
sourceOffset:0 sourceBytesPerRow:srcInfo->scanStride sourceBytesPerImage:srcInfo->scanStride * dh sourceSize:MTLSizeMake(dw, dh, 1)
toTexture:dest destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(dx1, dy1, 0)];
[blitEncoder endEncoding];
}
return result;
}
/**
* Inner loop used for copying a source system memory ("Sw") surface to a
* destination MTL "Surface". This method is invoked from
* MTLBlitLoops_Blit().
*/
static void
MTLBlitSwToTextureViaPooledTexture(
MTLContext *mtlc, SurfaceDataRasInfo *srcInfo, BMTLSDOps * bmtlsdOps,
MTLRasterFormatInfo * rfi, jboolean useBlitEncoder, jint hint,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
{
const int sw = srcInfo->bounds.x2 - srcInfo->bounds.x1;
const int sh = srcInfo->bounds.y2 - srcInfo->bounds.y1;
id<MTLTexture> dest = bmtlsdOps->pTexture;
MTLPooledTextureHandle * texHandle = [mtlc.texturePool getTexture:sw height:sh format:rfi->format];
if (texHandle == nil) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitSwToTextureViaPooledTexture: can't obtain temporary texture object from pool");
return;
}
[[mtlc getCommandBufferWrapper] registerPooledTexture:texHandle];
[texHandle release];
id<MTLTexture> texBuff = texHandle.texture;
id<MTLTexture> swizzledTexture = replaceTextureRegion(mtlc, texBuff, srcInfo, rfi, 0, 0, sw, sh);
if (useBlitEncoder) {
id <MTLBlitCommandEncoder> blitEncoder = [mtlc.encoderManager createBlitEncoder];
[blitEncoder copyFromTexture:swizzledTexture != nil ? swizzledTexture : texBuff
sourceSlice:0
sourceLevel:0
sourceOrigin:MTLOriginMake(0, 0, 0)
sourceSize:MTLSizeMake(sw, sh, 1)
toTexture:dest
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(dx1, dy1, 0)];
[blitEncoder endEncoding];
} else {
drawTex2Tex(mtlc, swizzledTexture != nil ? swizzledTexture : texBuff, dest, !rfi->hasAlpha, bmtlsdOps->isOpaque, hint,
0, 0, sw, sh, dx1, dy1, dx2, dy2);
}
if (swizzledTexture != nil) {
[swizzledTexture release];
}
}
static
jboolean isIntegerAndUnscaled(
jint sx1, jint sy1, jint sx2, jint sy2,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2
) {
const jdouble epsilon = 0.0001f;
// check that dx1,dy1 is integer
if (fabs(dx1 - (int)dx1) > epsilon || fabs(dy1 - (int)dy1) > epsilon) {
return JNI_FALSE;
}
// check that destSize equals srcSize
if (fabs(dx2 - dx1 - sx2 + sx1) > epsilon || fabs(dy2 - dy1 - sy2 + sy1) > epsilon) {
return JNI_FALSE;
}
return JNI_TRUE;
}
static
jboolean clipDestCoords(
jdouble *dx1, jdouble *dy1, jdouble *dx2, jdouble *dy2,
jint *sx1, jint *sy1, jint *sx2, jint *sy2,
jint destW, jint destH, const MTLScissorRect * clipRect
) {
// Trim destination rect by clip-rect (or dest.bounds)
const jint sw = *sx2 - *sx1;
const jint sh = *sy2 - *sy1;
const jdouble dw = *dx2 - *dx1;
const jdouble dh = *dy2 - *dy1;
jdouble dcx1 = 0;
jdouble dcx2 = destW;
jdouble dcy1 = 0;
jdouble dcy2 = destH;
if (clipRect != NULL) {
if (clipRect->x > dcx1)
dcx1 = clipRect->x;
const int maxX = clipRect->x + clipRect->width;
if (dcx2 > maxX)
dcx2 = maxX;
if (clipRect->y > dcy1)
dcy1 = clipRect->y;
const int maxY = clipRect->y + clipRect->height;
if (dcy2 > maxY)
dcy2 = maxY;
if (dcx1 >= dcx2) {
J2dTraceLn2(J2D_TRACE_ERROR, "\tclipDestCoords: dcx1=%1.2f, dcx2=%1.2f", dcx1, dcx2);
dcx1 = dcx2;
}
if (dcy1 >= dcy2) {
J2dTraceLn2(J2D_TRACE_ERROR, "\tclipDestCoords: dcy1=%1.2f, dcy2=%1.2f", dcy1, dcy2);
dcy1 = dcy2;
}
}
if (*dx2 <= dcx1 || *dx1 >= dcx2 || *dy2 <= dcy1 || *dy1 >= dcy2) {
J2dTraceLn(J2D_TRACE_INFO, "\tclipDestCoords: dest rect doesn't intersect clip area");
J2dTraceLn4(J2D_TRACE_INFO, "\tdx2=%1.4f <= dcx1=%1.4f || *dx1=%1.4f >= dcx2=%1.4f", *dx2, dcx1, *dx1, dcx2);
J2dTraceLn4(J2D_TRACE_INFO, "\t*dy2=%1.4f <= dcy1=%1.4f || *dy1=%1.4f >= dcy2=%1.4f", *dy2, dcy1, *dy1, dcy2);
return JNI_FALSE;
}
if (*dx1 < dcx1) {
J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdx1=%1.2f, will be clipped to %1.2f | sx1+=%d", *dx1, dcx1, (jint)((dcx1 - *dx1) * (sw/dw)));
*sx1 += (jint)((dcx1 - *dx1) * (sw/dw));
*dx1 = dcx1;
}
if (*dx2 > dcx2) {
J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdx2=%1.2f, will be clipped to %1.2f | sx2-=%d", *dx2, dcx2, (jint)((*dx2 - dcx2) * (sw/dw)));
*sx2 -= (jint)((*dx2 - dcx2) * (sw/dw));
*dx2 = dcx2;
}
if (*dy1 < dcy1) {
J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdy1=%1.2f, will be clipped to %1.2f | sy1+=%d", *dy1, dcy1, (jint)((dcy1 - *dy1) * (sh/dh)));
*sy1 += (jint)((dcy1 - *dy1) * (sh/dh));
*dy1 = dcy1;
}
if (*dy2 > dcy2) {
J2dTraceLn3(J2D_TRACE_VERBOSE, "\t\tdy2=%1.2f, will be clipped to %1.2f | sy2-=%d", *dy2, dcy2, (jint)((*dy2 - dcy2) * (sh/dh)));
*sy2 -= (jint)((*dy2 - dcy2) * (sh/dh));
*dy2 = dcy2;
}
return JNI_TRUE;
}
/**
* General blit method for copying a native MTL surface to another MTL "Surface".
* Parameter texture == true forces to use 'texture' codepath (dest coordinates will always be integers).
* Parameter xform == true only when AffineTransform is used (invoked only from TransformBlit, dest coordinates will always be integers).
*/
void
MTLBlitLoops_IsoBlit(JNIEnv *env,
MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
jboolean xform, jint hint, jboolean texture,
jint sx1, jint sy1, jint sx2, jint sy2,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
{
BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps);
BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps);
RETURN_IF_NULL(mtlc);
RETURN_IF_NULL(srcOps);
RETURN_IF_NULL(dstOps);
id<MTLTexture> srcTex = srcOps->pTexture;
id<MTLTexture> dstTex = dstOps->pTexture;
if (srcTex == nil || srcTex == nil) {
J2dTraceLn2(J2D_TRACE_ERROR, "MTLBlitLoops_IsoBlit: surface is null (stex=%p, dtex=%p)", srcTex, dstTex);
return;
}
const jint sw = sx2 - sx1;
const jint sh = sy2 - sy1;
const jdouble dw = dx2 - dx1;
const jdouble dh = dy2 - dy1;
if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) {
J2dTraceLn4(J2D_TRACE_WARNING, "MTLBlitLoops_IsoBlit: invalid dimensions: sw=%d, sh%d, dw=%d, dh=%d", sw, sh, dw, dh);
return;
}
#ifdef DEBUG_ISOBLIT
if ((xform == JNI_TRUE) != (mtlc.useTransform == JNI_TRUE)) {
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE,
"MTLBlitLoops_IsoBlit state error: xform=%d, mtlc.useTransform=%d, texture=%d",
xform, mtlc.useTransform, texture);
}
#endif // DEBUG_ISOBLIT
clipDestCoords(
&dx1, &dy1, &dx2, &dy2,
&sx1, &sy1, &sx2, &sy2,
dstTex.width, dstTex.height, texture ? NULL : [mtlc.clip getRect]
);
SurfaceDataBounds bounds;
bounds.x1 = sx1;
bounds.y1 = sy1;
bounds.x2 = sx2;
bounds.y2 = sy2;
SurfaceData_IntersectBoundsXYXY(&bounds, 0, 0, srcOps->width, srcOps->height);
if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLBlitLoops_IsoBlit: source rectangle doesn't intersect with source surface bounds");
J2dTraceLn6(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d sw=%d sh=%d", sx1, sy1, sx2, sy2, srcOps->width, srcOps->height);
J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2);
return;
}
if (bounds.x1 != sx1) {
dx1 += (bounds.x1 - sx1) * (dw / sw);
sx1 = bounds.x1;
}
if (bounds.y1 != sy1) {
dy1 += (bounds.y1 - sy1) * (dh / sh);
sy1 = bounds.y1;
}
if (bounds.x2 != sx2) {
dx2 += (bounds.x2 - sx2) * (dw / sw);
sx2 = bounds.x2;
}
if (bounds.y2 != sy2) {
dy2 += (bounds.y2 - sy2) * (dh / sh);
sy2 = bounds.y2;
}
#ifdef TRACE_ISOBLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE,
"MTLBlitLoops_IsoBlit [tx=%d, xf=%d, AC=%s]: src=%s, dst=%s | (%d, %d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)",
texture, xform, [mtlc getCompositeDescription].cString,
getSurfaceDescription(srcOps).cString, getSurfaceDescription(dstOps).cString,
sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
#endif //TRACE_ISOBLIT
if (!texture && !xform
&& srcOps->isOpaque
&& isIntegerAndUnscaled(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2)
&& (dstOps->isOpaque || !srcOps->isOpaque)
) {
#ifdef TRACE_ISOBLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via blitEncoder]");
#endif //TRACE_ISOBLIT
id <MTLBlitCommandEncoder> blitEncoder = [mtlc.encoderManager createBlitEncoder];
[blitEncoder copyFromTexture:srcTex
sourceSlice:0
sourceLevel:0
sourceOrigin:MTLOriginMake(sx1, sy1, 0)
sourceSize:MTLSizeMake(sx2 - sx1, sy2 - sy1, 1)
toTexture:dstTex
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(dx1, dy1, 0)];
[blitEncoder endEncoding];
return;
}
#ifdef TRACE_ISOBLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via sampling]");
#endif //TRACE_ISOBLIT
drawTex2Tex(mtlc, srcTex, dstTex,
srcOps->isOpaque, dstOps->isOpaque,
hint, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
}
/**
* General blit method for copying a system memory ("Sw") surface to a native MTL surface.
* Parameter texture == true only in SwToTextureBlit (straight copy from sw to texture), dest coordinates will always be integers.
* Parameter xform == true only when AffineTransform is used (invoked only from TransformBlit, dest coordinates will always be integers).
*/
void
MTLBlitLoops_Blit(JNIEnv *env,
MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
jboolean xform, jint hint,
jint srctype, jboolean texture,
jint sx1, jint sy1, jint sx2, jint sy2,
jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
{
SurfaceDataOps *srcOps = (SurfaceDataOps *)jlong_to_ptr(pSrcOps);
BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps);
RETURN_IF_NULL(mtlc);
RETURN_IF_NULL(srcOps);
RETURN_IF_NULL(dstOps);
id<MTLTexture> dest = dstOps->pTexture;
if (dest == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: dest is null");
return;
}
if (srctype < 0 || srctype >= sizeof(RasterFormatInfos)/ sizeof(MTLRasterFormatInfo)) {
J2dTraceLn1(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: source pixel format %d isn't supported", srctype);
return;
}
const jint sw = sx2 - sx1;
const jint sh = sy2 - sy1;
const jdouble dw = dx2 - dx1;
const jdouble dh = dy2 - dy1;
if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: invalid dimensions");
return;
}
#ifdef DEBUG_BLIT
if (
(xform == JNI_TRUE) != (mtlc.useTransform == JNI_TRUE)
|| (xform && texture)
) {
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE,
"MTLBlitLoops_Blit state error: xform=%d, mtlc.useTransform=%d, texture=%d",
xform, mtlc.useTransform, texture);
}
if (texture) {
if (!isIntegerAndUnscaled(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2)) {
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE,
"MTLBlitLoops_Blit state error: texture=true, but src and dst dimensions aren't equal or dest coords aren't integers");
}
if (!dstOps->isOpaque && !RasterFormatInfos[srctype].hasAlpha) {
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE,
"MTLBlitLoops_Blit state error: texture=true, but dest has alpha and source hasn't alpha, can't use texture-codepath");
}
}
#endif // DEBUG_BLIT
clipDestCoords(
&dx1, &dy1, &dx2, &dy2,
&sx1, &sy1, &sx2, &sy2,
dest.width, dest.height, texture ? NULL : [mtlc.clip getRect]
);
SurfaceDataRasInfo srcInfo;
srcInfo.bounds.x1 = sx1;
srcInfo.bounds.y1 = sy1;
srcInfo.bounds.x2 = sx2;
srcInfo.bounds.y2 = sy2;
// NOTE: This function will modify the contents of the bounds field to represent the maximum available raster data.
if (srcOps->Lock(env, srcOps, &srcInfo, SD_LOCK_READ) != SD_SUCCESS) {
J2dTraceLn(J2D_TRACE_WARNING, "MTLBlitLoops_Blit: could not acquire lock");
return;
}
if (srcInfo.bounds.x2 > srcInfo.bounds.x1 && srcInfo.bounds.y2 > srcInfo.bounds.y1) {
srcOps->GetRasInfo(env, srcOps, &srcInfo);
if (srcInfo.rasBase) {
if (srcInfo.bounds.x1 != sx1) {
const int dx = srcInfo.bounds.x1 - sx1;
dx1 += dx * (dw / sw);
}
if (srcInfo.bounds.y1 != sy1) {
const int dy = srcInfo.bounds.y1 - sy1;
dy1 += dy * (dh / sh);
}
if (srcInfo.bounds.x2 != sx2) {
const int dx = srcInfo.bounds.x2 - sx2;
dx2 += dx * (dw / sw);
}
if (srcInfo.bounds.y2 != sy2) {
const int dy = srcInfo.bounds.y2 - sy2;
dy2 += dy * (dh / sh);
}
#ifdef TRACE_BLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE,
"MTLBlitLoops_Blit [tx=%d, xf=%d, AC=%s]: bdst=%s, src=%p (%dx%d) O=%d premul=%d | (%d, %d, %d, %d)->(%1.2f, %1.2f, %1.2f, %1.2f)",
texture, xform, [mtlc getCompositeDescription].cString,
getSurfaceDescription(dstOps).cString, srcOps,
sx2 - sx1, sy2 - sy1,
RasterFormatInfos[srctype].hasAlpha ? 0 : 1, RasterFormatInfos[srctype].isPremult ? 1 : 0,
sx1, sy1, sx2, sy2,
dx1, dy1, dx2, dy2);
#endif //TRACE_BLIT
MTLRasterFormatInfo rfi = RasterFormatInfos[srctype];
const jboolean useReplaceRegion = texture ||
(!rfi.hasAlpha
&& !xform
&& isIntegerAndUnscaled(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2));
if (useReplaceRegion) {
if (dstOps->isOpaque || rfi.hasAlpha) {
#ifdef TRACE_BLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [replaceTextureRegion]");
#endif //TRACE_BLIT
replaceTextureRegion(mtlc, dest, &srcInfo, &rfi, (int) dx1, (int) dy1, (int) dx2, (int) dy2);
} else {
#ifdef TRACE_BLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via pooled + blit]");
#endif //TRACE_BLIT
MTLBlitSwToTextureViaPooledTexture(mtlc, &srcInfo, dstOps, &rfi, false, hint, dx1, dy1, dx2, dy2);
}
} else { // !useReplaceRegion
#ifdef TRACE_BLIT
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE," [via pooled texture]");
#endif //TRACE_BLIT
MTLBlitSwToTextureViaPooledTexture(mtlc, &srcInfo, dstOps, &rfi, false, hint, dx1, dy1, dx2, dy2);
}
}
SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
}
SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
}
/**
* Specialized blit method for copying a native MTL "Surface" (pbuffer,
* window, etc.) to a system memory ("Sw") surface.
*/
void
MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc,
jlong pSrcOps, jlong pDstOps, jint dsttype,
jint srcx, jint srcy, jint dstx, jint dsty,
jint width, jint height)
{
J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLBlitLoops_SurfaceToSwBlit: sx=%d sy=%d w=%d h=%d dx=%d dy=%d", srcx, srcy, width, height, dstx, dsty);
BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps);
SurfaceDataOps *dstOps = (SurfaceDataOps *)jlong_to_ptr(pDstOps);
SurfaceDataRasInfo srcInfo, dstInfo;
if (dsttype < 0 || dsttype >= sizeof(RasterFormatInfos)/ sizeof(MTLRasterFormatInfo)) {
J2dTraceLn1(J2D_TRACE_ERROR, "MTLBlitLoops_SurfaceToSwBlit: destination pixel format %d isn't supported", dsttype);
return;
}
if (width <= 0 || height <= 0) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_SurfaceToSwBlit: dimensions are non-positive");
return;
}
RETURN_IF_NULL(srcOps);
RETURN_IF_NULL(dstOps);
RETURN_IF_NULL(mtlc);
srcInfo.bounds.x1 = srcx;
srcInfo.bounds.y1 = srcy;
srcInfo.bounds.x2 = srcx + width;
srcInfo.bounds.y2 = srcy + height;
dstInfo.bounds.x1 = dstx;
dstInfo.bounds.y1 = dsty;
dstInfo.bounds.x2 = dstx + width;
dstInfo.bounds.y2 = dsty + height;
if (dstOps->Lock(env, dstOps, &dstInfo, SD_LOCK_WRITE) != SD_SUCCESS) {
J2dTraceLn(J2D_TRACE_WARNING,"MTLBlitLoops_SurfaceToSwBlit: could not acquire dst lock");
return;
}
SurfaceData_IntersectBoundsXYXY(&srcInfo.bounds,
0, 0, srcOps->width, srcOps->height);
SurfaceData_IntersectBlitBounds(&dstInfo.bounds, &srcInfo.bounds,
srcx - dstx, srcy - dsty);
if (srcInfo.bounds.x2 > srcInfo.bounds.x1 &&
srcInfo.bounds.y2 > srcInfo.bounds.y1)
{
dstOps->GetRasInfo(env, dstOps, &dstInfo);
if (dstInfo.rasBase) {
void *pDst = dstInfo.rasBase;
srcx = srcInfo.bounds.x1;
srcy = srcInfo.bounds.y1;
dstx = dstInfo.bounds.x1;
dsty = dstInfo.bounds.y1;
width = srcInfo.bounds.x2 - srcInfo.bounds.x1;
height = srcInfo.bounds.y2 - srcInfo.bounds.y1;
pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride);
pDst = PtrPixelsRow(pDst, dsty, dstInfo.scanStride);
// Metal texture is (0,0) at left-top
srcx = srcOps->xOffset + srcx;
srcy = srcOps->yOffset + srcy;
const int srcLength = width * height * 4; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm
// Create MTLBuffer (or use static)
MTLRasterFormatInfo rfi = RasterFormatInfos[dsttype];
const jboolean directCopy = rfi.permuteMap == NULL;
id<MTLBuffer> mtlbuf;
#ifdef USE_STATIC_BUFFER
if (directCopy) {
// NOTE: theoretically we can use newBufferWithBytesNoCopy, but pDst must be allocated with special API
// mtlbuf = [mtlc.device
// newBufferWithBytesNoCopy:pDst
// length:(NSUInteger) srcLength
// options:MTLResourceCPUCacheModeDefaultCache
// deallocator:nil];
//
// see https://developer.apple.com/documentation/metal/mtldevice/1433382-newbufferwithbytesnocopy?language=objc
//
// The storage allocation of the returned new MTLBuffer object is the same as the pointer input value.
// The existing memory allocation must be covered by a single VM region, typically allocated with vm_allocate or mmap.
// Memory allocated by malloc is specifically disallowed.
}
static id<MTLBuffer> mtlIntermediateBuffer = nil; // need to reimplement with MTLBufferManager
if (mtlIntermediateBuffer == nil || mtlIntermediateBuffer.length < srcLength) {
if (mtlIntermediateBuffer != nil) {
[mtlIntermediateBuffer release];
}
mtlIntermediateBuffer = [mtlc.device newBufferWithLength:srcLength options:MTLResourceCPUCacheModeDefaultCache];
}
mtlbuf = mtlIntermediateBuffer;
#else // USE_STATIC_BUFFER
mtlbuf = [mtlc.device newBufferWithLength:width*height*4 options:MTLResourceStorageModeShared];
#endif // USE_STATIC_BUFFER
// Read from surface into MTLBuffer
// NOTE: using of separate blitCommandBuffer can produce errors (draw into surface (with general cmd-buf)
// can be unfinished when reading raster from blit cmd-buf).
// Consider to use [mtlc.encoderManager createBlitEncoder] and [mtlc commitCommandBuffer:JNI_TRUE];
J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLBlitLoops_SurfaceToSwBlit: source texture %p", srcOps->pTexture);
id<MTLCommandBuffer> cb = [mtlc createCommandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
[blitEncoder synchronizeTexture:srcOps->pTexture slice:0 level:0];
[blitEncoder copyFromTexture:srcOps->pTexture
sourceSlice:0
sourceLevel:0
sourceOrigin:MTLOriginMake(srcx, srcy, 0)
sourceSize:MTLSizeMake(width, height, 1)
toBuffer:mtlbuf
destinationOffset:0 /*offset already taken in: pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride)*/
destinationBytesPerRow:width*4
destinationBytesPerImage:width * height*4];
[blitEncoder endEncoding];
// Commit and wait for reading complete
[cb commit];
[cb waitUntilCompleted];
// Perform conversion if necessary
if (directCopy) {
if ((dstInfo.scanStride == width * dstInfo.pixelStride) &&
(height == (dstInfo.bounds.y2 - dstInfo.bounds.y1))) {
// mtlbuf.contents have same dimensions as of pDst
memcpy(pDst, mtlbuf.contents, srcLength);
} else {
// mtlbuf.contents have smaller dimensions than pDst
// copy each row from mtlbuf.contents at appropriate position in pDst
// Note : pDst is already addjusted for offsets using PtrAddBytes above
int rowSize = width * dstInfo.pixelStride;
for (int y = 0; y < height; y++) {
memcpy(pDst, mtlbuf.contents + (y * rowSize), rowSize);
pDst = PtrAddBytes(pDst, dstInfo.scanStride);
}
}
} else {
J2dTraceLn6(J2D_TRACE_VERBOSE,"MTLBlitLoops_SurfaceToSwBlit: dsttype=%d, raster conversion will be performed, dest rfi: %d, %d, %d, %d, hasA=%d",
dsttype, rfi.permuteMap[0], rfi.permuteMap[1], rfi.permuteMap[2], rfi.permuteMap[3], rfi.hasAlpha);
// perform raster conversion: mtlIntermediateBuffer(8888) -> pDst(rfi)
// invoked only from rq-thread, so use static buffers
// but it's better to use thread-local buffers (or special buffer manager)
vImage_Buffer srcBuf;
srcBuf.height = height;
srcBuf.width = width;
srcBuf.rowBytes = 4*width;
srcBuf.data = mtlbuf.contents;
vImage_Buffer destBuf;
destBuf.height = height;
destBuf.width = width;
destBuf.rowBytes = dstInfo.scanStride;
destBuf.data = pDst;
vImagePermuteChannels_ARGB8888(&srcBuf, &destBuf, rfi.permuteMap, kvImageNoFlags);
}
#ifndef USE_STATIC_BUFFER
[mtlbuf release];
#endif // USE_STATIC_BUFFER
}
SurfaceData_InvokeRelease(env, dstOps, &dstInfo);
}
SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
}
void
MTLBlitLoops_CopyArea(JNIEnv *env,
MTLContext *mtlc, BMTLSDOps *dstOps,
jint x, jint y, jint width, jint height,
jint dx, jint dy)
{
#ifdef DEBUG
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_CopyArea: bdst=%p [tex=%p] %dx%d | src (%d, %d), %dx%d -> dst (%d, %d)",
dstOps, dstOps->pTexture, ((id<MTLTexture>)dstOps->pTexture).width, ((id<MTLTexture>)dstOps->pTexture).height, x, y, width, height, dx, dy);
#endif //DEBUG
@autoreleasepool {
id<MTLCommandBuffer> cb = [mtlc createCommandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
// Create an intrermediate buffer
int totalBuffsize = width * height * 4;
id <MTLBuffer> buff = [[mtlc.device newBufferWithLength:totalBuffsize options:MTLResourceStorageModePrivate] autorelease];
[blitEncoder copyFromTexture:dstOps->pTexture
sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(x, y, 0) sourceSize:MTLSizeMake(width, height, 1)
toBuffer:buff destinationOffset:0 destinationBytesPerRow:(width * 4) destinationBytesPerImage:totalBuffsize];
[blitEncoder copyFromBuffer:buff
sourceOffset:0 sourceBytesPerRow:width*4 sourceBytesPerImage:totalBuffsize sourceSize:MTLSizeMake(width, height, 1)
toTexture:dstOps->pTexture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(x + dx, y + dy, 0)];
[blitEncoder endEncoding];
[cb commit];
//[cb waitUntilCompleted];
/*[blitEncoder
copyFromTexture:dstOps->pTexture
sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(x, y, 0) sourceSize:MTLSizeMake(width, height, 1)
toTexture:dstOps->pTexture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(x + dx, y + dy, 0)];
[blitEncoder endEncoding];*/
}
// TODO:
// 1. check rect bounds
// 2. support CopyArea with extra-alpha (and with custom Composite if necessary)
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLBufImgOps_h_Included
#define MTLBufImgOps_h_Included
#include "MTLContext.h"
@interface MTLRescaleOp : NSObject
- (id)init:(jboolean)isNonPremult factors:(unsigned char *)factors offsets:(unsigned char *)offsets;
- (jfloat *)getScaleFactors;
- (jfloat *)getOffsets;
- (NSString *)getDescription; // creates autorelease string
@property (readonly) jboolean isNonPremult;
@end
@interface MTLConvolveOp : NSObject
- (id)init:(jboolean)edgeZeroFill kernelWidth:(jint)kernelWidth
kernelHeight:(jint)kernelHeight
srcWidth:(jint)srcWidth
srcHeight:(jint)srcHeight
kernel:(unsigned char *)kernel
device:(id<MTLDevice>)device;
- (void) dealloc;
- (id<MTLBuffer>) getBuffer;
- (const float *) getImgEdge;
- (NSString *)getDescription; // creates autorelease string
@property (readonly) jboolean isEdgeZeroFill;
@property (readonly) int kernelSize;
@end
@interface MTLLookupOp : NSObject
- (id)init:(jboolean)nonPremult shortData:(jboolean)shortData
numBands:(jint)numBands
bandLength:(jint)bandLength
offset:(jint)offset
tableValues:(void *)tableValues
device:(id<MTLDevice>)device;
- (void) dealloc;
- (jfloat *)getOffset;
- (id<MTLTexture>) getLookupTexture;
- (NSString *)getDescription; // creates autorelease string
@property (readonly) jboolean isUseSrcAlpha;
@property (readonly) jboolean isNonPremult;
@end
#endif /* MTLBufImgOps_h_Included */

View File

@@ -0,0 +1,227 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include <jlong.h>
#include "MTLBufImgOps.h"
#include "MTLContext.h"
#include "MTLRenderQueue.h"
#include "MTLSurfaceDataBase.h"
#include "GraphicsPrimitiveMgr.h"
@implementation MTLRescaleOp {
jboolean _isNonPremult;
jfloat _normScaleFactors[4];
jfloat _normOffsets[4];
}
-(jfloat *) getScaleFactors {
return _normScaleFactors;
}
-(jfloat *) getOffsets {
return _normOffsets;
}
- (id)init:(jboolean)isNonPremult factors:(unsigned char *)factors offsets:(unsigned char *)offsets {
self = [super init];
if (self) {
J2dTraceLn1(J2D_TRACE_INFO,"Created MTLRescaleOp: isNonPremult=%d", isNonPremult);
_isNonPremult = isNonPremult;
_normScaleFactors[0] = NEXT_FLOAT(factors);
_normScaleFactors[1] = NEXT_FLOAT(factors);
_normScaleFactors[2] = NEXT_FLOAT(factors);
_normScaleFactors[3] = NEXT_FLOAT(factors);
_normOffsets[0] = NEXT_FLOAT(offsets);
_normOffsets[1] = NEXT_FLOAT(offsets);
_normOffsets[2] = NEXT_FLOAT(offsets);
_normOffsets[3] = NEXT_FLOAT(offsets);
}
return self;
}
- (NSString *)getDescription {
return [NSString stringWithFormat:@"rescale: nonPremult=%d", _isNonPremult];
}
@end
@implementation MTLConvolveOp {
id<MTLBuffer> _buffer;
float _imgEdge[4];
int _kernelSize;
jboolean _isEdgeZeroFill;
}
- (id)init:(jboolean)edgeZeroFill kernelWidth:(jint)kernelWidth
kernelHeight:(jint)kernelHeight
srcWidth:(jint)srcWidth
srcHeight:(jint)srcHeight
kernel:(unsigned char *)kernel
device:(id<MTLDevice>)device {
self = [super init];
if (self) {
J2dTraceLn2(J2D_TRACE_INFO,"Created MTLConvolveOp: kernelW=%d kernelH=%d", kernelWidth, kernelHeight);
_isEdgeZeroFill = edgeZeroFill;
_kernelSize = kernelWidth * kernelHeight;
_buffer = [device newBufferWithLength:_kernelSize*sizeof(vector_float3) options:MTLResourceStorageModeShared];
float * kernelVals = [_buffer contents];
int kIndex = 0;
for (int i = -kernelHeight/2; i < kernelHeight/2+1; i++) {
for (int j = -kernelWidth/2; j < kernelWidth/2+1; j++) {
kernelVals[kIndex+0] = j/(float)srcWidth;
kernelVals[kIndex+1] = i/(float)srcHeight;
kernelVals[kIndex+2] = NEXT_FLOAT(kernel);
kIndex += 3;
}
}
_imgEdge[0] = (kernelWidth/2)/(float)srcWidth;
_imgEdge[1] = (kernelHeight/2)/(float)srcHeight;
_imgEdge[2] = 1 - _imgEdge[0];
_imgEdge[3] = 1 - _imgEdge[1];
}
return self;
}
- (void) dealloc {
[_buffer release];
[super dealloc];
}
- (id<MTLBuffer>) getBuffer {
return _buffer;
}
- (const float *) getImgEdge {
return _imgEdge;
}
- (NSString *)getDescription {
return [NSString stringWithFormat:@"convolve: isEdgeZeroFill=%d", _isEdgeZeroFill];
}
@end
@implementation MTLLookupOp {
float _offset[4];
jboolean _isUseSrcAlpha;
jboolean _isNonPremult;
id<MTLTexture> _lookupTex;
}
- (id)init:(jboolean)nonPremult shortData:(jboolean)shortData
numBands:(jint)numBands
bandLength:(jint)bandLength
offset:(jint)offset
tableValues:(void *)tableValues
device:(id<MTLDevice>)device {
self = [super init];
if (self) {
J2dTraceLn4(J2D_TRACE_INFO,"Created MTLLookupOp: short=%d num=%d len=%d off=%d",
shortData, numBands, bandLength, offset);
_isUseSrcAlpha = numBands != 4;
_isNonPremult = nonPremult;
_offset[0] = offset / 255.0f;
_offset[1] = _offset[0];
_offset[2] = _offset[0];
_offset[3] = _offset[0];
MTLTextureDescriptor *textureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatA8Unorm
width:(NSUInteger)256
height:(NSUInteger)4
mipmapped:NO];
_lookupTex = [device newTextureWithDescriptor:textureDescriptor];
void *bands[4];
for (int i = 0; i < 4; i++) {
bands[i] = NULL;
}
int bytesPerElem = (shortData ? 2 : 1);
if (numBands == 1) {
// replicate the single band for R/G/B; alpha band is unused
for (int i = 0; i < 3; i++) {
bands[i] = tableValues;
}
bands[3] = NULL;
} else if (numBands == 3) {
// user supplied band for each of R/G/B; alpha band is unused
for (int i = 0; i < 3; i++) {
bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);
}
bands[3] = NULL;
} else if (numBands == 4) {
// user supplied band for each of R/G/B/A
for (int i = 0; i < 4; i++) {
bands[i] = PtrAddBytes(tableValues, i*bandLength*bytesPerElem);
}
}
for (int i = 0; i < 4; i++) {
if (bands[i] == NULL)
continue;
MTLRegion region = {
{0, i, 0},
{bandLength, 1,1}
};
[_lookupTex replaceRegion:region
mipmapLevel:0
withBytes:bands[i]
bytesPerRow:bandLength*bytesPerElem];
}
}
return self;
}
- (void) dealloc {
[_lookupTex release];
[super dealloc];
}
- (jfloat *) getOffset {
return _offset;
}
- (id<MTLTexture>) getLookupTexture {
return _lookupTex;
}
- (NSString *)getDescription {
return [NSString stringWithFormat:@"lookup: offset=%f", _offset[0]];
}
@end
#endif /* !HEADLESS */

View File

@@ -0,0 +1,57 @@
#import <limits.h>
#ifndef MTLClip_h_Included
#define MTLClip_h_Included
#import <Metal/Metal.h>
#include <jni.h>
#include "MTLSurfaceDataBase.h"
enum Clip {
NO_CLIP,
RECT_CLIP,
SHAPE_CLIP
};
@class MTLContext;
@class MTLPipelineStatesStorage;
/**
* The MTLClip class represents clip mode (rect or stencil)
* */
@interface MTLClip : NSObject
@property (readonly) id<MTLTexture> stencilAADataRef;
@property (readonly) id<MTLTexture> stencilTextureRef;
@property (readonly) BOOL stencilMaskGenerationInProgress;
- (id)init;
- (BOOL)isEqual:(MTLClip *)other; // used to compare requested with cached
- (void)copyFrom:(MTLClip *)other; // used to save cached
- (BOOL)isShape;
- (BOOL)isRect;
// returns null when clipType != RECT_CLIP
- (const MTLScissorRect *) getRect;
- (void)reset;
- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2;
- (void)beginShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc;
- (void)endShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc;
- (void)setScissorOrStencil:(id<MTLRenderCommandEncoder>)encoder
destWidth:(NSUInteger)dw
destHeight:(NSUInteger)dh
device:(id<MTLDevice>)device;
- (void)setMaskGenerationPipelineState:(id<MTLRenderCommandEncoder>)encoder
destWidth:(NSUInteger)dw
destHeight:(NSUInteger)dh
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage;
- (NSString *)getDescription __unused; // creates autorelease string
@end
#endif // MTLClip_h_Included

View File

@@ -0,0 +1,385 @@
#include "MTLClip.h"
#include "MTLContext.h"
#include "common.h"
static MTLRenderPipelineDescriptor * templateStencilPipelineDesc = nil;
static void initTemplatePipelineDescriptors() {
if (templateStencilPipelineDesc != nil)
return;
MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease];
vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat2;
vertDesc.attributes[VertexAttributePosition].offset = 0;
vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer;
vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex);
vertDesc.layouts[MeshVertexBuffer].stepRate = 1;
vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
templateStencilPipelineDesc = [MTLRenderPipelineDescriptor new];
templateStencilPipelineDesc.sampleCount = 1;
templateStencilPipelineDesc.vertexDescriptor = vertDesc;
templateStencilPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatR8Uint; // A byte buffer format
templateStencilPipelineDesc.label = @"template_stencil";
}
static id<MTLDepthStencilState> getStencilState(id<MTLDevice> device) {
static id<MTLDepthStencilState> stencilState = nil;
if (stencilState == nil) {
MTLDepthStencilDescriptor* stencilDescriptor;
stencilDescriptor = [[MTLDepthStencilDescriptor new] autorelease];
stencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual;
stencilDescriptor.frontFaceStencil.stencilFailureOperation = MTLStencilOperationKeep;
// TODO : backFaceStencil can be set to nil if all primitives are drawn as front-facing primitives
// currently, fill parallelogram uses back-facing primitive drawing - that needs to be changed.
// Once that part is changed, set backFaceStencil to nil
//stencilDescriptor.backFaceStencil = nil;
stencilDescriptor.backFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual;
stencilDescriptor.backFaceStencil.stencilFailureOperation = MTLStencilOperationKeep;
stencilState = [device newDepthStencilStateWithDescriptor:stencilDescriptor];
}
return stencilState;
}
@implementation MTLClip {
jint _clipType;
MTLScissorRect _clipRect;
MTLContext* _mtlc;
BMTLSDOps* _dstOps;
BOOL _stencilMaskGenerationInProgress;
BOOL _clipReady;
BOOL _aaClipReady;
}
- (id)init {
self = [super init];
if (self) {
_clipType = NO_CLIP;
_mtlc = nil;
_dstOps = NULL;
_stencilMaskGenerationInProgress = NO;
_clipReady = NO;
_aaClipReady = NO;
}
return self;
}
- (BOOL)isEqual:(MTLClip *)other {
if (self == other)
return YES;
if (_stencilMaskGenerationInProgress == JNI_TRUE)
return other->_stencilMaskGenerationInProgress == JNI_TRUE;
if (_clipType != other->_clipType)
return NO;
if (_clipType == NO_CLIP)
return YES;
if (_clipType == RECT_CLIP) {
return _clipRect.x == other->_clipRect.x && _clipRect.y == other->_clipRect.y
&& _clipRect.width == other->_clipRect.width && _clipRect.height == other->_clipRect.height;
}
// NOTE: can compare stencil-data pointers here
return YES;
}
- (BOOL)isShape {
return _clipType == SHAPE_CLIP;
}
- (BOOL)isRect __unused {
return _clipType == RECT_CLIP;
}
- (const MTLScissorRect * _Nullable) getRect {
return _clipType == RECT_CLIP ? &_clipRect : NULL;
}
- (void)copyFrom:(MTLClip *)other {
_clipType = other->_clipType;
_stencilMaskGenerationInProgress = other->_stencilMaskGenerationInProgress;
_dstOps = other->_dstOps;
if (other->_clipType == RECT_CLIP) {
_clipRect = other->_clipRect;
}
}
- (void)reset {
_clipType = NO_CLIP;
_stencilMaskGenerationInProgress = JNI_FALSE;
}
- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 {
if (_clipType == SHAPE_CLIP) {
_dstOps = NULL;
}
if (x1 >= x2 || y1 >= y2) {
J2dTraceLn4(J2D_TRACE_ERROR, "MTLClip.setClipRect: invalid rect: x1=%d y1=%d x2=%d y2=%d", x1, y1, x2, y2);
_clipType = NO_CLIP;
}
const jint width = x2 - x1;
const jint height = y2 - y1;
J2dTraceLn4(J2D_TRACE_INFO, "MTLClip.setClipRect: x=%d y=%d w=%d h=%d", x1, y1, width, height);
_clipRect.x = (NSUInteger)((x1 >= 0) ? x1 : 0);
_clipRect.y = (NSUInteger)((y1 >= 0) ? y1 : 0);
_clipRect.width = (NSUInteger)((width >= 0) ? width : 0);
_clipRect.height = (NSUInteger)((height >= 0) ? height : 0);
_clipType = RECT_CLIP;
}
- (void)beginShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc {
_stencilMaskGenerationInProgress = YES;
if ((dstOps == NULL) || (dstOps->pStencilData == NULL) || (dstOps->pStencilTexture == NULL)) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_beginShapeClip: stencil render target or stencil texture is NULL");
return;
}
// Clear the stencil render buffer & stencil texture
@autoreleasepool {
if (dstOps->width <= 0 || dstOps->height <= 0) {
return;
}
NSUInteger width = (NSUInteger)dstOps->width;
NSUInteger height = (NSUInteger)dstOps->height;
NSUInteger size = width*height;
id <MTLBuffer> buff = [mtlc.device newBufferWithLength:size*4 options:MTLResourceStorageModePrivate];
id<MTLCommandBuffer> commandBuf = [mtlc createCommandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder];
[blitEncoder fillBuffer:buff range:NSMakeRange(0, size*4) value:0];
MTLOrigin origin = MTLOriginMake(0, 0, 0);
MTLSize sourceSize = MTLSizeMake(width, height, 1);
[blitEncoder copyFromBuffer:buff
sourceOffset:0
sourceBytesPerRow:width
sourceBytesPerImage:size
sourceSize:sourceSize
toTexture:dstOps->pStencilData
destinationSlice:0
destinationLevel:0
destinationOrigin:origin];
[blitEncoder endEncoding];
[commandBuf commit];
[commandBuf waitUntilCompleted];
[buff release];
}
}
- (void)endShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc {
if ((dstOps == NULL) || (dstOps->pStencilData == NULL) || (dstOps->pStencilTexture == NULL)) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_endShapeClip: stencil render target or stencil texture is NULL");
return;
}
// Complete the rendering to the stencil buffer ------------
[mtlc.encoderManager endEncoder];
MTLCommandBufferWrapper* cbWrapper = [mtlc pullCommandBufferWrapper];
id<MTLCommandBuffer> commandBuffer = [cbWrapper getCommandBuffer];
[commandBuffer addCompletedHandler:^(id <MTLCommandBuffer> c) {
[cbWrapper release];
}];
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
// Now the stencil data is ready, this needs to be used while rendering further
@autoreleasepool {
if (dstOps->width > 0 && dstOps->height > 0) {
NSUInteger width = (NSUInteger)dstOps->width;
NSUInteger height = (NSUInteger)dstOps->height;
NSUInteger size = width*height;
NSUInteger sizeX4 = size*4;
id<MTLCommandBuffer> cb = [mtlc createCommandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
MTLSize sourceSize = MTLSizeMake(width, height, 1);
MTLOrigin origin = MTLOriginMake(0, 0, 0);
[blitEncoder copyFromTexture:dstOps->pStencilData
sourceSlice:0
sourceLevel:0
sourceOrigin:origin
sourceSize:sourceSize
toBuffer:dstOps->pStencilDataBuf
destinationOffset:0
destinationBytesPerRow:width
destinationBytesPerImage:size];
[blitEncoder endEncoding];
[cb commit];
[cb waitUntilCompleted];
}
}
_stencilMaskGenerationInProgress = JNI_FALSE;
_mtlc = mtlc;
_dstOps = dstOps;
_clipType = SHAPE_CLIP;
_clipReady = NO;
_aaClipReady = NO;
}
- (void)setMaskGenerationPipelineState:(id<MTLRenderCommandEncoder>)encoder
destWidth:(NSUInteger)dw
destHeight:(NSUInteger)dh
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage
{
initTemplatePipelineDescriptors();
// A PipelineState for rendering to a byte-buffered texture that will be used as a stencil
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:templateStencilPipelineDesc
vertexShaderId:@"vert_stencil"
fragmentShaderId:@"frag_stencil"];
[encoder setRenderPipelineState:pipelineState];
struct FrameUniforms uf; // color is ignored while writing to stencil buffer
memset(&uf, 0, sizeof(uf));
[encoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
_clipRect.x = 0;
_clipRect.y = 0;
_clipRect.width = dw;
_clipRect.height = dh;
[encoder setScissorRect:_clipRect]; // just for insurance (to reset possible clip from previous drawing)
}
- (void)setScissorOrStencil:(id<MTLRenderCommandEncoder>)encoder
destWidth:(NSUInteger)dw
destHeight:(NSUInteger)dh
device:(id<MTLDevice>)device
{
if (_clipType == NO_CLIP || _clipType == SHAPE_CLIP) {
_clipRect.x = 0;
_clipRect.y = 0;
_clipRect.width = dw;
_clipRect.height = dh;
}
[encoder setScissorRect:_clipRect];
if (_clipType == NO_CLIP || _clipType == RECT_CLIP) {
// NOTE: It seems that we can use the same encoder (with disabled stencil test) when mode changes from SHAPE to RECT.
// But [encoder setDepthStencilState:nil] causes crash, so we have to recreate encoder in such case.
// So we can omit [encoder setDepthStencilState:nil] here.
return;
}
if (_clipType == SHAPE_CLIP) {
// Enable stencil test
[encoder setDepthStencilState:getStencilState(device)];
[encoder setStencilReferenceValue:0xFF];
}
}
- (NSString *)getDescription __unused {
if (_clipType == NO_CLIP) {
return @"NO_CLIP";
}
if (_clipType == RECT_CLIP) {
return [NSString stringWithFormat:@"RECT_CLIP [%lu,%lu - %lux%lu]", _clipRect.x, _clipRect.y, _clipRect.width, _clipRect.height];
}
return [NSString stringWithFormat:@"SHAPE_CLIP"];
}
- (id<MTLTexture>) stencilTextureRef {
if (_dstOps == NULL) return nil;
id <MTLTexture> _stencilTextureRef = _dstOps->pStencilTexture;
if (!_clipReady) {
@autoreleasepool {
id <MTLCommandBuffer> cb = [_mtlc createCommandBuffer];
id <MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
id <MTLBuffer> _stencilDataBufRef = _dstOps->pStencilDataBuf;
NSUInteger width = _stencilTextureRef.width;
NSUInteger height = _stencilTextureRef.height;
[blitEncoder copyFromBuffer:_stencilDataBufRef
sourceOffset:0
sourceBytesPerRow:width
sourceBytesPerImage:width * height
sourceSize:MTLSizeMake(width, height, 1)
toTexture:_stencilTextureRef
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(0, 0, 0)];
[blitEncoder endEncoding];
[cb commit];
[cb waitUntilCompleted];
_clipReady = YES;
}
}
return _stencilTextureRef;
}
- (id<MTLTexture>) stencilAADataRef {
if (_dstOps == NULL) return nil;
id <MTLTexture> _stencilAADataRef = _dstOps->pAAStencilData;
if (!_aaClipReady) {
@autoreleasepool {
id <MTLCommandBuffer> cb = [_mtlc createCommandBuffer];
id <MTLComputeCommandEncoder> computeEncoder = [cb computeCommandEncoder];
id<MTLComputePipelineState> computePipelineState = [_mtlc.pipelineStateStorage getComputePipelineState:@"stencil2tex"];
id <MTLBuffer> _stencilDataBufRef = _dstOps->pStencilDataBuf;
id <MTLBuffer> _stencilAADataBufRef = _dstOps->pAAStencilDataBuf;
NSUInteger width = _stencilAADataRef.width;
NSUInteger height = _stencilAADataRef.height;
NSUInteger size = width * height;
[computeEncoder setComputePipelineState:computePipelineState];
[computeEncoder setBuffer:_stencilDataBufRef offset:0 atIndex:0];
[computeEncoder setBuffer:_stencilAADataBufRef offset:0 atIndex:1];
NSUInteger threadGroupSize = computePipelineState.maxTotalThreadsPerThreadgroup;
if (threadGroupSize > _stencilDataBufRef.length)
{
threadGroupSize = _stencilDataBufRef.length;
}
MTLSize threadgroupCounts = MTLSizeMake(threadGroupSize, 1, 1);
MTLSize threadgroups = MTLSizeMake(_stencilDataBufRef.length / threadGroupSize,
1, 1);
[computeEncoder dispatchThreadgroups:threadgroups
threadsPerThreadgroup:threadgroupCounts];
[computeEncoder endEncoding];
id <MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
[blitEncoder copyFromBuffer:_stencilAADataBufRef
sourceOffset:0
sourceBytesPerRow:width * 4
sourceBytesPerImage:size * 4
sourceSize:MTLSizeMake(width, height, 1)
toTexture:_stencilAADataRef
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(0, 0, 0)];
[blitEncoder endEncoding];
[cb commit];
[cb waitUntilCompleted];
_aaClipReady = YES;
}
}
return _stencilAADataRef;
}
@end

View File

@@ -0,0 +1,39 @@
#ifndef MTLComposite_h_Included
#define MTLComposite_h_Included
#import <Metal/Metal.h>
#include <jni.h>
#define FLT_EPS (0.001f)
#define FLT_LT(x,y) ((x) < (y) - FLT_EPS)
#define FLT_GE(x,y) ((x) >= (y) - FLT_EPS)
#define FLT_LE(x,y) ((x) <= (y) + FLT_EPS)
#define FLT_GT(x,y) ((x) > (y) + FLT_EPS)
/**
* The MTLComposite class represents composite mode
* */
@interface MTLComposite : NSObject
- (id)init;
- (BOOL)isEqual:(MTLComposite *)other; // used to compare requested with cached
- (void)copyFrom:(MTLComposite *)other; // used to save cached
- (void)setRule:(jint)rule; // sets extraAlpha=1
- (void)setRule:(jint)rule extraAlpha:(jfloat)extraAlpha;
- (void)reset;
- (void)setXORComposite:(jint)color;
- (void)setAlphaComposite:(jint)rule;
- (jint)getCompositeState;
- (jint)getRule;
- (jint)getXorColor;
- (jfloat)getExtraAlpha;
- (NSString *)getDescription; // creates autorelease string
@end
#endif // MTLComposite_h_Included

View File

@@ -0,0 +1,167 @@
#include "MTLComposite.h"
#include "sun_java2d_SunGraphics2D.h"
#include "java_awt_AlphaComposite.h"
@implementation MTLComposite {
jint _compState;
jint _compositeRule;
jint _xorPixel;
jfloat _extraAlpha;
}
- (id)init {
self = [super init];
if (self) {
_compositeRule = -1;
_compState = -1;
_xorPixel = 0;
_extraAlpha = 1;
}
return self;
}
- (BOOL)isEqual:(MTLComposite *)other {
if (self == other)
return YES;
if (_compState == other->_compState) {
if (_compState == sun_java2d_SunGraphics2D_COMP_XOR) {
return _xorPixel == other->_xorPixel;
}
if (_compState == sun_java2d_SunGraphics2D_COMP_ALPHA) {
return _extraAlpha == other->_extraAlpha
&& _compositeRule == other->_compositeRule;
}
}
return NO;
}
- (void)copyFrom:(MTLComposite *)other {
_extraAlpha = other->_extraAlpha;
_compositeRule = other->_compositeRule;
_compState = other->_compState;
_xorPixel = other->_xorPixel;
}
- (void)setRule:(jint)rule {
_extraAlpha = 1.f;
_compositeRule = rule;
}
- (void)setRule:(jint)rule extraAlpha:(jfloat)extraAlpha {
_compState = sun_java2d_SunGraphics2D_COMP_ALPHA;
_extraAlpha = extraAlpha;
_compositeRule = rule;
}
- (void)reset {
_compState = sun_java2d_SunGraphics2D_COMP_ISCOPY;
_compositeRule = java_awt_AlphaComposite_SRC;
_extraAlpha = 1.f;
}
- (jint)getRule {
return _compositeRule;
}
- (NSString *)getDescription {
const char * result = "";
switch (_compositeRule) {
case java_awt_AlphaComposite_CLEAR:
{
result = "CLEAR";
}
break;
case java_awt_AlphaComposite_SRC:
{
result = "SRC";
}
break;
case java_awt_AlphaComposite_DST:
{
result = "DST";
}
break;
case java_awt_AlphaComposite_SRC_OVER:
{
result = "SRC_OVER";
}
break;
case java_awt_AlphaComposite_DST_OVER:
{
result = "DST_OVER";
}
break;
case java_awt_AlphaComposite_SRC_IN:
{
result = "SRC_IN";
}
break;
case java_awt_AlphaComposite_DST_IN:
{
result = "DST_IN";
}
break;
case java_awt_AlphaComposite_SRC_OUT:
{
result = "SRC_OUT";
}
break;
case java_awt_AlphaComposite_DST_OUT:
{
result = "DST_OUT";
}
break;
case java_awt_AlphaComposite_SRC_ATOP:
{
result = "SRC_ATOP";
}
break;
case java_awt_AlphaComposite_DST_ATOP:
{
result = "DST_ATOP";
}
break;
case java_awt_AlphaComposite_XOR:
{
result = "XOR";
}
break;
default:
result = "UNKNOWN";
break;
}
const double epsilon = 0.001f;
if (fabs(_extraAlpha - 1.f) > epsilon) {
return [NSString stringWithFormat:@"%s [%1.2f]", result, _extraAlpha];
}
return [NSString stringWithFormat:@"%s", result];
}
- (void)setAlphaComposite:(jint)rule {
_compState = sun_java2d_SunGraphics2D_COMP_ALPHA;
[self setRule:rule];
}
- (jint)getCompositeState {
return _compState;
}
-(void)setXORComposite:(jint)color {
_compState = sun_java2d_SunGraphics2D_COMP_XOR;
_xorPixel = color;
}
-(jint)getXorColor {
return _xorPixel;
}
- (jfloat)getExtraAlpha {
return _extraAlpha;
}
@end

View File

@@ -0,0 +1,271 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLContext_h_Included
#define MTLContext_h_Included
#include "sun_java2d_pipe_BufferedContext.h"
#include "sun_java2d_metal_MTLContext.h"
#include "sun_java2d_metal_MTLContext_MTLContextCaps.h"
#import <Metal/Metal.h>
#include "MTLTexturePool.h"
#include "MTLPipelineStatesStorage.h"
#include "MTLTransform.h"
#include "MTLComposite.h"
#include "MTLPaints.h"
#include "MTLClip.h"
#include "EncoderManager.h"
#define MTLC_BLIT_TILE_SIZE 128
/**
* The MTLCommandBufferWrapper class contains command buffer and
* associated resources that will be released in completion handler
* */
@interface MTLCommandBufferWrapper : NSObject
- (id<MTLCommandBuffer>) getCommandBuffer;
- (void) onComplete; // invoked from completion handler in some pooled thread
- (void) registerPooledTexture:(MTLPooledTextureHandle *)handle;
@end
/**
* The MTLContext class contains cached state relevant to the native
* MTL context stored within the native ctxInfo field. Each Java-level
* MTLContext object is associated with a native-level MTLContext class.
* */
@interface MTLContext : NSObject
@property (readonly) MTLComposite * composite;
@property (readwrite, retain) MTLPaint * paint;
@property (readonly) MTLTransform * transform;
@property (readonly) MTLClip * clip;
@property jint textureFunction;
@property jboolean vertexCacheEnabled;
@property jboolean aaEnabled;
@property (readonly, strong) id<MTLDevice> device;
@property (strong) id<MTLLibrary> library;
@property (strong) id<MTLCommandQueue> commandQueue;
@property (strong) id<MTLCommandQueue> blitCommandQueue;
@property (strong) id<MTLBuffer> vertexBuffer;
@property (readonly) EncoderManager * encoderManager;
@property (strong)MTLPipelineStatesStorage* pipelineStateStorage;
@property (strong)MTLTexturePool* texturePool;
- (MTLCommandBufferWrapper *) getCommandBufferWrapper; // creates command buffer wrapper (when doesn't exist)
- (MTLCommandBufferWrapper *) pullCommandBufferWrapper; // returns current buffer wrapper with loosing object ownership
/**
* Fetches the MTLContext associated with the given destination surface,
* makes the context current for those surfaces, updates the destination
* viewport, and then returns a pointer to the MTLContext.
*/
+ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst;
- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib;
- (void)dealloc;
/**
* Resets the current clip state (disables both scissor and depth tests).
*/
- (void)resetClip;
/**
* Sets the Metal scissor bounds to the provided rectangular clip bounds.
*/
- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2;
- (const MTLScissorRect *)clipRect;
/**
* Sets up a complex (shape) clip using the Metal stencil buffer. This
* method prepares the stencil buffer so that the clip Region spans can
* be "rendered" into it. The stencil buffer is first cleared, then the
* stencil func is setup so that when we render the clip spans,
* nothing is rendered into the color buffer, but for each pixel that would
* be rendered, a 0xFF value is placed into that location in the stencil
* buffer. With stencil test enabled, pixels will only be rendered into the
* color buffer if the corresponding value at that (x,y) location in the
* stencil buffer is equal to 0xFF.
*/
- (void)beginShapeClip:(BMTLSDOps *)dstOps;
/**
* Finishes setting up the shape clip by resetting the stencil func
* so that future rendering operations will once again be encoded for the
* color buffer (while respecting the clip set up in the stencil buffer).
*/
- (void)endShapeClip:(BMTLSDOps *)dstOps;
/**
* Initializes the OpenGL state responsible for applying extra alpha. This
* step is only necessary for any operation that uses glDrawPixels() or
* glCopyPixels() with a non-1.0f extra alpha value. Since the source is
* always premultiplied, we apply the extra alpha value to both alpha and
* color components using GL_*_SCALE.
*/
- (void)setExtraAlpha:(jfloat)ea;
/**
* Resets all OpenGL compositing state (disables blending and logic
* operations).
*/
- (void)resetComposite;
/**
* Initializes the OpenGL blending state. XOR mode is disabled and the
* appropriate blend functions are setup based on the AlphaComposite rule
* constant.
*/
- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)extraAlpha
flags:(jint)flags;
/**
* Returns autorelease string with composite description (for debugging only)
*/
- (NSString*)getCompositeDescription;
/**
* Returns autorelease string with paint description (for debugging only)
*/
- (NSString*)getPaintDescription;
/**
* Initializes the OpenGL logic op state to XOR mode. Blending is disabled
* before enabling logic op mode. The XOR pixel value will be applied
* later in the MTLContext_SetColor() method.
*/
- (void)setXorComposite:(jint)xorPixel;
- (jboolean)useXORComposite;
/**
* Resets the OpenGL transform state back to the identity matrix.
*/
- (void)resetTransform;
/**
* Initializes the OpenGL transform state by setting the modelview transform
* using the given matrix parameters.
*
* REMIND: it may be worthwhile to add serial id to AffineTransform, so we
* could do a quick check to see if the xform has changed since
* last time... a simple object compare won't suffice...
*/
- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10
M01:(jdouble) m01 M11:(jdouble) m11
M02:(jdouble) m02 M12:(jdouble) m12;
/**
* Initializes a small texture tile for use with tiled blit operations (see
* MTLBlitLoops.c and MTLMaskBlit.c for usage examples). The texture ID for
* the tile is stored in the given MTLContext. The tile is initially filled
* with garbage values, but the tile is updated as needed (via
* glTexSubImage2D()) with real RGBA values used in tiled blit situations.
* The internal format for the texture is GL_RGBA8, which should be sufficient
* for storing system memory surfaces of any known format (see PixelFormats
* for a list of compatible surface formats).
*/
- (jboolean)initBlitTileTexture;
/**
* Creates a 2D texture of the given format and dimensions and returns the
* texture object identifier. This method is typically used to create a
* temporary texture for intermediate work, such as in the
* MTLContext_InitBlitTileTexture() method below.
*/
- (jint)createBlitTextureFormat:(jint)internalFormat pixelFormat:(jint)pixelFormat
width:(jint)width height:(jint)height;
- (void)destroyContextResources;
- (void)resetPaint;
- (void)setColorPaint:(int)pixel;
- (void)setGradientPaintUseMask:(jboolean)useMask
cyclic:(jboolean)cyclic
p0:(jdouble)p0
p1:(jdouble)p1
p3:(jdouble)p3
pixel1:(jint)pixel1
pixel2:(jint) pixel2;
- (void)setLinearGradientPaint:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jint)cycleMethod
numStops:(jint)numStops
p0:(jfloat)p0
p1:(jfloat)p1
p3:(jfloat)p3
fractions:(jfloat *)fractions
pixels:(jint *)pixels;
- (void)setRadialGradientPaint:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jboolean)cycleMethod
numStops:(jint)numStops
m00:(jfloat)m00
m01:(jfloat)m01
m02:(jfloat)m02
m10:(jfloat)m10
m11:(jfloat)m11
m12:(jfloat)m12
focusX:(jfloat)focusX
fractions:(void *)fractions
pixels:(void *)pixels;
- (void)setTexturePaint:(jboolean)useMask
pSrcOps:(jlong)pSrcOps
filter:(jboolean)filter
xp0:(jdouble)xp0
xp1:(jdouble)xp1
xp3:(jdouble)xp3
yp0:(jdouble)yp0
yp1:(jdouble)yp1
yp3:(jdouble)yp3;
// Sets current image conversion operation (instance of MTLConvolveOp, MTLRescaleOp, MTLLookupOp).
// Used only in MTLIsoBlit (to blit image with some conversion). Pattern of usage: enableOp -> IsoBlit -> disableOp.
// TODO: Need to remove it from MTLContext and pass it as an argument for IsoBlit (because it's more
// simple and clear)
-(void)setBufImgOp:(NSObject*)bufImgOp;
-(NSObject*)getBufImgOp;
- (id<MTLCommandBuffer>)createCommandBuffer;
- (id<MTLCommandBuffer>)createBlitCommandBuffer;
@end
/**
* See BufferedContext.java for more on these flags...
*/
#define MTLC_NO_CONTEXT_FLAGS \
sun_java2d_pipe_BufferedContext_NO_CONTEXT_FLAGS
#define MTLC_SRC_IS_OPAQUE \
sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
#define MTLC_USE_MASK \
sun_java2d_pipe_BufferedContext_USE_MASK
#endif /* MTLContext_h_Included */

View File

@@ -0,0 +1,474 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include <stdlib.h>
#include "sun_java2d_SunGraphics2D.h"
#include "jlong.h"
#import "MTLContext.h"
#include "MTLRenderQueue.h"
extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo);
static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
{{-1.0, 1.0}, {0.0, 0.0}},
{{1.0, 1.0}, {1.0, 0.0}},
{{1.0, -1.0}, {1.0, 1.0}},
{{1.0, -1.0}, {1.0, 1.0}},
{{-1.0, -1.0}, {0.0, 1.0}},
{{-1.0, 1.0}, {0.0, 0.0}}
};
MTLTransform* tempTransform = nil;
@implementation MTLCommandBufferWrapper {
id<MTLCommandBuffer> _commandBuffer;
NSMutableArray * _pooledTextures;
}
- (id) initWithCommandBuffer:(id<MTLCommandBuffer>)cmdBuf {
self = [super init];
if (self) {
_commandBuffer = [cmdBuf retain];
_pooledTextures = [[NSMutableArray alloc] init];
}
return self;
}
- (id<MTLCommandBuffer>) getCommandBuffer {
return _commandBuffer;
}
- (void) onComplete { // invoked from completion handler in some pooled thread
for (int c = 0; c < [_pooledTextures count]; ++c)
[[_pooledTextures objectAtIndex:c] releaseTexture];
[_pooledTextures removeAllObjects];
}
- (void) registerPooledTexture:(MTLPooledTextureHandle *)handle {
[_pooledTextures addObject:handle];
}
- (void) dealloc {
[self onComplete];
[self->_pooledTextures release];
[self->_commandBuffer release];
[super dealloc];
}
@end
@implementation MTLContext {
MTLCommandBufferWrapper * _commandBufferWrapper;
MTLComposite * _composite;
MTLPaint * _paint;
MTLTransform * _transform;
MTLTransform * _tempTransform;
MTLClip * _clip;
NSObject* _bufImgOp; // TODO: pass as parameter of IsoBlit
EncoderManager * _encoderManager;
}
@synthesize textureFunction,
vertexCacheEnabled, aaEnabled, device, library, pipelineStateStorage,
commandQueue, blitCommandQueue, vertexBuffer,
texturePool, paint=_paint;
extern void initSamplers(id<MTLDevice> device);
- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib {
self = [super init];
if (self) {
// Initialization code here.
device = d;
texturePool = [[MTLTexturePool alloc] initWithDevice:device];
pipelineStateStorage = [[MTLPipelineStatesStorage alloc] initWithDevice:device shaderLibPath:shadersLib];
vertexBuffer = [device newBufferWithBytes:verts
length:sizeof(verts)
options:MTLResourceCPUCacheModeDefaultCache];
NSError *error = nil;
library = [device newLibraryWithFile:shadersLib error:&error];
if (!library) {
NSLog(@"Failed to load library. error %@", error);
exit(0);
}
_encoderManager = [[EncoderManager alloc] init];
[_encoderManager setContext:self];
_composite = [[MTLComposite alloc] init];
_paint = [[MTLPaint alloc] init];
_transform = [[MTLTransform alloc] init];
_clip = [[MTLClip alloc] init];
_bufImgOp = nil;
_commandBufferWrapper = nil;
// Create command queue
commandQueue = [device newCommandQueue];
blitCommandQueue = [device newCommandQueue];
_tempTransform = [[MTLTransform alloc] init];
initSamplers(device);
}
return self;
}
- (void)dealloc {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc");
self.texturePool = nil;
self.library = nil;
self.vertexBuffer = nil;
self.commandQueue = nil;
self.blitCommandQueue = nil;
self.pipelineStateStorage = nil;
[_encoderManager release];
[_composite release];
[_paint release];
[_transform release];
[_tempTransform release];
[_clip release];
[super dealloc];
}
- (MTLCommandBufferWrapper *) getCommandBufferWrapper {
if (_commandBufferWrapper == nil) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext : commandBuffer is NULL");
// NOTE: Command queues are thread-safe and allow multiple outstanding command buffers to be encoded simultaneously.
_commandBufferWrapper = [[MTLCommandBufferWrapper alloc] initWithCommandBuffer:[self.commandQueue commandBuffer]];// released in [layer blitTexture]
}
return _commandBufferWrapper;
}
- (MTLCommandBufferWrapper *) pullCommandBufferWrapper {
MTLCommandBufferWrapper * result = _commandBufferWrapper;
_commandBufferWrapper = nil;
return result;
}
+ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst {
BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrc);
BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDst);
MTLContext *mtlc = NULL;
if (srcOps == NULL || dstOps == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_SetSurfaces: ops are null");
return NULL;
}
J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLContext_SetSurfaces: bsrc=%p (tex=%p type=%d), bdst=%p (tex=%p type=%d)", srcOps, srcOps->pTexture, srcOps->drawableType, dstOps, dstOps->pTexture, dstOps->drawableType);
if (dstOps->drawableType == MTLSD_TEXTURE) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLContext_SetSurfaces: texture cannot be used as destination");
return NULL;
}
if (dstOps->drawableType == MTLSD_UNDEFINED) {
// initialize the surface as an OGLSD_WINDOW
if (!MTLSD_InitMTLWindow(env, dstOps)) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLContext_SetSurfaces: could not init OGL window");
return NULL;
}
}
// make the context current
MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps;
mtlc = dstCGLOps->configInfo->context;
if (mtlc == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLContext_SetSurfaces: could not make context current");
return NULL;
}
// perform additional one-time initialization, if necessary
if (dstOps->needsInit) {
if (dstOps->isOpaque) {
// in this case we are treating the destination as opaque, but
// to do so, first we need to ensure that the alpha channel
// is filled with fully opaque values (see 6319663)
//MTLContext_InitAlphaChannel();
}
dstOps->needsInit = JNI_FALSE;
}
return mtlc;
}
- (void)resetClip {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetClip");
[_clip reset];
}
- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 {
J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setClipRect: %d,%d - %d,%d", x1, y1, x2, y2);
[_clip setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2];
}
- (void)beginShapeClip:(BMTLSDOps *)dstOps {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.beginShapeClip");
[_clip beginShapeClip:dstOps context:self];
// Store the current transform as we need to use identity transform
// for clip spans rendering
[_tempTransform copyFrom:_transform];
[self resetTransform];
}
- (void)endShapeClip:(BMTLSDOps *)dstOps {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.endShapeClip");
[_clip endShapeClip:dstOps context:self];
// Reset transform for further rendering
[_transform copyFrom:_tempTransform];
}
- (void)resetComposite {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext_ResetComposite");
[_composite reset];
}
- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)extraAlpha
flags:(jint)flags {
J2dTraceLn3(J2D_TRACE_INFO, "MTLContext_SetAlphaComposite: rule=%d, extraAlpha=%1.2f, flags=%d", rule, extraAlpha, flags);
[_composite setRule:rule extraAlpha:extraAlpha];
}
- (NSString*)getCompositeDescription {
return [_composite getDescription];
}
- (NSString*)getPaintDescription {
return [_paint getDescription];
}
- (void)setXorComposite:(jint)xp {
J2dTraceLn1(J2D_TRACE_INFO, "MTLContext.setXorComposite: xorPixel=%08x", xp);
[_composite setXORComposite:xp];
}
- (jboolean) useXORComposite {
return ([_composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR);
}
- (void)resetTransform {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetTransform");
[_transform resetTransform];
}
- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10
M01:(jdouble) m01 M11:(jdouble) m11
M02:(jdouble) m02 M12:(jdouble) m12 {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext_SetTransform");
[_transform setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12];
}
- (jboolean)initBlitTileTexture {
//TODO
J2dTraceLn(J2D_TRACE_INFO, "MTLContext_InitBlitTileTexture -- :TODO");
return JNI_TRUE;
}
- (jint)createBlitTextureFormat:(jint)internalFormat pixelFormat:(jint)pixelFormat
width:(jint)width height:(jint)height {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext_InitBlitTileTexture -- :TODO");
//TODO
return 0;
}
- (void)resetPaint {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetPaint");
self.paint = [[[MTLPaint alloc] init] autorelease];
}
- (void)setColorPaint:(int)pixel {
J2dTraceLn5(J2D_TRACE_INFO, "MTLContext.setColorPaint: pixel=%08x [r=%d g=%d b=%d a=%d]", pixel, (pixel >> 16) & (0xFF), (pixel >> 8) & 0xFF, (pixel) & 0xFF, (pixel >> 24) & 0xFF);
self.paint = [[[MTLColorPaint alloc] initWithColor:pixel] autorelease];
}
- (void)setGradientPaintUseMask:(jboolean)useMask
cyclic:(jboolean)cyclic
p0:(jdouble)p0
p1:(jdouble)p1
p3:(jdouble)p3
pixel1:(jint)pixel1
pixel2:(jint) pixel2
{
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setGradientPaintUseMask");
self.paint = [[[MTLGradPaint alloc] initWithUseMask:useMask
cyclic:cyclic
p0:p0
p1:p1
p3:p3
pixel1:pixel1
pixel2:pixel2] autorelease];
}
- (void)setLinearGradientPaint:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jint)cycleMethod
// 0 - NO_CYCLE
// 1 - REFLECT
// 2 - REPEAT
numStops:(jint)numStops
p0:(jfloat)p0
p1:(jfloat)p1
p3:(jfloat)p3
fractions:(jfloat*)fractions
pixels:(jint*)pixels
{
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setLinearGradientPaint");
self.paint = [[[MTLLinearGradPaint alloc] initWithUseMask:useMask
linear:linear
cycleMethod:cycleMethod
numStops:numStops
p0:p0
p1:p1
p3:p3
fractions:fractions
pixels:pixels] autorelease];
}
- (void)setRadialGradientPaint:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jboolean)cycleMethod
numStops:(jint)numStops
m00:(jfloat)m00
m01:(jfloat)m01
m02:(jfloat)m02
m10:(jfloat)m10
m11:(jfloat)m11
m12:(jfloat)m12
focusX:(jfloat)focusX
fractions:(void *)fractions
pixels:(void *)pixels
{
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.setRadialGradientPaint");
self.paint = [[[MTLRadialGradPaint alloc] initWithUseMask:useMask
linear:linear
cycleMethod:cycleMethod
numStops:numStops
m00:m00
m01:m01
m02:m02
m10:m10
m11:m11
m12:m12
focusX:focusX
fractions:fractions
pixels:pixels] autorelease];
}
- (void)setTexturePaint:(jboolean)useMask
pSrcOps:(jlong)pSrcOps
filter:(jboolean)filter
xp0:(jdouble)xp0
xp1:(jdouble)xp1
xp3:(jdouble)xp3
yp0:(jdouble)yp0
yp1:(jdouble)yp1
yp3:(jdouble)yp3
{
BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps);
if (srcOps == NULL || srcOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_setTexturePaint: texture paint - texture is null");
return;
}
J2dTraceLn1(J2D_TRACE_INFO, "MTLContext.setTexturePaint [tex=%p]", srcOps->pTexture);
self.paint = [[[MTLTexturePaint alloc] initWithUseMask:useMask
textureID:srcOps->pTexture
filter:filter
xp0:xp0
xp1:xp1
xp3:xp3
yp0:yp0
yp1:yp1
yp3:yp3] autorelease] ;
}
- (id<MTLCommandBuffer>)createCommandBuffer {
return [self.commandQueue commandBuffer];
}
/*
* This should be exclusively used only for final blit
* and present of CAMetalDrawable in MTLLayer
*/
- (id<MTLCommandBuffer>)createBlitCommandBuffer {
return [self.blitCommandQueue commandBuffer];
}
-(void)setBufImgOp:(NSObject*)bufImgOp {
if (_bufImgOp != nil) {
[_bufImgOp release]; // context owns bufImgOp object
}
_bufImgOp = bufImgOp;
}
-(NSObject*)getBufImgOp {
return _bufImgOp;
}
@end
/*
* Class: sun_java2d_metal_MTLContext
* Method: getMTLIdString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sun_java2d_metal_MTLContext_getMTLIdString
(JNIEnv *env, jclass mtlcc)
{
char *vendor, *renderer, *version;
char *pAdapterId;
jobject ret = NULL;
int len;
return NULL;
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLFuncs_h_Included
#define MTLFuncs_h_Included
#ifdef MACOSX
#include <dlfcn.h>
#endif
#include "jni.h"
#include "Trace.h"
jboolean MTLFuncs_OpenLibrary();
void MTLFuncs_CloseLibrary();
jboolean MTLFuncs_InitPlatformFuncs();
jboolean MTLFuncs_InitBaseFuncs();
jboolean MTLFuncs_InitExtFuncs();
#endif /* MTLFuncs_h_Included */

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include "MTLFuncs.h"
jboolean
MTLFuncs_OpenLibrary()
{
//TODO
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_OpenLibrary");
return JNI_TRUE;
}
void
MTLFuncs_CloseLibrary()
{
//TODO
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_CloseLibrary");
}
jboolean
MTLFuncs_InitPlatformFuncs()
{
//TODO
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitPlatformFuncs");
return JNI_TRUE;
}
jboolean
MTLFuncs_InitBaseFuncs()
{
//TODO
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitBaseFuncs");
return JNI_TRUE;
}
jboolean
MTLFuncs_InitExtFuncs()
{
//TODO
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitExtFuncs");
return JNI_TRUE;
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLGlyphCache_h_Included
#define MTLGlyphCache_h_Included
#ifdef __cplusplus
extern "C" {
#endif
#include "jni.h"
#include "fontscalerdefs.h"
#import <Metal/Metal.h>
typedef void (MTLFlushFunc)();
typedef struct _MTLCacheCellInfo MTLCacheCellInfo;
typedef struct {
CacheCellInfo *head;
CacheCellInfo *tail;
id<MTLTexture> texture;
jint width;
jint height;
jint cellWidth;
jint cellHeight;
MTLFlushFunc *Flush;
} MTLGlyphCacheInfo;
struct _MTLCacheCellInfo {
MTLGlyphCacheInfo *cacheInfo;
struct GlyphInfo *glyphInfo;
// next cell info in the cache's list
MTLCacheCellInfo *next;
// REMIND: find better name?
// next cell info in the glyph's cell list (next Glyph Cache Info)
MTLCacheCellInfo *nextGCI;
jint timesRendered;
jint x;
jint y;
// number of pixels from the left or right edge not considered touched
// by the glyph
jint leftOff;
jint rightOff;
jfloat tx1;
jfloat ty1;
jfloat tx2;
jfloat ty2;
};
MTLGlyphCacheInfo *
MTLGlyphCache_Init(jint width, jint height,
jint cellWidth, jint cellHeight,
MTLFlushFunc *func);
MTLCacheCellInfo *
MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, struct GlyphInfo *glyph);
bool
MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph);
void
MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache);
void
MTLGlyphCache_AddCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo);
void
MTLGlyphCache_RemoveCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo);
MTLCacheCellInfo *
MTLGlyphCache_GetCellInfoForCache(struct GlyphInfo *glyph,
MTLGlyphCacheInfo *cache);
JNIEXPORT void
MTLGlyphCache_RemoveAllCellInfos(struct GlyphInfo *glyph);
void
MTLGlyphCache_Free(MTLGlyphCacheInfo *cache);
#ifdef __cplusplus
};
#endif
#endif /* MTLGlyphCache_h_Included */

View File

@@ -0,0 +1,365 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdlib.h>
#include "jni.h"
#include "MTLGlyphCache.h"
#include "Trace.h"
/**
* When the cache is full, we will try to reuse the cache cells that have
* been used relatively less than the others (and we will save the cells that
* have been rendered more than the threshold defined here).
*/
#define TIMES_RENDERED_THRESHOLD 5
/**
* Creates a new GlyphCacheInfo structure, fills in the initial values, and
* then returns a pointer to the GlyphCacheInfo record.
*
* Note that this method only sets up a data structure describing a
* rectangular region of accelerated memory, containing "virtual" cells of
* the requested size. The cell information is added lazily to the linked
* list describing the cache as new glyphs are added. Platform specific
* glyph caching code is responsible for actually creating the accelerated
* memory surface that will contain the individual glyph images.
*
* Each glyph contains a reference to a list of cell infos - one per glyph
* cache. There may be multiple glyph caches (for example, one per graphics
* adapter), so if the glyph is cached on two devices its cell list will
* consists of two elements corresponding to different glyph caches.
*
* The platform-specific glyph caching code is supposed to use
* GetCellInfoForCache method for retrieving cache infos from the glyph's list.
*
* Note that if it is guaranteed that there will be only one global glyph
* cache then it one does not have to use AccelGlyphCache_GetCellInfoForCache
* for retrieving cell info for the glyph, but instead just use the struct's
* field directly.
*/
MTLGlyphCacheInfo *
MTLGlyphCache_Init(jint width, jint height,
jint cellWidth, jint cellHeight,
MTLFlushFunc *func)
{
MTLGlyphCacheInfo *gcinfo;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Init");
gcinfo = (MTLGlyphCacheInfo *)malloc(sizeof(MTLGlyphCacheInfo));
if (gcinfo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLGlyphCache_Init: could not allocate MTLGlyphCacheInfo");
return NULL;
}
gcinfo->head = NULL;
gcinfo->tail = NULL;
gcinfo->width = width;
gcinfo->height = height;
gcinfo->cellWidth = cellWidth;
gcinfo->cellHeight = cellHeight;
gcinfo->Flush = func;
return gcinfo;
}
/**
* Attempts to add the provided glyph to the specified cache. If the
* operation is successful, a pointer to the newly occupied cache cell is
* stored in the glyph's cellInfo field; otherwise, its cellInfo field is
* set to NULL, indicating that the glyph's original bits should be rendered
* instead. If the cache is full, the least-recently-used glyph is
* invalidated and its cache cell is reassigned to the new glyph being added.
*
* Note that this method only ensures that a rectangular region in the
* "virtual" glyph cache is available for the glyph image. Platform specific
* glyph caching code is responsible for actually caching the glyph image
* in the associated accelerated memory surface.
*
* Returns created cell info if it was successfully created and added to the
* cache and glyph's cell lists, NULL otherwise.
*/
MTLCacheCellInfo *
MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
{
MTLCacheCellInfo *cellinfo = NULL;
jint w = glyph->width;
jint h = glyph->height;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_AddGlyph");
if ((glyph->width > cache->cellWidth) ||
(glyph->height > cache->cellHeight))
{
return NULL;
}
jint x, y;
if (cache->head == NULL) {
x = 0;
y = 0;
} else {
x = cache->tail->x + cache->cellWidth;
y = cache->tail->y;
if ((x + cache->cellWidth) > cache->width) {
x = 0;
y += cache->cellHeight;
}
}
// create new CacheCellInfo
cellinfo = (MTLCacheCellInfo *)malloc(sizeof(MTLCacheCellInfo));
if (cellinfo == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "could not allocate CellInfo");
return NULL;
}
cellinfo->cacheInfo = cache;
cellinfo->glyphInfo = glyph;
cellinfo->timesRendered = 0;
cellinfo->x = x;
cellinfo->y = y;
cellinfo->leftOff = 0;
cellinfo->rightOff = 0;
cellinfo->tx1 = (jfloat)cellinfo->x / cache->width;
cellinfo->ty1 = (jfloat)cellinfo->y / cache->height;
cellinfo->tx2 = cellinfo->tx1 + ((jfloat)w / cache->width);
cellinfo->ty2 = cellinfo->ty1 + ((jfloat)h / cache->height);
if (cache->head == NULL) {
// initialize the head cell
cache->head = cellinfo;
} else {
// update existing tail cell
cache->tail->next = cellinfo;
}
// add the new cell to the end of the list
cache->tail = cellinfo;
cellinfo->next = NULL;
cellinfo->nextGCI = NULL;
// add cache cell to the glyph's cells list
MTLGlyphCache_AddCellInfo(glyph, cellinfo);
return cellinfo;
}
bool
MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
{
jint w = glyph->width;
jint h = glyph->height;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_IsCacheFull");
jint x, y;
if (cache->head == NULL) {
return JNI_FALSE;
} else {
x = cache->tail->x + cache->cellWidth;
y = cache->tail->y;
if ((x + cache->cellWidth) > cache->width) {
x = 0;
y += cache->cellHeight;
if ((y + cache->cellHeight) > cache->height) {
return JNI_TRUE;
}
}
}
return JNI_FALSE;
}
/**
* Invalidates all cells in the cache. Note that this method does not
* attempt to compact the cache in any way; it just invalidates any cells
* that already exist.
*/
void
MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache)
{
MTLCacheCellInfo *cellinfo;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Invalidate");
if (cache == NULL) {
return;
}
// flush any pending vertices that may be depending on the current
// glyph cache layout
if (cache->Flush != NULL) {
cache->Flush();
}
cellinfo = cache->head;
while (cellinfo != NULL) {
if (cellinfo->glyphInfo != NULL) {
// if the cell is occupied, notify the base glyph that its
// cached version for this cache is about to be invalidated
MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
}
cellinfo = cellinfo->next;
}
}
/**
* Invalidates and frees all cells and the cache itself. The "cache" pointer
* becomes invalid after this function returns.
*/
void
MTLGlyphCache_Free(MTLGlyphCacheInfo *cache)
{
MTLCacheCellInfo *cellinfo;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Free");
if (cache == NULL) {
return;
}
// flush any pending vertices that may be depending on the current
// glyph cache
if (cache->Flush != NULL) {
cache->Flush();
}
while (cache->head != NULL) {
cellinfo = cache->head;
if (cellinfo->glyphInfo != NULL) {
// if the cell is occupied, notify the base glyph that its
// cached version for this cache is about to be invalidated
MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
}
cache->head = cellinfo->next;
free(cellinfo);
}
free(cache);
}
/**
* Add cell info to the head of the glyph's list of cached cells.
*/
void
MTLGlyphCache_AddCellInfo(GlyphInfo *glyph, MTLCacheCellInfo *cellInfo)
{
// assert (glyph != NULL && cellInfo != NULL)
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_AddCellInfo");
J2dTraceLn2(J2D_TRACE_VERBOSE, " glyph 0x%x: adding cell 0x%x to the list",
glyph, cellInfo);
cellInfo->glyphInfo = glyph;
cellInfo->nextGCI = glyph->cellInfo;
glyph->cellInfo = cellInfo;
glyph->managed = MANAGED_GLYPH;
}
/**
* Removes cell info from the glyph's list of cached cells.
*/
void
MTLGlyphCache_RemoveCellInfo(GlyphInfo *glyph, MTLCacheCellInfo *cellInfo)
{
MTLCacheCellInfo *currCellInfo = glyph->cellInfo;
MTLCacheCellInfo *prevInfo = NULL;
// assert (glyph!= NULL && glyph->cellInfo != NULL && cellInfo != NULL)
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_RemoveCellInfo");
do {
if (currCellInfo == cellInfo) {
J2dTraceLn2(J2D_TRACE_VERBOSE,
" glyph 0x%x: removing cell 0x%x from glyph's list",
glyph, currCellInfo);
if (prevInfo == NULL) { // it's the head, chop-chop
glyph->cellInfo = currCellInfo->nextGCI;
} else {
prevInfo->nextGCI = currCellInfo->nextGCI;
}
currCellInfo->glyphInfo = NULL;
currCellInfo->nextGCI = NULL;
return;
}
prevInfo = currCellInfo;
currCellInfo = currCellInfo->nextGCI;
} while (currCellInfo != NULL);
J2dTraceLn2(J2D_TRACE_WARNING, "MTLGlyphCache_RemoveCellInfo: "\
"no cell 0x%x in glyph 0x%x's cell list",
cellInfo, glyph);
}
/**
* Removes cell info from the glyph's list of cached cells.
*/
JNIEXPORT void
MTLGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph)
{
MTLCacheCellInfo *currCell, *prevCell;
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_RemoveAllCellInfos");
if (glyph == NULL || glyph->cellInfo == NULL) {
return;
}
// invalidate all of this glyph's accelerated cache cells
currCell = glyph->cellInfo;
do {
currCell->glyphInfo = NULL;
prevCell = currCell;
currCell = currCell->nextGCI;
prevCell->nextGCI = NULL;
} while (currCell != NULL);
glyph->cellInfo = NULL;
}
/**
* Returns cell info associated with particular cache from the glyph's list of
* cached cells.
*/
MTLCacheCellInfo *
MTLGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, MTLGlyphCacheInfo *cache)
{
// assert (glyph != NULL && cache != NULL)
J2dTraceLn(J2D_TRACE_VERBOSE2, "MTLGlyphCache_GetCellInfoForCache");
if (glyph->cellInfo != NULL) {
MTLCacheCellInfo *cellInfo = glyph->cellInfo;
do {
if (cellInfo->cacheInfo == cache) {
J2dTraceLn3(J2D_TRACE_VERBOSE2,
" glyph 0x%x: found cell 0x%x for cache 0x%x",
glyph, cellInfo, cache);
return cellInfo;
}
cellInfo = cellInfo->nextGCI;
} while (cellInfo != NULL);
}
J2dTraceLn2(J2D_TRACE_VERBOSE2, " glyph 0x%x: no cell for cache 0x%x",
glyph, cache);
return NULL;
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLGraphicsConfig_h_Included
#define MTLGraphicsConfig_h_Included
#import "jni.h"
#import "MTLSurfaceDataBase.h"
#import "MTLContext.h"
#import <Cocoa/Cocoa.h>
#import <Metal/Metal.h>
@interface MTLGraphicsConfigUtil : NSObject {}
+ (void) _getMTLConfigInfo: (NSMutableArray *)argValue;
@end
// REMIND: Using an NSOpenGLPixelBuffer as the scratch surface has been
// problematic thus far (seeing garbage and flickering when switching
// between an NSView and the scratch surface), so the following enables
// an alternate codepath that uses a hidden NSWindow/NSView as the scratch
// surface, for the purposes of making a context current in certain
// situations. It appears that calling [NSOpenGLContext setView] too
// frequently contributes to the bad behavior, so we should try to avoid
// switching to the scratch surface whenever possible.
/* Do we need this if we are using all off-screen drawing ? */
#define USE_NSVIEW_FOR_SCRATCH 1
/* Uncomment to have an additional CAOGLLayer instance tied to
* each instance, which can be used to test remoting the layer
* to an out of process window. The additional layer is needed
* because a layer can only be attached to one context (view/window).
* This is only for testing purposes and can be removed if/when no
* longer needed.
*/
/**
* The MTLGraphicsConfigInfo structure contains information specific to a
* given CGLGraphicsConfig (pixel format).
*
* jint screen;
* The screen and PixelFormat for the associated CGLGraphicsConfig.
*
* NSOpenGLPixelFormat *pixfmt;
* The pixel format of the native NSOpenGL context.
*
* MTLContext *context;
* The context associated with this CGLGraphicsConfig.
*/
typedef struct _MTLGraphicsConfigInfo {
jint screen;
NSOpenGLPixelFormat *pixfmt;
MTLContext *context;
} MTLGraphicsConfigInfo;
// From "Metal Feature Set Tables"
// There are 2 GPU families for mac - MTLGPUFamilyMac1 and MTLGPUFamilyMac2
// Both of them support "Maximum 2D texture width and height" of 16384 pixels
// Note : there is no API to get this value, hence hardcoding by reading from the table
#define MaxTextureSize 16384
#endif /* MTLGraphicsConfig_h_Included */

View File

@@ -0,0 +1,222 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "sun_java2d_metal_MTLGraphicsConfig.h"
#import "MTLGraphicsConfig.h"
#import "MTLSurfaceData.h"
#import "ThreadUtilities.h"
#import "awt.h"
#import <stdlib.h>
#import <string.h>
#import <ApplicationServices/ApplicationServices.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#pragma mark -
#pragma mark "--- Mac OS X specific methods for GL pipeline ---"
/**
* Disposes all memory and resources associated with the given
* CGLGraphicsConfigInfo (including its native MTLContext data).
*/
void
MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo)
{
J2dTraceLn(J2D_TRACE_INFO, "MTLGC_DestroyMTLGraphicsConfig");
MTLGraphicsConfigInfo *mtlinfo =
(MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
if (mtlinfo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLGC_DestroyMTLGraphicsConfig: info is null");
return;
}
MTLContext *mtlc = (MTLContext*)mtlinfo->context;
if (mtlc != NULL) {
[mtlinfo->context release];
mtlinfo->context = nil;
}
free(mtlinfo);
}
#pragma mark -
#pragma mark "--- MTLGraphicsConfig methods ---"
/**
* Attempts to initialize CGL and the core OpenGL library.
*/
JNIEXPORT jboolean JNICALL
Java_sun_java2d_metal_MTLGraphicsConfig_initMTL
(JNIEnv *env, jclass cglgc)
{
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_initMTL");
FILE *f = popen("/usr/sbin/system_profiler SPDisplaysDataType", "r");
bool metalSupport = FALSE;
while (getc(f) != EOF)
{
char str[60];
if (fgets(str, 60, f) != NULL) {
// Check for string
// "Metal: Supported, feature set macOS GPUFamily1 v4"
if (strstr(str, "Metal") != NULL) {
puts(str);
metalSupport = JNI_TRUE;
break;
}
}
}
pclose(f);
if (!metalSupport) {
fprintf(stderr, "Metal support not present\n");
} else {
fprintf(stderr, "Metal support is present\n");
}
if (!MTLFuncs_OpenLibrary()) {
return JNI_FALSE;
}
if (!MTLFuncs_InitPlatformFuncs() ||
!MTLFuncs_InitBaseFuncs() ||
!MTLFuncs_InitExtFuncs())
{
MTLFuncs_CloseLibrary();
return JNI_FALSE;
}
return JNI_TRUE;
}
/**
* Determines whether the CGL pipeline can be used for a given GraphicsConfig
* provided its screen number and visual ID. If the minimum requirements are
* met, the native CGLGraphicsConfigInfo structure is initialized for this
* GraphicsConfig with the necessary information (pixel format, etc.)
* and a pointer to this structure is returned as a jlong. If
* initialization fails at any point, zero is returned, indicating that CGL
* cannot be used for this GraphicsConfig (we should fallback on an existing
* 2D pipeline).
*/
JNIEXPORT jlong JNICALL
Java_sun_java2d_metal_MTLGraphicsConfig_getMTLConfigInfo
(JNIEnv *env, jclass cglgc, jint displayID, jstring mtlShadersLib)
{
jlong ret = 0L;
JNF_COCOA_ENTER(env);
NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3];
[retArray addObject: [NSNumber numberWithInt: (int)displayID]];
[retArray addObject: [NSString stringWithUTF8String: JNU_GetStringPlatformChars(env, mtlShadersLib, 0)]];
if ([NSThread isMainThread]) {
[MTLGraphicsConfigUtil _getMTLConfigInfo: retArray];
} else {
[MTLGraphicsConfigUtil performSelectorOnMainThread: @selector(_getMTLConfigInfo:) withObject: retArray waitUntilDone: YES];
}
NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];
ret = (jlong)[num longValue];
JNF_COCOA_EXIT(env);
return ret;
}
@implementation MTLGraphicsConfigUtil
+ (void) _getMTLConfigInfo: (NSMutableArray *)argValue {
AWT_ASSERT_APPKIT_THREAD;
jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
NSString *mtlShadersLib = (NSString *)[argValue objectAtIndex: 1];
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
[argValue removeAllObjects];
J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_getMTLConfigInfo");
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSRect contentRect = NSMakeRect(0, 0, 64, 64);
NSWindow *window =
[[NSWindow alloc]
initWithContentRect: contentRect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered
defer: false];
if (window == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: NSWindow is NULL");
[argValue addObject: [NSNumber numberWithLong: 0L]];
return;
}
NSView *scratchSurface =
[[NSView alloc]
initWithFrame: contentRect];
if (scratchSurface == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: NSView is NULL");
[argValue addObject: [NSNumber numberWithLong: 0L]];
return;
}
[window setContentView: scratchSurface];
MTLContext *mtlc = [[MTLContext alloc] initWithDevice:CGDirectDisplayCopyCurrentMetalDevice(displayID)
shadersLib:mtlShadersLib];
if (mtlc == 0L) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGC_InitMTLContext: could not allocate memory for mtlc");
[argValue addObject: [NSNumber numberWithLong: 0L]];
return;
}
// create the MTLGraphicsConfigInfo record for this config
MTLGraphicsConfigInfo *mtlinfo = (MTLGraphicsConfigInfo *)malloc(sizeof(MTLGraphicsConfigInfo));
if (mtlinfo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not allocate memory for mtlinfo");
free(mtlc);
[argValue addObject: [NSNumber numberWithLong: 0L]];
return;
}
memset(mtlinfo, 0, sizeof(MTLGraphicsConfigInfo));
mtlinfo->screen = displayID;
mtlinfo->context = mtlc;
[argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(mtlinfo)]];
[pool drain];
}
@end //GraphicsConfigUtil
JNIEXPORT jint JNICALL
Java_sun_java2d_metal_MTLGraphicsConfig_nativeGetMaxTextureSize
(JNIEnv *env, jclass mtlgc)
{
J2dTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_nativeGetMaxTextureSize");
return (jint)MaxTextureSize;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLLayer_h_Included
#define MTLLayer_h_Included
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#import "common.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
@interface MTLLayer : CAMetalLayer
{
@private
JNFWeakJObjectWrapper *javaLayer;
// intermediate buffer, used the RQ lock to synchronize
MTLContext* ctx;
float bufferWidth;
float bufferHeight;
id<MTLTexture> buffer;
int nextDrawableCount;
int topInset;
int leftInset;
}
@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
@property (readwrite, assign) MTLContext* ctx;
@property (readwrite, assign) float bufferWidth;
@property (readwrite, assign) float bufferHeight;
@property (readwrite, assign) id<MTLTexture> buffer;
@property (readwrite, assign) int nextDrawableCount;
@property (readwrite, assign) int topInset;
@property (readwrite, assign) int leftInset;
- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
- (void) blitTexture;
- (void) fillParallelogramCtxX:(jfloat)x
Y:(jfloat)y
DX1:(jfloat)dx1
DY1:(jfloat)dy1
DX2:(jfloat)dx2
DY2:(jfloat)dy2;
- (void) blitCallback;
- (void) display;
@end
#endif /* CGLLayer_h_Included */

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "MTLGraphicsConfig.h"
#import "MTLLayer.h"
#import "ThreadUtilities.h"
#import "LWCToolkit.h"
#import "MTLSurfaceData.h"
@implementation MTLLayer
@synthesize javaLayer;
@synthesize ctx;
@synthesize bufferWidth;
@synthesize bufferHeight;
@synthesize buffer;
@synthesize topInset;
@synthesize leftInset;
@synthesize nextDrawableCount;
- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer
{
AWT_ASSERT_APPKIT_THREAD;
// Initialize ourselves
self = [super init];
if (self == nil) return self;
self.javaLayer = layer;
self.contentsGravity = kCAGravityTopLeft;
//Disable CALayer's default animation
NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
[NSNull null], @"anchorPoint",
[NSNull null], @"bounds",
[NSNull null], @"contents",
[NSNull null], @"contentsScale",
[NSNull null], @"onOrderIn",
[NSNull null], @"onOrderOut",
[NSNull null], @"position",
[NSNull null], @"sublayers",
nil];
self.actions = actions;
[actions release];
self.topInset = 0;
self.leftInset = 0;
self.framebufferOnly = NO;
self.nextDrawableCount = 0;
self.opaque = FALSE;
return self;
}
- (void) blitTexture {
if (self.ctx == NULL || self.javaLayer == NULL || self.buffer == nil || self.ctx.device == nil) {
J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: uninitialized (mtlc=%p, javaLayer=%p, buffer=%p, devide=%p)", self.ctx, self.javaLayer, self.buffer, ctx.device);
return;
}
if (self.nextDrawableCount != 0)
return;
@autoreleasepool {
if ((self.buffer.width == 0) || (self.buffer.height == 0)) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: cannot create drawable of size 0");
return;
}
id<MTLCommandBuffer> commandBuf = [self.ctx createBlitCommandBuffer];
if (commandBuf == nil) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: commandBuf is null");
return;
}
id<CAMetalDrawable> mtlDrawable = [self nextDrawable];
if (mtlDrawable == nil) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nextDrawable is null)");
return;
}
self.nextDrawableCount++;
id <MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder];
[blitEncoder
copyFromTexture:self.buffer sourceSlice:0 sourceLevel:0
sourceOrigin:MTLOriginMake((jint)(self.leftInset*self.contentsScale), (jint)(self.topInset*self.contentsScale), 0)
sourceSize:MTLSizeMake(self.buffer.width, self.buffer.height, 1)
toTexture:mtlDrawable.texture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(0, 0, 0)];
[blitEncoder endEncoding];
[commandBuf presentDrawable:mtlDrawable];
[commandBuf addCompletedHandler:^(id <MTLCommandBuffer> commandBuf) {
self.nextDrawableCount--;
}];
[commandBuf commit];
}
}
- (void) dealloc {
self.javaLayer = nil;
[super dealloc];
}
- (void) blitCallback {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/metal/MTLLayer");
static JNF_MEMBER_CACHE(jm_drawInMTLContext, jc_JavaLayer, "drawInMTLContext", "()V");
jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
return;
}
JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInMTLContext);
(*env)->DeleteLocalRef(env, javaLayerLocalRef);
}
- (void) display {
AWT_ASSERT_APPKIT_THREAD;
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_display() called");
[self blitCallback];
[super display];
}
@end
/*
* Class: sun_java2d_metal_MTLLayer
* Method: nativeCreateLayer
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_sun_java2d_metal_MTLLayer_nativeCreateLayer
(JNIEnv *env, jobject obj)
{
__block MTLLayer *layer = nil;
JNF_COCOA_ENTER(env);
JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
layer = [[MTLLayer alloc] initWithJavaLayer: javaLayer];
}];
JNF_COCOA_EXIT(env);
return ptr_to_jlong(layer);
}
// Must be called under the RQ lock.
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLLayer_validate
(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
{
MTLLayer *layer = OBJC(layerPtr);
if (surfaceData != NULL) {
BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData);
layer.bufferWidth = bmtlsdo->width;
layer.bufferHeight = bmtlsdo->width;
layer.buffer = bmtlsdo->pTexture;
layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
layer.device = layer.ctx.device;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
layer.drawableSize =
CGSizeMake(layer.buffer.width,
layer.buffer.height);
} else {
layer.ctx = NULL;
}
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLLayer_nativeSetScale
(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
{
JNF_COCOA_ENTER(env);
MTLLayer *layer = jlong_to_ptr(layerPtr);
// We always call all setXX methods asynchronously, exception is only in
// this method where we need to change native texture size and layer's scale
// in one call on appkit, otherwise we'll get window's contents blinking,
// during screen-2-screen moving.
[ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
layer.contentsScale = scale;
}];
JNF_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLLayer_nativeSetInsets
(JNIEnv *env, jclass cls, jlong layerPtr, jint top, jint left)
{
MTLLayer *layer = jlong_to_ptr(layerPtr);
layer.topInset = top;
layer.leftInset = left;
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLLayer_blitTexture
(JNIEnv *env, jclass cls, jlong layerPtr)
{
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blitTexture");
MTLLayer *layer = jlong_to_ptr(layerPtr);
MTLContext * ctx = layer.ctx;
if (layer == NULL || ctx == NULL) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_blit : Layer or Context is null");
return;
}
[layer blitTexture];
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLMaskBlit_h_Included
#define MTLMaskBlit_h_Included
#include "MTLContext.h"
void MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps,
jint dstx, jint dsty,
jint width, jint height,
void *pPixels);
#endif /* MTLMaskBlit_h_Included */

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include <stdlib.h>
#include <jlong.h>
#include "MTLMaskBlit.h"
#include "MTLRenderQueue.h"
#include "MTLBlitLoops.h"
/**
* REMIND: This method assumes that the dimensions of the incoming pixel
* array are less than or equal to the cached blit texture tile;
* these are rather fragile assumptions, and should be cleaned up...
*/
void
MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps,
jint dstx, jint dsty,
jint width, jint height,
void *pPixels)
{
J2dTraceLn(J2D_TRACE_INFO, "MTLMaskBlit_MaskBlit");
if (width <= 0 || height <= 0) {
J2dTraceLn(J2D_TRACE_WARNING, "MTLMaskBlit_MaskBlit: invalid dimensions");
return;
}
RETURN_IF_NULL(pPixels);
RETURN_IF_NULL(mtlc);
MTLPooledTextureHandle * texHandle = [mtlc.texturePool
getTexture:width
height:height
format:MTLPixelFormatBGRA8Unorm];
if (texHandle == nil) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLMaskBlit_MaskBlit: can't obtain temporary texture object from pool");
return;
}
[[mtlc getCommandBufferWrapper] registerPooledTexture:texHandle];
[texHandle release];
id<MTLTexture> texBuff = texHandle.texture;
MTLRegion region = MTLRegionMake2D(0, 0, width, height);
[texBuff replaceRegion:region mipmapLevel:0 withBytes:pPixels bytesPerRow:4*width];
drawTex2Tex(mtlc, texBuff, dstOps->pTexture, JNI_FALSE, dstOps->isOpaque, 0,
0, 0, width, height, dstx, dsty, dstx + width, dsty + height);
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLMaskFill_h_Included
#define MTLMaskFill_h_Included
#include "MTLContext.h"
void MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x, jint y, jint w, jint h,
jint maskoff, jint maskscan, jint masklen,
unsigned char *pMask);
#endif /* MTLMaskFill_h_Included */

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include "sun_java2d_metal_MTLMaskFill.h"
#include "MTLMaskFill.h"
#include "MTLRenderQueue.h"
#include "MTLVertexCache.h"
/**
* This implementation first copies the alpha tile into a texture and then
* maps that texture to the destination surface. This approach appears to
* offer the best performance despite being a two-step process.
*
* When the source paint is a Color, we can simply use the GL_MODULATE
* function to multiply the current color (already premultiplied with the
* extra alpha value from the AlphaComposite) with the alpha value from
* the mask texture tile. In picture form, this process looks like:
*
* A R G B
* primary color Pa Pr Pg Pb (modulated with...)
* texture unit 0 Ca Ca Ca Ca
* ---------------------------------------
* resulting color Ra Rr Rg Rb
*
* where:
* Px = current color (already premultiplied by extra alpha)
* Cx = coverage value from mask tile
* Rx = resulting color/alpha component
*
* When the source paint is not a Color, it means that we are rendering with
* a complex paint (e.g. GradientPaint, TexturePaint). In this case, we
* rely on the GL_ARB_multitexture extension to effectively multiply the
* paint fragments (autogenerated on texture unit 1, see the
* MTLPaints_Set{Gradient,Texture,etc}Paint() methods for more details)
* with the coverage values from the mask texture tile (provided on texture
* unit 0), all of which is multiplied with the current color value (which
* contains the extra alpha value). In picture form:
*
* A R G B
* primary color Ea Ea Ea Ea (modulated with...)
* texture unit 0 Ca Ca Ca Ca (modulated with...)
* texture unit 1 Pa Pr Pg Pb
* ---------------------------------------
* resulting color Ra Rr Rg Rb
*
* where:
* Ea = extra alpha
* Cx = coverage value from mask tile
* Px = gradient/texture paint color (generated for each fragment)
* Rx = resulting color/alpha component
*
* Here are some descriptions of the many variables used in this method:
* x,y - upper left corner of the tile destination
* w,h - width/height of the mask tile
* x0 - placekeeper for the original destination x location
* tw,th - width/height of the actual texture tile in pixels
* sx1,sy1 - upper left corner of the mask tile source region
* sx2,sy2 - lower left corner of the mask tile source region
* sx,sy - "current" upper left corner of the mask tile region of interest
*/
void
MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x, jint y, jint w, jint h,
jint maskoff, jint maskscan, jint masklen,
unsigned char *pMask)
{
J2dTraceLn5(J2D_TRACE_INFO, "MTLMaskFill_MaskFill (x=%d y=%d w=%d h=%d pMask=%p)", x, y, w, h, dstOps->pTexture);
MTLVertexCache_EnableMaskCache(mtlc, dstOps);
jint tw, th, x0;
jint sx1, sy1, sx2, sy2;
jint sx, sy, sw, sh;
x0 = x;
tw = MTLVC_MASK_CACHE_TILE_WIDTH;
th = MTLVC_MASK_CACHE_TILE_HEIGHT;
sx1 = maskoff % maskscan;
sy1 = maskoff / maskscan;
sx2 = sx1 + w;
sy2 = sy1 + h;
for (sy = sy1; sy < sy2; sy += th, y += th) {
x = x0;
sh = ((sy + th) > sy2) ? (sy2 - sy) : th;
for (sx = sx1; sx < sx2; sx += tw, x += tw) {
sw = ((sx + tw) > sx2) ? (sx2 - sx) : tw;
MTLVertexCache_AddMaskQuad(mtlc,
sx, sy, x, y, sw, sh,
maskscan, pMask, dstOps);
}
}
MTLVertexCache_DisableMaskCache(mtlc);
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLMaskFill_maskFill
(JNIEnv *env, jobject self,
jint x, jint y, jint w, jint h,
jint maskoff, jint maskscan, jint masklen,
jbyteArray maskArray)
{
MTLContext *mtlc = MTLRenderQueue_GetCurrentContext();
BMTLSDOps *dstOps = MTLRenderQueue_GetCurrentDestination();
unsigned char *mask;
J2dTraceLn(J2D_TRACE_ERROR, "MTLMaskFill_maskFill");
if (maskArray != NULL) {
mask = (unsigned char *)
(*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
} else {
mask = NULL;
}
MTLMaskFill_MaskFill(mtlc, dstOps,
x, y, w, h,
maskoff, maskscan, masklen, mask);
if (mask != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
}
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLPaints_h_Included
#define MTLPaints_h_Included
#import <Metal/Metal.h>
#import <awt/common.h>
#include "RenderOptions.h"
#define sun_java2d_SunGraphics2D_PAINT_UNDEFINED -1
@class MTLContext;
@class MTLComposite;
@class MTLClip;
@class MTLPipelineStatesStorage;
/**
* The MTLPaint class represents paint mode (color, gradient, e.t.c.)
* */
@interface MTLPaint : NSObject
- (id)initWithState:(jint)state;
- (BOOL)isEqual:(MTLPaint *)other; // used to compare requested with cached
- (NSString *)getDescription;
// For the current paint mode and passed composite (and flags):
// 1. Selects vertex+fragment shader (and corresponding pipelineDesc) and set pipelineState
// 2. Prepares corresponding buffers of vertex and fragment shaders
- (void)setPipelineState:(id <MTLRenderCommandEncoder>)encoder
context:(MTLContext *)mtlc
renderOptions:(const RenderOptions *)renderOptions
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage;
- (void)setXorModePipelineState:(id <MTLRenderCommandEncoder>)encoder
context:(MTLContext *)mtlc
renderOptions:(const RenderOptions *)renderOptions
pipelineStateStorage:(MTLPipelineStatesStorage *)pipelineStateStorage;
@end
@interface MTLColorPaint : MTLPaint
- (id)initWithColor:(jint)color;
@property (nonatomic, readonly) jint color;
@end
@interface MTLBaseGradPaint : MTLPaint {
@public
jint _cyclic;
}
- (id)initWithState:(jint)state
mask:(jboolean)useMask
cyclic:(jboolean)cyclic;
@end
@interface MTLGradPaint : MTLBaseGradPaint
- (id)initWithUseMask:(jboolean)useMask
cyclic:(jboolean)cyclic
p0:(jdouble)p0
p1:(jdouble)p1
p3:(jdouble)p3
pixel1:(jint)pixel1
pixel2:(jint)pixel2;
@end
@interface MTLBaseMultiGradPaint : MTLBaseGradPaint
- (id)initWithState:(jint)state
mask:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jboolean)cycleMethod
numStops:(jint)numStops
fractions:(jfloat *)fractions
pixels:(jint *)pixels;
@end
@interface MTLLinearGradPaint : MTLBaseMultiGradPaint
- (id)initWithUseMask:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jboolean)cycleMethod
numStops:(jint)numStops
p0:(jfloat)p0
p1:(jfloat)p1
p3:(jfloat)p3
fractions:(jfloat *)fractions
pixels:(jint *)pixels;
@end
@interface MTLRadialGradPaint : MTLBaseMultiGradPaint
- (id)initWithUseMask:(jboolean)useMask
linear:(jboolean)linear
cycleMethod:(jint)cycleMethod
numStops:(jint)numStops
m00:(jfloat)m00
m01:(jfloat)m01
m02:(jfloat)m02
m10:(jfloat)m10
m11:(jfloat)m11
m12:(jfloat)m12
focusX:(jfloat)focusX
fractions:(void *)fractions
pixels:(void *)pixels;
@end
@interface MTLTexturePaint : MTLPaint
- (id)initWithUseMask:(jboolean)useMask
textureID:(id <MTLTexture>)textureID
filter:(jboolean)filter
xp0:(jdouble)xp0
xp1:(jdouble)xp1
xp3:(jdouble)xp3
yp0:(jdouble)yp0
yp1:(jdouble)yp1
yp3:(jdouble)yp3;
@end
#endif /* MTLPaints_h_Included */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
#ifndef MTLPipelineStatesStorage_h_Included
#define MTLPipelineStatesStorage_h_Included
#import "MTLUtils.h"
#include "RenderOptions.h"
@class MTLComposite;
/**
* The MTLPipelineStatesStorage class used to obtain MTLRenderPipelineState
* */
@interface MTLPipelineStatesStorage : NSObject {
@private
id<MTLDevice> device;
id<MTLLibrary> library;
NSMutableDictionary<NSString*, id<MTLFunction>> * shaders;
NSMutableDictionary<NSString*, id<MTLComputePipelineState>> * computeStates;
}
@property (readwrite, assign) id<MTLDevice> device;
@property (readwrite, retain) id<MTLLibrary> library;
@property (readwrite, retain) NSMutableDictionary<NSString*, id<MTLFunction>> * shaders;
@property (readwrite, retain) NSMutableDictionary<NSString*, NSMutableDictionary *> * states;
- (id) initWithDevice:(id<MTLDevice>)device shaderLibPath:(NSString *)shadersLib;
- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor
vertexShaderId:(NSString *)vertexShaderId
fragmentShaderId:(NSString *)fragmentShaderId;
- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor
vertexShaderId:(NSString *)vertexShaderId
fragmentShaderId:(NSString *)fragmentShaderId
composite:(MTLComposite*)composite
renderOptions:(const RenderOptions *)renderOptions
stencilNeeded:(bool)stencilNeeded;
- (id<MTLComputePipelineState>) getComputePipelineState:(NSString *)computeShaderId;
- (id<MTLFunction>) getShader:(NSString *)name;
@end
#endif // MTLPipelineStatesStorage_h_Included

View File

@@ -0,0 +1,384 @@
#import "MTLPipelineStatesStorage.h"
#include "GraphicsPrimitiveMgr.h"
#import "MTLComposite.h"
#include "sun_java2d_SunGraphics2D.h"
extern const SurfaceRasterFlags defaultRasterFlags;
static void setBlendingFactors(
MTLRenderPipelineColorAttachmentDescriptor * cad,
MTLComposite* composite,
const RenderOptions * renderOptions);
@implementation MTLPipelineStatesStorage
@synthesize device;
@synthesize library;
@synthesize shaders;
@synthesize states;
- (id) initWithDevice:(id<MTLDevice>)dev shaderLibPath:(NSString *)shadersLib {
self = [super init];
if (self == nil) return self;
self.device = dev;
NSError *error = nil;
self.library = [dev newLibraryWithFile:shadersLib error:&error];
if (!self.library) {
NSLog(@"Failed to load library. error %@", error);
exit(0);
}
self.shaders = [NSMutableDictionary dictionaryWithCapacity:10];
self.states = [NSMutableDictionary dictionaryWithCapacity:10];
computeStates = [[NSMutableDictionary dictionaryWithCapacity:10] retain] ;
return self;
}
- (NSPointerArray * ) getSubStates:(NSString *)vertexShaderId fragmentShader:(NSString *)fragmentShaderId {
NSMutableDictionary * vSubStates = states[vertexShaderId];
if (vSubStates == nil) {
@autoreleasepool {
vSubStates = [NSMutableDictionary dictionary];
[states setObject:vSubStates forKey:vertexShaderId];
}
}
NSPointerArray * sSubStates = vSubStates[fragmentShaderId];
if (sSubStates == nil) {
@autoreleasepool {
sSubStates = [NSPointerArray strongObjectsPointerArray];
[vSubStates setObject:sSubStates forKey:fragmentShaderId];
}
}
return sSubStates;
}
- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor
vertexShaderId:(NSString *)vertexShaderId
fragmentShaderId:(NSString *)fragmentShaderId
{
RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}};
return [self getPipelineState:pipelineDescriptor
vertexShaderId:vertexShaderId
fragmentShaderId:fragmentShaderId
composite:nil
renderOptions:&defaultOptions
stencilNeeded:NO];
}
// Base method to obtain MTLRenderPipelineState.
// NOTE: parameters compositeRule, srcFlags, dstFlags are used to set MTLRenderPipelineColorAttachmentDescriptor multipliers
- (id<MTLRenderPipelineState>) getPipelineState:(MTLRenderPipelineDescriptor *) pipelineDescriptor
vertexShaderId:(NSString *)vertexShaderId
fragmentShaderId:(NSString *)fragmentShaderId
composite:(MTLComposite*) composite
renderOptions:(const RenderOptions *)renderOptions
stencilNeeded:(bool)stencilNeeded;
{
jint compositeRule = composite != nil ? [composite getRule] : RULE_Src;
const jboolean useXorComposite = composite != nil && [composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR;
const jboolean useComposite = composite != nil && compositeRule >= 0
&& compositeRule < java_awt_AlphaComposite_MAX_RULE;
// Calculate index by flags and compositeRule
// TODO: reimplement, use map with convenient key (calculated by all arguments)
int subIndex = 0;
if (useXorComposite) {
// compositeRule value is already XOR_COMPOSITE_RULE
}
else {
if (useComposite) {
if (!renderOptions->srcFlags.isPremultiplied)
subIndex |= 1;
if (renderOptions->srcFlags.isOpaque)
subIndex |= 1 << 1;
if (!renderOptions->dstFlags.isPremultiplied)
subIndex |= 1 << 2;
if (renderOptions->dstFlags.isOpaque)
subIndex |= 1 << 3;
} else
compositeRule = RULE_Src;
}
if (stencilNeeded) {
subIndex |= 1 << 4;
}
if (renderOptions->isAA) {
subIndex |= 1 << 5;
}
if ((composite != nil && FLT_LT([composite getExtraAlpha], 1.0f))) {
subIndex |= 1 << 6;
}
int index = compositeRule*64 + subIndex;
NSPointerArray * subStates = [self getSubStates:vertexShaderId fragmentShader:fragmentShaderId];
while (index >= [subStates count]) {
[subStates addPointer:NULL]; // obj-c collections haven't resize methods, so do that
}
id<MTLRenderPipelineState> result = [subStates pointerAtIndex:index];
if (result == nil) {
@autoreleasepool {
id <MTLFunction> vertexShader = [self getShader:vertexShaderId];
id <MTLFunction> fragmentShader = [self getShader:fragmentShaderId];
MTLRenderPipelineDescriptor *pipelineDesc = [[pipelineDescriptor copy] autorelease];
pipelineDesc.vertexFunction = vertexShader;
pipelineDesc.fragmentFunction = fragmentShader;
if (useXorComposite) {
/* The below configuration is the best performant implementation of XOR mode rendering.
It was found that it works ONLY for basic Colors and not for all RGB combinations.
Hence, a slow performant XOR mode rendering has been implemented by
disabling blending & committing after each draw call.
In XOR mode rendering, subsequent draw calls are rendered
by shader using already rendered framebuffer pixel value XORed
with current draw color and XOR color.
pipelineDesc.colorAttachments[0].blendingEnabled = YES;
pipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOneMinusDestinationColor;
pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceColor;
*/
pipelineDesc.colorAttachments[0].blendingEnabled = NO;
} else if (useComposite ||
(composite != nil &&
FLT_LT([composite getExtraAlpha], 1.0f)))
{
setBlendingFactors(
pipelineDesc.colorAttachments[0],
composite,
renderOptions
);
}
if (stencilNeeded) {
pipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatStencil8;
}
if (renderOptions->isAA) {
pipelineDesc.sampleCount = MTLAASampleCount;
pipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
pipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
pipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
pipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
pipelineDesc.colorAttachments[0].blendingEnabled = YES;
}
NSError *error = nil;
result = [[self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error] autorelease];
if (result == nil) {
NSLog(@"Failed to create pipeline state, error %@", error);
exit(0);
}
[subStates insertPointer:result atIndex:index];
}
}
return result;
}
- (id<MTLComputePipelineState>) getComputePipelineState:(NSString *)computeShaderId {
id<MTLComputePipelineState> result = computeStates[computeShaderId];
if (result == nil) {
id <MTLFunction> computeShader = [self getShader:computeShaderId];
@autoreleasepool {
NSError *error = nil;
result = (id <MTLComputePipelineState>) [[self.device newComputePipelineStateWithFunction:computeShader error:&error] autorelease];
if (result == nil) {
NSLog(@"Failed to create pipeline state, error %@", error);
exit(0);
}
computeStates[computeShaderId] = result;
}
}
return result;
}
- (id<MTLFunction>) getShader:(NSString *)name {
id<MTLFunction> result = [self.shaders valueForKey:name];
if (result == nil) {
result = [[self.library newFunctionWithName:name] autorelease];
[self.shaders setValue:result forKey:name];
}
return result;
}
- (void) dealloc {
[super dealloc];
[computeStates release];
}
@end
static void setBlendingFactors(
MTLRenderPipelineColorAttachmentDescriptor * cad,
MTLComposite* composite,
const RenderOptions * renderOptions
) {
const jint compositeRule = composite != nil ? [composite getRule] : RULE_Src;
if (compositeRule == RULE_Src &&
(composite == nil || FLT_GE([composite getExtraAlpha], 1.0f))) {
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_Src but blending is disabled because src is opaque");
return;
}
cad.blendingEnabled = YES;
// RGB = Source.rgb * SBFc + Dest.rgb * DBFc
// A = Source.a * SBFa + Dest.a * DBFa
//
// default mode == RULE_Src with constants:
// DBFa=0
// DBFc=0
// SBFa=1
// SBFc=1
//
// NOTE: constants MTLBlendFactorBlendAlpha, MTLBlendFactorOneMinusBlendAlpha refers to [encoder setBlendColorRed:green:blue:alpha:] (default value is zero)
//
// TODO: implement alpha-composite via shaders (will be much more simpler and can support all rules and modes)
switch (compositeRule) {
case RULE_SrcOver: {
// Ar = As + Ad*(1-As)
// Cr = Cs + Cd*(1-As)
if (renderOptions->srcFlags.isOpaque &&
(composite == nil ||
FLT_GE([composite getExtraAlpha], 1.0f)))
{
J2dTraceLn(J2D_TRACE_VERBOSE, "rule=RULE_SrcOver, but blending is disabled because src is opaque");
cad.blendingEnabled = NO;
return;
}
if (renderOptions->dstFlags.isOpaque) {
// Ar = 1, can be ignored, so
// Cr = Cs + Cd*(1-As)
// TODO: select any multiplier with best performance
// for example: cad.destinationAlphaBlendFactor = MTLBlendFactorZero;
} else {
cad.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
}
if (!renderOptions->srcFlags.isPremultiplied) {
cad.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
}
if (composite != nil && FLT_LT([composite getExtraAlpha], 1.0f)) {
cad.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
}
cad.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_SrcOver");
break;
}
case RULE_DstOver: {
// Ar = As*(1-Ad) + Ad
// Cr = Cs*(1-Ad) + Cd
if (renderOptions->srcFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_ERROR, "Composite rule RULE_DstOver with opaque src isn't implemented (src alpha won't be ignored)");
}
if (renderOptions->dstFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_ERROR, "Composite rule RULE_DstOver with opaque dest hasn't any sense");
}
if (!renderOptions->srcFlags.isPremultiplied) {
J2dTrace(J2D_TRACE_ERROR, "Composite rule RULE_DstOver with non-premultiplied source isn't implemented (scr alpha will be ignored for rgb-component)");
}
cad.sourceAlphaBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.sourceRGBBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.destinationAlphaBlendFactor = MTLBlendFactorOne;
cad.destinationRGBBlendFactor = MTLBlendFactorOne;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_DstOver");
break;
}
case RULE_SrcIn: {
// Ar = As*Ad
// Cr = Cs*Ad
if (renderOptions->srcFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_ERROR, "Composite rule RULE_SrcIn with opaque src isn't implemented (src alpha won't be ignored)");
}
if (renderOptions->dstFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_VERBOSE, "rule=RULE_SrcIn, but blending is disabled because dest is opaque");
cad.blendingEnabled = NO;
return;
}
if (!renderOptions->srcFlags.isPremultiplied) {
J2dTrace(J2D_TRACE_ERROR, "Composite rule RULE_SrcIn with non-premultiplied source isn't implemented (scr alpha will be ignored for rgb-component)");
}
cad.sourceAlphaBlendFactor = MTLBlendFactorDestinationAlpha;
cad.sourceRGBBlendFactor = MTLBlendFactorDestinationAlpha;
cad.destinationAlphaBlendFactor = MTLBlendFactorZero;
cad.destinationRGBBlendFactor = MTLBlendFactorZero;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_SrcIn");
break;
}
case RULE_DstIn: {
// Ar = Ad*As
// Cr = Cd*As
if (renderOptions->srcFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_ERROR, "Composite rule RULE_DstIn with opaque src isn't implemented (src alpha won't be ignored)");
}
if (renderOptions->dstFlags.isOpaque) {
J2dTraceLn(J2D_TRACE_ERROR, "Composite rule RULE_DstIn with opaque dest isn't implemented (dest alpha won't be ignored)");
}
cad.sourceAlphaBlendFactor = MTLBlendFactorZero;
cad.sourceRGBBlendFactor = MTLBlendFactorZero;
cad.destinationAlphaBlendFactor = MTLBlendFactorSourceAlpha;
cad.destinationRGBBlendFactor = MTLBlendFactorSourceAlpha;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_DstIn");
break;
}
case RULE_SrcOut: {
// Ar = As*(1-Ad)
// Cr = Cs*(1-Ad)
if (!renderOptions->srcFlags.isPremultiplied) {
J2dTrace(J2D_TRACE_ERROR, "Composite rule SrcOut with non-premultiplied source isn't implemented (scr alpha will be ignored for rgb-component)");
}
cad.sourceAlphaBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.sourceRGBBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.destinationAlphaBlendFactor = MTLBlendFactorZero;
cad.destinationRGBBlendFactor = MTLBlendFactorZero;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_SrcOut");
break;
}
case RULE_DstOut: {
// Ar = Ad*(1-As)
// Cr = Cd*(1-As)
cad.sourceAlphaBlendFactor = MTLBlendFactorZero;
cad.sourceRGBBlendFactor = MTLBlendFactorZero;
cad.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
cad.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_DstOut");
break;
}
case RULE_Xor: {
// Ar = As*(1-Ad) + Ad*(1-As)
// Cr = Cs*(1-Ad) + Cd*(1-As)
if (!renderOptions->srcFlags.isPremultiplied) {
J2dTrace(J2D_TRACE_ERROR, "Composite rule Xor with non-premultiplied source isn't implemented (scr alpha will be ignored for rgb-component)");
}
cad.sourceAlphaBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.sourceRGBBlendFactor = MTLBlendFactorOneMinusDestinationAlpha;
cad.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
cad.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_Xor");
break;
}
case RULE_Clear: {
// Ar = 0
// Cr = 0
cad.sourceAlphaBlendFactor = MTLBlendFactorZero;
cad.sourceRGBBlendFactor = MTLBlendFactorZero;
cad.destinationAlphaBlendFactor = MTLBlendFactorZero;
cad.destinationRGBBlendFactor = MTLBlendFactorZero;
J2dTraceLn(J2D_TRACE_VERBOSE, "set RULE_Clear");
break;
}
default: {
J2dTrace1(J2D_TRACE_ERROR, "Unimplemented composite rule %d (will be used Src)", compositeRule);
cad.blendingEnabled = NO;
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLRenderQueue_h_Included
#define MTLRenderQueue_h_Included
#include "MTLContext.h"
#include "MTLSurfaceData.h"
#include "MTLVertexCache.h"
/*
* The following macros are used to pick values (of the specified type) off
* the queue.
*/
#define NEXT_VAL(buf, type) (((type *)((buf) += sizeof(type)))[-1])
#define NEXT_BYTE(buf) NEXT_VAL(buf, unsigned char)
#define NEXT_INT(buf) NEXT_VAL(buf, jint)
#define NEXT_FLOAT(buf) NEXT_VAL(buf, jfloat)
#define NEXT_BOOLEAN(buf) (jboolean)NEXT_INT(buf)
#define NEXT_LONG(buf) NEXT_VAL(buf, jlong)
#define NEXT_DOUBLE(buf) NEXT_VAL(buf, jdouble)
// Operations for CheckPreviousOp
enum {
MTL_OP_INIT,
MTL_OP_AA,
MTL_OP_SET_COLOR,
MTL_OP_RESET_PAINT,
MTL_OP_SYNC,
MTL_OP_SHAPE_CLIP_SPANS,
MTL_OP_OTHER
};
/*
* These macros now simply delegate to the CheckPreviousOp() method.
*/
#define CHECK_PREVIOUS_OP(op) MTLRenderQueue_CheckPreviousOp(op)
#define RESET_PREVIOUS_OP() {mtlPreviousOp = MTL_OP_INIT;}
/*
* Increments a pointer (buf) by the given number of bytes.
*/
#define SKIP_BYTES(buf, numbytes) buf += (numbytes)
/*
* Extracts a value at the given offset from the provided packed value.
*/
#define EXTRACT_VAL(packedval, offset, mask) \
(((packedval) >> (offset)) & (mask))
#define EXTRACT_BYTE(packedval, offset) \
(unsigned char)EXTRACT_VAL(packedval, offset, 0xff)
#define EXTRACT_BOOLEAN(packedval, offset) \
(jboolean)EXTRACT_VAL(packedval, offset, 0x1)
/*
* The following macros allow the caller to return (or continue) if the
* provided value is NULL. (The strange else clause is included below to
* allow for a trailing ';' after RETURN/CONTINUE_IF_NULL() invocations.)
*/
#define ACT_IF_NULL(ACTION, value) \
if ((value) == NULL) { \
J2dTraceLn1(J2D_TRACE_ERROR, \
"%s is null", #value); \
ACTION; \
} else do { } while (0)
#define RETURN_IF_NULL(value) ACT_IF_NULL(return, value)
#define CONTINUE_IF_NULL(value) ACT_IF_NULL(continue, value)
MTLContext *MTLRenderQueue_GetCurrentContext();
BMTLSDOps *MTLRenderQueue_GetCurrentDestination();
void commitEncodedCommands();
extern jint mtlPreviousOp;
#endif /* MTLRenderQueue_h_Included */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLRenderer_h_Included
#define MTLRenderer_h_Included
#include "sun_java2d_pipe_BufferedRenderPipe.h"
#include "MTLContext.h"
#include "MTLGraphicsConfig.h"
#import "MTLLayer.h"
#define BYTES_PER_POLY_POINT \
sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_POLY_POINT
#define BYTES_PER_SCANLINE \
sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SCANLINE
#define BYTES_PER_SPAN \
sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SPAN
void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x1, jint y1, jint x2, jint y2);
void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x, jint y);
void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x, jint y, jint w, jint h);
void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,
jint nPoints, jint isClosed,
jint transX, jint transY,
jint *xPoints, jint *yPoints);
void MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
jint count, jint *scanlines);
void MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lw21, jfloat lw12);
void MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lw21, jfloat lw12);
void MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps,
jint x, jint y, jint w, jint h);
void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps,
jint count, jint *spans);
void MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
void MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
void MTLRenderer_EnableAAParallelogramProgram();
void MTLRenderer_DisableAAParallelogramProgram();
#endif /* MTLRenderer_h_Included */

View File

@@ -0,0 +1,825 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef HEADLESS
#include <jlong.h>
#include <jni_util.h>
#include <math.h>
#include "sun_java2d_metal_MTLRenderer.h"
#include "MTLRenderer.h"
#include "MTLRenderQueue.h"
#include "MTLSurfaceData.h"
#include "MTLUtils.h"
#import "MTLLayer.h"
/**
* Note: Some of the methods in this file apply a "magic number"
* translation to line segments. The OpenGL specification lays out the
* "diamond exit rule" for line rasterization, but it is loose enough to
* allow for a wide range of line rendering hardware. (It appears that
* some hardware, such as the Nvidia GeForce2 series, does not even meet
* the spec in all cases.) As such it is difficult to find a mapping
* between the Java2D and OpenGL line specs that works consistently across
* all hardware combinations.
*
* Therefore the "magic numbers" you see here have been empirically derived
* after testing on a variety of graphics hardware in order to find some
* reasonable middle ground between the two specifications. The general
* approach is to apply a fractional translation to vertices so that they
* hit pixel centers and therefore touch the same pixels as in our other
* pipelines. Emphasis was placed on finding values so that MTL lines with
* a slope of +/- 1 hit all the same pixels as our other (software) loops.
* The stepping in other diagonal lines rendered with MTL may deviate
* slightly from those rendered with our software loops, but the most
* important thing is that these magic numbers ensure that all MTL lines
* hit the same endpoints as our software loops.
*
* If you find it necessary to change any of these magic numbers in the
* future, just be sure that you test the changes across a variety of
* hardware to ensure consistent rendering everywhere.
*/
void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1, jint x2, jint y2) {
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawLine: dest is null");
return;
}
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawLine (x1=%d y1=%d x2=%d y2=%d), dst tex=%p", x1, y1, x2, y2, dstOps->pTexture);
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
// DrawLine implementation same as in OGLRenderer.c
struct Vertex verts[2];
if (y1 == y2) {
// horizontal
float fx1 = (float)x1;
float fx2 = (float)x2;
float fy = ((float)y1) + 0.2f;
if (x1 > x2) {
float t = fx1; fx1 = fx2; fx2 = t;
}
verts[0].position[0] = fx1 + 0.2f;
verts[0].position[1] = fy;
verts[1].position[0] = fx2 + 1.2f;
verts[1].position[1] = fy;
} else if (x1 == x2) {
// vertical
float fx = ((float)x1) + 0.2f;
float fy1 = (float)y1;
float fy2 = (float)y2;
if (y1 > y2) {
float t = fy1; fy1 = fy2; fy2 = t;
}
verts[0].position[0] = fx;
verts[0].position[1] = fy1 + 0.2f;
verts[1].position[0] = fx;
verts[1].position[1] = fy2 + 1.2f;
} else {
// diagonal
float fx1 = (float)x1;
float fy1 = (float)y1;
float fx2 = (float)x2;
float fy2 = (float)y2;
if (x1 < x2) {
fx1 += 0.2f;
fx2 += 1.0f;
} else {
fx1 += 0.8f;
fx2 -= 0.2f;
}
if (y1 < y2) {
fy1 += 0.2f;
fy2 += 1.0f;
} else {
fy1 += 0.8f;
fy2 -= 0.2f;
}
verts[0].position[0] = fx1;
verts[0].position[1] = fy1;
verts[1].position[0] = fx2;
verts[1].position[1] = fy2;
}
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
}
void MTLRenderer_DrawPixel(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y) {
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPixel: dest is null");
return;
}
id<MTLTexture> dest = dstOps->pTexture;
J2dTraceLn3(J2D_TRACE_INFO, "MTLRenderer_DrawPixel (x=%d y=%d), dst tex=%p", x, y, dest);
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
// Translate each vertex by a fraction so
// that we hit pixel centers.
float fx = (float)x + 0.2f;
float fy = (float)y + 0.5f;
struct Vertex vert = {{fx, fy}};
[mtlEncoder setVertexBytes:&vert length:sizeof(vert) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypePoint vertexStart:0 vertexCount:1];
}
void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) {
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawRect: dest is null");
return;
}
id<MTLTexture> dest = dstOps->pTexture;
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
// TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
// Translate each vertex by a fraction so
// that we hit pixel centers.
const int verticesCount = 5;
float fx = (float)x + 0.2f;
float fy = (float)y + 0.5f;
float fw = (float)w;
float fh = (float)h;
struct Vertex vertices[5] = {
{{fx, fy}},
{{fx + fw, fy}},
{{fx + fw, fy + fh}},
{{fx, fy + fh}},
{{fx, fy}},
};
[mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
}
const int POLYLINE_BUF_SIZE = 64;
NS_INLINE void fillVertex(struct Vertex * vertex, int x, int y) {
vertex->position[0] = x;
vertex->position[1] = y;
}
void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,
jint nPoints, jint isClosed,
jint transX, jint transY,
jint *xPoints, jint *yPoints)
{
// Note that BufferedRenderPipe.drawPoly() has already rejected polys
// with nPoints<2, so we can be certain here that we have nPoints>=2.
if (xPoints == NULL || yPoints == NULL || nPoints < 2) { // just for insurance
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: points array is empty");
return;
}
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: dest is null");
return;
}
J2dTraceLn4(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: %d points, transX=%d, transY=%d, dst tex=%p", nPoints, transX, transY, dstOps->pTexture);
__block struct {
struct Vertex verts[POLYLINE_BUF_SIZE];
} pointsChunk;
// We intend to submit draw commands in batches of POLYLINE_BUF_SIZE vertices at a time
// Subsequent batches need to be connected - so end point in one batch is repeated as first point in subsequent batch
// This inflates the total number of points by a factor of number of batches of size POLYLINE_BUF_SIZE
nPoints += (nPoints/POLYLINE_BUF_SIZE);
jint prevX = *(xPoints++);
jint prevY = *(yPoints++);
const jint firstX = prevX;
const jint firstY = prevY;
while (nPoints > 0) {
const bool isLastChunk = nPoints <= POLYLINE_BUF_SIZE;
__block int chunkSize = isLastChunk ? nPoints : POLYLINE_BUF_SIZE;
fillVertex(pointsChunk.verts, prevX + transX + 0.5f, prevY + transY + 0.5f);
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)", prevX + transX + 0.5f, prevY + transY + 0.5f);
for (int i = 1; i < chunkSize; i++) {
prevX = *(xPoints++);
prevY = *(yPoints++);
fillVertex(pointsChunk.verts + i, prevX + transX + 0.5f, prevY + transY + 0.5f);
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)", prevX + transX + 0.5f,prevY + transY + 0.5f);
}
bool drawCloseSegment = false;
if (isClosed && isLastChunk) {
if (chunkSize + 2 <= POLYLINE_BUF_SIZE) {
fillVertex(pointsChunk.verts + chunkSize, firstX + transX + 0.5f, firstY + transY + 0.5f);
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: Point - (%1.2f, %1.2f)",firstX + transX + 0.5f, firstY + transY + 0.5f);
++chunkSize;
} else
drawCloseSegment = true;
}
nPoints -= chunkSize;
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
[mtlEncoder setVertexBytes:pointsChunk.verts length:sizeof(pointsChunk.verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:chunkSize];
if (drawCloseSegment) {
struct Vertex vertices[2] = {
{{prevX + transX + 0.5f, prevY + transY + 0.5f}},
{{firstX + transX + 0.5f, firstY + transY + 0.5f}}
};
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: last segment Point1 - (%1.2f, %1.2f)",prevX + transX + 0.5f, prevY + transY + 0.5f);
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: last segment Point2 - (%1.2f, %1.2f)",firstX + transX + 0.5f, firstY + transY + 0.5f);
[mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
}
}
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLRenderer_drawPoly
(JNIEnv *env, jobject mtlr,
jintArray xpointsArray, jintArray ypointsArray,
jint nPoints, jboolean isClosed,
jint transX, jint transY)
{
jint *xPoints, *yPoints;
//TODO
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_drawPoly -- :TODO");
}
void
MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
jint scanlineCount, jint *scanlines)
{
J2dTraceLn2(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines (scanlineCount=%d), dst tex=%p", scanlineCount, dstOps->pTexture);
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawScanlines: dest is null");
return;
}
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil) return;
struct Vertex verts[2*scanlineCount];
for (int j = 0, i = 0; j < scanlineCount; j++) {
// Translate each vertex by a fraction so
// that we hit pixel centers.
float x1 = ((float)*(scanlines++)) + 0.2f;
float x2 = ((float)*(scanlines++)) + 1.2f;
float y = ((float)*(scanlines++)) + 0.5f;
struct Vertex v1 = {{x1, y}};
struct Vertex v2 = {{x2, y}};
verts[i++] = v1;
verts[i++] = v2;
}
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2*scanlineCount];
}
void
MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h)
{
J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillRect");
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillRect: current dest is null");
return;
}
struct Vertex verts[QUAD_VERTEX_COUNT] = {
{ {x, y}},
{ {x, y+h}},
{ {x+w, y}},
{ {x+w, y+h}
}};
id<MTLTexture> dest = dstOps->pTexture;
J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_FillRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
// Encode render command.
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
}
void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
{
J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillSpans");
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: dest is null");
return;
}
// MTLRenderCommandEncoder setVertexBytes usage is recommended if the data is of 4KB.
// We use a buffer that closely matches the 4KB limit size
// This buffer is resued multiple times to encode draw calls of a triangle list
// NOTE : Due to nature of *spans data - it is not possible to use triangle strip.
// We use triangle list to draw spans
// Destination texture to which render commands are encoded
id<MTLTexture> dest = dstOps->pTexture;
id<MTLTexture> destAA = nil;
BOOL isDestOpaque = dstOps->isOpaque;
if (mtlc.clip.stencilMaskGenerationInProgress == JNI_TRUE) {
dest = dstOps->pStencilData;
isDestOpaque = NO;
}
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dest isDstOpaque:isDestOpaque];
if (mtlEncoder == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: mtlEncoder is nil");
return;
}
// This is the max no of vertices (of struct Vertex - 8 bytes) we can accomodate in 4KB
const int TOTAL_VERTICES_IN_BLOCK = 510;
struct Vertex vertexList[TOTAL_VERTICES_IN_BLOCK]; // a total of 170 triangles ==> 85 spans
int counter = 0;
jint *aaspans = spans;
for (int i = 0; i < spanCount; i++) {
jfloat x1 = *(spans++);
jfloat y1 = *(spans++);
jfloat x2 = *(spans++);
jfloat y2 = *(spans++);
struct Vertex verts[6] = {
{{x1, y1}},
{{x1, y2}},
{{x2, y1}},
{{x1, y2}},
{{x2, y1}},
{{x2, y2}
}};
memcpy(&vertexList[counter], &verts, sizeof(verts));
counter += 6;
// If vertexList buffer full
if (counter % TOTAL_VERTICES_IN_BLOCK == 0) {
[mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:TOTAL_VERTICES_IN_BLOCK];
counter = 0;
}
}
// Draw triangles using remaining vertices if any
if (counter != 0) {
[mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:counter];
}
}
void
MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12)
{
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: current dest is null");
return;
}
id<MTLTexture> dest = dstOps->pTexture;
J2dTraceLn7(J2D_TRACE_INFO,
"MTLRenderer_FillParallelogram "
"(x=%6.2f y=%6.2f "
"dx1=%6.2f dy1=%6.2f "
"dx2=%6.2f dy2=%6.2f dst tex=%p)",
fx11, fy11,
dx21, dy21,
dx12, dy12, dest);
struct Vertex verts[QUAD_VERTEX_COUNT] = {
{ {fx11, fy11}},
{ {fx11+dx21, fy11+dy21}},
{ {fx11+dx12, fy11+dy12}},
{ {fx11 + dx21 + dx12, fy11+ dy21 + dy12}
}};
// Encode render command.
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
}
void
MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12)
{
// dx,dy for line width in the "21" and "12" directions.
jfloat ldx21 = dx21 * lwr21;
jfloat ldy21 = dy21 * lwr21;
jfloat ldx12 = dx12 * lwr12;
jfloat ldy12 = dy12 * lwr12;
// calculate origin of the outer parallelogram
jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f;
jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f;
J2dTraceLn8(J2D_TRACE_INFO,
"MTLRenderer_DrawParallelogram "
"(x=%6.2f y=%6.2f "
"dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
"dx2=%6.2f dy2=%6.2f lwr2=%6.2f)",
fx11, fy11,
dx21, dy21, lwr21,
dx12, dy12, lwr12);
// Only need to generate 4 quads if the interior still
// has a hole in it (i.e. if the line width ratio was
// less than 1.0)
if (lwr21 < 1.0f && lwr12 < 1.0f) {
// Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are
// relative to whether the dxNN variables are positive
// and negative. The math works fine regardless of
// their signs, but for conceptual simplicity the
// comments will refer to the sides as if the dxNN
// were all positive. "TOP" and "BOTTOM" segments
// are defined by the dxy21 deltas. "LEFT" and "RIGHT"
// segments are defined by the dxy12 deltas.
// Each segment includes its starting corner and comes
// to just short of the following corner. Thus, each
// corner is included just once and the only lengths
// needed are the original parallelogram delta lengths
// and the "line width deltas". The sides will cover
// the following relative territories:
//
// T T T T T R
// L R
// L R
// L R
// L R
// L B B B B B
// Every segment is drawn as a filled Parallelogram quad
// Each quad is encoded using two triangles
// For 4 segments - there are 8 triangles in total
// Each triangle has 3 vertices
const int TOTAL_VERTICES = 8 * 3;
struct Vertex vertexList[TOTAL_VERTICES];
int i = 0;
// TOP segment, to left side of RIGHT edge
// "width" of original pgram, "height" of hor. line size
fx11 = ox11;
fy11 = oy11;
fillVertex(vertexList + (i++), fx11, fy11);
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
fillVertex(vertexList + (i++), fx11, fy11);
// RIGHT segment, to top of BOTTOM edge
// "width" of vert. line size , "height" of original pgram
fx11 = ox11 + dx21;
fy11 = oy11 + dy21;
fillVertex(vertexList + (i++), fx11, fy11);
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
fillVertex(vertexList + (i++), fx11, fy11);
// BOTTOM segment, from right side of LEFT edge
// "width" of original pgram, "height" of hor. line size
fx11 = ox11 + dx12 + ldx21;
fy11 = oy11 + dy12 + ldy21;
fillVertex(vertexList + (i++), fx11, fy11);
fillVertex(vertexList + (i++), fx11 + dx21, fy11 + dy21);
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
fillVertex(vertexList + (i++), fx11 + dx21 + ldx12, fy11 + dy21 + ldy12);
fillVertex(vertexList + (i++), fx11 + ldx12, fy11 + ldy12);
fillVertex(vertexList + (i++), fx11, fy11);
// LEFT segment, from bottom of TOP edge
// "width" of vert. line size , "height" of inner pgram
fx11 = ox11 + ldx12;
fy11 = oy11 + ldy12;
fillVertex(vertexList + (i++), fx11, fy11);
fillVertex(vertexList + (i++), fx11 + ldx21, fy11 + ldy21);
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
fillVertex(vertexList + (i++), fx11 + ldx21 + dx12, fy11 + ldy21 + dy12);
fillVertex(vertexList + (i++), fx11 + dx12, fy11 + dy12);
fillVertex(vertexList + (i++), fx11, fy11);
// Encode render command.
id<MTLRenderCommandEncoder> mtlEncoder = [mtlc.encoderManager getRenderEncoder:dstOps];
if (mtlEncoder == nil)
return;
[mtlEncoder setVertexBytes:vertexList length:sizeof(vertexList) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:TOTAL_VERTICES];
} else {
// The line width ratios were large enough to consume
// the entire hole in the middle of the parallelogram
// so we can just issue one large quad for the outer
// parallelogram.
dx21 += ldx21;
dy21 += ldy21;
dx12 += ldx12;
dy12 += ldy12;
MTLRenderer_FillParallelogram(mtlc, dstOps, ox11, oy11, dx21, dy21, dx12, dy12);
}
}
static GLhandleARB aaPgramProgram = 0;
/*
* This shader fills the space between an outer and inner parallelogram.
* It can be used to draw an outline by specifying both inner and outer
* values. It fills pixels by estimating what portion falls inside the
* outer shape, and subtracting an estimate of what portion falls inside
* the inner shape. Specifying both inner and outer values produces a
* standard "wide outline". Specifying an inner shape that falls far
* outside the outer shape allows the same shader to fill the outer
* shape entirely since pixels that fall within the outer shape are never
* inside the inner shape and so they are filled based solely on their
* coverage of the outer shape.
*
* The setup code renders this shader over the bounds of the outer
* shape (or the only shape in the case of a fill operation) and
* sets the texture 0 coordinates so that 0,0=>0,1=>1,1=>1,0 in those
* texture coordinates map to the four corners of the parallelogram.
* Similarly the texture 1 coordinates map the inner shape to the
* unit square as well, but in a different coordinate system.
*
* When viewed in the texture coordinate systems the parallelograms
* we are filling are unit squares, but the pixels have then become
* tiny parallelograms themselves. Both of the texture coordinate
* systems are affine transforms so the rate of change in X and Y
* of the texture coordinates are essentially constants and happen
* to correspond to the size and direction of the slanted sides of
* the distorted pixels relative to the "square mapped" boundary
* of the parallelograms.
*
* The shader uses the dFdx() and dFdy() functions to measure the "rate
* of change" of these texture coordinates and thus gets an accurate
* measure of the size and shape of a pixel relative to the two
* parallelograms. It then uses the bounds of the size and shape
* of a pixel to intersect with the unit square to estimate the
* coverage of the pixel. Unfortunately, without a lot more work
* to calculate the exact area of intersection between a unit
* square (the original parallelogram) and a parallelogram (the
* distorted pixel), this shader only approximates the pixel
* coverage, but emperically the estimate is very useful and
* produces visually pleasing results, if not theoretically accurate.
*/
static const char *aaPgramShaderSource =
"void main() {"
// Calculate the vectors for the "legs" of the pixel parallelogram
// for the outer parallelogram.
" vec2 oleg1 = dFdx(gl_TexCoord[0].st);"
" vec2 oleg2 = dFdy(gl_TexCoord[0].st);"
// Calculate the bounds of the distorted pixel parallelogram.
" vec2 corner = gl_TexCoord[0].st - (oleg1+oleg2)/2.0;"
" vec2 omin = min(corner, corner+oleg1);"
" omin = min(omin, corner+oleg2);"
" omin = min(omin, corner+oleg1+oleg2);"
" vec2 omax = max(corner, corner+oleg1);"
" omax = max(omax, corner+oleg2);"
" omax = max(omax, corner+oleg1+oleg2);"
// Calculate the vectors for the "legs" of the pixel parallelogram
// for the inner parallelogram.
" vec2 ileg1 = dFdx(gl_TexCoord[1].st);"
" vec2 ileg2 = dFdy(gl_TexCoord[1].st);"
// Calculate the bounds of the distorted pixel parallelogram.
" corner = gl_TexCoord[1].st - (ileg1+ileg2)/2.0;"
" vec2 imin = min(corner, corner+ileg1);"
" imin = min(imin, corner+ileg2);"
" imin = min(imin, corner+ileg1+ileg2);"
" vec2 imax = max(corner, corner+ileg1);"
" imax = max(imax, corner+ileg2);"
" imax = max(imax, corner+ileg1+ileg2);"
// Clamp the bounds of the parallelograms to the unit square to
// estimate the intersection of the pixel parallelogram with
// the unit square. The ratio of the 2 rectangle areas is a
// reasonable estimate of the proportion of coverage.
" vec2 o1 = clamp(omin, 0.0, 1.0);"
" vec2 o2 = clamp(omax, 0.0, 1.0);"
" float oint = (o2.y-o1.y)*(o2.x-o1.x);"
" float oarea = (omax.y-omin.y)*(omax.x-omin.x);"
" vec2 i1 = clamp(imin, 0.0, 1.0);"
" vec2 i2 = clamp(imax, 0.0, 1.0);"
" float iint = (i2.y-i1.y)*(i2.x-i1.x);"
" float iarea = (imax.y-imin.y)*(imax.x-imin.x);"
// Proportion of pixel in outer shape minus the proportion
// of pixel in the inner shape == the coverage of the pixel
// in the area between the two.
" float coverage = oint/oarea - iint / iarea;"
" gl_FragColor = gl_Color * coverage;"
"}";
#define ADJUST_PGRAM(V1, DV, V2) \
do { \
if ((DV) >= 0) { \
(V2) += (DV); \
} else { \
(V1) += (DV); \
} \
} while (0)
// Invert the following transform:
// DeltaT(0, 0) == (0, 0)
// DeltaT(1, 0) == (DX1, DY1)
// DeltaT(0, 1) == (DX2, DY2)
// DeltaT(1, 1) == (DX1+DX2, DY1+DY2)
// TM00 = DX1, TM01 = DX2, (TM02 = X11)
// TM10 = DY1, TM11 = DY2, (TM12 = Y11)
// Determinant = TM00*TM11 - TM01*TM10
// = DX1*DY2 - DX2*DY1
// Inverse is:
// IM00 = TM11/det, IM01 = -TM01/det
// IM10 = -TM10/det, IM11 = TM00/det
// IM02 = (TM01 * TM12 - TM11 * TM02) / det,
// IM12 = (TM10 * TM02 - TM00 * TM12) / det,
#define DECLARE_MATRIX(MAT) \
jfloat MAT ## 00, MAT ## 01, MAT ## 02, MAT ## 10, MAT ## 11, MAT ## 12
#define GET_INVERTED_MATRIX(MAT, X11, Y11, DX1, DY1, DX2, DY2, RET_CODE) \
do { \
jfloat det = DX1*DY2 - DX2*DY1; \
if (det == 0) { \
RET_CODE; \
} \
MAT ## 00 = DY2/det; \
MAT ## 01 = -DX2/det; \
MAT ## 10 = -DY1/det; \
MAT ## 11 = DX1/det; \
MAT ## 02 = (DX2 * Y11 - DY2 * X11) / det; \
MAT ## 12 = (DY1 * X11 - DX1 * Y11) / det; \
} while (0)
#define TRANSFORM(MAT, TX, TY, X, Y) \
do { \
TX = (X) * MAT ## 00 + (Y) * MAT ## 01 + MAT ## 02; \
TY = (X) * MAT ## 10 + (Y) * MAT ## 11 + MAT ## 12; \
} while (0)
void
MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12)
{
if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: current dest is null");
return;
}
J2dTraceLn7(J2D_TRACE_INFO,
"MTLRenderer_FillAAParallelogram "
"(x=%6.2f y=%6.2f "
"dx1=%6.2f dy1=%6.2f "
"dx2=%6.2f dy2=%6.2f dst tex=%p)",
fx11, fy11,
dx21, dy21,
dx12, dy12, dstOps->pTexture);
struct Vertex verts[QUAD_VERTEX_COUNT] = {
{ {fx11, fy11}},
{ {fx11+dx21, fy11+dy21}},
{ {fx11+dx12, fy11+dy12}},
{ {fx11 + dx21 + dx12, fy11+ dy21 + dy12}
}};
id<MTLTexture> dstTxt = dstOps->pTexture;
// Encode render command.
id<MTLRenderCommandEncoder> mtlEncoder =
[mtlc.encoderManager getAARenderEncoder:dstOps];
if (mtlEncoder == nil) {
return;
}
[mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
[mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: QUAD_VERTEX_COUNT];
}
void
MTLRenderer_FillAAParallelogramInnerOuter(MTLContext *mtlc, MTLSDOps *dstOps,
jfloat ox11, jfloat oy11,
jfloat ox21, jfloat oy21,
jfloat ox12, jfloat oy12,
jfloat ix11, jfloat iy11,
jfloat ix21, jfloat iy21,
jfloat ix12, jfloat iy12)
{
//TODO
J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillAAParallelogramInnerOuter -- :TODO");
}
void
MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
jfloat fx11, jfloat fy11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12)
{
//TODO
// dx,dy for line width in the "21" and "12" directions.
jfloat ldx21, ldy21, ldx12, ldy12;
// parameters for "outer" parallelogram
jfloat ofx11, ofy11, odx21, ody21, odx12, ody12;
// parameters for "inner" parallelogram
jfloat ifx11, ify11, idx21, idy21, idx12, idy12;
J2dTraceLn8(J2D_TRACE_ERROR,
"MTLRenderer_DrawAAParallelogram -- :TODO"
"(x=%6.2f y=%6.2f "
"dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
"dx2=%6.2f dy2=%6.2f lwr2=%6.2f)",
fx11, fy11,
dx21, dy21, lwr21,
dx12, dy12, lwr12);
}
void
MTLRenderer_EnableAAParallelogramProgram()
{
//TODO
J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_EnableAAParallelogramProgram -- :TODO");
}
void
MTLRenderer_DisableAAParallelogramProgram()
{
//TODO
J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_DisableAAParallelogramProgram -- :TODO");
}
#endif /* !HEADLESS */

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLSurfaceData_h_Included
#define MTLSurfaceData_h_Included
#import "MTLSurfaceDataBase.h"
#import "MTLGraphicsConfig.h"
#import "AWTWindow.h"
#import "MTLLayer.h"
/**
* The CGLSDOps structure contains the CGL-specific information for a given
* MTLSurfaceData. It is referenced by the native MTLSDOps structure.
*/
typedef struct _MTLSDOps {
AWTView *peerData;
MTLLayer *layer;
jint argb[4]; // background clear color
MTLGraphicsConfigInfo *configInfo;
} MTLSDOps;
// debug-method
NSString * getSurfaceDescription(const BMTLSDOps * bmtlsdOps);
#endif /* MTLSurfaceData_h_Included */

View File

@@ -0,0 +1,420 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import <stdlib.h>
#import "sun_java2d_metal_MTLSurfaceData.h"
#import "jni_util.h"
#import "MTLRenderQueue.h"
#import "MTLGraphicsConfig.h"
#import "MTLSurfaceData.h"
#import "ThreadUtilities.h"
#include "jlong.h"
/**
* The following methods are implemented in the windowing system (i.e. GLX
* and WGL) source files.
*/
extern jlong MTLSD_GetNativeConfigInfo(BMTLSDOps *bmtlsdo);
extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, BMTLSDOps *bmtlsdo);
extern void MTLSD_DestroyMTLSurface(JNIEnv *env, BMTLSDOps *bmtlsdo);
void MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *bmtlsdo, jint w, jint h);
static jboolean MTLSurfaceData_initTexture(BMTLSDOps *bmtlsdo, jboolean isOpaque, jboolean rtt, jint width, jint height) {
@autoreleasepool {
if (bmtlsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: ops are null");
return JNI_FALSE;
}
if (width <= 0 || height <= 0) {
J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: texture dimensions is incorrect, w=%d, h=%d", width, height);
return JNI_FALSE;
}
MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps;
if (mtlsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps are null");
return JNI_FALSE;
}
if (mtlsdo->configInfo == NULL || mtlsdo->configInfo->context == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps wasn't initialized (context is null)");
return JNI_FALSE;
}
MTLContext* ctx = mtlsdo->configInfo->context;
width = (width <= MaxTextureSize) ? width : 0;
height = (height <= MaxTextureSize) ? height : 0;
J2dTraceLn3(J2D_TRACE_VERBOSE, " desired texture dimensions: w=%d h=%d max=%d",
width, height, MaxTextureSize);
// if either dimension is 0, we cannot allocate a texture with the
// requested dimensions
if ((width == 0 || height == 0)) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: texture dimensions too large");
return JNI_FALSE;
}
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm width: width height: height mipmapped: NO];
textureDescriptor.usage = MTLTextureUsageUnknown;
textureDescriptor.storageMode = MTLStorageModePrivate;
bmtlsdo->pTexture = [ctx.device newTextureWithDescriptor: textureDescriptor];
MTLTextureDescriptor *stencilDataDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR8Uint width:width height:height mipmapped:NO];
stencilDataDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
stencilDataDescriptor.storageMode = MTLStorageModePrivate;
bmtlsdo->pStencilData = [ctx.device newTextureWithDescriptor:stencilDataDescriptor];
bmtlsdo->pAAStencilData = [ctx.device newTextureWithDescriptor:textureDescriptor];
bmtlsdo->pStencilDataBuf = [ctx.device newBufferWithLength:width*height options:MTLResourceStorageModePrivate];
bmtlsdo->pAAStencilDataBuf = [ctx.device newBufferWithLength:width*height*4 options:MTLResourceStorageModePrivate];
MTLTextureDescriptor *stencilTextureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatStencil8 width:width height:height mipmapped:NO];
stencilTextureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
stencilTextureDescriptor.storageMode = MTLStorageModePrivate;
bmtlsdo->pStencilTexture = [ctx.device newTextureWithDescriptor:stencilTextureDescriptor];
bmtlsdo->isOpaque = isOpaque;
bmtlsdo->xOffset = 0;
bmtlsdo->yOffset = 0;
bmtlsdo->width = width;
bmtlsdo->height = height;
bmtlsdo->textureWidth = width;
bmtlsdo->textureHeight = height;
bmtlsdo->textureTarget = -1;
bmtlsdo->drawableType = rtt ? MTLSD_RT_TEXTURE : MTLSD_TEXTURE;
J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLSurfaceData_initTexture: w=%d h=%d bp=%p [tex=%p] opaque=%d rtt=%d", width, height, bmtlsdo, bmtlsdo->pTexture, isOpaque, rtt);
return JNI_TRUE;
}
}
/**
* Initializes an MTL texture, using the given width and height as
* a guide.
*/
JNIEXPORT jboolean JNICALL
Java_sun_java2d_metal_MTLSurfaceData_initTexture(
JNIEnv *env, jobject mtlsd,
jlong pData, jboolean isOpaque,
jint width, jint height
) {
if (!MTLSurfaceData_initTexture((BMTLSDOps *)pData, isOpaque, JNI_FALSE, width, height))
return JNI_FALSE;
MTLSD_SetNativeDimensions(env, (BMTLSDOps *)pData, width, height);
return JNI_TRUE;
}
/**
* Initializes a framebuffer object, using the given width and height as
* a guide. See MTLSD_InitTextureObject() and MTLSD_initRTexture()
* for more information.
*/
JNIEXPORT jboolean JNICALL
Java_sun_java2d_metal_MTLSurfaceData_initRTexture
(JNIEnv *env, jobject mtlsd,
jlong pData, jboolean isOpaque,
jint width, jint height)
{
if (!MTLSurfaceData_initTexture((BMTLSDOps *)pData, isOpaque, JNI_TRUE, width, height))
return JNI_FALSE;
MTLSD_SetNativeDimensions(env, (BMTLSDOps *)pData, width, height);
return JNI_TRUE;
}
/**
* Initializes a surface in the backbuffer of a given double-buffered
* onscreen window for use in a BufferStrategy.Flip situation. The bounds of
* the backbuffer surface should always be kept in sync with the bounds of
* the underlying native window.
*/
JNIEXPORT jboolean JNICALL
Java_sun_java2d_metal_MTLSurfaceData_initFlipBackbuffer
(JNIEnv *env, jobject mtlsd,
jlong pData)
{
//TODO
MTLSDOps *mtlsdo = (MTLSDOps *)jlong_to_ptr(pData);
J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_initFlipBackbuffer -- :TODO");
return JNI_TRUE;
}
JNIEXPORT jlong JNICALL
Java_sun_java2d_metal_MTLSurfaceData_getMTLTexturePointer(JNIEnv *env, jobject mtlsd, jlong pData) {
if (pData == 0)
return 0;
return ptr_to_jlong(((BMTLSDOps *)pData)->pTexture);
}
/**
* Initializes nativeWidth/Height fields of the surfaceData object with
* passed arguments.
*/
void
MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo,
jint width, jint height)
{
jobject sdObject;
sdObject = (*env)->NewLocalRef(env, mtlsdo->sdOps.sdObject);
if (sdObject == NULL) {
return;
}
JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width);
if (!((*env)->ExceptionOccurred(env))) {
JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height);
}
(*env)->DeleteLocalRef(env, sdObject);
}
/**
* Deletes native OpenGL resources associated with this surface.
*/
void
MTLSD_Delete(JNIEnv *env, BMTLSDOps *bmtlsdo)
{
J2dTraceLn3(J2D_TRACE_VERBOSE, "MTLSD_Delete: type=%d %p [tex=%p]", bmtlsdo->drawableType, bmtlsdo, bmtlsdo->pTexture);
if (bmtlsdo->drawableType == MTLSD_WINDOW) {
MTLSD_DestroyMTLSurface(env, bmtlsdo);
} else if (
bmtlsdo->drawableType == MTLSD_RT_TEXTURE
|| bmtlsdo->drawableType == MTLSD_TEXTURE
|| bmtlsdo->drawableType == MTLSD_FLIP_BACKBUFFER
) {
[(NSObject *)bmtlsdo->pTexture release];
[(NSObject *)bmtlsdo->pStencilTexture release];
[(NSObject *)bmtlsdo->pStencilData release];
[(NSObject *)bmtlsdo->pStencilDataBuf release];
[(NSObject *)bmtlsdo->pAAStencilData release];
[(NSObject *)bmtlsdo->pAAStencilDataBuf release];
bmtlsdo->pTexture = NULL;
bmtlsdo->drawableType = MTLSD_UNDEFINED;
}
}
/**
* This is the implementation of the general DisposeFunc defined in
* SurfaceData.h and used by the Disposer mechanism. It first flushes all
* native OpenGL resources and then frees any memory allocated within the
* native MTLSDOps structure.
*/
void
MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
{
BMTLSDOps *bmtlsdo = (BMTLSDOps *)ops;
jobject graphicsConfig = bmtlsdo->graphicsConfig;
JNU_CallStaticMethodByName(env, NULL, "sun/java2d/metal/MTLSurfaceData",
"dispose",
"(JLsun/java2d/metal/MTLGraphicsConfig;)V",
ptr_to_jlong(ops), graphicsConfig);
(*env)->DeleteGlobalRef(env, graphicsConfig);
bmtlsdo->graphicsConfig = NULL;
}
/**
* This is the implementation of the general surface LockFunc defined in
* SurfaceData.h.
*/
jint
MTLSD_Lock(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo,
jint lockflags)
{
JNU_ThrowInternalError(env, "MTLSD_Lock not implemented!");
return SD_FAILURE;
}
/**
* This is the implementation of the general GetRasInfoFunc defined in
* SurfaceData.h.
*/
void
MTLSD_GetRasInfo(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo)
{
JNU_ThrowInternalError(env, "MTLSD_GetRasInfo not implemented!");
}
/**
* This is the implementation of the general surface UnlockFunc defined in
* SurfaceData.h.
*/
void
MTLSD_Unlock(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo)
{
JNU_ThrowInternalError(env, "MTLSD_Unlock not implemented!");
}
/**
* This function disposes of any native windowing system resources associated
* with this surface.
*/
void
MTLSD_DestroyMTLSurface(JNIEnv *env, BMTLSDOps * bmtlsdo)
{
J2dTraceLn(J2D_TRACE_ERROR, "MTLSD_DestroyMTLSurface not implemented!");
JNF_COCOA_ENTER(env);
if (bmtlsdo->drawableType == MTLSD_WINDOW) {
// TODO: detach the NSView from the metal context
}
bmtlsdo->drawableType = MTLSD_UNDEFINED;
JNF_COCOA_EXIT(env);
}
/**
* This function initializes a native window surface and caches the window
* bounds in the given BMTLSDOps. Returns JNI_TRUE if the operation was
* successful; JNI_FALSE otherwise.
*/
jboolean
MTLSD_InitMTLWindow(JNIEnv *env, BMTLSDOps *bmtlsdo)
{
if (bmtlsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: ops are null");
return JNI_FALSE;
}
MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps;
if (mtlsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: priv ops are null");
return JNI_FALSE;
}
AWTView *v = mtlsdo->peerData;
if (v == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSD_InitMTLWindow: view is invalid");
return JNI_FALSE;
}
JNF_COCOA_ENTER(env);
NSRect surfaceBounds = [v bounds];
bmtlsdo->drawableType = MTLSD_WINDOW;
bmtlsdo->isOpaque = JNI_TRUE;
bmtlsdo->width = surfaceBounds.size.width;
bmtlsdo->height = surfaceBounds.size.height;
JNF_COCOA_EXIT(env);
J2dTraceLn2(J2D_TRACE_VERBOSE, " created window: w=%d h=%d", bmtlsdo->width, bmtlsdo->height);
return JNI_TRUE;
}
void
MTLSD_SwapBuffers(JNIEnv *env, jlong pPeerData)
{
J2dTraceLn(J2D_TRACE_ERROR, "OGLSD_SwapBuffers -- :TODO");
}
#pragma mark -
#pragma mark "--- CGLSurfaceData methods ---"
extern LockFunc MTLSD_Lock;
extern GetRasInfoFunc MTLSD_GetRasInfo;
extern UnlockFunc MTLSD_Unlock;
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLSurfaceData_initOps
(JNIEnv *env, jobject mtlsd, jobject gc,
jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
jint xoff, jint yoff, jboolean isOpaque)
{
BMTLSDOps *bmtlsdo = (BMTLSDOps *)SurfaceData_InitOps(env, mtlsd, sizeof(BMTLSDOps));
MTLSDOps *mtlsdo = (MTLSDOps *)malloc(sizeof(MTLSDOps));
J2dTraceLn1(J2D_TRACE_INFO, "MTLSurfaceData_initOps p=%p", bmtlsdo);
J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData));
J2dTraceLn1(J2D_TRACE_INFO, " layerPtr=%p", jlong_to_ptr(layerPtr));
J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff);
gc = (*env)->NewGlobalRef(env, gc);
if (gc == NULL) {
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
if (mtlsdo == NULL) {
(*env)->DeleteGlobalRef(env, gc);
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
// later the graphicsConfig will be used for deallocation of mtlsdo
bmtlsdo->privOps = mtlsdo;
bmtlsdo->graphicsConfig = gc;
bmtlsdo->sdOps.Lock = MTLSD_Lock;
bmtlsdo->sdOps.GetRasInfo = MTLSD_GetRasInfo;
bmtlsdo->sdOps.Unlock = MTLSD_Unlock;
bmtlsdo->sdOps.Dispose = MTLSD_Dispose;
bmtlsdo->drawableType = MTLSD_UNDEFINED;
bmtlsdo->needsInit = JNI_TRUE;
bmtlsdo->xOffset = xoff;
bmtlsdo->yOffset = yoff;
bmtlsdo->isOpaque = isOpaque;
mtlsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData);
mtlsdo->layer = (MTLLayer *)jlong_to_ptr(layerPtr);
mtlsdo->configInfo = (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
if (mtlsdo->configInfo == NULL) {
free(mtlsdo);
JNU_ThrowNullPointerException(env, "Config info is null in initOps");
}
}
JNIEXPORT void JNICALL
Java_sun_java2d_metal_MTLSurfaceData_clearWindow
(JNIEnv *env, jobject cglsd)
{
J2dTraceLn(J2D_TRACE_INFO, "CGLSurfaceData_clearWindow");
BMTLSDOps *mtlsdo = (MTLSDOps*) SurfaceData_GetOps(env, cglsd);
MTLSDOps *cglsdo = (MTLSDOps*) mtlsdo->privOps;
cglsdo->peerData = NULL;
cglsdo->layer = NULL;
}
NSString * getSurfaceDescription(const BMTLSDOps * bmtlsdOps) {
if (bmtlsdOps == NULL)
return @"NULL";
return [NSString stringWithFormat:@"%p [tex=%p, %dx%d, O=%d]", bmtlsdOps, bmtlsdOps->pTexture, bmtlsdOps->width, bmtlsdOps->height, bmtlsdOps->isOpaque];
}

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef MTLSurfaceDataBase_h_Included
#define MTLSurfaceDataBase_h_Included
#include "java_awt_image_AffineTransformOp.h"
#include "sun_java2d_metal_MTLSurfaceData.h"
#include "sun_java2d_pipe_hw_AccelSurface.h"
#include "SurfaceData.h"
#include "Trace.h"
#include "MTLFuncs.h"
/**
* The MTLPixelFormat structure contains all the information OpenGL needs to
* know when copying from or into a particular system memory image buffer (via
* glDrawPixels(), glReadPixels, glTexSubImage2D(), etc).
*
* GLenum format;
* The pixel format parameter used in glDrawPixels() and other similar calls.
* Indicates the component ordering for each pixel (e.g. GL_BGRA).
*
* GLenum type;
* The pixel data type parameter used in glDrawPixels() and other similar
* calls. Indicates the data type for an entire pixel or for each component
* in a pixel (e.g. GL_UNSIGNED_BYTE with GL_BGR means a pixel consists of
* 3 unsigned byte components, blue first, then green, then red;
* GL_UNSIGNED_INT_8_8_8_8_REV with GL_BGRA means a pixel consists of 1
* unsigned integer comprised of four byte components, alpha first, then red,
* then green, then blue).
*
* jint alignment;
* The byte alignment parameter used in glPixelStorei(GL_UNPACK_ALIGNMENT). A
* value of 4 indicates that each pixel starts on a 4-byte aligned region in
* memory, and so on. This alignment parameter helps OpenGL speed up pixel
* transfer operations by transferring memory in aligned blocks.
*
* jboolean hasAlpha;
* If true, indicates that this pixel format contains an alpha component.
*
* jboolean isPremult;
* If true, indicates that this pixel format contains color components that
* have been pre-multiplied by their corresponding alpha component.
*/
typedef struct {
//GLenum format;
//GLenum type;
jint format;
jint type;
jint alignment;
jboolean hasAlpha;
jboolean isPremult;
} MTPixelFormat;
/**
* The MTLSDOps structure describes a native OpenGL surface and contains all
* information pertaining to the native surface. Some information about
* the more important/different fields:
*
* void *privOps;
* Pointer to native-specific (GLX, WGL, etc.) SurfaceData info, such as the
* native Drawable handle and GraphicsConfig data.
*
* jint drawableType;
* The surface type; can be any one of the surface type constants defined
* below (MTLSD_WINDOW, MTLSD_TEXTURE, etc).
*
* GLenum activeBuffer;
* Can be either GL_FRONT if this is the front buffer surface of an onscreen
* window or a pbuffer surface, or GL_BACK if this is the backbuffer surface
* of an onscreen window.
*
* jboolean isOpaque;
* If true, the surface should be treated as being fully opaque. If
* the underlying surface (e.g. pbuffer) has an alpha channel and isOpaque
* is true, then we should take appropriate action (i.e. call glColorMask()
* to disable writes into the alpha channel) to ensure that the surface
* remains fully opaque.
*
* jboolean needsInit;
* If true, the surface requires some one-time initialization, which should
* be performed after a context has been made current to the surface for
* the first time.
*
* jint x/yOffset
* The offset in pixels of the OpenGL viewport origin from the lower-left
* corner of the heavyweight drawable. For example, a top-level frame on
* Windows XP has lower-left insets of (4,4). The OpenGL viewport origin
* would typically begin at the lower-left corner of the client region (inside
* the frame decorations), but AWT/Swing will take the insets into account
* when rendering into that window. So in order to account for this, we
* need to adjust the OpenGL viewport origin by an x/yOffset of (-4,-4). On
* X11, top-level frames typically don't have this insets issue, so their
* x/yOffset would be (0,0) (the same applies to pbuffers).
*
* jint width/height;
* The cached surface bounds. For offscreen surface types (MTLSD_FBOBJECT,
* MTLSD_TEXTURE, etc.) these values must remain constant. Onscreen window
* surfaces (MTLSD_WINDOW, MTLSD_FLIP_BACKBUFFER, etc.) may have their
* bounds changed in response to a programmatic or user-initiated event, so
* these values represent the last known dimensions. To determine the true
* current bounds of this surface, query the native Drawable through the
* privOps field.
*
* GLuint textureID;
* The texture object handle, as generated by glGenTextures(). If this value
* is zero, the texture has not yet been initialized.
*
* jint textureWidth/Height;
* The actual bounds of the texture object for this surface. If the
* GL_ARB_texture_non_power_of_two extension is not present, the dimensions
* of an OpenGL texture object must be a power-of-two (e.g. 64x32 or 128x512).
* The texture image that we care about has dimensions specified by the width
* and height fields in this MTLSDOps structure. For example, if the image
* to be stored in the texture has dimensions 115x47, the actual OpenGL
* texture we allocate will have dimensions 128x64 to meet the pow2
* restriction. The image bounds within the texture can be accessed using
* floating point texture coordinates in the range [0.0,1.0].
*
* GLenum textureTarget;
* The texture target of the texture object for this surface. If this
* surface is not backed by a texture, this value is set to zero. Otherwise,
* this value is GL_TEXTURE_RECTANGLE_ARB when the GL_ARB_texture_rectangle
* extension is in use; if not, it is set to GL_TEXTURE_2D.
*
* GLint textureFilter;
* The current filter state for this texture object (can be either GL_NEAREST
* or GL_LINEAR). We cache this value here and check it before updating
* the filter state to avoid redundant calls to glTexParameteri() when the
* filter state remains constant (see the MTLSD_UPDATE_TEXTURE_FILTER()
* macro below).
*
* GLuint fbobjectID, depthID;
* The object handles for the framebuffer object and depth renderbuffer
* associated with this surface. These fields are only used when
* drawableType is MTLSD_FBOBJECT, otherwise they are zero.
*/
typedef struct {
SurfaceDataOps sdOps;
void *privOps;
jobject graphicsConfig;
jint drawableType;
jint activeBuffer;
jboolean isOpaque;
jboolean needsInit;
jint xOffset;
jint yOffset;
jint width;
jint height;
void* pTexture;
void* pStencilData; // stencil data to be rendered to this buffer
void* pStencilDataBuf; // MTLBuffer with stencil data
void* pStencilTexture; // stencil texture byte buffer stencil mask used in main rendering
void* pAAStencilData; // stencil data for AA rendering
void* pAAStencilDataBuf; // MTLBuffer with AA stencil data
jint textureWidth;
jint textureHeight;
/* GLenum */ jint textureTarget;
/* GLint */ jint textureFilter;
/* GLuint */ jint fbobjectID;
/* GLuint */ jint depthID;
} BMTLSDOps;
#define MTLSD_UNDEFINED sun_java2d_pipe_hw_AccelSurface_UNDEFINED
#define MTLSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW
#define MTLSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE
#define MTLSD_FLIP_BACKBUFFER sun_java2d_pipe_hw_AccelSurface_FLIP_BACKBUFFER
#define MTLSD_RT_TEXTURE sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE
/**
* These are shorthand names for the filtering method constants used by
* image transform methods.
*/
#define MTLSD_XFORM_DEFAULT 0
#define MTLSD_XFORM_NEAREST_NEIGHBOR \
java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR
#define MTLSD_XFORM_BILINEAR \
java_awt_image_AffineTransformOp_TYPE_BILINEAR
/**
* The SurfaceRasterFlags structure contains information about raster (of some MTLTexture):
*
* jboolean isOpaque;
* If true, indicates that this pixel format hasn't alpha component (and values of this component can contain garbage).
*
* jboolean isPremultiplied;
* If true, indicates that this pixel format contains color components that have been pre-multiplied by their
* corresponding alpha component.
*/
typedef struct {
jboolean isOpaque;
jboolean isPremultiplied;
} SurfaceRasterFlags;
/**
* Exported methods.
*/
jint MTLSD_Lock(JNIEnv *env,
SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo,
jint lockflags);
void MTLSD_GetRasInfo(JNIEnv *env,
SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo);
void MTLSD_Unlock(JNIEnv *env,
SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo);
void MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops);
void MTLSD_Delete(JNIEnv *env, BMTLSDOps *mtlsdo);
jint MTLSD_NextPowerOfTwo(jint val, jint max);
#endif /* MTLSurfaceDataBase_h_Included */

Some files were not shown because too many files have changed in this diff Show More