Unverified Commit 7c12a857 authored by Nikolai Rykunov's avatar Nikolai Rykunov Committed by GitHub

Fix memory leak because of missing autoreleasepool in offscreen rendering for Swing interop (#764)

parent 1afda4d3
......@@ -25,7 +25,26 @@ internal fun MetalAdapter.dispose() {
disposeAdapter(ptr)
}
/**
* [@autoreleasepool](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html)
*/
@Suppress("SpellCheckingInspection")
internal inline fun <R> autoreleasepool(block: () -> R): R {
val handle = openAutoreleasepool()
return try {
block()
} finally {
closeAutoreleasepool(handle)
}
}
private external fun chooseAdapter(adapterPriority: Int): Long
private external fun disposeAdapter(adapter: Long)
private external fun getAdapterName(adapter: Long): String
private external fun getAdapterMemorySize(adapter: Long): Long
\ No newline at end of file
private external fun getAdapterMemorySize(adapter: Long): Long
@Suppress("SpellCheckingInspection")
private external fun openAutoreleasepool(): Long
@Suppress("SpellCheckingInspection")
private external fun closeAutoreleasepool(handle: Long)
\ No newline at end of file
......@@ -154,11 +154,8 @@ internal class MetalRedrawer(
// - it makes frames consistent and limits FPS
displayLinkThrottler.waitVSync(windowPtr = layer.windowHandle)
val handle = startRendering()
try {
autoreleasepool {
contextHandler.draw()
} finally {
endRendering(handle)
}
}
}
......@@ -188,6 +185,4 @@ internal class MetalRedrawer(
private external fun setContentScale(device: Long, contentScale: Float)
private external fun setVSyncEnabled(device: Long, enabled: Boolean)
private external fun isOccluded(window: Long): Boolean
private external fun startRendering(): Long
private external fun endRendering(handle: Long)
}
......@@ -44,21 +44,25 @@ internal class MetalSwingRedrawer(
super.dispose()
}
override fun onRender(g: Graphics2D, width: Int, height: Int, nanoTime: Long) = autoCloseScope {
val renderTarget = makeRenderTarget(width, height).autoClose()
val surface = Surface.makeFromBackendRenderTarget(
context,
renderTarget,
SurfaceOrigin.TOP_LEFT,
SurfaceColorFormat.BGRA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = PixelGeometry.UNKNOWN)
)?.autoClose() ?: throw RenderException("Cannot create surface")
val canvas = surface.canvas
canvas.clear(Color.TRANSPARENT)
skikoView.onRender(canvas, width, height, nanoTime)
flush(surface, g)
override fun onRender(g: Graphics2D, width: Int, height: Int, nanoTime: Long) {
autoreleasepool {
autoCloseScope {
val renderTarget = makeRenderTarget(width, height).autoClose()
val surface = Surface.makeFromBackendRenderTarget(
context,
renderTarget,
SurfaceOrigin.TOP_LEFT,
SurfaceColorFormat.BGRA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = PixelGeometry.UNKNOWN)
)?.autoClose() ?: throw RenderException("Cannot create surface")
val canvas = surface.canvas
canvas.clear(Color.TRANSPARENT)
skikoView.onRender(canvas, width, height, nanoTime)
flush(surface, g)
}
}
}
private fun flush(surface: Surface, g: Graphics2D) {
......
......@@ -26,6 +26,21 @@
extern "C"
{
extern "C" void* objc_autoreleasePoolPush(void);
extern "C" void objc_autoreleasePoolPop(void*);
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_MetalApiKt_openAutoreleasepool(
JNIEnv * env, jobject redrawer)
{
return (jlong)objc_autoreleasePoolPush();
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_MetalApiKt_closeAutoreleasepool(
JNIEnv * env, jobject redrawer, jlong handle)
{
objc_autoreleasePoolPop((void*)handle);
}
BOOL isUsingIntegratedGPU() {
kern_return_t kernResult = 0;
io_iterator_t iterator = IO_OBJECT_NULL;
......
......@@ -54,21 +54,6 @@
extern "C"
{
extern "C" void* objc_autoreleasePoolPush(void);
extern "C" void objc_autoreleasePoolPop(void*);
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_startRendering(
JNIEnv * env, jobject redrawer)
{
return (jlong)objc_autoreleasePoolPush();
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_endRendering(
JNIEnv * env, jobject redrawer, jlong handle)
{
objc_autoreleasePoolPop((void*)handle);
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMetalDevice(
JNIEnv *env, jobject redrawer, jlong windowPtr, jboolean transparency, jlong adapterPtr, jlong platformInfoPtr)
{
......
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