Skip to content

Commit

Permalink
Fix crash when creating SwingRedrawer on DirectX (#917)
Browse files Browse the repository at this point in the history
### Changes
Throw `RenderException` when constructing `Direct3DSwingRedrawer` with
`nullptr` device. (Similar to `Direct3DRedrawer`)

To avoid crash in:
```
DirectXOffscreenDevice *d3dDevice = fromJavaPointer<DirectXOffscreenDevice *>(devicePtr);
GrD3DBackendContext backendContext = d3dDevice->backendContext;
return toJavaPointer(GrDirectContext::MakeDirect3D(backendContext).release());
```

### Fixes

Speculative fix for crash with a stack head below:
```
---------------  T H R E A D  ---------------

Current thread (0x000001cbcb0793f0):  JavaThread "AWT-EventQueue-0" [_thread_in_native, id=16744, stack(0x0000009488c00000,0x0000009488d00000)]

Stack: [0x0000009488c00000,0x0000009488d00000],  sp=0x0000009488cfc670,  free space=1009k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [skiko-windows-x64.dll+0x58afa]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.jetbrains.skiko.swing.Direct3DSwingRedrawer.makeDirectXContext(J)J+0
```

### Note
I've found suspicious place in
```kotlin
// RedrawManager.kt:30
_renderApi = fallbackRenderApiQueue.removeAt(0)
_redrawer = redrawerFactory(_renderApi, redrawer)
```
Seems like `redrawer` is disposed twice if `redrawerFactory` throws
(both paths constructing `RedrawerManager` are affected).

@igordmn can you have a look?
It's a universal path for all desktop users, so I wonder why it didn't
backfire, if it's indeed incorrect.
May be it's because we don't really call `redrawerFactory` if a redrawer
was constructed correctly, so disposal of old one doesn't ever get
called in this context. I'm not sure where are the invariant boundaries
here.
  • Loading branch information
elijah-semyonov authored Apr 26, 2024
1 parent 37ef84b commit 57dea50
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ internal class RedrawerManager<R>(
_renderApi = fallbackRenderApiQueue.removeAt(0)
_redrawer = redrawerFactory(_renderApi, redrawer)
} catch (e: RenderException) {
_redrawer = null
Logger.warn(e) { "Fallback to next API" }
thrown = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ internal class Direct3DSwingRedrawer(

private val swingOffscreenDrawer = SwingOffscreenDrawer(swingLayerProperties)

private val context = DirectContext(
makeDirectXContext(device)
)
private val context = if (device == 0L) {
throw RenderException("Failed to create DirectX12 device.")
} else {
DirectContext(
makeDirectXContext(device)
)
}

private var texturePtr: Long = 0
private var bytesToDraw = ByteArray(0)
Expand Down

0 comments on commit 57dea50

Please sign in to comment.