On Tue, 21 Jan 2020 21:53:29 GMT, Kevin Rushforth <k...@openjdk.org> wrote:
>>> >>> >>> Looks good to me. >>> Below is just an observation about time taken by the API, >>> Platform: Windows10, `maxTextureSize`: 4096 >>> For a snapshot of (4096 * n, 4096 * n): each call to `doSnapshotTile()` >>> takes ~100 ms, and each call to `setPixels()` takes ~30 ms. >>> >>> Please wait for one more approval before integrating. >> >> Do you have the same kind of measurements for similar uses cases without >> this patch? I'm expecting performances to remain the same for snapshots less >> than `maxTextureSize*maxTextureSize` in size, since there is no extra pixel >> copy in that case, and the rest of the code if globally unchanged. >> >> Still there exists a window for performance regressions, which for instance >> on Windows 10 w/ the D3D rendering pipeline would be when one of the >> dimension of a snapshot is >4096 and <8192: in that case a snapshot would >> require up to 4 extra copy pixels steps with this patch. >> This is due to the fact that the old code would accept to render in a >> texture of a size up to the non-clamped max texture size (8192 in D3D, 16384 >> in ES2), but because I couldn't find a clean way to access the non clamped >> maxTextureSize exposed by the render factory from the Scene class, I settled >> for Prsim.maxTextureSize, which is the clamped value (4096 by default). >> I haven't dug deep enough in the code to understand precisely why the max >> texture size is clamped to 4096 by default, but assuming that it is for a >> good reason wouldn't that also apply in that case? Or is it always safe to >> use the non-clamped value in that particular case? > > I haven't done any testing yet, but I have two comments on the patch: > > 1. Using the clamped texture size as the upper limit is the right thing to > do, but `Prism.maxTexture` isn't guaranteed to be that size. The > `Prism.maxTexture` constant represents the value to clamp the texture size > to. In the event that D3D or OpenGL were to report a maximum less than the > value of `Prism.maxTexture` (unlikely, but maybe on some low-end embedded > systems?), then that value is what should be used. The way to get the clamped > texture size is to call > [`ResourceFactory::getMaximumTextureSize`](https://github.com/openjdk/jfx/blob/jfx14/modules/javafx.graphics/src/main/java/com/sun/prism/ResourceFactory.java#L222), > but you can't do that directly from the scene graph code. > > 2. Allocating multiple `WritableImage` objects and using > `PixelWriter::setPixels` to stitch them together will take more temporary > memory, and is likely to be slower, than having the snapshot code write into > a subimage of the larger allocated image directly. > > Having said that, the current proposed solution is still better than the > current behavior is almost all cases, although there could be a performance > hit in the case of an 8K x 8K image, which will now be tiled. I want to do a > more careful review and some testing. If any other users of snapshot have any > comments or concerns, they would be welcome. > > I think the best long-term solution might be to modify the > [`QuantumToolkit::renderToImage`](https://github.com/openjdk/jfx/blob/jfx14/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java#L1490) > method, although that would certainly be out of scope for JavaFX 14. I've put together a small benchmark to measure the time it takes to snapshots into images of sizes varying from 1024*1024 to 8192*8192, by increment of 1024 in each dimension, which you can find here: https://github.com/fthevenet/snapshot-perf-meter/blob/master/src/main/java/eu/fthevenet/SnapshotPerfMeter.java ------------- PR: https://git.openjdk.java.net/jfx/pull/68