diff --git a/benchmarks/multiplatform/README.md b/benchmarks/multiplatform/README.md index f8c0e1a666..591fc0f371 100644 --- a/benchmarks/multiplatform/README.md +++ b/benchmarks/multiplatform/README.md @@ -1,11 +1,16 @@ # Compose Multiplatform benchmarks ## Run Desktop -- `./gradlew :run` +- `./gradlew :benchmarks:run` + +## Run native on iOS +Open the project in Fleet or Android Studio with KMM plugin installed and +choose `iosApp` run configuration. Make sure that you build the app in `Release` configuration. +Alternatively you may open `iosApp/iosApp` project in XCode and run the app from there. ## Run native on MacOS - - `./gradlew runReleaseExecutableMacosArm64` (Works on Arm64 processors) - - `./gradlew runReleaseExecutableMacosX64` (Works on Intel processors) + - `./gradlew :benchmarks:runReleaseExecutableMacosArm64` (Works on Arm64 processors) + - `./gradlew :benchmarks:runReleaseExecutableMacosX64` (Works on Intel processors) ## Run in web browser: @@ -13,4 +18,4 @@ Please run your browser with manual GC enabled before running the benchmark, lik `open -a Google\ Chrome --args --js-flags="--expose-gc"` -- `./gradlew wasmJsBrowserProductionRun` (you can see the results printed on the page itself) \ No newline at end of file +- `./gradlew :benchmarks:wasmJsBrowserProductionRun` (you can see the results printed on the page itself) \ No newline at end of file diff --git a/benchmarks/multiplatform/benchmarks/build.gradle.kts b/benchmarks/multiplatform/benchmarks/build.gradle.kts new file mode 100644 index 0000000000..64bbccfbb9 --- /dev/null +++ b/benchmarks/multiplatform/benchmarks/build.gradle.kts @@ -0,0 +1,98 @@ +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack + +plugins { + kotlin("multiplatform") + id("org.jetbrains.kotlin.plugin.compose") + id("org.jetbrains.compose") +} + +version = "1.0-SNAPSHOT" + +repositories { + mavenLocal() + google() + mavenCentral() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") +} + +kotlin { + jvm("desktop") + + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { iosTarget -> + iosTarget.binaries.framework { + baseName = "benchmarks" + isStatic = true + } + } + + listOf( + macosX64(), + macosArm64() + ).forEach { macosTarget -> + macosTarget.binaries { + executable { + entryPoint = "main" + } + } + } + + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + binaries.executable() + browser () + } + + sourceSets { + val commonMain by getting { + dependencies { + implementation(compose.ui) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.runtime) + @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) + implementation(compose.components.resources) + } + } + + val desktopMain by getting { + dependencies { + implementation(compose.desktop.currentOs) + runtimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.7.1") + } + } + } +} + +compose.desktop { + application { + mainClass = "Main_desktopKt" + } +} + +val runArguments: String? by project + +// Handle runArguments property +gradle.taskGraph.whenReady { + tasks.named("run") { + args(runArguments?.split(" ") ?: listOf()) + } + tasks.forEach { t -> + if ((t is Exec) && t.name.startsWith("runReleaseExecutableMacos")) { + t.args(runArguments?.split(" ") ?: listOf()) + } + } + tasks.named("wasmJsBrowserProductionRun") { + val args = runArguments?.split(" ") + ?.mapIndexed { index, arg -> "arg$index=$arg" } + ?.joinToString("&") ?: "" + + devServerProperty = devServerProperty.get().copy( + open = "http://localhost:8080?$args" + ) + } +} diff --git a/benchmarks/multiplatform/benchmarks/src/appleMain/kotlin/GraphicsContext.apple.kt b/benchmarks/multiplatform/benchmarks/src/appleMain/kotlin/GraphicsContext.apple.kt new file mode 100644 index 0000000000..97c3903bdc --- /dev/null +++ b/benchmarks/multiplatform/benchmarks/src/appleMain/kotlin/GraphicsContext.apple.kt @@ -0,0 +1,74 @@ +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.objcPtr +import org.jetbrains.skia.BackendRenderTarget +import org.jetbrains.skia.ColorSpace +import org.jetbrains.skia.DirectContext +import org.jetbrains.skia.PixelGeometry +import org.jetbrains.skia.Surface +import org.jetbrains.skia.SurfaceColorFormat +import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.SurfaceProps +import platform.Metal.MTLCreateSystemDefaultDevice +import platform.Metal.MTLPixelFormatBGRA8Unorm +import platform.Metal.MTLTextureDescriptor +import platform.Metal.MTLTextureType2D +import platform.Metal.MTLTextureUsageRenderTarget +import platform.Metal.MTLTextureUsageShaderRead +import platform.Metal.MTLTextureUsageShaderWrite +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +@OptIn(ExperimentalForeignApi::class) +fun graphicsContext() = object : GraphicsContext { + private val device = MTLCreateSystemDefaultDevice() ?: throw IllegalStateException("Can't create MTLDevice") + private val commandQueue = device.newCommandQueue() ?: throw IllegalStateException("Can't create MTLCommandQueue") + private val directContext = DirectContext.makeMetal(device.objcPtr(), commandQueue.objcPtr()) + private var cachedSurface: Surface? = null + + override fun surface(width: Int, height: Int): Surface { + val oldSurface = cachedSurface + + if (oldSurface != null && oldSurface.width == width && oldSurface.height == height) { + return oldSurface + } + + val descriptor = MTLTextureDescriptor() + descriptor.width = width.toULong() + descriptor.height = height.toULong() + descriptor.usage = MTLTextureUsageShaderRead or MTLTextureUsageShaderWrite or MTLTextureUsageRenderTarget + descriptor.textureType = MTLTextureType2D + descriptor.pixelFormat = MTLPixelFormatBGRA8Unorm + descriptor.mipmapLevelCount = 1UL + + val texture = device.newTextureWithDescriptor(descriptor) ?: throw IllegalStateException("Can't create MTLTexture") + + val renderTarget = BackendRenderTarget.makeMetal(width, height, texture.objcPtr()) + + return Surface.makeFromBackendRenderTarget( + directContext, + renderTarget, + SurfaceOrigin.TOP_LEFT, + SurfaceColorFormat.BGRA_8888, + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = PixelGeometry.UNKNOWN) + ).also { + cachedSurface = it + } ?: throw IllegalStateException("Can't create Surface") + } + + override suspend fun awaitGPUCompletion() { + val commandBuffer = commandQueue.commandBuffer() ?: return + + suspendCoroutine { continuation -> + commandBuffer.addCompletedHandler { + continuation.resume(Unit) + } + + commandBuffer.commit() + } + } +} + + + + diff --git a/benchmarks/multiplatform/src/macosMain/kotlin/runGC.native.kt b/benchmarks/multiplatform/benchmarks/src/appleMain/kotlin/runGC.native.kt similarity index 100% rename from benchmarks/multiplatform/src/macosMain/kotlin/runGC.native.kt rename to benchmarks/multiplatform/benchmarks/src/appleMain/kotlin/runGC.native.kt diff --git a/benchmarks/multiplatform/src/commonMain/composeResources/drawable/compose-multiplatform.xml b/benchmarks/multiplatform/benchmarks/src/commonMain/composeResources/drawable/compose-multiplatform.xml similarity index 100% rename from benchmarks/multiplatform/src/commonMain/composeResources/drawable/compose-multiplatform.xml rename to benchmarks/multiplatform/benchmarks/src/commonMain/composeResources/drawable/compose-multiplatform.xml diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/Args.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/Args.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/Args.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/Args.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/Benchmarks.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/Benchmarks.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/Benchmarks.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/Benchmarks.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/MeasureComposable.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/MeasureComposable.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/MeasureComposable.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/MeasureComposable.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt similarity index 90% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt index 29e13d2244..fa9d8d78ef 100644 --- a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt +++ b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt @@ -13,8 +13,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import compose_benchmarks.generated.resources.Res -import compose_benchmarks.generated.resources.compose_multiplatform +import compose_benchmarks.benchmarks.generated.resources.Res +import compose_benchmarks.benchmarks.generated.resources.compose_multiplatform import kotlinx.coroutines.delay import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt b/benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt similarity index 100% rename from benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt rename to benchmarks/multiplatform/benchmarks/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt diff --git a/benchmarks/multiplatform/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/multiplatform/benchmarks/src/desktopMain/kotlin/main.desktop.kt similarity index 100% rename from benchmarks/multiplatform/src/desktopMain/kotlin/main.desktop.kt rename to benchmarks/multiplatform/benchmarks/src/desktopMain/kotlin/main.desktop.kt diff --git a/benchmarks/multiplatform/src/desktopMain/kotlin/runGC.jvm.kt b/benchmarks/multiplatform/benchmarks/src/desktopMain/kotlin/runGC.jvm.kt similarity index 100% rename from benchmarks/multiplatform/src/desktopMain/kotlin/runGC.jvm.kt rename to benchmarks/multiplatform/benchmarks/src/desktopMain/kotlin/runGC.jvm.kt diff --git a/benchmarks/multiplatform/benchmarks/src/iosMain/kotlin/main.ios.kt b/benchmarks/multiplatform/benchmarks/src/iosMain/kotlin/main.ios.kt new file mode 100644 index 0000000000..c49b912015 --- /dev/null +++ b/benchmarks/multiplatform/benchmarks/src/iosMain/kotlin/main.ios.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +import kotlinx.coroutines.runBlocking + +fun main(args : List) { + Args.parseArgs(args.toTypedArray()) + runBlocking { runBenchmarks(graphicsContext = graphicsContext()) } +} diff --git a/benchmarks/multiplatform/benchmarks/src/macosMain/kotlin/main.macos.kt b/benchmarks/multiplatform/benchmarks/src/macosMain/kotlin/main.macos.kt new file mode 100644 index 0000000000..494a4c8eb6 --- /dev/null +++ b/benchmarks/multiplatform/benchmarks/src/macosMain/kotlin/main.macos.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ +import kotlinx.coroutines.runBlocking + +fun main(args : Array) { + Args.parseArgs(args) + runBlocking { runBenchmarks(graphicsContext = graphicsContext()) } +} diff --git a/benchmarks/multiplatform/src/wasmJsMain/kotlin/main.wasmJs.kt b/benchmarks/multiplatform/benchmarks/src/wasmJsMain/kotlin/main.wasmJs.kt similarity index 100% rename from benchmarks/multiplatform/src/wasmJsMain/kotlin/main.wasmJs.kt rename to benchmarks/multiplatform/benchmarks/src/wasmJsMain/kotlin/main.wasmJs.kt diff --git a/benchmarks/multiplatform/src/wasmJsMain/kotlin/runGC.wasmJs.kt b/benchmarks/multiplatform/benchmarks/src/wasmJsMain/kotlin/runGC.wasmJs.kt similarity index 100% rename from benchmarks/multiplatform/src/wasmJsMain/kotlin/runGC.wasmJs.kt rename to benchmarks/multiplatform/benchmarks/src/wasmJsMain/kotlin/runGC.wasmJs.kt diff --git a/benchmarks/multiplatform/src/wasmJsMain/resources/index.html b/benchmarks/multiplatform/benchmarks/src/wasmJsMain/resources/index.html similarity index 90% rename from benchmarks/multiplatform/src/wasmJsMain/resources/index.html rename to benchmarks/multiplatform/benchmarks/src/wasmJsMain/resources/index.html index 4168e1755c..fb8a8127cf 100644 --- a/benchmarks/multiplatform/src/wasmJsMain/resources/index.html +++ b/benchmarks/multiplatform/benchmarks/src/wasmJsMain/resources/index.html @@ -3,7 +3,7 @@ Benchmarks Compose + K/Wasm - +