Skip to content

Commit

Permalink
Don't try to init D3D with zero size (#858)
Browse files Browse the repository at this point in the history
* Don't try to init D3D with zero size

* Pass AWT size for swap chain initialization

* Avoid reading size twice
  • Loading branch information
MatkovIvan authored Jan 29, 2024
1 parent 03928d6 commit 21d7a12
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 38 deletions.
11 changes: 3 additions & 8 deletions skiko/src/awtMain/cpp/windows/directXRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,7 @@ class DirectXDevice
device.reset(nullptr);
}

void initSwapChain() {
RECT windowRect;
GetClientRect(window, &windowRect);
UINT width = windowRect.right - windowRect.left;
UINT height = windowRect.bottom - windowRect.top;

void initSwapChain(UINT width, UINT height) {
gr_cp<IDXGIFactory4> swapChainFactory4;
gr_cp<IDXGISwapChain1> swapChain1;
CreateDXGIFactory2(0, IID_PPV_ARGS(&swapChainFactory4));
Expand Down Expand Up @@ -330,12 +325,12 @@ extern "C"
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_initSwapChain(
JNIEnv *env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr, jint width, jint height)
{
__try
{
DirectXDevice *d3dDevice = fromJavaPointer<DirectXDevice *>(devicePtr);
d3dDevice->initSwapChain();
d3dDevice->initSwapChain((UINT) width, (UINT) height);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
auto code = GetExceptionCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,38 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye
}
return false
}
private var isD3DInited = false

override fun initCanvas() {
val context = context ?: return
val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
val surfaceProps = SurfaceProps(pixelGeometry = layer.pixelGeometry)
val width = (layer.width * scale).toInt()
val height = (layer.height * scale).toInt()

if (isSizeChanged(w, h) || isSurfacesNull()) {
if (width <= 0 || height <= 0) {
return
}

if (isSizeChanged(width, height) || isSurfacesNull()) {
disposeCanvas()
context?.flush()

if (!isD3DInited) {
directXRedrawer.initSwapChain()
} else {
directXRedrawer.resizeBuffers(w, h)
}

context.flush()

val justInitialized = directXRedrawer.changeSize(width, height)
try {
for (bufferIndex in 0..bufferCount - 1) {
surfaces[bufferIndex] = directXRedrawer.makeSurface(getPtr(context!!), w, h, surfaceProps, bufferIndex)
val surfaceProps = SurfaceProps(pixelGeometry = layer.pixelGeometry)
for (bufferIndex in 0 until bufferCount) {
surfaces[bufferIndex] = directXRedrawer.makeSurface(
context = getPtr(context),
width = width,
height = height,
surfaceProps = surfaceProps,
index = bufferIndex
)
}
} finally {
Reference.reachabilityFence(context!!)
Reference.reachabilityFence(context)
}

if (!isD3DInited) {
isD3DInited = true
if (justInitialized) {
directXRedrawer.initFence()
}
}
Expand All @@ -77,14 +81,13 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye
}

override fun flush() {
val context = context ?: return
val surface = surface ?: return
try {
flush(
getPtr(context!!),
getPtr(surface!!)
)
flush(getPtr(context), getPtr(surface))
} finally {
Reference.reachabilityFence(context!!)
Reference.reachabilityFence(surface!!)
Reference.reachabilityFence(context)
Reference.reachabilityFence(surface)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal class Direct3DRedrawer(
override val renderInfo: String get() = contextHandler.rendererInfo()

private var drawLock = Any()
private var isSwapChainInitialized = false

private var device: Long = 0L
get() {
Expand Down Expand Up @@ -84,10 +85,11 @@ internal class Direct3DRedrawer(
}

private fun drawAndSwap(withVsync: Boolean) = synchronized(drawLock) {
if (!isDisposed) {
contextHandler.draw()
swap(device, withVsync)
if (isDisposed) {
return
}
contextHandler.draw()
swap(withVsync)
}

fun makeContext() = DirectContext(
Expand All @@ -100,10 +102,25 @@ internal class Direct3DRedrawer(
}
}

fun resizeBuffers(width: Int, height: Int) = resizeBuffers(device, width, height)
fun changeSize(width: Int, height: Int): Boolean {
return if (!isSwapChainInitialized) {
initSwapChain(device, width, height)
isSwapChainInitialized = true
true
} else {
resizeBuffers(device, width, height)
false
}
}

private fun swap(withVsync: Boolean) {
if (!isSwapChainInitialized) {
return
}
swap(device, withVsync)
}

fun getBufferIndex() = getBufferIndex(device)
fun initSwapChain() = initSwapChain(device)
fun initFence() = initFence(device)

// Called from native code
Expand All @@ -117,7 +134,7 @@ internal class Direct3DRedrawer(
private external fun swap(device: Long, isVsyncEnabled: Boolean)
private external fun disposeDevice(device: Long)
private external fun getBufferIndex(device: Long): Int
private external fun initSwapChain(device: Long)
private external fun initSwapChain(device: Long, width: Int, height: Int)
private external fun initFence(device: Long)
private external fun getAdapterName(adapter: Long): String
private external fun getAdapterMemorySize(adapter: Long): Long
Expand Down

0 comments on commit 21d7a12

Please sign in to comment.