Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
333d444e
Unverified
Commit
333d444e
authored
Nov 02, 2021
by
Igor Demin
Committed by
GitHub
Nov 02, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix memory leaks on macOs, enable Arc compilation (#340)
parent
ee8e4cc9
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
240 additions
and
306 deletions
+240
-306
build.gradle.kts
skiko/build.gradle.kts
+1
-0
NativeApplication.kt
...c/jvmMain/kotlin/org/jetbrains/skiko/NativeApplication.kt
+3
-0
MetalRedrawer.kt
...Main/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt
+10
-7
Drawlayer.mm
skiko/src/jvmMain/objectiveC/macos/Drawlayer.mm
+62
-55
MetalRedrawer.mm
skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm
+111
-98
NativeApplication.mm
skiko/src/jvmMain/objectiveC/macos/NativeApplication.mm
+16
-0
OpenGLRedrawer.mm
skiko/src/jvmMain/objectiveC/macos/OpenGLRedrawer.mm
+0
-146
SkiaWindowTest.kt
.../src/jvmTest/kotlin/org/jetbrains/skiko/SkiaWindowTest.kt
+37
-0
No files found.
skiko/build.gradle.kts
View file @
333d444e
...
@@ -723,6 +723,7 @@ project.tasks.register<Exec>("objcCompile") {
...
@@ -723,6 +723,7 @@ project.tasks.register<Exec>("objcCompile") {
"-I$skiaDir"
,
"-I$skiaDir"
,
"-I$skiaDir/include"
,
"-I$skiaDir/include"
,
"-I$skiaDir/include/gpu"
,
"-I$skiaDir/include/gpu"
,
"-fobjc-arc"
,
"-DSK_METAL"
,
"-DSK_METAL"
,
"-std=c++17"
,
"-std=c++17"
,
"-c"
,
"-c"
,
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/NativeApplication.kt
0 → 100644
View file @
333d444e
package
org.jetbrains.skiko
internal
external
fun
getApplicationWindowCount
():
Int
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt
View file @
333d444e
package
org.jetbrains.skiko.redrawer
package
org.jetbrains.skiko.redrawer
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.swing.Swing
import
kotlinx.coroutines.swing.Swing
...
@@ -73,14 +74,11 @@ internal class MetalRedrawer(
...
@@ -73,14 +74,11 @@ internal class MetalRedrawer(
// Dispatchers.IO: 50 FPS, 200% CPU
// Dispatchers.IO: 50 FPS, 200% CPU
layer
.
inDrawScope
{
layer
.
inDrawScope
{
withContext
(
Dispatchers
.
IO
)
{
withContext
(
Dispatchers
.
IO
)
{
val
handle
=
startRendering
()
try
{
performDraw
()
performDraw
()
}
finally
{
endRendering
(
handle
)
}
}
}
}
}
if
(
isDisposed
)
throw
CancellationException
()
// When window is not visible - it doesn't make sense to redraw fast to avoid battery drain.
// When window is not visible - it doesn't make sense to redraw fast to avoid battery drain.
// In theory, we could be more precise, and just suspend rendering in
// In theory, we could be more precise, and just suspend rendering in
// `NSWindowDidChangeOcclusionStateNotification`, but current approach seems to work as well in practise.
// `NSWindowDidChangeOcclusionStateNotification`, but current approach seems to work as well in practise.
...
@@ -90,7 +88,12 @@ internal class MetalRedrawer(
...
@@ -90,7 +88,12 @@ internal class MetalRedrawer(
private
fun
performDraw
()
=
synchronized
(
drawLock
)
{
private
fun
performDraw
()
=
synchronized
(
drawLock
)
{
if
(!
isDisposed
)
{
if
(!
isDisposed
)
{
val
handle
=
startRendering
()
try
{
layer
.
draw
()
layer
.
draw
()
}
finally
{
endRendering
(
handle
)
}
}
}
}
}
...
...
skiko/src/jvmMain/objectiveC/macos/Drawlayer.mm
View file @
333d444e
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
@property jobject canvasGlobalRef;
@property jobject canvasGlobalRef;
@property (retain, strong) CALayer *container;
@property (retain, strong) CALayer *container;
@property (
retain, strong
) NSWindow *window;
@property (
weak
) NSWindow *window;
@end
@end
...
@@ -59,14 +59,6 @@
...
@@ -59,14 +59,6 @@
return self;
return self;
}
}
-(void) dealloc
{
self.canvasGlobalRef = NULL;
[self.container release];
[self.window release];
[super dealloc];
}
- (void) setUpCustomHeader
- (void) setUpCustomHeader
{
{
/**
/**
...
@@ -265,7 +257,7 @@ NSWindow *findCALayerWindow(NSView *rootView, CALayer *layer) {
...
@@ -265,7 +257,7 @@ NSWindow *findCALayerWindow(NSView *rootView, CALayer *layer) {
NSWindow *findWindow(jlong platformInfoPtr)
NSWindow *findWindow(jlong platformInfoPtr)
{
{
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *)
platformInfoPtr
;
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *)
((void*)platformInfoPtr)
;
CALayer* ca_layer = [dsi_mac windowLayer];
CALayer* ca_layer = [dsi_mac windowLayer];
NSWindow* target_window = nil;
NSWindow* target_window = nil;
...
@@ -281,74 +273,88 @@ NSWindow *findWindow(jlong platformInfoPtr)
...
@@ -281,74 +273,88 @@ NSWindow *findWindow(jlong platformInfoPtr)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr)
{
{
@autoreleasepool {
if (layerStorage == nil)
if (layerStorage == nil)
{
{
layerStorage = [[NSMutableSet alloc] init];
layerStorage = [[NSMutableSet alloc] init];
}
}
LayerHandler *layersSet
= [[LayerHandler alloc] init];
LayerHandler *layer
= [[LayerHandler alloc] init];
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers>
*) platformInfoPtr;
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) (void
*) platformInfoPtr;
layersSet
.container = [dsi_mac windowLayer];
layer
.container = [dsi_mac windowLayer];
jobject canvasGlobalRef = env->NewGlobalRef(canvas);
jobject canvasGlobalRef = env->NewGlobalRef(canvas);
[layersSet
setCanvasGlobalRef: canvasGlobalRef];
[layer
setCanvasGlobalRef: canvasGlobalRef];
layersSet
.window = findWindow(platformInfoPtr);
layer
.window = findWindow(platformInfoPtr);
[layerStorage addObject: layersSet];
[layerStorage addObject: layer];
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeDispose(JNIEnv *env, jobject canvas)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeDispose(JNIEnv *env, jobject canvas)
{
{
@autoreleasepool {
LayerHandler *layer = findByObject(env, canvas);
LayerHandler *layer = findByObject(env, canvas);
if (layer != NULL)
if (layer != NULL)
{
{
[layerStorage removeObject: layer];
[layerStorage removeObject: layer];
env->DeleteGlobalRef(layer.canvasGlobalRef);
env->DeleteGlobalRef(layer.canvasGlobalRef);
[layer release];
}
}
}
}
}
JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxIsFullscreenNative(JNIEnv *env, jobject properties, jobject component)
JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxIsFullscreenNative(JNIEnv *env, jobject properties, jobject component)
{
{
@autoreleasepool {
LayerHandler *layer = findByObject(env, component);
LayerHandler *layer = findByObject(env, component);
if (layer != NULL)
if (layer != NULL)
{
{
return [layer isFullScreen];
return [layer isFullScreen];
}
}
return false;
return false;
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxSetFullscreenNative(JNIEnv *env, jobject properties, jobject component, jboolean value)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxSetFullscreenNative(JNIEnv *env, jobject properties, jobject component, jboolean value)
{
{
@autoreleasepool {
LayerHandler *layer = findByObject(env, component);
LayerHandler *layer = findByObject(env, component);
if (layer != NULL)
if (layer != NULL)
{
{
[layer makeFullscreen:value];
[layer makeFullscreen:value];
}
}
}
}
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject c
anvas
, jlong platformInfoPtr)
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject c
omponent
, jlong platformInfoPtr)
{
{
NSWindow* window = findWindow(platformInfoPtr);
@autoreleasepool {
return (jlong)window;
LayerHandler *layer = findByObject(env, component);
return (jlong) (__bridge void*) layer.window;
}
}
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getContentHandle(JNIEnv *env, jobject c
anvas
, jlong platformInfoPtr)
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getContentHandle(JNIEnv *env, jobject c
omponent
, jlong platformInfoPtr)
{
{
NSWindow* window = findWindow(platformInfoPtr);
@autoreleasepool {
return (jlong)window;
LayerHandler *layer = findByObject(env, component);
return (jlong) (__bridge void*) layer.window;
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxDisableTitleBar(JNIEnv *env, jobject properties, jobject component, jfloat customHeaderHeight)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxDisableTitleBar(JNIEnv *env, jobject properties, jobject component, jfloat customHeaderHeight)
{
{
@autoreleasepool {
LayerHandler *layer = findByObject(env, component);
LayerHandler *layer = findByObject(env, component);
if (layer != NULL)
if (layer != NULL)
{
{
[layer disableTitlebar:((CGFloat) customHeaderHeight)];
[layer disableTitlebar:((CGFloat) customHeaderHeight)];
}
}
}
}
}
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_SystemTheme_1jvmKt_getCurrentSystemTheme(JNIEnv *env, jobject topLevel)
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_SystemTheme_1jvmKt_getCurrentSystemTheme(JNIEnv *env, jobject topLevel)
{
{
@autoreleasepool {
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
if ([@"Dark" isEqualToString:osxMode]) {
if ([@"Dark" isEqualToString:osxMode]) {
// Dark.
// Dark.
...
@@ -357,14 +363,15 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_SystemTheme_1jvmKt_getCurrentSys
...
@@ -357,14 +363,15 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_SystemTheme_1jvmKt_getCurrentSys
// Light.
// Light.
return 0;
return 0;
}
}
}
}
}
void getMetalDeviceAndQueue(void** device, void** queue)
void getMetalDeviceAndQueue(void** device, void** queue)
{
{
id<MTLDevice> fDevice = MTLCreateSystemDefaultDevice();
id<MTLDevice> fDevice = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> fQueue = [fDevice newCommandQueue];
id<MTLCommandQueue> fQueue = [fDevice newCommandQueue];
*device = (__bridge void*)fDevice;
*device = (__bridge void*)
fDevice;
*queue = (__bridge void*)fQueue;
*queue = (__bridge void*)
fQueue;
}
}
} // extern C
} // extern C
\ No newline at end of file
skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm
View file @
333d444e
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
@interface MetalDevice : NSObject
@interface MetalDevice : NSObject
@property (
retain, strong
) CALayer *container;
@property (
weak
) CALayer *container;
@property (retain, strong) AWTMetalLayer *layer;
@property (retain, strong) AWTMetalLayer *layer;
@property (retain, strong) id<MTLDevice> device;
@property (retain, strong) id<MTLDevice> device;
@property (retain, strong) id<MTLCommandQueue> queue;
@property (retain, strong) id<MTLCommandQueue> queue;
...
@@ -71,15 +71,6 @@
...
@@ -71,15 +71,6 @@
return self;
return self;
}
}
-(void)dealloc {
[self.layer removeFromSuperlayer];
[self.layer release];
[self.device release];
[self.queue release];
[self.drawableHandle release];
[super dealloc];
}
@end
@end
extern "C"
extern "C"
...
@@ -88,26 +79,30 @@ extern "C"
...
@@ -88,26 +79,30 @@ extern "C"
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_makeMetalContext(
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_makeMetalContext(
JNIEnv* env, jobject redrawer, jlong devicePtr)
JNIEnv* env, jobject redrawer, jlong devicePtr)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void*) devicePtr;
GrMtlBackendContext backendContext = {};
GrMtlBackendContext backendContext = {};
backendContext.fDevice.retain((
GrMTLHandle) device.device);
backendContext.fDevice.retain((__bridge
GrMTLHandle) device.device);
backendContext.fQueue.retain((
GrMTLHandle) device.queue);
backendContext.fQueue.retain((__bridge
GrMTLHandle) device.queue);
return (jlong) GrDirectContext::MakeMetal(backendContext).release();
return (jlong) GrDirectContext::MakeMetal(backendContext).release();
}
}
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_makeMetalRenderTarget(
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_makeMetalRenderTarget(
JNIEnv * env, jobject redrawer, jlong devicePtr, jint width, jint height)
JNIEnv * env, jobject redrawer, jlong devicePtr, jint width, jint height)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
GrBackendRenderTarget* renderTarget = NULL;
GrBackendRenderTarget* renderTarget = NULL;
id<CAMetalDrawable> currentDrawable = [device.layer nextDrawable];
id<CAMetalDrawable> currentDrawable = [device.layer nextDrawable];
if (!currentDrawable) return 0;
if (!currentDrawable) return 0;
device.drawableHandle = currentDrawable;
device.drawableHandle = currentDrawable;
GrMtlTextureInfo info;
GrMtlTextureInfo info;
info.fTexture.retain(
currentDrawable.texture);
info.fTexture.retain((__bridge GrMTLHandle)
currentDrawable.texture);
renderTarget = new GrBackendRenderTarget(width, height, 0, info);
renderTarget = new GrBackendRenderTarget(width, height, 0, info);
return (jlong) renderTarget;
return (jlong) renderTarget;
}
}
}
extern "C" void* objc_autoreleasePoolPush(void);
extern "C" void* objc_autoreleasePoolPush(void);
...
@@ -185,9 +180,10 @@ id<MTLDevice> MTLCreateIntegratedDevice(int adapterPriority) {
...
@@ -185,9 +180,10 @@ id<MTLDevice> MTLCreateIntegratedDevice(int adapterPriority) {
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMetalDevice(
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMetalDevice(
JNIEnv *env, jobject redrawer, jlong windowPtr, jboolean transparency, jint adapterPriority, jlong platformInfoPtr)
JNIEnv *env, jobject redrawer, jlong windowPtr, jboolean transparency, jint adapterPriority, jlong platformInfoPtr)
{
{
@autoreleasepool {
MetalDevice *device = [MetalDevice new];
MetalDevice *device = [MetalDevice new];
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers>
*) platformInfoPtr;
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) (void
*) platformInfoPtr;
CALayer *container = [dsi_mac windowLayer];
CALayer *container = [dsi_mac windowLayer];
[container removeAllAnimations];
[container removeAllAnimations];
...
@@ -216,17 +212,19 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMe
...
@@ -216,17 +212,19 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMe
if (transparency)
if (transparency)
{
{
NSWindow* window = (NSWindow*)
windowPtr;
NSWindow* window = (__bridge NSWindow*) (void *)
windowPtr;
window.hasShadow = NO;
window.hasShadow = NO;
}
}
return (jlong) device;
return (jlong) (__bridge_retained void *) device;
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLayers(
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLayers(
JNIEnv *env, jobject redrawer, jlong devicePtr, jint x, jint y, jint width, jint height)
JNIEnv *env, jobject redrawer, jlong devicePtr, jint x, jint y, jint width, jint height)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
float scale = device.layer.contentsScale;
float scale = device.layer.contentsScale;
CGRect frame = CGRectMake(x, y, width, height);
CGRect frame = CGRectMake(x, y, width, height);
CGSize drawableSize = CGSizeMake(width * scale, height * scale);
CGSize drawableSize = CGSizeMake(width * scale, height * scale);
...
@@ -240,11 +238,13 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLay
...
@@ -240,11 +238,13 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLay
}
}
[CATransaction commit];
[CATransaction commit];
[CATransaction flush];
[CATransaction flush];
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale(JNIEnv *env, jobject obj, jlong devicePtr, jfloat contentScale)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale(JNIEnv *env, jobject obj, jlong devicePtr, jfloat contentScale)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
if (!device || !device.layer || device.layer.contentsScale == contentScale) {
if (!device || !device.layer || device.layer.contentsScale == contentScale) {
return;
return;
}
}
...
@@ -255,18 +255,22 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setConten
...
@@ -255,18 +255,22 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setConten
device.layer.contentsScale = contentScale;
device.layer.contentsScale = contentScale;
[CATransaction commit];
[CATransaction commit];
[CATransaction flush];
[CATransaction flush];
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setVSyncEnabled(JNIEnv *env, jobject obj, jlong devicePtr, jboolean enabled)
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setVSyncEnabled(JNIEnv *env, jobject obj, jlong devicePtr, jboolean enabled)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
device.layer.displaySyncEnabled = enabled;
device.layer.displaySyncEnabled = enabled;
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_finishFrame(
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_finishFrame(
JNIEnv *env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
id<CAMetalDrawable> currentDrawable = device.drawableHandle;
id<CAMetalDrawable> currentDrawable = device.drawableHandle;
...
@@ -277,37 +281,46 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_finishFra
...
@@ -277,37 +281,46 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_finishFra
[commandBuffer commit];
[commandBuffer commit];
device.drawableHandle = nil;
device.drawableHandle = nil;
}
}
}
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_disposeDevice(
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_disposeDevice(
JNIEnv *env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge_transfer MetalDevice *) (void *) devicePtr;
env->DeleteGlobalRef(device.layer.javaRef);
env->DeleteGlobalRef(device.layer.javaRef);
[device release];
[device.layer removeFromSuperlayer];
}
}
}
JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterName(
JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterName(
JNIEnv *env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
const char *currentAdapterName = [[device.device name] cStringUsingEncoding:NSASCIIStringEncoding];
const char *currentAdapterName = [[device.device name] cStringUsingEncoding:NSASCIIStringEncoding];
jstring result = env->NewStringUTF(currentAdapterName);
jstring result = env->NewStringUTF(currentAdapterName);
return result;
return result;
}
}
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterMemorySize(
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterMemorySize(
JNIEnv *env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
{
MetalDevice *device = (MetalDevice *) devicePtr;
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
uint64_t totalMemory = [device.device recommendedMaxWorkingSetSize];
uint64_t totalMemory = [device.device recommendedMaxWorkingSetSize];
return (jlong)totalMemory;
return (jlong)totalMemory;
}
}
}
JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_isOccluded(
JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_isOccluded(
JNIEnv *env, jobject redrawer, jlong windowPtr) {
JNIEnv *env, jobject redrawer, jlong windowPtr) {
NSWindow* window = (NSWindow*)windowPtr;
@autoreleasepool {
NSWindow* window = (__bridge NSWindow*) (void *) windowPtr;
return ([window occlusionState] & NSWindowOcclusionStateVisible) == 0;
return ([window occlusionState] & NSWindowOcclusionStateVisible) == 0;
}
}
}
} // extern C
} // extern C
...
...
skiko/src/jvmMain/objectiveC/macos/NativeApplication.mm
0 → 100644
View file @
333d444e
#import "jawt.h"
#import "jawt_md.h"
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
extern "C"
{
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_NativeApplicationKt_getApplicationWindowCount(JNIEnv *env, jobject obj)
{
@autoreleasepool {
return [[[NSApplication sharedApplication] windows] count];
}
}
}
skiko/src/jvmMain/objectiveC/macos/OpenGLRedrawer.mm
deleted
100644 → 0
View file @
ee8e4cc9
#import "jawt.h"
#import "jawt_md.h"
#define GL_SILENCE_DEPRECATION
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGL/gl3.h>
JavaVM *jvm = NULL;
@interface AWTGLLayer : CAOpenGLLayer
@property jobject javaRef;
@end
@implementation AWTGLLayer
- (id)init
{
self = [super init];
assert(self != NULL);
[self removeAllAnimations];
[self setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
return self;
}
-(BOOL)canDrawInCGLContext:(CGLContextObj)ctx
pixelFormat:(CGLPixelFormatObj)pf
forLayerTime:(CFTimeInterval)t
displayTime:(const CVTimeStamp *)ts
{
assert(jvm != NULL);
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
static jclass cls = NULL;
static jmethodID method = NULL;
if (!cls) cls = env->GetObjectClass(self.javaRef);
if (!method) method = env->GetMethodID(cls, "canDraw", "()Z");
return env->CallBooleanMethod(self.javaRef, method);
}
-(void)drawInCGLContext:(CGLContextObj)ctx
pixelFormat:(CGLPixelFormatObj)pf
forLayerTime:(CFTimeInterval)t
displayTime:(const CVTimeStamp *)ts
{
CGLSetCurrentContext(ctx);
assert(jvm != NULL);
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
static jclass cls = NULL;
static jmethodID method = NULL;
if (!cls) cls = env->GetObjectClass(self.javaRef);
if (!method) method = env->GetMethodID(cls, "performDraw", "()V");
env->CallVoidMethod(self.javaRef, method);
[super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts];
}
@end
extern "C"
{
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_initContainer(JNIEnv *env, jobject redrawer, jlong platformInfoPtr)
{
env->GetJavaVM(&jvm);
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) platformInfoPtr;
CALayer *container = [dsi_mac windowLayer];
[container removeAllAnimations];
[container setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[container setNeedsDisplayOnBoundsChange: YES];
return (jlong) container;
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_setContentScale(JNIEnv *env, jobject obj, jlong layerPtr, jfloat contentScale)
{
CALayer *layer = (CALayer *) layerPtr;
assert(contentScale != 0);
layer.contentsScale = contentScale;
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_initAWTGLLayer(JNIEnv *env, jobject obj, jlong containerPtr, jobject layer, jboolean setNeedsDisplayOnBoundsChange)
{
CALayer *container = (CALayer *) containerPtr;
AWTGLLayer *glLayer = [AWTGLLayer new];
glLayer.javaRef = env->NewGlobalRef(layer);
[glLayer setNeedsDisplayOnBoundsChange: setNeedsDisplayOnBoundsChange];
[container addSublayer: glLayer];
return (jlong) glLayer;
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_disposeAWTGLLayer(JNIEnv *env, jobject obj, jlong ptr)
{
AWTGLLayer *glLayer = (AWTGLLayer *) ptr;
[glLayer removeFromSuperlayer];
env->DeleteGlobalRef(glLayer.javaRef);
[glLayer release];
}
JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_redrawer_AWTGLLayer_isAsynchronous(JNIEnv *env, jobject obj, jlong ptr)
{
AWTGLLayer *glLayer = (AWTGLLayer *) ptr;
return glLayer.isAsynchronous;
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AWTGLLayer_setAsynchronous(JNIEnv *env, jobject obj, jlong ptr, jboolean isAsynchronous)
{
AWTGLLayer *glLayer = (AWTGLLayer *) ptr;
[glLayer setAsynchronous: isAsynchronous];
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AWTGLLayer_setNeedsDisplayOnMainThread(JNIEnv *env, jobject obj, jlong ptr)
{
AWTGLLayer *glLayer = (AWTGLLayer *) ptr;
[glLayer performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:0 waitUntilDone:NO];
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AWTGLLayer_setFrame(JNIEnv *env, jobject obj, jlong containerPtr, jlong ptr, jfloat x, jfloat y, jfloat width, jfloat height)
{
CALayer *container = (AWTGLLayer *) containerPtr;
AWTGLLayer *glLayer = (AWTGLLayer *) ptr;
y = (int)container.frame.size.height - y - height;
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions]; // disable animations
glLayer.frame = CGRectMake(x, y, width, height);
[CATransaction commit];
}
} // extern C
\ No newline at end of file
skiko/src/jvmTest/kotlin/org/jetbrains/skiko/SkiaWindowTest.kt
View file @
333d444e
...
@@ -15,6 +15,7 @@ import org.jetbrains.skiko.context.ContextHandler
...
@@ -15,6 +15,7 @@ import org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.redrawer.Redrawer
import
org.jetbrains.skiko.redrawer.Redrawer
import
org.jetbrains.skiko.util.ScreenshotTestRule
import
org.jetbrains.skiko.util.ScreenshotTestRule
import
org.jetbrains.skiko.util.swingTest
import
org.jetbrains.skiko.util.swingTest
import
org.junit.Assert
import
org.junit.Assert.assertEquals
import
org.junit.Assert.assertEquals
import
org.junit.Assume.assumeTrue
import
org.junit.Assume.assumeTrue
import
org.junit.Rule
import
org.junit.Rule
...
@@ -63,6 +64,42 @@ class SkiaWindowTest {
...
@@ -63,6 +64,42 @@ class SkiaWindowTest {
@get
:
Rule
@get
:
Rule
val
screenshots
=
ScreenshotTestRule
()
val
screenshots
=
ScreenshotTestRule
()
@Test
fun
`
should
not
leak
native
windows
`
()
=
swingTest
{
assumeTrue
(
hostOs
.
isMacOS
)
suspend
fun
createAndDisposeWindow
()
{
val
layer
=
SkiaLayer
()
val
frame
=
JFrame
()
frame
.
contentPane
.
add
(
layer
)
frame
.
size
=
Dimension
(
200
,
200
)
frame
.
isVisible
=
true
delay
(
30
)
layer
.
dispose
()
frame
.
dispose
()
}
// warm caches
repeat
(
8
)
{
createAndDisposeWindow
()
}
delay
(
1000
)
val
initialWindowCount
=
getApplicationWindowCount
()
repeat
(
32
)
{
createAndDisposeWindow
()
}
delay
(
1000
)
val
actualWindowCount
=
getApplicationWindowCount
()
assertTrue
(
initialWindowCount
>=
actualWindowCount
,
"initialWindowCount=$initialWindowCount, actualWindowCount=$actualWindowCount"
)
}
@Test
@Test
fun
`
render
single
window
`
()
=
swingTest
{
fun
`
render
single
window
`
()
=
swingTest
{
val
window
=
SkiaWindow
()
val
window
=
SkiaWindow
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment