OK, thanks -- I'll add a `colorModel.getColorSpace().isCS_sRGB()` check
here as well.

Take care,

Daniel



On Thu, Sep 4, 2025 at 11:55 PM Philip Race <philip.r...@oracle.com> wrote:

> It doesn't seem like a change that needs a project.
> I would make sure that call to colorModel.getRGB(..) isn't needed and I
> think that you aren't doing that.
> Basically it needs to be sRGB already (as that is the target color space).
>
> -phil.
>
> On 9/4/25 1:37 PM, Daniel Gredler wrote:
>
> Hi Jeremy, Laurent,
>
> Thanks for having a look. What sorts of changes are you thinking of when
> you propose a separate project?
>
> For myself, I don't really have a bigger-picture vision of systematic
> changes that I'd like to make. Similar to JDK-8337681, JDK-8344668 and
> JDK-8356814, this suggestion is just an ad hoc optimization opportunity
> that came up based on spending some time with a profiler.
>
> My takeaway right now is that this specific suggestion doesn't look
> obviously stupid to anyone, and is worth triple checking on my end. If my
> local sanity checks all come back green, I would create a small issue in
> JBS and submit a PR, and then let the review process carry on as usual. It
> can take a little time, but it seems to me that useful optimizations,
> submitted individually, can be incorporated without too many issues.
>
> Which takes me back to my original question -- what type of change(s) are
> you thinking about, where proving things out in a separate project is
> necessary?
>
> Take care,
>
> Daniel
>
>
> On Sat, Aug 30, 2025 at 11:47 AM Laurent Bourgès <bourges.laur...@pm.me>
> wrote:
>
>> Hi guys,
>>
>> I do love optimizing java2d, so Ido support & sponsor your buffered image
>> (ARGB PRE or not) changes.
>>
>> Let's start a github project to start this concrete patch... as I did for
>> the marlin renderer or we could use the marlin repository to host your
>> changes to java.awt or java2d packages.
>>
>> See jdk (25?) branch:
>>
>> https://github.com/bourgesl/marlin-renderer/tree/jdk/src/main/java/sun/java2d
>>
>> Cheers,
>> Laurent
>>
>>
>> -------- Message d'origine --------
>> Le 22/08/2025 14:04, Daniel Gredler a écrit :
>>
>> Hi all,
>>
>> `BufferedImage.getRGB(int, int, int, int, int[], int, int)` is often used
>> for processing of individual image pixels. A common pattern is to loop
>> through each row of pixels, calling this method once per row to populate
>> the row pixel `int[]` and then process it.
>>
>> There are many types of `BufferedImage`, but one of the most common types
>> is `TYPE_INT_ARGB`. Based on a quick search on GitHub, about one third of
>> all BufferedImages are of this type [1]. This is also the representation
>> which `BufferedImage.getRGB(int, int, int, int, int[], int, int)` uses for
>> its output.
>>
>> I think there may be an opportunity here (in `BufferedImage.getRGB(int,
>> int, int, int, int[], int, int)`) to skip the pixel-by-pixel color model
>> conversion if the `BufferedImage` is already of type `TYPE_INT_ARGB`, which
>> is relatively common. See here [2] for what this optimization could look
>> like.
>>
>> In my local testing, a simple test program [3] went from running in 220
>> seconds without the change to running in 7 seconds with the change.
>> Separately, a real-world program which uses the row-by-row pixel access
>> pattern went from running in 45 seconds to running in 29 seconds.
>>
>> Does this look like a good change to those of you who know this part of
>> the code? Am I missing something that might make this dangerous or
>> undesirable? Is it making too many assumptions? I know this area is fraught
>> with gotchas -- color models, color spaces, strides, etc.
>>
>> Thanks!
>>
>> Daniel
>>
>> ---
>>
>> [1]
>> BufferedImage.TYPE_CUSTOM: 2k
>> BufferedImage.TYPE_INT_RGB: 114k
>> BufferedImage.TYPE_INT_ARGB: 93k << 35%
>> BufferedImage.TYPE_INT_ARGB_PRE: 5k
>> BufferedImage.TYPE_INT_BGR: 4k
>> BufferedImage.TYPE_3BYTE_BGR: 10k
>> BufferedImage.TYPE_4BYTE_ABGR: 9k
>> BufferedImage.TYPE_4BYTE_ABGR_PRE: 2k
>> BufferedImage.TYPE_USHORT_565_RGB: 1k
>> BufferedImage.TYPE_USHORT_555_RGB: 1k
>> BufferedImage.TYPE_BYTE_GRAY: 11k
>> BufferedImage.TYPE_USHORT_GRAY: 2k
>> BufferedImage.TYPE_BYTE_BINARY: 5k
>> BufferedImage.TYPE_BYTE_INDEXED: 3k
>> Total: 262k
>>
>> [2]
>> https://github.com/gredler/jdk/commit/b98f6cdf7573b7e89067c757890193517aeb472e
>>
>> [3]
>> public final class PerfTest {
>>     public static void main(final String[] args) {
>>         int w = 1_000;
>>         int h = 1_000;
>>         int accumulator = 0;
>>         BufferedImage image = new BufferedImage(w, h,
>> BufferedImage.TYPE_INT_ARGB);
>>         int[] row = new int[w];
>>         long start = System.currentTimeMillis();
>>         for (int i = 0; i < 100_000; i++) {
>>             for (int y = 0; y < h; y++) {
>>                 image.getRGB(0, y, w, 1, row, 0, w);
>>                 accumulator += row[i % w];
>>             }
>>         }
>>         long end = System.currentTimeMillis();
>>         System.out.println("Total time: " + ((end - start) / 1_000) + "
>> seconds");
>>         System.out.println("Accumulator: " + accumulator);
>>     }
>> }
>>
>>
>

Reply via email to