On Sat, 5 Aug 2023 13:00:36 GMT, Marius Hanl <mh...@openjdk.org> wrote:
> When the `D3DPipeline` is reinitialized, the adapter ordinal of all the > `Screen`s are outdated. > As a consequence, when a `D3DResourceFactory` is created for a `Screen` > (adapter ordinal), the code may fail with an `ArrayIndexOutOfBoundsException` > as the ordinal is higher than what we would expect it to be. > > Example: > We have 3 screens. Adapter ordinal 0, 1, 2. > If we now disconnect 2 screens, we only have one screen left. > The `D3DPipeline` is reinitialized as a > [D3DERR_DEVICEREMOVED](https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3derr) > is reported from Direct3d9. > Now the remaining screen may have the adapter ordinal 1 (from before). But > since we only have 1 screen left, it should have the adapter ordinal 0. > > Direct3d9 will also return 0 as adapter ordinal if you call it. And that is > what we do to update the `Screen` and fix this problem. > > See also the ticket for information how to reproduce this problem (Windows > only). I tested the patch with a docking station and two external displays like this: 1. Put Windows into sleep mode 2. Disconnect the docking station / external monitor 3. Resume Windows Without the patch, the exception occurs. With the patch applied, everything works as expected. I notice that the logic to assign adapter ordinals is now duplicated in two places in the codebase. Have you thought about moving the implementation into the `Screen` class? Here's how that could work: Remove `Screen.setAdapterOrdinal(int)` and add the following method to the `Screen` class: public static void updateAdapterOrdinals() { for (Screen screen : getScreens()) { screen.adapter = GraphicsPipeline.getPipeline().getAdapterOrdinal(screen); } } Remove `QuantumToolkit.assignScreenAdapters()` and call `Screen.updateAdapterOrdinals()` from the two call sites instead. You can then just call `Screen.updateAdapterOrdinals()` from `D3DPipeline` as well. For good measure, you could initialize `Screen.adapter` to `-1` and change `Screen.getAdapterOrdinal()` as follows: public int getAdapterOrdinal() { + if (adapter < 0) { + throw new IllegalStateException("Adapter ordinal is not initialized."); + } + return adapter; } ------------- PR Comment: https://git.openjdk.org/jfx/pull/1200#issuecomment-1671954361