Skip to content

Commit

Permalink
sync awt layer background and CALayer background
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeevPavel committed Apr 3, 2023
1 parent e49782c commit fb4f34d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
7 changes: 7 additions & 0 deletions skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ actual open class SkiaLayer internal constructor(
}
}
}

addPropertyChangeListener("background") { evt ->
val color = (evt.newValue as Color).let { color ->
org.jetbrains.skia.Color.makeARGB(color.alpha, color.red, color.green, color.blue)
}
redrawer?.setLayerBackground(color)
}
}

private var fullscreenAdapter = FullscreenAdapter(backedLayer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.jetbrains.skia.BackendRenderTarget
import org.jetbrains.skia.Color
import org.jetbrains.skia.DirectContext
import org.jetbrains.skiko.*
import org.jetbrains.skiko.context.MetalContextHandler
Expand Down Expand Up @@ -39,7 +40,10 @@ internal class MetalRedrawer(
adapterMemorySize = getAdapterMemorySize(adapter)
onDeviceChosen(adapterName)
device = layer.backedLayer.useDrawingSurfacePlatformInfo {
createMetalDevice(layer.windowHandle, layer.transparency, adapter, it)
val color = layer.background.let { color ->
Color.makeARGB(color.alpha, color.red, color.green, color.blue)
}
createMetalDevice(layer.windowHandle, layer.transparency, color, adapter, it)
}
}

Expand Down Expand Up @@ -140,6 +144,10 @@ internal class MetalRedrawer(
setLayerVisible(device, isVisible)
}

override fun setLayerBackground(color: Int) {
setLayerBackground(device, color)
}

fun makeContext() = DirectContext(
makeMetalContext(device)
)
Expand All @@ -151,13 +159,14 @@ internal class MetalRedrawer(
fun finishFrame() = finishFrame(device)

private external fun chooseAdapter(adapterPriority: Int): Long
private external fun createMetalDevice(window:Long, transparency: Boolean, adapter: Long, platformInfo: Long): Long
private external fun createMetalDevice(window:Long, transparency: Boolean, color: Int, adapter: Long, platformInfo: Long): Long
private external fun makeMetalContext(device: Long): Long
private external fun makeMetalRenderTarget(device: Long, width: Int, height: Int): Long
private external fun disposeDevice(device: Long)
private external fun finishFrame(device: Long)
private external fun resizeLayers(device: Long, x: Int, y: Int, width: Int, height: Int)
private external fun setLayerVisible(device: Long, isVisible: Boolean)
private external fun setLayerBackground(device: Long, color: Int)
private external fun setContentScale(device: Long, contentScale: Float)
private external fun setVSyncEnabled(device: Long, enabled: Boolean)
private external fun isOccluded(window: Long): Boolean
Expand Down
36 changes: 34 additions & 2 deletions skiko/src/awtMain/objectiveC/macos/MetalRedrawer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,28 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_chooseAd
}
}

CGColorRef decodeColor(int color) {
CGFloat alpha = ((color >> 24) & 0xFF) / 255.0;
CGFloat red = ((color >> 16) & 0xFF) / 255.0;
CGFloat green = ((color >> 8) & 0xFF) / 255.0;
CGFloat blue = (color & 0xFF) / 255.0;

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {red, green, blue, alpha};
CGColorRef result = CGColorCreate(colorSpace, components);
CGColorSpaceRelease(colorSpace);

return result;
}

JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMetalDevice(
JNIEnv *env, jobject redrawer, jlong windowPtr, jboolean transparency, jlong adapterPtr, jlong platformInfoPtr)
JNIEnv *env,
jobject redrawer,
jlong windowPtr,
jboolean transparency,
jint backgroundColor,
jlong adapterPtr,
jlong platformInfoPtr)
{
@autoreleasepool {
id<MTLDevice> adapter = (__bridge_transfer id<MTLDevice>) (void *) adapterPtr;
Expand Down Expand Up @@ -225,7 +245,7 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMe
device.layer.backgroundColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), transparent);
window.hasShadow = NO;
} else {
device.layer.backgroundColor = window.backgroundColor.CGColor;
device.layer.backgroundColor = decodeColor(backgroundColor);
}

return (jlong) (__bridge_retained void *) device;
Expand Down Expand Up @@ -270,6 +290,18 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setLayerV
}
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setLayerBackground(
JNIEnv *env, jobject redrawer, jlong devicePtr, jint color)
{
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
if (!device || !device.layer) {
return;
}
device.layer.backgroundColor = decodeColor(color); // = CGColorCreate(CGColorSpaceCreateDeviceRGB(), (CGFloat[]){red, green, blue, alpha});
}
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale(JNIEnv *env, jobject obj, jlong devicePtr, jfloat contentScale)
{
@autoreleasepool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ internal interface Redrawer {
fun redrawImmediately()
fun syncSize() = Unit
fun setVisible(isVisible: Boolean) = Unit
// ARGB encoded as in org.jetbrains.skia.Color
fun setLayerBackground(color: Int) = Unit
val renderInfo: String
}

0 comments on commit fb4f34d

Please sign in to comment.