From kcr at openjdk.org Thu May 1 17:24:47 2025 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 1 May 2025 17:24:47 GMT Subject: RFR: 8332947: [macos] java.awt.desktop.OpenURIHandler is not receiving events [v5] In-Reply-To: References: Message-ID: On Tue, 29 Apr 2025 22:44:22 GMT, Pabulaner IV wrote: > Answer to question 2: > > I found the issue and moved the registration of the embedded event handler up. This way the embedded events can be received, even if AWT runs embedded. With this latest update, I can see how this will work; and the log output you provided shows that it wouldn't have in the original form. We'll review the proposed solution when we can. ------------- PR Comment: https://git.openjdk.org/jdk/pull/24379#issuecomment-2845301517 From honkar at openjdk.org Thu May 1 18:40:49 2025 From: honkar at openjdk.org (Harshitha Onkar) Date: Thu, 1 May 2025 18:40:49 GMT Subject: RFR: 8350203: [macos] Newlines and tabs are not ignored when drawing text to a Graphics2D object In-Reply-To: References: Message-ID: On Mon, 17 Feb 2025 14:06:53 GMT, Daniel Gredler wrote: > On other platforms like Windows and Linux, the `\n`, `\r` and `\t` characters are ignored when drawing text to a `Graphics2D` object. On macOS this is not currently the case. > > See, for example, `CMap.getControlCodeGlyph(int, boolean)` or `RasterPrinterJob.removeControlChars(String)`. > > This bug was found while running `test/jdk/java/awt/print/PrinterJob/PrintTextTest.java` on macOS. > > The new test class passes on Linux, Windows and macOS. @gredler Tested your fix by applying your changes on top of harfbuzz upgrade - https://github.com/openjdk/jdk/pull/24973 . Initial testing of your fix with IgnoredWhitespaceTest.java test and NLGlyphTest.java looks good. I haven't done a full fledged testing yet. This PR fixes the same issue observed on another test - `java/awt/font/TextLayout/TestControls.java` - [JDK-8353187](https://bugs.openjdk.org/browse/JDK-8353187). You can link the additional JBS ID to this PR with `/issue add 8353187` I will be integrating harfbuzz upgrade PR soon after which you can sync your branch with mainline to test it on your end. ------------- PR Review: https://git.openjdk.org/jdk/pull/23665#pullrequestreview-2810426871 From dgredler at openjdk.org Thu May 1 19:09:47 2025 From: dgredler at openjdk.org (Daniel Gredler) Date: Thu, 1 May 2025 19:09:47 GMT Subject: RFR: 8350203: [macos] Newlines and tabs are not ignored when drawing text to a Graphics2D object In-Reply-To: <5mfWz8FHdIhs-j2Hn6q9NwomFhabKffMB9omJfE9phw=.d50f285c-32f4-4f8e-a428-98d3a8680e65@github.com> References: <5mfWz8FHdIhs-j2Hn6q9NwomFhabKffMB9omJfE9phw=.d50f285c-32f4-4f8e-a428-98d3a8680e65@github.com> Message-ID: <31Af0IbTC_NoxDcBkSSNU_57y8t1sahHY1rKDoM_Ju0=.7b18ec9c-f540-490d-92b3-b154d3e0ba72@github.com> On Thu, 3 Apr 2025 22:12:28 GMT, Harshitha Onkar wrote: >> @gredler Yes, JDK harfbuzz was just upgraded to v10.4.0 - https://github.com/openjdk/jdk/pull/23910. >> >> @prrace Do we consider patching the fix from upstream (https://github.com/harfbuzz/harfbuzz/pull/5119) for this upgrade or can it wait till the next time harfbuzz is upgraded on jdk ? > >> @honkar-jdk pls remember we need an updated harfbuzz for this PR to proceed. > > Noted. Thank you for the reminder. @honkar-jdk Great, thanks! I'll keep an eye on the HarfBuzz upgrade PR and sync + test once it has been integrated. ------------- PR Comment: https://git.openjdk.org/jdk/pull/23665#issuecomment-2845524602 From dgredler at openjdk.org Thu May 1 20:05:45 2025 From: dgredler at openjdk.org (Daniel Gredler) Date: Thu, 1 May 2025 20:05:45 GMT Subject: RFR: 8353230: Emoji rendering regression after JDK-8208377 In-Reply-To: References: <-N8_d2SHcl-h9yG8t6-WKGF_nGLJZQTu4ymMD2oPGrg=.651c8251-b235-4681-b82a-4ee680eb6593@github.com> Message-ID: On Tue, 29 Apr 2025 09:55:56 GMT, Nikita Gubarkov wrote: >> It looks like this regression actually fits into a longer series of fixes / regressions in this area: >> >> - [JDK-4517298](https://bugs.openjdk.org/browse/JDK-4517298) fixed metrics for zero-width characters, but broke some ligatures / glyph substitutions >> - [JDK-7017058](https://bugs.openjdk.org/browse/JDK-7017058) fixed the ligatures / glyph substitutions, but broke some zero-width metrics >> - [JDK-8208377](https://bugs.openjdk.org/browse/JDK-8208377) fixed some metrics and rendering for zero-width characters, but broke some ligatures / glyph substitutions >> - Now, with this PR, we aim to fix the ligatures without re-breaking zero-width metrics and display >> >> We have two different types of use cases pulling `CharToGlyphMapper` in two different directions: the users who need raw, untransformed glyph info, and the users who need normalized / transformed glyph info. >> >> It looks to me like, in the current code base, the only `CharToGlyphMapper` user which requires raw font data is HarfBuzz (explicitly confirmed with the HarfBuzz team here: https://github.com/harfbuzz/harfbuzz/discussions/5234). >> >> The regression mechanism at play here is that the HarfBuzz font callbacks are currently providing HarfBuzz with transformed glyph info (e.g. ZWJ -> INVISIBLE_GLYPH_ID), which prevents HarfBuzz from recognizing and applying the correct font GSUB substitutions (which involve ZWJ). >> >> In order to fix this without (yet again) breaking metrics and display behavior elsewhere, I've added two methods to `CharToGlyphMapper` which provide access to raw glyph info, to be used by the HarfBuzz font callbacks: `charToGlyphRaw(int)` and `charToVariationGlyphRaw(int)`. >> >> Note two intricacies related to `CompositeGlyphMapper`: >> 1. We need to be careful to only cache raw (untransformed) values, to avoid conflicts between requests for a raw version of a glyph and a transformed version of the same glyph. Another option would have been two separate caches, but I don't think that's necessary. >> 2. Consumers who are using `CompositeGlyphMapper.SLOTMASK` to check glyph slots (e.g. `FontRunIterator` and `CTextPipe`) will "see" invisible glyphs as having come from slot 0. This isn't new, and I think it's OK, but something to be aware of. >> >> The glyph cache handling in `CCharToGlyphMapper` (for macOS) also requires care to avoid mixing value types. >> >> Please also note that I'm not sure if the tweak to `sunFont.c` is being tested, since FFM is being used by default for Harf... > > By the way, I see that in each implementation, both `charToGlyph` and `charToGlyphRaw` call a common method, like `getGlyph(int uniciode, boolean raw)`. At first there was just `charToGlyph`, then `charToVariationGlyph` was added and now you added a "raw" version for each of them, I see that in the future we will need other variants and how it's already starting an exponential explosion. Overriding all of those methods in each implementation brings quite a bit of boilerplate, and it becomes easier to miss something. Maybe take a step back and refactor this into a single `charToGlyph(int unicode, int variationSelector, boolean raw)` version? > Also, this `raw` parameter only really controls `isDefaultIgnorable` check in the end of each method. Maybe we could factor this out without bringing it separately into each mapper implementation? @YaaZ: Thanks for the additional feedback, please see my thoughts below: > By the way, I see that in each implementation, both charToGlyph and charToGlyphRaw call a common method, like getGlyph(int uniciode, boolean raw). At first there was just charToGlyph, then charToVariationGlyph was added and now you added a "raw" version for each of them, I see that in the future we will need other variants and how it's already starting an exponential explosion. I don't know if I would call two changes to `CharToGlyphMapper` in 20 years an exponential explosion, but I get your point :-) > Overriding all of those methods in each implementation brings quite a bit of boilerplate, and it becomes easier to miss something. True, but again keep in mind that there are only 5 implementations, only one of which (the macOS `CCharToGlyphMapper`) has been added in the last 20 years. > Maybe take a step back and refactor this into a single charToGlyph(int unicode, int variationSelector, boolean raw) version? We'd still need separate methods for `int` vs. `char`, but I think this might reduce 5 methods down to 3? The changeset would be a bit more intrusive (lots of callers would need to change to reflect the new method signature). I'd be interested to hear thoughts from some of the reviewers on this one. > Also, this raw parameter only really controls isDefaultIgnorable check in the end of each method. Maybe we could factor this out without bringing it separately into each mapper implementation? I prefer to think of it as controlling whether or not any transformations to `INVISIBLE_GLYPH_ID` happen (right now it's just for default-ignorable characters, but there may be other scenarios in the future, e.g. `\r`, `\n` and `\t` which currently are handled elsewhere). Any ideas for what this refactoring might look like? ------------- PR Comment: https://git.openjdk.org/jdk/pull/24412#issuecomment-2845646011 From prr at openjdk.org Thu May 1 20:06:45 2025 From: prr at openjdk.org (Phil Race) Date: Thu, 1 May 2025 20:06:45 GMT Subject: RFR: JDK-8355528 : Update HarfBuzz to 11.2.0 In-Reply-To: References: Message-ID: <7uJYkK2vsUG7zEUrn9jJLkD6Tu1iuIYVaHAlNGFWfV0=.d69f55f2-b7f9-42e3-b3e2-fa32fb631ccc@github.com> On Wed, 30 Apr 2025 19:37:29 GMT, Harshitha Onkar wrote: > HarfBuzz upgraded to 11.2.0 > > 4 newly added files and 99 modified files. Marked as reviewed by prr (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/24973#pullrequestreview-2810607371 From ngubarkov at openjdk.org Thu May 1 21:57:45 2025 From: ngubarkov at openjdk.org (Nikita Gubarkov) Date: Thu, 1 May 2025 21:57:45 GMT Subject: RFR: 8353230: Emoji rendering regression after JDK-8208377 In-Reply-To: <-N8_d2SHcl-h9yG8t6-WKGF_nGLJZQTu4ymMD2oPGrg=.651c8251-b235-4681-b82a-4ee680eb6593@github.com> References: <-N8_d2SHcl-h9yG8t6-WKGF_nGLJZQTu4ymMD2oPGrg=.651c8251-b235-4681-b82a-4ee680eb6593@github.com> Message-ID: On Thu, 3 Apr 2025 11:23:42 GMT, Daniel Gredler wrote: > It looks like this regression actually fits into a longer series of fixes / regressions in this area: > > - [JDK-4517298](https://bugs.openjdk.org/browse/JDK-4517298) fixed metrics for zero-width characters, but broke some ligatures / glyph substitutions > - [JDK-7017058](https://bugs.openjdk.org/browse/JDK-7017058) fixed the ligatures / glyph substitutions, but broke some zero-width metrics > - [JDK-8208377](https://bugs.openjdk.org/browse/JDK-8208377) fixed some metrics and rendering for zero-width characters, but broke some ligatures / glyph substitutions > - Now, with this PR, we aim to fix the ligatures without re-breaking zero-width metrics and display > > We have two different types of use cases pulling `CharToGlyphMapper` in two different directions: the users who need raw, untransformed glyph info, and the users who need normalized / transformed glyph info. > > It looks to me like, in the current code base, the only `CharToGlyphMapper` user which requires raw font data is HarfBuzz (explicitly confirmed with the HarfBuzz team here: https://github.com/harfbuzz/harfbuzz/discussions/5234). > > The regression mechanism at play here is that the HarfBuzz font callbacks are currently providing HarfBuzz with transformed glyph info (e.g. ZWJ -> INVISIBLE_GLYPH_ID), which prevents HarfBuzz from recognizing and applying the correct font GSUB substitutions (which involve ZWJ). > > In order to fix this without (yet again) breaking metrics and display behavior elsewhere, I've added two methods to `CharToGlyphMapper` which provide access to raw glyph info, to be used by the HarfBuzz font callbacks: `charToGlyphRaw(int)` and `charToVariationGlyphRaw(int)`. > > Note two intricacies related to `CompositeGlyphMapper`: > 1. We need to be careful to only cache raw (untransformed) values, to avoid conflicts between requests for a raw version of a glyph and a transformed version of the same glyph. Another option would have been two separate caches, but I don't think that's necessary. > 2. Consumers who are using `CompositeGlyphMapper.SLOTMASK` to check glyph slots (e.g. `FontRunIterator` and `CTextPipe`) will "see" invisible glyphs as having come from slot 0. This isn't new, and I think it's OK, but something to be aware of. > > The glyph cache handling in `CCharToGlyphMapper` (for macOS) also requires care to avoid mixing value types. > > Please also note that I'm not sure if the tweak to `sunFont.c` is being tested, since FFM is being used by default for HarfBuzz integration. (Is there a plan to remove... I was talking about the explosion because there is a scenario in my mind, which I didn't make clear for everybody else. There is a change which I didn't have time to contribute, but would like to: it's related to composite fonts and variation selectors. We may need 2 variants for retrieving a glyph with a variation selector - one strictly matching a variation selector and another with a fallback to the base glyph, multiplied by raw/transformed versions, which adds 2 more methods. Not like it's a big problem, but given that they all end up calling a single method anyway... You get the point. > there may be other scenarios in the future, e.g. \r, \n and \t which currently are handled elsewhere). Are those scenarios specific to a patricular mapper/font type? I was thinking that those transformations are generic. > Any ideas for what this refactoring might look like? I was thinking about moving this default-ignorable or any potential generic transformation into base `CharToGlyphMapper` or even `Font2D`. For example, make default implementation of `CharToGlyphMapper.charToGlyph` check ignorable characters and then call `charToGlyphRaw` - then other implementations would only need to override `charToGlyphRaw`. ------------- PR Comment: https://git.openjdk.org/jdk/pull/24412#issuecomment-2845865987 From serb at openjdk.org Thu May 1 22:12:02 2025 From: serb at openjdk.org (Sergey Bylokhov) Date: Thu, 1 May 2025 22:12:02 GMT Subject: RFR: 8355790: Enhance code consistency: java.desktop/unix:sun.awt Message-ID: <7s8jC8r-uAS3k0NsaKJyhZMzhHVCOFbb-ZStbeBv9Pw=.b78af72d-c17f-4c57-b620-6a630a2aef80@github.com> The `java.desktop` module currently lacks proper use of the `@Override` annotation for methods and the `final` modifier for classes. While similar changes were previously made in the [JavaSound](https://github.com/openjdk/jdk/commit/e0c7d59246cf36644d494eced76e4b9d96ff1ded#diff-ae3e5f9c40fe25ef03e7a89844de174ef5c15e6179d769e2a4bcb7e73688c9b5), [java.desktop/windows](https://github.com/openjdk/jdk/pull/24170) (and some of the classes on demand), these changes are not as critical now due to the new jdk "encapsulation", but they are still useful for improving code consistency. To make the code review process easier I have made the following changes: 1. I chose `java.desktop/unix:sun.awt` as the starting package because it contains a relatively small number of classes 2. The public API was not affected so there is no need to worry about a CSR Note: I will submit additional patches in this area later because: 1. Only lines with `@Override` and `final` were modified to keep the diff clear - header dates were not updated (that could be covered by one patch similar to [this](https://bugs.openjdk.org/browse/JDK-8345797)) 2. I skipped adding `@Override` for anonymous classes Any feedback or suggestions are welcome! Here is a [link](https://patch-diff.githubusercontent.com/raw/openjdk/jdk/pull/24941.diff) to a simple diff file, it might be more convenient for reviewing the changes. To download the diff file and filter only the modified lines you can use the following script: curl -s https://patch-diff.githubusercontent.com/raw/openjdk/jdk/pull/24941.diff -o d.txt && grep -E '^+|^-' d.txt The build was successful, and I ran all the open jtreg tests without issues. But it's possible that some closed tests may be affected by these changes. It would be good to verify this by mach5 to ensure everything works as expected. ------------- Commit messages: - override in java.desktop/unix:sun.awt - final in java.desktop/unix:sun.awt Changes: https://git.openjdk.org/jdk/pull/24941/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24941&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8355790 Stats: 748 lines in 105 files changed: 646 ins; 1 del; 101 mod Patch: https://git.openjdk.org/jdk/pull/24941.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24941/head:pull/24941 PR: https://git.openjdk.org/jdk/pull/24941 From prr at openjdk.org Thu May 1 22:41:30 2025 From: prr at openjdk.org (Phil Race) Date: Thu, 1 May 2025 22:41:30 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip Message-ID: A simple API to replace java.applet.AudioClip ------------- Commit messages: - 8356049 - 8356049 Changes: https://git.openjdk.org/jdk/pull/24991/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24991&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8356049 Stats: 320 lines in 7 files changed: 317 ins; 1 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/24991.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24991/head:pull/24991 PR: https://git.openjdk.org/jdk/pull/24991 From mvs at openjdk.org Fri May 2 09:29:46 2025 From: mvs at openjdk.org (Manukumar V S) Date: Fri, 2 May 2025 09:29:46 GMT Subject: RFR: 8288471: java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI [v4] In-Reply-To: References: Message-ID: On Mon, 28 Apr 2025 09:32:26 GMT, Manukumar V S wrote: >> java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI, especially in MacOS machines. >> Also the frame created in this test is not disposed which may interfere with other tests. >> >> Fix: >> Some stabilisations added and the frame is disposed properly. >> >> Testing: >> Tested 100 times per platform(macosx-x64,macosx-aarch64,windows-x64,linux-x64) and got all PASS. >> I have also tested this on Windows-x64 with JDK 8u60b04 and JDK 8u60b20 as the original issue related to this test(JDK-8077409) was fixed in JDK 8u60b20. >> With JDK 8u60b04: >> Exception in thread "main" java.lang.RuntimeException: Wrong position of component in ScrollPane >> at bug8077409Test.main(bug8077409Test.java:142) >> >> With JDK 8u60b20: >> Passed..... > > Manukumar V S has updated the pull request incrementally with one additional commit since the last revision: > > Review comments fixed : Removed unwanted code and updated copyright year Any sponsors? ------------- PR Comment: https://git.openjdk.org/jdk/pull/24292#issuecomment-2846779659 From abhiscxk at openjdk.org Fri May 2 10:01:55 2025 From: abhiscxk at openjdk.org (Abhishek Kumar) Date: Fri, 2 May 2025 10:01:55 GMT Subject: RFR: 8288471: java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI [v4] In-Reply-To: References: Message-ID: <_zlFiWA0VIFjTaoKMr6gGZhuoO3v-IJZJ-Ya5T7g6O4=.1b96b879-27c4-42a3-95a5-f5198800fdfc@github.com> On Mon, 28 Apr 2025 09:32:26 GMT, Manukumar V S wrote: >> java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI, especially in MacOS machines. >> Also the frame created in this test is not disposed which may interfere with other tests. >> >> Fix: >> Some stabilisations added and the frame is disposed properly. >> >> Testing: >> Tested 100 times per platform(macosx-x64,macosx-aarch64,windows-x64,linux-x64) and got all PASS. >> I have also tested this on Windows-x64 with JDK 8u60b04 and JDK 8u60b20 as the original issue related to this test(JDK-8077409) was fixed in JDK 8u60b20. >> With JDK 8u60b04: >> Exception in thread "main" java.lang.RuntimeException: Wrong position of component in ScrollPane >> at bug8077409Test.main(bug8077409Test.java:142) >> >> With JDK 8u60b20: >> Passed..... > > Manukumar V S has updated the pull request incrementally with one additional commit since the last revision: > > Review comments fixed : Removed unwanted code and updated copyright year test/jdk/java/awt/ScrollPane/bug8077409Test.java line 32: > 30: */ > 31: > 32: Extra blank line can be removed. test/jdk/java/awt/ScrollPane/bug8077409Test.java line 58: > 56: add(pane, BorderLayout.CENTER); > 57: setSize(320, 480); > 58: For consistency, blank line can be removed. test/jdk/java/awt/ScrollPane/bug8077409Test.java line 75: > 73: throw new RuntimeException("Wrong position of component in ScrollPane"); > 74: } else { > 75: System.out.println("Passed....."); Redundant print statement. test/jdk/java/awt/ScrollPane/bug8077409Test.java line 85: > 83: protected void processKeyEvent(KeyEvent e) { > 84: super.processKeyEvent(e); > 85: For consistency, blank line can be removed. test/jdk/java/awt/ScrollPane/bug8077409Test.java line 89: > 87: > 88: class MyCanvas extends Canvas { > 89: public Dimension getPreferredSize() { You can add @Override for overridden method test/jdk/java/awt/ScrollPane/bug8077409Test.java line 93: > 91: } > 92: > 93: public void paint(Graphics g) { You can add `@Override` for overridden method ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071382835 PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071386731 PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071384232 PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071386531 PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071385141 PR Review Comment: https://git.openjdk.org/jdk/pull/24292#discussion_r2071384845 From mvs at openjdk.org Fri May 2 10:49:03 2025 From: mvs at openjdk.org (Manukumar V S) Date: Fri, 2 May 2025 10:49:03 GMT Subject: RFR: 8288471: java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI [v5] In-Reply-To: References: Message-ID: <2Y1tZfd5uHIxowWxcws3jxMJDP558uHTUABw7TqOQhE=.9d8930c9-118c-4510-86c2-fa887ae4228a@github.com> > java/awt/ScrollPane/bug8077409Test.java is unstable and fails intermittently in CI, especially in MacOS machines. > Also the frame created in this test is not disposed which may interfere with other tests. > > Fix: > Some stabilisations added and the frame is disposed properly. > > Testing: > Tested 100 times per platform(macosx-x64,macosx-aarch64,windows-x64,linux-x64) and got all PASS. > I have also tested this on Windows-x64 with JDK 8u60b04 and JDK 8u60b20 as the original issue related to this test(JDK-8077409) was fixed in JDK 8u60b20. > With JDK 8u60b04: > Exception in thread "main" java.lang.RuntimeException: Wrong position of component in ScrollPane > at bug8077409Test.main(bug8077409Test.java:142) > > With JDK 8u60b20: > Passed..... Manukumar V S has updated the pull request incrementally with one additional commit since the last revision: Review comments fixed : Formatting changes, added @override ------------- Changes: - all: https://git.openjdk.org/jdk/pull/24292/files - new: https://git.openjdk.org/jdk/pull/24292/files/13d1deeb..58349b9a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=24292&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=24292&range=03-04 Stats: 10 lines in 1 file changed: 2 ins; 8 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/24292.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24292/head:pull/24292 PR: https://git.openjdk.org/jdk/pull/24292 From ngubarkov at openjdk.org Fri May 2 16:16:46 2025 From: ngubarkov at openjdk.org (Nikita Gubarkov) Date: Fri, 2 May 2025 16:16:46 GMT Subject: RFR: 8352407: PixelInterleavedSampleModel with unused components throws RasterFormatException: Incorrect pixel stride [v2] In-Reply-To: References: <0IkJpQYFv_3lUjxKvd1T0EqtOeO4wN5XYEX1pJFf6Pc=.0eac5063-1b53-461b-8bc8-ca1320147a5a@github.com> <7PoUZmVaNchLPzKKv-Y2Kb3K2iTCIwF_GBxWgYOeSj8=.7c57eb44-10de-4e95-9fea-07ea39ed53ee@github.com> <9t4GmM3f624NKzcRzc1I4m-jDABNjukX93uJiEge0Bs=.b3a8c0f9-cd9c-4f61-9d80-700e5d37fcc7@github.com> <8dCI6Y3gKiDufYZEKkqrUk7Fn3lz3cwHVyi2gS7-Qck=.e4d29c99-7cce-4aad-a635-31f199970b61@github.com> Message-ID: <7b80MMi1QZ9zqKkL7LCFhaYSBiEMcVc5AgHmrWw5oO4=.23847f28-e1b0-43bb-b88e-2177b7ef9c09@github.com> On Fri, 25 Apr 2025 19:12:39 GMT, Sergey Bylokhov wrote: >> In your sample you provided an example, when raster fits whole pixels (`scanline * (height - 1) + pixelStride * width`), which, I agree, is a perfectly fine case and must be supported by accelerated pipelines. But the question is: should partial pixels be handled by our pipelines too (`scanline * (height - 1) + pixelStride * (width - 1) + maxBandOffset + 1` where `maxBandOffset + 1 < pixelStride`), or should whole pixels be enforced? I am for the latter. > > However, this is not a case of a "partial pixel"- the data for the pixel itself is present. Therefore, the user can still manually create a buffer that discards the tail of the image and it will be accepted: > > DataBuffer manualBuffer = new DataBufferByte( > scanlineStride * (SIZE - 1) + pixelStride * (SIZE - 1) + 2/*maxBandOffset*/ + 1 /*size of last component*/ > ); > > The current logic seems to imply that: > > * The scanline stride doesn't matter for a single-line image, or for the last line in the image. > * The pixel stride is irrelevant if there's only one pixel in the image, or for the last pixel in a row. > > This behavior is validated in src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java#verify, with the exception of the single-pixel image we mentioned earlier. > > I believe that exception for the 1-pixel image is a bug (pixelStride > data.length) that was overlooked during the work on commit [86104df](https://github.com/openjdk/jdk/commit/86104df#diff-f5003f18f0f4594a4859901ea950652467137fb1d07900208a84617036142746R891-L891), where a similar check for scanlineStride > data.length was fixed. Ok, I found another argument as to why I think we should allocate memory according to `pixelStride`, including padding. I am currently optimizing the Vulkan blit and specifically reducing the amount of extra copies, so the issue is real. In order to do draw an image, we need a Vulkan image. To bring raster data into Vulkan image we are currently doing 2 copies: software raster -> VkBuffer -> VkImage. We could get rid of one copy if we imported raster memory as an external allocation and bind VkBuffer to it directly: VkBuffer(software raster) -> VkImage. In theory we could even wrap host memory as an image and use it directly, but I doubt that would be more performant. So, if we try to import raster data as an external allocation, it becomes useless for the purposes of copying or sampling, because Vulkan requires the whole memory region to be resident, it will copy `height` rows of `rowLength` bytes and there is no way it could work in that strange scenario when we have RGBx raster with 1 byte of padding in the end, mapping to RGBA Vulkan format, and there is just a single missing byte in the end of the whole raster ruining our optimization, forcing us to memcpy the whole raster into a temporary buffer, which is just 1 byte larger so that we could properly copy that into Vulkan image. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24111#discussion_r2071847084 From duke at openjdk.org Fri May 2 17:18:51 2025 From: duke at openjdk.org (Hendrik Schick) Date: Fri, 2 May 2025 17:18:51 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip In-Reply-To: References: Message-ID: On Thu, 1 May 2025 22:31:32 GMT, Phil Race wrote: > A simple API to replace java.applet.AudioClip src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 101: > 99: clip.init(stream); > 100: } catch (final Exception e) { > 101: // AudioClip will be no-op if some exception will occurred Suggestion: // AudioClip will be no-op if some exception will occur or 'has occurred' (?) src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 114: > 112: clip.init(uc.getInputStream()); > 113: } catch (final Exception ignored) { > 114: // Playing the clip will be a no-op if an exception occured in inititialization. Suggestion: // Playing the clip will be a no-op if an exception occured in initialization. src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 124: > 122: clip.init(url.openStream()); > 123: } catch (final Exception ignored) { > 124: // Playing the clip will be a no-op if an exception occurred in inititialization. Suggestion: // Playing the clip will be a no-op if an exception occurred in initialization. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071917249 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071917636 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071917934 From duke at openjdk.org Fri May 2 17:23:50 2025 From: duke at openjdk.org (Hendrik Schick) Date: Fri, 2 May 2025 17:23:50 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip In-Reply-To: References: Message-ID: On Thu, 1 May 2025 22:31:32 GMT, Phil Race wrote: > A simple API to replace java.applet.AudioClip src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 294: > 292: public synchronized void update(LineEvent event) { > 293: if (clip != null) { > 294: if (clip == event.getSource()) { merge the two ifs to one if? test/jdk/javax/sound/SoundClip/SoundClipTest.java line 40: > 38: > 39: public static void main(String[] args) throws Exception { > 40: Suggestion: ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071921500 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071922997 From duke at openjdk.org Fri May 2 17:29:49 2025 From: duke at openjdk.org (Hendrik Schick) Date: Fri, 2 May 2025 17:29:49 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip In-Reply-To: References: Message-ID: On Thu, 1 May 2025 22:31:32 GMT, Phil Race wrote: > A simple API to replace java.applet.AudioClip test/jdk/javax/sound/SoundClip/SoundClipTest.java line 100: > 98: } > 99: } catch (Exception e) { > 100: System.err.println("Exception occured: "+e); Suggestion: System.err.println("Exception occurred: " + e); ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2071926408 From achung at openjdk.org Fri May 2 17:35:04 2025 From: achung at openjdk.org (Alisen Chung) Date: Fri, 2 May 2025 17:35:04 GMT Subject: RFR: 8343739: Test java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java failed: Wrong extended key code [v3] In-Reply-To: References: Message-ID: <-VKRExcwuamNGxB1FbvYY_rA-dXICYFodaqiI2QnSe0=.0c5f4481-4016-4333-8360-3c6d519f710b@github.com> > Test was failing on Ubuntu, looks to be a synchronous error in the test so I rewrote it to improve stability. Alisen Chung has updated the pull request incrementally with one additional commit since the last revision: check eventsCount ------------- Changes: - all: https://git.openjdk.org/jdk/pull/24885/files - new: https://git.openjdk.org/jdk/pull/24885/files/2199d038..711bd81f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=24885&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=24885&range=01-02 Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/24885.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24885/head:pull/24885 PR: https://git.openjdk.org/jdk/pull/24885 From achung at openjdk.org Fri May 2 18:34:45 2025 From: achung at openjdk.org (Alisen Chung) Date: Fri, 2 May 2025 18:34:45 GMT Subject: RFR: 8343739: Test java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java failed: Wrong extended key code [v3] In-Reply-To: <-VKRExcwuamNGxB1FbvYY_rA-dXICYFodaqiI2QnSe0=.0c5f4481-4016-4333-8360-3c6d519f710b@github.com> References: <-VKRExcwuamNGxB1FbvYY_rA-dXICYFodaqiI2QnSe0=.0c5f4481-4016-4333-8360-3c6d519f710b@github.com> Message-ID: On Fri, 2 May 2025 17:35:04 GMT, Alisen Chung wrote: >> Test was failing on Ubuntu, looks to be a synchronous error in the test so I rewrote it to improve stability. > > Alisen Chung has updated the pull request incrementally with one additional commit since the last revision: > > check eventsCount I've updated the test to include logging and ran the test 200x without failures. I think it's ok to push the test with these changes so that if the test ever does fail again we can use the logs and analyze the problem. ------------- PR Comment: https://git.openjdk.org/jdk/pull/24885#issuecomment-2847848635 From prr at openjdk.org Fri May 2 23:00:32 2025 From: prr at openjdk.org (Phil Race) Date: Fri, 2 May 2025 23:00:32 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip [v2] In-Reply-To: References: Message-ID: > A simple API to replace java.applet.AudioClip Phil Race has updated the pull request incrementally with one additional commit since the last revision: 8356049 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/24991/files - new: https://git.openjdk.org/jdk/pull/24991/files/d5ae1aef..299bce17 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=24991&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=24991&range=00-01 Stats: 2 lines in 2 files changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/24991.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24991/head:pull/24991 PR: https://git.openjdk.org/jdk/pull/24991 From prr at openjdk.org Fri May 2 23:00:33 2025 From: prr at openjdk.org (Phil Race) Date: Fri, 2 May 2025 23:00:33 GMT Subject: RFR: 8356049: Need a simple way to play back a sound clip [v2] In-Reply-To: References: Message-ID: On Fri, 2 May 2025 17:15:29 GMT, Hendrik Schick wrote: >> Phil Race has updated the pull request incrementally with one additional commit since the last revision: >> >> 8356049 > > src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 101: > >> 99: clip.init(stream); >> 100: } catch (final Exception e) { >> 101: // AudioClip will be no-op if some exception will occurred > > Suggestion: > > // AudioClip will be no-op if some exception will occur > > or 'has occurred' (?) I'm just going to delete the comment here as it is a bit out of place. The more interesting question is whether IOException should be thrown or swallowed like all other exceptions. The current code throws it (clearly) and so the app has to handle it. But if we swallow other exceptions ... ? > src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 114: > >> 112: clip.init(uc.getInputStream()); >> 113: } catch (final Exception ignored) { >> 114: // Playing the clip will be a no-op if an exception occured in inititialization. > > Suggestion: > > // Playing the clip will be a no-op if an exception occurred in initialization. No plans to fix typos comments for code I'm not touching and expect to delete in the near future > src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 124: > >> 122: clip.init(url.openStream()); >> 123: } catch (final Exception ignored) { >> 124: // Playing the clip will be a no-op if an exception occurred in inititialization. > > Suggestion: > > // Playing the clip will be a no-op if an exception occurred in initialization. No plans to fix typos comments for code I'm not touching and expect to delete in the near future > src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java line 294: > >> 292: public synchronized void update(LineEvent event) { >> 293: if (clip != null) { >> 294: if (clip == event.getSource()) { > > merge the two ifs to one if? I could .. but this way it is clearer that clip may actually be null .. > test/jdk/javax/sound/SoundClip/SoundClipTest.java line 40: > >> 38: >> 39: public static void main(String[] args) throws Exception { >> 40: > > Suggestion: I like blank lines there > test/jdk/javax/sound/SoundClip/SoundClipTest.java line 100: > >> 98: } >> 99: } catch (Exception e) { >> 100: System.err.println("Exception occured: "+e); > > Suggestion: > > System.err.println("Exception occurred: " + e); I copied that from another test. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072221321 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072221421 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072221490 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072222130 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072222289 PR Review Comment: https://git.openjdk.org/jdk/pull/24991#discussion_r2072222456 From serb at openjdk.org Sat May 3 01:02:52 2025 From: serb at openjdk.org (Sergey Bylokhov) Date: Sat, 3 May 2025 01:02:52 GMT Subject: RFR: 8352407: PixelInterleavedSampleModel with unused components throws RasterFormatException: Incorrect pixel stride [v2] In-Reply-To: <7b80MMi1QZ9zqKkL7LCFhaYSBiEMcVc5AgHmrWw5oO4=.23847f28-e1b0-43bb-b88e-2177b7ef9c09@github.com> References: <0IkJpQYFv_3lUjxKvd1T0EqtOeO4wN5XYEX1pJFf6Pc=.0eac5063-1b53-461b-8bc8-ca1320147a5a@github.com> <7PoUZmVaNchLPzKKv-Y2Kb3K2iTCIwF_GBxWgYOeSj8=.7c57eb44-10de-4e95-9fea-07ea39ed53ee@github.com> <9t4GmM3f624NKzcRzc1I4m-jDABNjukX93uJiEge0Bs=.b3a8c0f9-cd9c-4f61-9d80-700e5d37fcc7@github.com> <8dCI6Y3gKiDufYZEKkqrUk7Fn3lz3cwHVyi2gS7-Qck=.e4d29c99-7cce-4aad-a635-31f199970b61@github.com> <7b80MMi1QZ9zqKkL7LCFhaYSBiEMcVc5AgHmrWw5oO4=.23847f28-e1b0-43bb-b88e-2177b7ef9c09@ github.com> Message-ID: On Fri, 2 May 2025 16:14:30 GMT, Nikita Gubarkov wrote: >> However, this is not a case of a "partial pixel"- the data for the pixel itself is present. Therefore, the user can still manually create a buffer that discards the tail of the image and it will be accepted: >> >> DataBuffer manualBuffer = new DataBufferByte( >> scanlineStride * (SIZE - 1) + pixelStride * (SIZE - 1) + 2/*maxBandOffset*/ + 1 /*size of last component*/ >> ); >> >> The current logic seems to imply that: >> >> * The scanline stride doesn't matter for a single-line image, or for the last line in the image. >> * The pixel stride is irrelevant if there's only one pixel in the image, or for the last pixel in a row. >> >> This behavior is validated in src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java#verify, with the exception of the single-pixel image we mentioned earlier. >> >> I believe that exception for the 1-pixel image is a bug (pixelStride > data.length) that was overlooked during the work on commit [86104df](https://github.com/openjdk/jdk/commit/86104df#diff-f5003f18f0f4594a4859901ea950652467137fb1d07900208a84617036142746R891-L891), where a similar check for scanlineStride > data.length was fixed. > > Ok, I found another argument as to why I think we should allocate memory according to `pixelStride`, including padding. I am currently optimizing the Vulkan blit and specifically reducing the amount of extra copies, so the issue is real. > > In order to do draw an image, we need a Vulkan image. To bring raster data into Vulkan image we are currently doing 2 copies: software raster -> VkBuffer -> VkImage. We could get rid of one copy if we imported raster memory as an external allocation and bind VkBuffer to it directly: VkBuffer(software raster) -> VkImage. In theory we could even wrap host memory as an image and use it directly, but I doubt that would be more performant. > > So, if we try to import raster data as an external allocation, it becomes useless for the purposes of copying or sampling, because Vulkan requires the whole memory region to be resident, it will copy `height` rows of `rowLength` bytes and there is no way it could work in that strange scenario when we have RGBx raster with 1 byte of padding in the end, mapping to RGBA Vulkan format, and there is just a single missing byte in the end of the whole raster ruining our optimization, forcing us to memcpy the whole raster into a temporary buffer, which is just 1 byte larger so that we could properly copy that into Vulkan image. But even if we start allocating raster memory with padding internally, you will still need to support both cases anyway, right? So for now, maybe it's best to implement two versions of the blit: one optimized (assuming properly padded memory) and one fallback (handling the edge case with the missing padding). At runtime, we can select the appropriate version depending on the actual memory layout. Then we can compare performance and see whether supporting both is actually worth it. If the performance difference is significant, we can update our internal allocation strategy to always use the optimized layout, while still supporting custom rasters (with non-standard strides) using the slower path. Just to clarify - are we talking only about padding per pixel, or do we also need full row padding to meet Vulkan?s alignment requirements? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24111#discussion_r2072266843 From serb at openjdk.org Sat May 3 03:36:37 2025 From: serb at openjdk.org (Sergey Bylokhov) Date: Sat, 3 May 2025 03:36:37 GMT Subject: RFR: 8355078: java.awt.Color.createContext() uses unnecessary synchronization Message-ID: <0pWUD-E-stDoqVTXFmlRNJ2skEMIjeto6VFl6ydxyc0=.de5400a3-69a2-4621-a91a-45bdfbca4dd2@github.com> At some point, java.awt.Color.createContext() was marked as synchronized to support caching of a ColorPaintContext instance. The cache was later removed, but the synchronized modifier remained. Since there is no shared mutable state anymore, the synchronization is no longer necessary and can be safely removed. Note: This code path is rarely executed because a special optimization was introduced in [SunGraphics2D.setPaint](https://github.com/openjdk/jdk/blob/c514f135ccf08c3be016a32ae8f2c055fb941857/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java#L1003). As a result, unless a custom wrapper around the Color class is used, the Color.createContext() method is typically bypassed during rendering. Two tests are added: - ColorPaintContextBasicTest: Checks if different image types (BufferedImage and VolatileImage) produce the same results when using different ways to fill the image (setColor, setPaint, and custom Paint). This test intentionally uses a custom Paint implementation to bypass the optimization and ensure that Color.createContext() is invoked verifying its correct behavior. - ColorPaintContextStateTrackerTest: Checks that the raster used in ColorPaintContext.getRaster() can be properly cached in video memory and we do not need to call icr.markDirty() in ColorPaintContext.getRaster() ------------- Commit messages: - Merge branch 'openjdk:master' into colorctx - Update ColorPaintContextBasicTest.java - handle VolatileImage properly - Update ColorPaintContext.java - 8355078: java.awt.Color.createContext() uses unnecessary synchronization Changes: https://git.openjdk.org/jdk/pull/24771/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24771&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8355078 Stats: 304 lines in 4 files changed: 270 ins; 21 del; 13 mod Patch: https://git.openjdk.org/jdk/pull/24771.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24771/head:pull/24771 PR: https://git.openjdk.org/jdk/pull/24771 From liach at openjdk.org Sat May 3 03:36:37 2025 From: liach at openjdk.org (Chen Liang) Date: Sat, 3 May 2025 03:36:37 GMT Subject: RFR: 8355078: java.awt.Color.createContext() uses unnecessary synchronization In-Reply-To: <0pWUD-E-stDoqVTXFmlRNJ2skEMIjeto6VFl6ydxyc0=.de5400a3-69a2-4621-a91a-45bdfbca4dd2@github.com> References: <0pWUD-E-stDoqVTXFmlRNJ2skEMIjeto6VFl6ydxyc0=.de5400a3-69a2-4621-a91a-45bdfbca4dd2@github.com> Message-ID: <-_5oVNGUPmnehTXt3lCZZQ2ieSW8PRT21D5b5GVZwI8=.7151f571-311c-45b6-b007-2431790780d3@github.com> On Sun, 20 Apr 2025 08:15:38 GMT, Sergey Bylokhov wrote: > At some point, java.awt.Color.createContext() was marked as synchronized to support caching of a ColorPaintContext instance. The cache was later removed, but the synchronized modifier remained. Since there is no shared mutable state anymore, the synchronization is no longer necessary and can be safely removed. > > > Note: This code path is rarely executed because a special optimization was introduced in [SunGraphics2D.setPaint](https://github.com/openjdk/jdk/blob/c514f135ccf08c3be016a32ae8f2c055fb941857/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java#L1003). As a result, unless a custom wrapper around the Color class is used, the Color.createContext() method is typically bypassed during rendering. > > Two tests are added: > - ColorPaintContextBasicTest: Checks if different image types (BufferedImage and VolatileImage) produce the same results when using different ways to fill the image (setColor, setPaint, and custom Paint). This test intentionally uses a custom Paint implementation to bypass the optimization and ensure that Color.createContext() is invoked verifying its correct behavior. > - ColorPaintContextStateTrackerTest: Checks that the raster used in ColorPaintContext.getRaster() can be properly cached in video memory and we do not need to call icr.markDirty() in ColorPaintContext.getRaster() Is a CSR requested for the access flags change? Some method flags, notably `native` or `synchronized`, are not part of the API specificaion and not rendered, and thus can be changed without CSR reviews. For example, the [javadoc for this particular method](https://docs.oracle.com/en/java/javase/24/docs/api/java.desktop/java/awt/Color.html#createContext(java.awt.image.ColorModel,java.awt.Rectangle,java.awt.geom.Rectangle2D,java.awt.geom.AffineTransform,java.awt.RenderingHints)) does not include the `synchronized` modifier. ------------- PR Comment: https://git.openjdk.org/jdk/pull/24771#issuecomment-2817252429 From serb at openjdk.org Sat May 3 03:36:37 2025 From: serb at openjdk.org (Sergey Bylokhov) Date: Sat, 3 May 2025 03:36:37 GMT Subject: RFR: 8355078: java.awt.Color.createContext() uses unnecessary synchronization In-Reply-To: <0pWUD-E-stDoqVTXFmlRNJ2skEMIjeto6VFl6ydxyc0=.de5400a3-69a2-4621-a91a-45bdfbca4dd2@github.com> References: <0pWUD-E-stDoqVTXFmlRNJ2skEMIjeto6VFl6ydxyc0=.de5400a3-69a2-4621-a91a-45bdfbca4dd2@github.com> Message-ID: <--OqL7L8b4WyVcaOPjzRd5HIOV1otfWrRnUfWHPrqrY=.248a6752-7b11-4207-83a8-e180e4d6cee7@github.com> On Sun, 20 Apr 2025 08:15:38 GMT, Sergey Bylokhov wrote: > At some point, java.awt.Color.createContext() was marked as synchronized to support caching of a ColorPaintContext instance. The cache was later removed, but the synchronized modifier remained. Since there is no shared mutable state anymore, the synchronization is no longer necessary and can be safely removed. > > > Note: This code path is rarely executed because a special optimization was introduced in [SunGraphics2D.setPaint](https://github.com/openjdk/jdk/blob/c514f135ccf08c3be016a32ae8f2c055fb941857/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java#L1003). As a result, unless a custom wrapper around the Color class is used, the Color.createContext() method is typically bypassed during rendering. > > Two tests are added: > - ColorPaintContextBasicTest: Checks if different image types (BufferedImage and VolatileImage) produce the same results when using different ways to fill the image (setColor, setPaint, and custom Paint). This test intentionally uses a custom Paint implementation to bypass the optimization and ensure that Color.createContext() is invoked verifying its correct behavior. > - ColorPaintContextStateTrackerTest: Checks that the raster used in ColorPaintContext.getRaster() can be properly cached in video memory and we do not need to call icr.markDirty() in ColorPaintContext.getRaster() src/java.desktop/share/classes/java/awt/ColorPaintContext.java line 39: > 37: private final int color; > 38: private volatile WritableRaster savedTile; > 39: Since ColorPaintContext is no longer cached within the Color class, it's unlikely that this object will be accessed by multiple threads in typical JDK usage. Therefore, the synchronized modifier has been removed from the getRaster() method. However, to ensure thread safety in the rare case where a ColorPaintContext instance is shared across threads (if app decides to do so for some reason), the savedTile field has been declared as volatile. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/24771#discussion_r2071030293