Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8283401

ArrayIndexOutOfBoundsException when disconnecting screen(s)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • jfx22
    • jfx19
    • javafx
    • None
    • b05
    • windows

      Newest JavaFX EA build (19-ea+3)
      OS = Windows (not sure if also reproducable for other OS)
      ---

      Sometimes an ArrayIndexOutOfBoundsException is thrown when disconnecting screen(s).
      It looks like this only can happen when there are multiple screens.
      Also the main screen should be the second screen, so when it gets disconnected, everything will move to the first screen.

      Related mailing list article: https://mail.openjdk.java.net/pipermail/openjfx-dev/2022-February/033607.html

      So in short:
      [Screen 1] [Screen 2*]
      * = main screen with JavaFX app
      Disconnect Screen 2. -> Sometimes exception.
      ---

      One time my JVM also crashed and generated a hs_err_pid file.
      I attached it on this ticket.

      The following stacktrace appeared:
      java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
          at com.sun.prism.d3d.D3DPipeline.getD3DResourceFactory(D3DPipeline.java:217)
          at com.sun.prism.d3d.D3DPipeline.getResourceFactory(D3DPipeline.java:284)
          at com.sun.scenario.effect.impl.prism.ps.PPSRenderer.validate(PPSRenderer.java:101)
          at com.sun.scenario.effect.impl.prism.ps.PPSRenderer.getCompatibleImage(PPSRenderer.java:221)
          at com.sun.scenario.effect.impl.prism.ps.PPSRenderer.getCompatibleImage(PPSRenderer.java:67)
          at com.sun.scenario.effect.Effect.getCompatibleImage(Effect.java:479)
          at com.sun.javafx.sg.prism.NodeEffectInput.getImageDataForBoundedNode(NodeEffectInput.java:228)
          at com.sun.javafx.sg.prism.NodeEffectInput.filter(NodeEffectInput.java:131)
          at com.sun.scenario.effect.FilterEffect.filter(FilterEffect.java:185)
          at com.sun.scenario.effect.Offset.filter(Offset.java:160)
          at com.sun.scenario.effect.Merge.filter(Merge.java:148)
          at com.sun.scenario.effect.DelegateEffect.filter(DelegateEffect.java:70)
          at com.sun.scenario.effect.impl.prism.PrEffectHelper.render(PrEffectHelper.java:166)
          at com.sun.javafx.sg.prism.EffectFilter.render(EffectFilter.java:61)
          at com.sun.javafx.sg.prism.NGNode.renderEffect(NGNode.java:2384)
          at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2069)
          at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1964)
          at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:270)
          at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:579)
          at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
          ... ( a lot of doRender(..), renderContent(..) calls... )
          at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:480)
          at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:329)
          at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:92)
          at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
          at java.base/java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:305)
          at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
          at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
          at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
          at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
          at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:126)
          at java.base/java.lang.Thread.run(Thread.java:829)

      ### REPRODUCE ###
      To reproduce this, the scene must have at least one node with an effect:
      VBox root = new VBox();
      root.setEffect(new Blend());

      Also the D3D Pipeline must be used.(See also stacktrace).

      The main screen should be the screen which is then disconnected.

      To easier reproduce it, there are some 'hacks' which work quite well to test this:
      1. Create a static boolean variable in com.sun.prism.impl.ps.BaseShaderContext (e.g. shouldRecreate)
      2. In D3DContext#testLostStateAndReset, the variable hr is now changed to D3DERR_DEVICEREMOVED when shouldRecreate is true
      3. Create a test scene with a button. The action when the button is pressed should be something like this: BaseShaderContext.shouldRecreate = true
      4. On Windows, press Windows + P and select the first option (PC screen only). This will basically 'disconnect' your screens. Interestingly D3D is not reporting a D3DERR_DEVICEREMOVED.
      If you click now on the button and let D3D recreate everything, the exception appears.

      Note: The setup should be as above: E.g. use the last screen and make it also the main screen.

      My initial setup [ 1 ][ 2 ][ 3* ]
      3 is the main screen with the JavaFX app.
      Windows + P -> [ 2 ] (other screens are disconnected)
      Now I recreate the D3D pipeline with the button -> Exception.

            mhanl Marius Hanl
            mhanl Marius Hanl
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: