On Thu, 3 Apr 2025 06:09:03 GMT, Sergey Bylokhov <s...@openjdk.org> wrote:

>>> > is it possible for pixelStride to be smaller than maxBandOff?
>>> 
>>> Surprisingly, yes! Band offsets are arbitrary, even for 
>>> `PixelInterleavedSampleModel`, the only restriction is that `maxBandOff - 
>>> minBandOff <= pixelStride`
>> 
>> But isn't it essentially the same thing? It just shifts the "pixelStride" 
>> window in one direction or another.
>> 
>>> Both could be correct and there doesn't seem to be any other info, which 
>>> could allow us to determine this unambiguously. This "real starting pixel 
>>> offset" is implicitly assumed, when working with [known types in native 
>>> code](https://github.com/openjdk/jdk/blob/209e72d311234c8279289172dab2cbb255e4fed9/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java#L319),
>>>  but is explicitly stored nowhere.
>> 
>> It depends on where and when the ColorModel/SampleModel/Raster were created. 
>> If the raster was created by our code and we can determine the starting 
>> offsets, and if we can confirm that the gaps are safe to read, then we could 
>> set some flags. These flags could be recognized by the pipelines to enable 
>> fast-path optimizations.
>> 
>> Just one example:
>> 
>>     private static BufferedImage makeCustom3BYTE_BGR() {
>>         ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
>>         int[] nBits = {8, 8, 8};
>>         int[] bOffs = {2, 1, 0};
>>         ColorModel colorModel = new ComponentColorModel(cs, nBits, false, 
>> false,
>>                                                         Transparency.OPAQUE,
>>                                                         
>> DataBuffer.TYPE_BYTE);
>>         
>>         PixelInterleavedSampleModel sm =
>>                 new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
>>                     2, 1, 400, 4000, bOffs);
>>         WritableRaster raster = Raster.createWritableRaster(sm, null);
>>         
>>         System.out.println("raster.getDataBuffer().getSize() = " + 
>> raster.getDataBuffer().getSize());
>>         return new BufferedImage(colorModel, raster, true, null);
>>     }
>> 
>>         BufferedImage bi = new BufferedImage(3000, 3000, TYPE_INT_ARGB);
>>         BufferedImage src = makeCustom3BYTE_BGR();
>>         Graphics2D g2d = bi.createGraphics();
>>         g2d.setTransform(new AffineTransform());
>>         g2d.drawImage(src, 0, 0, null);
>>         g2d.dispose();
>> 
>> 
>> The size of the image is "403", meaning it does not include the gap after 
>> the last pixel data.
>> 
>> Now, if we attempt to blit this into various pipelines, we may encounter 
>> different slow/fast pat...
>
> Probably, the changes similar to https://github.com/openjdk/jdk/pull/24378 
> will help in some cases. However, for the generic case with random rasters, 
> it will be necessary to determine whether the gaps at the end of the image 
> are actually stored in the raster or not.

> as of now, we simply don't have generic native loops that support pixel gaps

That was kinda what I was actually implementing in Vulkan when I faced this 
issue. I just accepted any pixel-interleaved surface with 4-byte stride and 
assumed that I can blit it directly. Just because the stride is 4 bytes, I know 
I can copy the whole scanline in one go into a matching Vulkan format, like 
B8G8R8A8_UNORM, and I can handle any component order (including missing alpha 
channel) with simple swizzling.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24111#discussion_r2026301933

Reply via email to