<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>