<div dir="ltr"><div dir="ltr"><div>OK, thanks -- I'll add a `colorModel.getColorSpace().isCS_sRGB()` check here as well.</div><div><br></div><div>Take care,</div><div><br></div><div>Daniel</div><div><br></div><div><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Thu, Sep 4, 2025 at 11:55 PM Philip Race <<a href="mailto:philip.race@oracle.com">philip.race@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div>
It doesn't seem like a change that needs a project.<br>
I would make sure that call to colorModel.getRGB(..) isn't needed
and I think that you aren't doing that.<br>
Basically it needs to be sRGB already (as that is the target color
space).<br>
<br>
-phil.<br>
<br>
<div>On 9/4/25 1:37 PM, Daniel Gredler
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>Hi Jeremy, Laurent,</div>
<div><br>
</div>
<div>Thanks for having a look. What sorts of changes are you
thinking of when you propose a separate project?</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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?</div>
<div><br>
</div>
<div>Take care,</div>
<div><br>
</div>
<div>Daniel</div>
<div><br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sat, Aug 30, 2025 at
11:47 AM Laurent Bourgès <<a href="mailto:bourges.laurent@pm.me" target="_blank">bourges.laurent@pm.me</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<p dir="ltr">Hi guys,</p>
<p dir="ltr">I do love optimizing java2d, so Ido support &
sponsor your buffered image (ARGB PRE or not) changes.</p>
<p dir="ltr">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.</p>
<p dir="ltr">See jdk (25?) branch:<br>
<a href="https://github.com/bourgesl/marlin-renderer/tree/jdk/src/main/java/sun/java2d" target="_blank">https://github.com/bourgesl/marlin-renderer/tree/jdk/src/main/java/sun/java2d</a></p>
<p dir="ltr">Cheers,<br>
Laurent</p>
<div> <br>
<br>
-------- Message d'origine -------- <br>
Le 22/08/2025 14:04, Daniel Gredler a écrit : <br>
<blockquote>
<div dir="ltr">
<div> Hi all, </div>
<div> <br>
</div>
<div> `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. </div>
<div> <br>
</div>
<div> 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. </div>
<div> <br>
</div>
<div> 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. </div>
<div> <br>
</div>
<div> 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. </div>
<div> <br>
</div>
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.
<div> <br>
</div>
<div> Thanks! </div>
<div> <br>
</div>
<div> Daniel </div>
<div> <br>
</div>
<div> --- </div>
<div> <br>
</div>
<div> [1] </div>
<div> BufferedImage.TYPE_CUSTOM: 2k <br>
BufferedImage.TYPE_INT_RGB: 114k <br>
BufferedImage.TYPE_INT_ARGB: 93k << 35% <br>
BufferedImage.TYPE_INT_ARGB_PRE: 5k <br>
BufferedImage.TYPE_INT_BGR: 4k <br>
BufferedImage.TYPE_3BYTE_BGR: 10k <br>
BufferedImage.TYPE_4BYTE_ABGR: 9k <br>
BufferedImage.TYPE_4BYTE_ABGR_PRE: 2k <br>
BufferedImage.TYPE_USHORT_565_RGB: 1k <br>
BufferedImage.TYPE_USHORT_555_RGB: 1k <br>
BufferedImage.TYPE_BYTE_GRAY: 11k <br>
BufferedImage.TYPE_USHORT_GRAY: 2k <br>
BufferedImage.TYPE_BYTE_BINARY: 5k <br>
BufferedImage.TYPE_BYTE_INDEXED: 3k <br>
Total: 262k </div>
<div> <br>
</div>
<div> [2] <a href="https://github.com/gredler/jdk/commit/b98f6cdf7573b7e89067c757890193517aeb472e" target="_blank">https://github.com/gredler/jdk/commit/b98f6cdf7573b7e89067c757890193517aeb472e</a>
</div>
<div> <br>
</div>
<div> [3] </div>
<div> public final class PerfTest { <br>
public static void main(final String[] args) { <br>
int w = 1_000; <br>
int h = 1_000; <br>
int accumulator = 0; <br>
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB); <br>
int[] row = new int[w]; <br>
long start = System.currentTimeMillis(); <br>
for (int i = 0; i < 100_000; i++) { <br>
for (int y = 0; y < h; y++) { <br>
image.getRGB(0, y, w, 1, row, 0, w); <br>
accumulator += row[i % w]; <br>
} <br>
} <br>
long end = System.currentTimeMillis(); <br>
System.out.println("Total time: " + ((end -
start) / 1_000) + " seconds"); <br>
System.out.println("Accumulator: " +
accumulator); <br>
} <br>
} </div>
<div> <br>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
<br>
</div>
</blockquote></div></div>