Unverified Commit 3facce45 authored by Nikolay Igotti's avatar Nikolay Igotti Committed by GitHub

Android support preparational work (#451)

parent ed81acba
buildscript {
repositories {
mavenLocal()
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
dependencies {
// __KOTLIN_COMPOSE_VERSION__
classpath(kotlin("gradle-plugin", version = "1.6.10"))
}
}
plugins {
kotlin("multiplatform") version "1.6.10"
}
......@@ -6,6 +20,7 @@ val coroutinesVersion = "1.5.2"
repositories {
mavenLocal()
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
......
......@@ -2,9 +2,7 @@ pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
maven {
url = uri("https://dl.bintray.com/kotlin/kotlin-eap")
}
google()
}
}
......
......@@ -202,12 +202,7 @@ val Project.supportWasm: Boolean
get() = findProperty("skiko.wasm.enabled") == "true" || isInIdea
val Project.supportAndroid: Boolean
get() = findProperty("skiko.android.enabled") == "true"
val skikoAwtJar by project.tasks.registering(Jar::class) {
archiveBaseName.set("skiko-awt")
from(kotlin.jvm("awt").compilations["main"].output.allOutputs)
}
get() = findProperty("skiko.android.enabled") == "true" // || isInIdea
kotlin {
jvm("awt") {
......@@ -218,11 +213,14 @@ kotlin {
}
if (supportAndroid) {
// todo: use android target
jvm("android") {
compilations.all {
kotlinOptions.jvmTarget = "11"
}
// We need an additional attribute to distinguish between JVM variants.
attributes {
attributes.attribute(Attribute.of("ui", String::class.java), "android")
}
// TODO: seems incorrect.
generateVersion(OS.Android, Arch.Arm64)
}
......@@ -230,7 +228,7 @@ kotlin {
if (supportWasm) {
js(IR) {
browser() {
browser {
testTask {
dependsOn("linkWasm")
useKarma {
......@@ -265,19 +263,11 @@ kotlin {
}
}
/*
val androidMain by getting {
dependencies {
}
} */
val jvmMain by creating {
dependsOn(commonMain)
dependencies {
implementation(kotlin("stdlib"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:$coroutinesVersion")
}
}
......@@ -609,17 +599,25 @@ fun skiaStaticLibraries(skiaDir: String, targetString: String): List<String> {
val allJvmRuntimeJars = mutableMapOf<Pair<OS, Arch>, TaskProvider<Jar>>()
val skikoJvmRuntimeJar = createSkikoJvmJarTask(hostOs, hostArch)
val skikoAwtJar by project.tasks.registering(Jar::class) {
archiveBaseName.set("skiko-awt")
from(kotlin.jvm("awt").compilations["main"].output.allOutputs)
}
val skikoJvmRuntimeJar = createSkikoJvmJarTask(hostOs, hostArch, skikoAwtJar)
val skikoRuntimeDirForTests = skikoRuntimeDirForTestsTask(hostOs, hostArch, skikoJvmRuntimeJar)
if (supportAndroid) {
val os = OS.Android
val skikoAndroidJar by project.tasks.registering(Jar::class) {
archiveBaseName.set("skiko-android")
from(kotlin.jvm("android").compilations["main"].output.allOutputs)
}
for (arch in arrayOf(Arch.X64, Arch.Arm64)) {
createSkikoJvmJarTask(os, arch)
createSkikoJvmJarTask(os, arch, skikoAndroidJar)
}
}
fun createSkikoJvmJarTask(os: OS, arch: Arch): TaskProvider<Jar> {
fun createSkikoJvmJarTask(os: OS, arch: Arch, commonJar: TaskProvider<Jar>): TaskProvider<Jar> {
val skiaBindingsDir = registerOrGetSkiaDirProvider(os, arch)
val compileBindings = createCompileJvmBindingsTask(os, arch, skiaBindingsDir)
val objcCompile = if (os == OS.MacOS) createObjcCompileTask(os, arch, skiaBindingsDir) else null
......@@ -651,7 +649,7 @@ fun createSkikoJvmJarTask(os: OS, arch: Arch): TaskProvider<Jar> {
nativeFiles.add(nativeLib2)
nativeFiles.add(createChecksums2.map { it.outputs.files.singleFile })
}
val skikoJvmRuntimeJar = skikoJvmRuntimeJarTask(os, arch, skikoAwtJar, nativeFiles)
val skikoJvmRuntimeJar = skikoJvmRuntimeJarTask(os, arch, commonJar, nativeFiles)
allJvmRuntimeJars[os to arch] = skikoJvmRuntimeJar
return skikoJvmRuntimeJar
}
......
package org.jetbrains.skiko
import org.jetbrains.skiko.redrawer.Redrawer
actual fun setSystemLookAndFeel(): Unit = TODO()
internal class AndroidOpenGLRedrawer(
private val layer: SkiaLayer,
private val properties: SkiaLayerProperties
) : Redrawer {
override fun dispose() = TODO()
override fun needRedraw() = TODO()
override fun redrawImmediately() = TODO()
override val renderInfo: String get() = "Android renderer"
}
internal actual fun makeDefaultRenderFactory(): RenderFactory {
return object : RenderFactory {
override fun createRedrawer(
layer: SkiaLayer,
renderApi: GraphicsApi,
properties: SkiaLayerProperties
): Redrawer = when (hostOs) {
OS.Android -> AndroidOpenGLRedrawer(layer, properties)
else -> throw IllegalArgumentException("Must not happen")
}
}
}
package org.jetbrains.skiko
import android.view.KeyEvent
import android.view.MotionEvent
import org.jetbrains.skia.Canvas
import org.jetbrains.skiko.redrawer.Redrawer
actual typealias SkikoGesturePlatformEvent = MotionEvent
actual typealias SkikoPlatformPointerEvent = MotionEvent
// TODO: most likely wrong.
actual typealias SkikoPlatformInputEvent = Any
actual typealias SkikoTouchPlatformEvent = Any
actual typealias SkikoPlatformKeyboardEvent = KeyEvent
actual open class SkiaLayer {
actual var renderApi: GraphicsApi = GraphicsApi.OPENGL
actual val contentScale: Float
get() = 1.0f
actual var fullscreen: Boolean
get() = false
set(value) {
if (value) throw IllegalArgumentException("fullscreen unsupported")
}
actual var transparency: Boolean
get() = false
set(value) {
if (value) throw IllegalArgumentException("transparency unsupported")
}
actual var skikoView: SkikoView? = null
actual fun attachTo(container: Any) {
TODO("Implement attachTo()")
}
actual fun detach() {
}
actual fun needRedraw() {
TODO("Implement needRedraw()")
}
internal var redrawer: Redrawer? = null
var width: Int = 0
var height: Int = 0
internal actual fun draw(canvas: Canvas): Unit = TODO()
}
\ No newline at end of file
package org.jetbrains.skiko
import android.view.KeyEvent.*
// See https://developer.android.com/reference/android/view/KeyEvent
actual enum class SkikoKey(val value: Int) {
KEY_UNKNOWN(KEYCODE_UNKNOWN),
KEY_A(KEYCODE_A),
KEY_S(KEYCODE_S),
KEY_D(KEYCODE_D),
KEY_F(KEYCODE_F),
KEY_H(KEYCODE_H),
KEY_G(KEYCODE_G),
KEY_Z(KEYCODE_Z),
KEY_X(KEYCODE_X),
KEY_C(KEYCODE_C),
KEY_V(KEYCODE_V),
KEY_B(KEYCODE_B),
KEY_Q(KEYCODE_Q),
KEY_W(KEYCODE_W),
KEY_E(KEYCODE_E),
KEY_R(KEYCODE_R),
KEY_Y(KEYCODE_Y),
KEY_T(KEYCODE_T),
KEY_U(KEYCODE_U),
KEY_I(KEYCODE_I),
KEY_P(KEYCODE_P),
KEY_L(KEYCODE_L),
KEY_J(KEYCODE_J),
KEY_K(KEYCODE_K),
KEY_N(KEYCODE_N),
KEY_M(KEYCODE_M),
KEY_O(KEYCODE_O),
KEY_1(KEYCODE_1),
KEY_2(KEYCODE_2),
KEY_3(KEYCODE_3),
KEY_4(KEYCODE_4),
KEY_5(KEYCODE_5),
KEY_6(KEYCODE_6),
KEY_7(KEYCODE_7),
KEY_8(KEYCODE_8),
KEY_9(KEYCODE_9),
KEY_0(KEYCODE_0),
KEY_CLOSE_BRACKET(KEYCODE_RIGHT_BRACKET),
KEY_OPEN_BRACKET(KEYCODE_LEFT_BRACKET),
KEY_QUOTE(KEYCODE_UNKNOWN),
KEY_SEMICOLON(KEYCODE_SEMICOLON),
KEY_SLASH(KEYCODE_SLASH),
KEY_COMMA(KEYCODE_COMMA),
KEY_BACKSLASH(KEYCODE_BACKSLASH),
KEY_PERIOD(KEYCODE_PERIOD),
KEY_BACK_QUOTE(KEYCODE_UNKNOWN),
KEY_EQUALS(KEYCODE_EQUALS),
KEY_MINUS(KEYCODE_MINUS),
KEY_ENTER(KEYCODE_ENTER),
KEY_ESCAPE(KEYCODE_ESCAPE),
KEY_TAB(KEYCODE_TAB),
KEY_BACKSPACE(KEYCODE_DEL),
KEY_SPACE(KEYCODE_SPACE),
KEY_CAPSLOCK(KEYCODE_CAPS_LOCK),
KEY_LEFT_META(KEYCODE_META_LEFT),
KEY_LEFT_SHIFT(KEYCODE_SHIFT_LEFT),
KEY_LEFT_ALT(KEYCODE_ALT_LEFT),
KEY_LEFT_CONTROL(KEYCODE_CTRL_LEFT),
KEY_RIGHT_META(KEYCODE_META_RIGHT),
KEY_RIGHT_SHIFT(KEYCODE_SHIFT_RIGHT),
KEY_RIGHT_ALT(KEYCODE_ALT_RIGHT),
KEY_RIGHT_CONTROL(KEYCODE_CTRL_RIGHT),
KEY_MENU(KEYCODE_UNKNOWN),
KEY_UP(KEYCODE_SYSTEM_NAVIGATION_UP),
KEY_DOWN(KEYCODE_SYSTEM_NAVIGATION_DOWN),
KEY_LEFT(KEYCODE_SYSTEM_NAVIGATION_LEFT),
KEY_RIGHT(KEYCODE_SYSTEM_NAVIGATION_RIGHT),
KEY_F1(KEYCODE_F1),
KEY_F2(KEYCODE_F2),
KEY_F3(KEYCODE_F3),
KEY_F4(KEYCODE_F4),
KEY_F5(KEYCODE_F5),
KEY_F6(KEYCODE_F6),
KEY_F7(KEYCODE_F7),
KEY_F8(KEYCODE_F8),
KEY_F9(KEYCODE_F9),
KEY_F10(KEYCODE_F10),
KEY_F11(KEYCODE_F11),
KEY_F12(KEYCODE_F12),
KEY_PRINTSCEEN(KEYCODE_UNKNOWN),
KEY_SCROLL_LOCK(KEYCODE_UNKNOWN),
KEY_PAUSE(KEYCODE_UNKNOWN),
KEY_INSERT(KEYCODE_INSERT),
KEY_HOME(KEYCODE_HOME),
KEY_PGUP(KEYCODE_PAGE_UP),
KEY_DELETE(KEYCODE_FORWARD_DEL),
KEY_END(KEYCODE_MOVE_END),
KEY_PGDOWN(KEYCODE_PAGE_DOWN),
KEY_NUM_LOCK(KEYCODE_UNKNOWN),
KEY_NUMPAD_0(KEYCODE_NUMPAD_0),
KEY_NUMPAD_1(KEYCODE_NUMPAD_1),
KEY_NUMPAD_2(KEYCODE_NUMPAD_2),
KEY_NUMPAD_3(KEYCODE_NUMPAD_3),
KEY_NUMPAD_4(KEYCODE_NUMPAD_4),
KEY_NUMPAD_5(KEYCODE_NUMPAD_5),
KEY_NUMPAD_6(KEYCODE_NUMPAD_6),
KEY_NUMPAD_7(KEYCODE_NUMPAD_7),
KEY_NUMPAD_8(KEYCODE_NUMPAD_8),
KEY_NUMPAD_9(KEYCODE_NUMPAD_9),
KEY_NUMPAD_ENTER(KEYCODE_NUMPAD_ENTER),
KEY_NUMPAD_ADD(KEYCODE_NUMPAD_ADD),
KEY_NUMPAD_SUBTRACT(KEYCODE_NUMPAD_SUBTRACT),
KEY_NUMPAD_MULTIPLY(KEYCODE_NUMPAD_MULTIPLY),
KEY_NUMPAD_DIVIDE(KEYCODE_NUMPAD_DIVIDE),
KEY_NUMPAD_DECIMAL(KEYCODE_UNKNOWN);
}
\ No newline at end of file
......@@ -466,7 +466,7 @@ actual open class SkiaLayer internal constructor(
}
}
internal fun draw(canvas: Canvas) {
actual internal fun draw(canvas: Canvas) {
check(!isDisposed) { "SkiaLayer is disposed" }
lockPicture {
canvas.drawPicture(it.instance)
......
package org.jetbrains.skiko.context
import org.jetbrains.skia.Surface
import org.jetbrains.skia.impl.Native
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.Direct3DRedrawer
......
package org.jetbrains.skiko.context
import org.jetbrains.skia.Surface
import org.jetbrains.skia.impl.Native
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.AbstractDirectSoftwareRedrawer
......
......@@ -4,7 +4,6 @@ import org.jetbrains.skia.Bitmap
import org.jetbrains.skia.Canvas
import org.jetbrains.skia.ColorAlphaType
import org.jetbrains.skia.ImageInfo
import org.jetbrains.skia.Picture
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.hostOs
import org.jetbrains.skiko.OS
......
package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing
import org.jetbrains.skia.BackendRenderTarget
import org.jetbrains.skia.DirectContext
import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.context.AngleContextHandler
import org.jetbrains.skiko.context.DirectSoftwareContextHandler
internal class AngleRedrawer(
private val layer: SkiaLayer,
......
package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.jetbrains.skia.DirectContext
import org.jetbrains.skia.Surface
import org.jetbrains.skiko.*
import org.jetbrains.skiko.context.AngleContextHandler
import org.jetbrains.skiko.context.Direct3DContextHandler
internal class Direct3DRedrawer(
......
......@@ -4,5 +4,5 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlinx.coroutines.swing.Swing
actual val MainUIDispatcher: MainCoroutineDispatcher
val MainUIDispatcher: MainCoroutineDispatcher
get() = Dispatchers.Swing
......@@ -3,7 +3,6 @@ package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.jetbrains.skia.BackendRenderTarget
import org.jetbrains.skia.DirectContext
......@@ -34,7 +33,7 @@ internal class MetalRedrawer(
setVSyncEnabled(device, properties.isVsyncEnabled)
}
private val frameDispatcher = FrameDispatcher(Dispatchers.Swing) {
private val frameDispatcher = FrameDispatcher(MainUIDispatcher) {
if (layer.isShowing) {
update(System.nanoTime())
draw()
......
......@@ -7,8 +7,6 @@ import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.context.SoftwareContextHandler
expect val MainUIDispatcher: MainCoroutineDispatcher
internal class SoftwareRedrawer(
private val layer: SkiaLayer,
private val properties: SkiaLayerProperties
......
......@@ -2,7 +2,6 @@ package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.jetbrains.skiko.*
import org.jetbrains.skiko.context.OpenGLContextHandler
......@@ -79,7 +78,7 @@ internal class WindowsOpenGLRedrawer(
.filterNot(WindowsOpenGLRedrawer::isDisposed)
.filter { it.layer.isShowing }
private val frameDispatcher = FrameDispatcher(Dispatchers.Swing) {
private val frameDispatcher = FrameDispatcher(MainUIDispatcher) {
toRedrawCopy.addAll(toRedraw)
toRedraw.clear()
......
package org.jetbrains.skiko
import kotlin.jvm.JvmInline
// Clicked mouse buttons bitmask.
inline class SkikoMouseButtons(val value: Int) {
@JvmInline
value class SkikoMouseButtons(val value: Int) {
companion object {
val NONE = SkikoMouseButtons(0)
val LEFT = SkikoMouseButtons(1)
......@@ -55,7 +58,8 @@ inline class SkikoMouseButtons(val value: Int) {
}
}
inline class SkikoInputModifiers(val value: Int) {
@JvmInline
value class SkikoInputModifiers(val value: Int) {
companion object {
val EMPTY = SkikoInputModifiers(0)
val META = SkikoInputModifiers(1)
......
package org.jetbrains.skiko
import org.jetbrains.skia.Canvas
import org.jetbrains.skia.Picture
expect open class SkiaLayer {
......@@ -15,6 +16,8 @@ expect open class SkiaLayer {
fun detach()
fun needRedraw()
internal fun draw(canvas: Canvas)
}
......
......@@ -172,7 +172,7 @@ actual open class SkiaLayer {
internal var redrawer: MetalRedrawer? = null
private var contextHandler: MetalContextHandler? = null
internal fun draw(canvas: Canvas) {
internal actual fun draw(canvas: Canvas) {
check(!isDisposed) { "SkiaLayer is disposed" }
val (w, h) = view!!.frame.useContents {
size.width to size.height
......
package org.jetbrains.skiko
import kotlinx.browser.window
import org.jetbrains.skia.Canvas
import org.w3c.dom.HTMLCanvasElement
import org.w3c.dom.events.InputEvent
import org.w3c.dom.events.KeyboardEvent
......@@ -101,6 +102,10 @@ actual open class SkiaLayer {
window.matchMedia("(resolution: ${contentScale}dppx)").addEventListener("change", { setOnChangeScaleNotifier() }, true)
onContentScaleChanged?.invoke(contentScale)
}
internal actual fun draw(canvas: Canvas) {
skikoView?.onRender(canvas, state!!.width, state!!.height, currentNanoTime())
}
}
var onContentScaleChanged: ((Float) -> Unit)? = null
......
package org.jetbrains.skiko
import org.jetbrains.skia.Canvas
actual open class SkiaLayer {
actual var renderApi: GraphicsApi
get() = TODO("Not yet implemented")
......@@ -21,6 +23,11 @@ actual open class SkiaLayer {
actual fun detach() {
TODO("unimplemented")
}
internal actual fun draw(canvas: Canvas) {
TODO("unimplemented")
}
actual var skikoView: SkikoView? = null
}
......
......@@ -25,7 +25,7 @@ import platform.Foundation.addObserver
import platform.darwin.NSObject
import platform.CoreGraphics.CGRectMake
actual open class SkiaLayer() {
actual open class SkiaLayer {
fun isShowing(): Boolean {
return true
}
......@@ -226,7 +226,7 @@ actual open class SkiaLayer() {
this.picture = PictureHolder(picture, pictureWidth.toInt(), pictureHeight.toInt())
}
internal fun draw(canvas: Canvas) {
internal actual fun draw(canvas: Canvas) {
picture?.also {
canvas.drawPicture(it.instance)
}
......
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