Commit b1dcc60a authored by Roman Sedaikin's avatar Roman Sedaikin

Fixed memory leak when closing window with DirectX rendering.

parent a30747fe
#include <jni.h> #include <jni.h>
#include "jni_helpers.h"
#include "GrBackendSurface.h" #include "GrBackendSurface.h"
#include "GrDirectContext.h" #include "GrDirectContext.h"
...@@ -19,6 +20,12 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_RenderTargetsKt_makeGLContextNa ...@@ -19,6 +20,12 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_RenderTargetsKt_makeGLContextNa
return reinterpret_cast<jlong>(GrDirectContext::MakeGL().release()); return reinterpret_cast<jlong>(GrDirectContext::MakeGL().release());
} }
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_RenderTargetsKt_destroyContext(JNIEnv *env, jobject object, jlong contextPtr)
{
GrDirectContext *context = fromJavaPointer<GrDirectContext*>(contextPtr);
delete context;
}
extern void getMetalDeviceAndQueue(void** device, void** queue); extern void getMetalDeviceAndQueue(void** device, void** queue);
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_RenderTargetsKt_makeMetalRenderTargetNative( JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_RenderTargetsKt_makeMetalRenderTargetNative(
......
...@@ -64,6 +64,10 @@ public: ...@@ -64,6 +64,10 @@ public:
{ {
CloseHandle(fenceEvent); CloseHandle(fenceEvent);
} }
fence.reset(nullptr);
swapChain.reset(nullptr);
queue.reset(nullptr);
device.reset(nullptr);
} }
}; };
...@@ -289,6 +293,7 @@ HRESULT D3DCompile( ...@@ -289,6 +293,7 @@ HRESULT D3DCompile(
{ {
return 0; return 0;
} }
deviceFactory.reset(nullptr);
// Create the command queue // Create the command queue
gr_cp<ID3D12CommandQueue> queue; gr_cp<ID3D12CommandQueue> queue;
...@@ -333,6 +338,8 @@ HRESULT D3DCompile( ...@@ -333,6 +338,8 @@ HRESULT D3DCompile(
GR_D3D_CALL_ERRCHECK(d3dDevice->device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3dDevice->fence))); GR_D3D_CALL_ERRCHECK(d3dDevice->device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3dDevice->fence)));
d3dDevice->fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); d3dDevice->fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
swapChainFactory.reset(nullptr);
return toJavaPointer(d3dDevice); return toJavaPointer(d3dDevice);
} }
......
...@@ -24,3 +24,5 @@ external private fun makeGLContextNative(): Long ...@@ -24,3 +24,5 @@ external private fun makeGLContextNative(): Long
external private fun makeMetalRenderTargetNative(width: Int, height: Int, sampleCnt: Int): Long external private fun makeMetalRenderTargetNative(width: Int, height: Int, sampleCnt: Int): Long
external private fun makeMetalContextNative(): Long external private fun makeMetalContextNative(): Long
external internal fun destroyContext(context: Long)
...@@ -99,6 +99,7 @@ open class SkiaLayer( ...@@ -99,6 +99,7 @@ open class SkiaLayer(
if (isInited) { if (isInited) {
redrawer?.dispose() // we should dispose redrawer first (to cancel `draw` in rendering thread) redrawer?.dispose() // we should dispose redrawer first (to cancel `draw` in rendering thread)
contextHandler?.dispose() contextHandler?.dispose()
contextHandler?.destroyContext()
picture?.instance?.close() picture?.instance?.close()
pictureRecorder.close() pictureRecorder.close()
backedLayer.dispose() backedLayer.dispose()
......
...@@ -30,7 +30,6 @@ internal abstract class ContextHandler(val layer: SkiaLayer) { ...@@ -30,7 +30,6 @@ internal abstract class ContextHandler(val layer: SkiaLayer) {
var canvas: Canvas? = null var canvas: Canvas? = null
abstract fun initContext(): Boolean abstract fun initContext(): Boolean
abstract fun initCanvas() abstract fun initCanvas()
fun clearCanvas() { fun clearCanvas() {
...@@ -49,4 +48,6 @@ internal abstract class ContextHandler(val layer: SkiaLayer) { ...@@ -49,4 +48,6 @@ internal abstract class ContextHandler(val layer: SkiaLayer) {
surface?.close() surface?.close()
renderTarget?.close() renderTarget?.close()
} }
open fun destroyContext() = Unit
} }
...@@ -11,6 +11,7 @@ import org.jetbrains.skija.impl.Native ...@@ -11,6 +11,7 @@ import org.jetbrains.skija.impl.Native
import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.Direct3DRedrawer import org.jetbrains.skiko.redrawer.Direct3DRedrawer
import org.jetbrains.skiko.redrawer.Redrawer import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.destroyContext
internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer) { internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
val directXRedrawer: Direct3DRedrawer val directXRedrawer: Direct3DRedrawer
...@@ -66,4 +67,8 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer) ...@@ -66,4 +67,8 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer)
Reference.reachabilityFence(surface!!) Reference.reachabilityFence(surface!!)
} }
} }
override fun destroyContext() {
destroyContext(Native.getPtr(context!!))
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment