From bd01722a247f9d9d9796c357518f9a3b163dbfb5 Mon Sep 17 00:00:00 2001 From: "Andrei.Salavei" Date: Wed, 21 Feb 2024 13:15:25 +0100 Subject: [PATCH 01/36] Import ui:uikit sample --- compose/runtime/runtime/build.gradle | 5 ++++ .../compose/runtime/UIKitAccessTest.kt | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle index 588bec28029fb..b1fc617e39369 100644 --- a/compose/runtime/runtime/build.gradle +++ b/compose/runtime/runtime/build.gradle @@ -126,6 +126,11 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { api("androidx.annotation:annotation:1.1.0") } } + uikitMain { + dependencies { + api project(":compose:ui:ui-uikit") + } + } commonTest.dependencies { implementation kotlin("test") diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt b/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt new file mode 100644 index 0000000000000..367c1be0722b2 --- /dev/null +++ b/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.compose.runtime + +import androidx.compose.ui.uikit.utils.CMPAccessibilityElement + +class UIKitAccessTest { + init { + println(">> Access ${CMPAccessibilityElement()}") + } +} \ No newline at end of file From 9e31136fc1b287683dfa08b6f51152bd43bbbbbc Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 12:55:50 +0100 Subject: [PATCH 02/36] Add logger stubs --- .../CMPUIKitUtils.xcodeproj/project.pbxproj | 12 ++++++ .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h | 22 +++++++++++ .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m | 38 +++++++++++++++++++ .../CMPUIKitUtils/CMPOSLoggerInterval.h | 19 ++++++++++ .../CMPUIKitUtils/CMPOSLoggerInterval.m | 30 +++++++++++++++ .../CMPUIKitUtils/CMPUIKitUtils.h | 1 + 6 files changed, 122 insertions(+) create mode 100644 compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h create mode 100644 compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m create mode 100644 compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h create mode 100644 compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj index 783bd076193a5..dac261482c638 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 997DFCFD2B18E5D3000B56B5 /* CMPUIKitUtilsTestApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DFCFC2B18E5D3000B56B5 /* CMPUIKitUtilsTestApp.swift */; }; EA70A7EB2B27106100300068 /* CMPAccessibilityElement.m in Sources */ = {isa = PBXBuildFile; fileRef = EA70A7E82B27106100300068 /* CMPAccessibilityElement.m */; }; EA70A7EC2B27106100300068 /* CMPAccessibilityContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = EA70A7E92B27106100300068 /* CMPAccessibilityContainer.m */; }; + EA82F4F92B86144E00465418 /* CMPOSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4F82B86144E00465418 /* CMPOSLogger.m */; }; + EA82F4FC2B86184F00465418 /* CMPOSLoggerInterval.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -64,6 +66,10 @@ EA70A7E82B27106100300068 /* CMPAccessibilityElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMPAccessibilityElement.m; sourceTree = ""; }; EA70A7E92B27106100300068 /* CMPAccessibilityContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMPAccessibilityContainer.m; sourceTree = ""; }; EA70A7EA2B27106100300068 /* CMPAccessibilityContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMPAccessibilityContainer.h; sourceTree = ""; }; + EA82F4F72B86144E00465418 /* CMPOSLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPOSLogger.h; sourceTree = ""; }; + EA82F4F82B86144E00465418 /* CMPOSLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPOSLogger.m; sourceTree = ""; }; + EA82F4FA2B86184F00465418 /* CMPOSLoggerInterval.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPOSLoggerInterval.h; sourceTree = ""; }; + EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPOSLoggerInterval.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -103,6 +109,10 @@ 996EFEF52B02CE8A0000FE0F /* CMPUIKitUtils.h */, 997DFCDC2B18D135000B56B5 /* CMPViewController.h */, 997DFCDD2B18D135000B56B5 /* CMPViewController.m */, + EA82F4F72B86144E00465418 /* CMPOSLogger.h */, + EA82F4F82B86144E00465418 /* CMPOSLogger.m */, + EA82F4FA2B86184F00465418 /* CMPOSLoggerInterval.h */, + EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */, ); path = CMPUIKitUtils; sourceTree = ""; @@ -276,7 +286,9 @@ files = ( 997DFCDE2B18D135000B56B5 /* CMPViewController.m in Sources */, EA70A7EC2B27106100300068 /* CMPAccessibilityContainer.m in Sources */, + EA82F4F92B86144E00465418 /* CMPOSLogger.m in Sources */, EA70A7EB2B27106100300068 /* CMPAccessibilityElement.m in Sources */, + EA82F4FC2B86184F00465418 /* CMPOSLoggerInterval.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h new file mode 100644 index 0000000000000..454e3c37b0ebe --- /dev/null +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h @@ -0,0 +1,22 @@ +// +// CMPOSLogger.h +// CMPUIKitUtils +// +// Created by Ilia.Semenov on 21/02/2024. +// + +#import + +#import "CMPOSLoggerInterval.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CMPOSLogger : NSObject + +- (instancetype)initWithCategoryName:(NSString *)name; +- (CMPOSLoggerInterval *)beginIntervalNamed:(NSString *)name; +- (void)endInterval:(CMPOSLoggerInterval *)interval; + +@end + +NS_ASSUME_NONNULL_END diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m new file mode 100644 index 0000000000000..954e7a5ef8e89 --- /dev/null +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m @@ -0,0 +1,38 @@ +// +// CMPOSLogger.m +// CMPUIKitUtils +// +// Created by Ilia.Semenov on 21/02/2024. +// + +#import "CMPOSLogger.h" + +@implementation CMPOSLogger { + os_log_t _log; + NSMutableArray *_intervalsPool; + NSLock *_poolLock; +} + +- (instancetype)initWithCategoryName:(NSString *)name { + self = [super init]; + + if (self) { + _log = os_log_create("androidx.compose", [name cStringUsingEncoding:NSUTF8StringEncoding]); + _intervalsPool = [NSMutableArray new]; + _poolLock = [NSLock new]; + } + + return self; +} + +- (CMPOSLoggerInterval *)beginIntervalNamed:(NSString *)name { + //return [CMPOSLoggerInterval new]; + return nil; +} + +- (void)endInterval:(CMPOSLoggerInterval *)interval { + +} + + +@end diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h new file mode 100644 index 0000000000000..012a534e1a8a3 --- /dev/null +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h @@ -0,0 +1,19 @@ +// +// CMPOSLoggerInterval.h +// CMPUIKitUtils +// +// Created by Ilia.Semenov on 21/02/2024. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CMPOSLoggerInterval : NSObject + +- (instancetype)initWithLog:(os_log_t)log; + +@end + +NS_ASSUME_NONNULL_END diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m new file mode 100644 index 0000000000000..75ccd5331e2bf --- /dev/null +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -0,0 +1,30 @@ +// +// CMPOSLoggerInterval.m +// CMPUIKitUtils +// +// Created by Ilia.Semenov on 21/02/2024. +// + +#import "CMPOSLoggerInterval.h" + +#import + +@implementation CMPOSLoggerInterval { + os_log_t _log; + os_signpost_id_t _signpost_id; + const char *_lastName; +} + +- (instancetype)initWithLog:(os_log_t)log { + self = [super init]; + + if (self) { + _log = log; + _signpost_id = os_signpost_id_generate(_log); + _lastName = NULL; + } + + return self; +} + +@end diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h index 47256df652818..cdced7fc0027a 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h @@ -25,3 +25,4 @@ FOUNDATION_EXPORT const unsigned char CMPUIKitUtilsVersionString[]; #import "CMPViewController.h" #import "CMPAccessibilityElement.h" #import "CMPAccessibilityContainer.h" +#import "CMPOSLogger.h" From 41dbd87b693463aed22eba2673b61645d18dd1ee Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 14:34:06 +0100 Subject: [PATCH 03/36] Add stubs for Trace. --- .../compose/runtime/Trace.linuxArm64.kt | 42 +++++++++++++++++++ .../compose/runtime/Trace.linuxX64.kt | 42 +++++++++++++++++++ .../androidx/compose/runtime/Trace.macos.kt | 42 +++++++++++++++++++ .../compose/runtime/Trace.mingwX64.kt | 42 +++++++++++++++++++ .../compose/runtime/ActualNative.native.kt | 9 ---- .../androidx/compose/runtime/Trace.tvOs.kt | 42 +++++++++++++++++++ .../androidx/compose/runtime/Trace.uikit.kt | 42 +++++++++++++++++++ .../androidx/compose/runtime/Trace.watchOs.kt | 42 +++++++++++++++++++ 8 files changed, 294 insertions(+), 9 deletions(-) create mode 100644 compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt create mode 100644 compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt create mode 100644 compose/runtime/runtime/src/macosMain/kotlin/androidx/compose/runtime/Trace.macos.kt create mode 100644 compose/runtime/runtime/src/mingwX64Main/kotlin/androidx/compose/runtime/Trace.mingwX64.kt create mode 100644 compose/runtime/runtime/src/tvOsMain/kotlin/androidx/compose/runtime/Trace.tvOs.kt create mode 100644 compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt create mode 100644 compose/runtime/runtime/src/watchOsMain/kotlin/androidx/compose/runtime/Trace.watchOs.kt diff --git a/compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt b/compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt b/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/macosMain/kotlin/androidx/compose/runtime/Trace.macos.kt b/compose/runtime/runtime/src/macosMain/kotlin/androidx/compose/runtime/Trace.macos.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/macosMain/kotlin/androidx/compose/runtime/Trace.macos.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/mingwX64Main/kotlin/androidx/compose/runtime/Trace.mingwX64.kt b/compose/runtime/runtime/src/mingwX64Main/kotlin/androidx/compose/runtime/Trace.mingwX64.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/mingwX64Main/kotlin/androidx/compose/runtime/Trace.mingwX64.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/nativeMain/kotlin/androidx/compose/runtime/ActualNative.native.kt b/compose/runtime/runtime/src/nativeMain/kotlin/androidx/compose/runtime/ActualNative.native.kt index f26989b0faa24..b79e7287941d3 100644 --- a/compose/runtime/runtime/src/nativeMain/kotlin/androidx/compose/runtime/ActualNative.native.kt +++ b/compose/runtime/runtime/src/nativeMain/kotlin/androidx/compose/runtime/ActualNative.native.kt @@ -58,15 +58,6 @@ private class MonotonicClockImpl : MonotonicFrameClock { } } -internal actual object Trace { - actual fun beginSection(name: String): Any? { - return null - } - - actual fun endSection(token: Any?) { - } -} - actual annotation class CheckResult actual constructor(actual val suggest: String) @ExperimentalComposeApi diff --git a/compose/runtime/runtime/src/tvOsMain/kotlin/androidx/compose/runtime/Trace.tvOs.kt b/compose/runtime/runtime/src/tvOsMain/kotlin/androidx/compose/runtime/Trace.tvOs.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/tvOsMain/kotlin/androidx/compose/runtime/Trace.tvOs.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file diff --git a/compose/runtime/runtime/src/watchOsMain/kotlin/androidx/compose/runtime/Trace.watchOs.kt b/compose/runtime/runtime/src/watchOsMain/kotlin/androidx/compose/runtime/Trace.watchOs.kt new file mode 100644 index 0000000000000..b3815dc46efb7 --- /dev/null +++ b/compose/runtime/runtime/src/watchOsMain/kotlin/androidx/compose/runtime/Trace.watchOs.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.runtime + +internal actual object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + actual fun beginSection(name: String): Any? { + return null + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param token The instance returned from the corresponding call to [beginSection]. + */ + actual fun endSection(token: Any?) { + } +} \ No newline at end of file From a158f20d1a8313611265aa4b6b4345e4e44b6c97 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 15:57:42 +0100 Subject: [PATCH 04/36] Integrate CMPOSLogger with runtime. --- .../androidx/compose/runtime/Trace.uikit.kt | 18 ++++++++++++- .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m | 27 +++++++++++++++++-- .../CMPUIKitUtils/CMPOSLoggerInterval.h | 2 ++ .../CMPUIKitUtils/CMPOSLoggerInterval.m | 18 ++++++++++--- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index b3815dc46efb7..1360822e67ec2 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -16,6 +16,19 @@ package androidx.compose.runtime +import androidx.compose.ui.uikit.utils.CMPOSLogger +import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval + + +@ExperimentalComposeRuntimeApi +fun enableTraceOSLog() { + if (traceImpl == null) { + traceImpl = CMPOSLogger() + } +} + +var traceImpl: CMPOSLogger? = null + internal actual object Trace { /** * Writes a trace message to indicate that a given section of code has begun. @@ -25,7 +38,7 @@ internal actual object Trace { * to [endSection]. May be null. */ actual fun beginSection(name: String): Any? { - return null + return traceImpl?.beginIntervalNamed(name) } /** @@ -38,5 +51,8 @@ internal actual object Trace { * @param token The instance returned from the corresponding call to [beginSection]. */ actual fun endSection(token: Any?) { + token?.let { + traceImpl?.endInterval(it as CMPOSLoggerInterval) + } } } \ No newline at end of file diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m index 954e7a5ef8e89..3195a25e91583 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m @@ -26,12 +26,35 @@ - (instancetype)initWithCategoryName:(NSString *)name { } - (CMPOSLoggerInterval *)beginIntervalNamed:(NSString *)name { - //return [CMPOSLoggerInterval new]; - return nil; + CMPOSLoggerInterval *interval; + + [_poolLock lock]; + + if (_intervalsPool.count > 0) { + interval = _intervalsPool.lastObject; + [_intervalsPool removeLastObject]; + } else { + interval = nil; + } + + [_poolLock unlock]; + + if (interval) { + return interval; + } else { + interval = [[CMPOSLoggerInterval alloc] initWithLog:_log]; + [interval beginWithName:name]; + return interval; + } } - (void)endInterval:(CMPOSLoggerInterval *)interval { + [interval end]; + [_poolLock lock]; + + [_intervalsPool addObject:interval]; + [_poolLock unlock]; } diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h index 012a534e1a8a3..faa619a7f7341 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h @@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN @interface CMPOSLoggerInterval : NSObject - (instancetype)initWithLog:(os_log_t)log; +- (void)beginWithName:(NSString *)name; +- (void)end; @end diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m index 75ccd5331e2bf..0ddfb9c47ce89 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -11,8 +11,8 @@ @implementation CMPOSLoggerInterval { os_log_t _log; - os_signpost_id_t _signpost_id; - const char *_lastName; + os_signpost_id_t _signpostId; + NSString *_name; } - (instancetype)initWithLog:(os_log_t)log { @@ -20,11 +20,21 @@ - (instancetype)initWithLog:(os_log_t)log { if (self) { _log = log; - _signpost_id = os_signpost_id_generate(_log); - _lastName = NULL; + _signpostId = os_signpost_id_generate(_log); + _name = nil; } return self; } +- (void)beginWithName:(NSString *)name { + _name = name; + + os_signpost_interval_begin(_log, _signpostId, "interval", "name: %{public}s", [name UTF8String]); +} + +- (void)end { + os_signpost_interval_end(_log, _signpostId, "interval", "name: %{public}s", [_name UTF8String]); +} + @end From 8f33b47837ae8f53bf3143e9ead6c2ad151bde00 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 15:58:40 +0100 Subject: [PATCH 05/36] Add category name to logger --- .../uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index 1360822e67ec2..33471c55b19c5 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval @ExperimentalComposeRuntimeApi fun enableTraceOSLog() { if (traceImpl == null) { - traceImpl = CMPOSLogger() + traceImpl = CMPOSLogger(categoryName = "androidx.compose.runtime") } } From 0e3165aed3142bcc2ecb67490378818d96067622 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 16:11:26 +0100 Subject: [PATCH 06/36] Add to Trace to ui. --- .../kotlin/androidx/compose/ui/Trace.uikit.kt | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt new file mode 100644 index 0000000000000..ec22ba54c26be --- /dev/null +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui + +import androidx.compose.runtime.ExperimentalComposeRuntimeApi +import androidx.compose.ui.uikit.utils.CMPOSLogger +import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval + +@ExperimentalComposeRuntimeApi +fun enableTraceOSLog() { + if (traceImpl == null) { + traceImpl = CMPOSLogger(categoryName = "androidx.compose.ui") + } +} + +var traceImpl: CMPOSLogger? = null + +// Verbatim of androidx.compose.runtime.Trace +internal object Trace { + /** + * Writes a trace message to indicate that a given section of code has begun. + * This call must be followed by a corresponding call to [endSection] on the same thread. + * + * @return An arbitrary token which will be supplied to the corresponding call + * to [endSection]. May be null. + */ + fun beginSection(name: String): CMPOSLoggerInterval? { + return traceImpl?.beginIntervalNamed(name) + } + + /** + * Writes a trace message to indicate that a given section of code has ended. + * This call must be preceded by a corresponding call to [beginSection]. + * Calling this method will mark the end of the most recently begun section of code, so care + * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and + * called from the same thread. + * + * @param interval The instance returned from the corresponding call to [beginSection]. + */ + fun endSection(interval: CMPOSLoggerInterval) { + traceImpl?.endInterval(interval) + } +} + +/** + * Wrap the specified [block] in calls to [Trace.beginSection] (with the supplied [sectionName]) + * and [Trace.endSection]. + */ +internal inline fun trace(sectionName: String, block: () -> T): T { + val token = Trace.beginSection(sectionName) + try { + return block() + } finally { + token?.let { + Trace.endSection(it) + } + } +} \ No newline at end of file From 0a6a45ee72cdc726ed6fb43ffcdbc89763b56d0f Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 16:11:52 +0100 Subject: [PATCH 07/36] Make trace impl private --- .../uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt | 2 +- .../ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index 33471c55b19c5..8c5361f484717 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -27,7 +27,7 @@ fun enableTraceOSLog() { } } -var traceImpl: CMPOSLogger? = null +private var traceImpl: CMPOSLogger? = null internal actual object Trace { /** diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt index ec22ba54c26be..5dcf5844993ce 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt @@ -27,7 +27,7 @@ fun enableTraceOSLog() { } } -var traceImpl: CMPOSLogger? = null +private var traceImpl: CMPOSLogger? = null // Verbatim of androidx.compose.runtime.Trace internal object Trace { From a2b87696c03ad9a6b0075344f2544c6b28bdc33a Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 16:16:39 +0100 Subject: [PATCH 08/36] Change annotation --- .../uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt | 5 ++++- .../uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt | 2 +- .../src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt index a228e726cabad..f4369746205d1 100644 --- a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt +++ b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt @@ -16,8 +16,11 @@ import bugs.StartRecompositionCheck import platform.UIKit.UIViewController -@OptIn(ExperimentalComposeApi::class) +@OptIn(ExperimentalComposeApi::class, ExperimentalComposeRuntimeApi::class) fun main(vararg args: String) { + androidx.compose.runtime.enableTraceOSLog() + androidx.compose.ui.enableTraceOSLog() + val arg = args.firstOrNull() ?: "" defaultUIKitMain("ComposeDemo", ComposeUIViewController(configure = { accessibilitySyncOptions = AccessibilitySyncOptions.WhenRequiredByAccessibilityServices(object: AccessibilityDebugLogger { diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index 8c5361f484717..486058ae88bc1 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.uikit.utils.CMPOSLogger import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval -@ExperimentalComposeRuntimeApi +@ExperimentalComposeApi fun enableTraceOSLog() { if (traceImpl == null) { traceImpl = CMPOSLogger(categoryName = "androidx.compose.runtime") diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt index 5dcf5844993ce..93c5cf91b4654 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt @@ -16,11 +16,11 @@ package androidx.compose.ui -import androidx.compose.runtime.ExperimentalComposeRuntimeApi +import androidx.compose.runtime.ExperimentalComposeApi import androidx.compose.ui.uikit.utils.CMPOSLogger import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval -@ExperimentalComposeRuntimeApi +@ExperimentalComposeApi fun enableTraceOSLog() { if (traceImpl == null) { traceImpl = CMPOSLogger(categoryName = "androidx.compose.ui") From e72cb33b6daad16bdfbb1e1d89d2b7491e663347 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 16:25:37 +0100 Subject: [PATCH 09/36] Add traces --- .../ui/scene/BaseComposeScene.skiko.kt | 47 ++++++++++--------- .../ui/scene/SingleLayerComposeScene.skiko.kt | 3 +- .../compose/ui/window/MetalRedrawer.uikit.kt | 29 +++++++----- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 167a1f5d16e72..5a91e516f07a2 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -38,6 +38,7 @@ import androidx.compose.ui.input.pointer.PointerType import androidx.compose.ui.node.SnapshotInvalidationTracker import androidx.compose.ui.platform.GlobalSnapshotManager import androidx.compose.ui.platform.PlatformContext +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlin.concurrent.Volatile @@ -145,27 +146,31 @@ internal abstract class BaseComposeScene( recomposer.performScheduledTasks() } - override fun render(canvas: Canvas, nanoTime: Long) = postponeInvalidation { - // Note that on Android the order is slightly different: - // - Recomposition - // - Layout - // - Draw - // - Composition effects - // - Synthetic events - // We do this differently in order to be able to observe changes made by synthetic events - // in the drawing phase, thus reducing the time before they are visible on screen. - // - // It is important, however, to run the composition effects before the synthetic events are - // dispatched, in order to allow registering for these events before they are sent. - // Otherwise, events like a synthetic mouse-enter sent due to a new element appearing under - // the pointer would be missed by e.g. InteractionSource.collectHoverAsState - recomposer.performScheduledTasks() - frameClock.sendFrame(nanoTime) // Recomposition - doLayout() // Layout - recomposer.performScheduledEffects() // Composition effects (e.g. LaunchedEffect) - inputHandler.updatePointerPosition() // Synthetic move event - snapshotInvalidationTracker.onDraw() - draw(canvas) // Draw + override fun render(canvas: Canvas, nanoTime: Long) { + return trace("BaseComposeScene:render") { + postponeInvalidation { + // Note that on Android the order is slightly different: + // - Recomposition + // - Layout + // - Draw + // - Composition effects + // - Synthetic events + // We do this differently in order to be able to observe changes made by synthetic events + // in the drawing phase, thus reducing the time before they are visible on screen. + // + // It is important, however, to run the composition effects before the synthetic events are + // dispatched, in order to allow registering for these events before they are sent. + // Otherwise, events like a synthetic mouse-enter sent due to a new element appearing under + // the pointer would be missed by e.g. InteractionSource.collectHoverAsState + recomposer.performScheduledTasks() + frameClock.sendFrame(nanoTime) // Recomposition + doLayout() // Layout + recomposer.performScheduledEffects() // Composition effects (e.g. LaunchedEffect) + inputHandler.updatePointerPosition() // Synthetic move event + snapshotInvalidationTracker.onDraw() + draw(canvas) // Draw + } + } } override fun sendPointerEvent( diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt index 6731a6ef27bdd..ce3b6eed01c9c 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.Dispatchers @@ -171,7 +172,7 @@ private class SingleLayerComposeSceneImpl( mainOwner.measureAndLayout() } - override fun draw(canvas: Canvas) { + override fun draw(canvas: Canvas) = trace("ComposeScene:draw") { mainOwner.draw(canvas) } diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index 2f20666f68d68..4f721d0e423ce 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.interop.UIKitInteropTransaction import androidx.compose.ui.interop.doLocked import androidx.compose.ui.interop.isNotEmpty import androidx.compose.ui.util.fastForEach +import androidx.compose.ui.util.trace import kotlin.math.roundToInt import kotlinx.cinterop.* import org.jetbrains.skia.* @@ -329,7 +330,7 @@ internal class MetalRedrawer( draw(waitUntilCompletion = true, CACurrentMediaTime()) } - private fun draw(waitUntilCompletion: Boolean, targetTimestamp: NSTimeInterval) { + private fun draw(waitUntilCompletion: Boolean, targetTimestamp: NSTimeInterval) = trace("MetalRedrawer:draw") { check(NSThread.isMainThread) lastRenderTimestamp = maxOf(targetTimestamp, lastRenderTimestamp) @@ -344,19 +345,21 @@ internal class MetalRedrawer( } // Perform timestep and record all draw commands into [Picture] - pictureRecorder.beginRecording( - Rect( - left = 0f, - top = 0f, - width.toFloat(), - height.toFloat() - ) - ).also { canvas -> - canvas.clear(if (metalLayer.opaque) Color.WHITE else Color.TRANSPARENT) - callbacks.render(canvas, lastRenderTimestamp) - } + val picture = trace("MetalRedrawer:draw:pictureRecording") { + pictureRecorder.beginRecording( + Rect( + left = 0f, + top = 0f, + width.toFloat(), + height.toFloat() + ) + ).also { canvas -> + canvas.clear(if (metalLayer.opaque) Color.WHITE else Color.TRANSPARENT) + callbacks.render(canvas, lastRenderTimestamp) + } - val picture = pictureRecorder.finishRecordingAsPicture() + pictureRecorder.finishRecordingAsPicture() + } dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER) From 8171bb0ec7640ae8032081270b4251ac4e8618df Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 21 Feb 2024 16:31:29 +0100 Subject: [PATCH 10/36] Add traces --- .../scene/ComposeSceneInputHandler.skiko.kt | 3 +- .../ui/scene/ComposeSceneRecomposer.skiko.kt | 5 +- .../ui/scene/SingleLayerComposeScene.skiko.kt | 2 +- .../compose/ui/window/MetalRedrawer.uikit.kt | 67 ++++++++++--------- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt index 6b370f73d3c9e..5e9e962308f52 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.input.pointer.SyntheticEventSender import androidx.compose.ui.input.pointer.areAnyPressed import androidx.compose.ui.input.pointer.copyFor import androidx.compose.ui.node.RootNodeOwner +import androidx.compose.ui.util.trace import org.jetbrains.skiko.currentNanoTime /** @@ -124,7 +125,7 @@ internal class ComposeSceneInputHandler( return processKeyEvent(keyEvent) } - fun updatePointerPosition() { + fun updatePointerPosition() = trace("ComposeSceneInputHandler:updatePointerPosition") { syntheticEventSender.updatePointerPosition() } diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt index 5b6b990655b8e..5aa082f683c5d 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composition import androidx.compose.runtime.CompositionContext import androidx.compose.runtime.Recomposer import androidx.compose.ui.platform.FlushCoroutineDispatcher +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart @@ -77,14 +78,14 @@ internal class ComposeSceneRecomposer( * Perform all scheduled tasks and wait for the tasks which are already * performing in the recomposition scope. */ - fun performScheduledTasks() { + fun performScheduledTasks() = trace("ComposeSceneRecomposer:performScheduledTasks") { recomposeDispatcher.flush() } /** * Perform all scheduled effects. */ - fun performScheduledEffects() { + fun performScheduledEffects() = trace("ComposeSceneRecomposer:performScheduledEffects") { effectDispatcher.flush() } diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt index ce3b6eed01c9c..603d21c6899b2 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt @@ -172,7 +172,7 @@ private class SingleLayerComposeSceneImpl( mainOwner.measureAndLayout() } - override fun draw(canvas: Canvas) = trace("ComposeScene:draw") { + override fun draw(canvas: Canvas) = trace("SingleLayerComposeSceneImpl:draw") { mainOwner.draw(canvas) } diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index 4f721d0e423ce..fc6ec4b9fda32 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -409,46 +409,53 @@ internal class MetalRedrawer( val mustEncodeAndPresentOnMainThread = true val encodeAndPresentBlock = { - surface.canvas.drawPicture(picture) - picture.close() - surface.flushAndSubmit() + trace("MetalRedrawer:draw:encodeAndPresent") { + surface.canvas.drawPicture(picture) + picture.close() + surface.flushAndSubmit() - val commandBuffer = queue.commandBuffer()!! - commandBuffer.label = "Present" + val commandBuffer = queue.commandBuffer()!! + commandBuffer.label = "Present" - if (!presentsWithTransaction) { - commandBuffer.presentDrawable(metalDrawable) - } + if (!presentsWithTransaction) { + commandBuffer.presentDrawable(metalDrawable) + } - commandBuffer.addCompletedHandler { - // Signal work finish, allow a new command buffer to be scheduled - dispatch_semaphore_signal(inflightSemaphore) - } - commandBuffer.commit() + commandBuffer.addCompletedHandler { + // Signal work finish, allow a new command buffer to be scheduled + dispatch_semaphore_signal(inflightSemaphore) + } + commandBuffer.commit() - if (presentsWithTransaction) { - // If there are pending changes in UIKit interop, [waitUntilScheduled](https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443036-waituntilscheduled) is called - // to ensure that transaction is available - commandBuffer.waitUntilScheduled() - metalDrawable.present() + if (presentsWithTransaction) { + // If there are pending changes in UIKit interop, [waitUntilScheduled](https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443036-waituntilscheduled) is called + // to ensure that transaction is available + trace("MetalRedrawer:draw:waitTransaction") { + commandBuffer.waitUntilScheduled() + } - interopTransaction.actions.fastForEach { - it.invoke() - } + metalDrawable.present() + + interopTransaction.actions.fastForEach { + it.invoke() + } - if (interopTransaction.state == UIKitInteropState.ENDED) { - isInteropActive = false + if (interopTransaction.state == UIKitInteropState.ENDED) { + isInteropActive = false + } } - } - surface.close() - renderTarget.close() + surface.close() + renderTarget.close() - // Track current inflight command buffers to synchronously wait for their schedule in case app goes background - inflightCommandBuffers.add(commandBuffer) + // Track current inflight command buffers to synchronously wait for their schedule in case app goes background + inflightCommandBuffers.add(commandBuffer) - if (waitUntilCompletion) { - commandBuffer.waitUntilCompleted() + if (waitUntilCompletion) { + trace("MetalRedrawer:draw:waitUntilCompleted") { + commandBuffer.waitUntilCompleted() + } + } } } From d30099dc797ea6c828c8772765af3f12cde6df22 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 09:04:04 +0100 Subject: [PATCH 11/36] Modify trace format --- .../kotlin/androidx/compose/mpp/demo/main.uikit.kt | 7 +++++-- .../objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt index f4369746205d1..bc14ca33436fe 100644 --- a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt +++ b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt @@ -4,7 +4,10 @@ package androidx.compose.mpp.demo import NativeModalWithNaviationExample import SwiftUIInteropExample import UIKitViewOrder -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ExperimentalComposeApi +import androidx.compose.runtime.ExperimentalComposeRuntimeApi +import androidx.compose.runtime.remember import androidx.compose.ui.main.defaultUIKitMain import androidx.compose.ui.platform.AccessibilityDebugLogger import androidx.compose.ui.platform.AccessibilitySyncOptions @@ -16,7 +19,7 @@ import bugs.StartRecompositionCheck import platform.UIKit.UIViewController -@OptIn(ExperimentalComposeApi::class, ExperimentalComposeRuntimeApi::class) +@OptIn(ExperimentalComposeApi::class) fun main(vararg args: String) { androidx.compose.runtime.enableTraceOSLog() androidx.compose.ui.enableTraceOSLog() diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m index 0ddfb9c47ce89..bc36d114d3710 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -30,11 +30,11 @@ - (instancetype)initWithLog:(os_log_t)log { - (void)beginWithName:(NSString *)name { _name = name; - os_signpost_interval_begin(_log, _signpostId, "interval", "name: %{public}s", [name UTF8String]); + os_signpost_interval_begin(_log, _signpostId, "interval", "%{public}s", [name UTF8String]); } - (void)end { - os_signpost_interval_end(_log, _signpostId, "interval", "name: %{public}s", [_name UTF8String]); + os_signpost_interval_end(_log, _signpostId, "interval"); } @end From 0571e978b6b8e76edeecb351140a2a0099897946 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 09:33:00 +0100 Subject: [PATCH 12/36] Fix bug --- .../CMPUIKitUtils.xcodeproj/project.pbxproj | 17 +++++++++++++++++ .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m | 1 + .../CMPUIKitUtils/CMPOSLoggerInterval.m | 4 ++-- .../CMPUIKitUtilsTestApp-Bridging-Header.h | 5 +++++ .../CMPUIKitUtilsTestApp.swift | 18 +++++++++++++++++- 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj index dac261482c638..c62e7b339f20b 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj @@ -18,6 +18,11 @@ EA70A7EC2B27106100300068 /* CMPAccessibilityContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = EA70A7E92B27106100300068 /* CMPAccessibilityContainer.m */; }; EA82F4F92B86144E00465418 /* CMPOSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4F82B86144E00465418 /* CMPOSLogger.m */; }; EA82F4FC2B86184F00465418 /* CMPOSLoggerInterval.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */; }; + EAC703E32B8C826E001ECDA6 /* CMPAccessibilityElement.m in Sources */ = {isa = PBXBuildFile; fileRef = EA70A7E82B27106100300068 /* CMPAccessibilityElement.m */; }; + EAC703E42B8C826E001ECDA6 /* CMPViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 997DFCDD2B18D135000B56B5 /* CMPViewController.m */; }; + EAC703E52B8C826E001ECDA6 /* CMPOSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4F82B86144E00465418 /* CMPOSLogger.m */; }; + EAC703E62B8C826E001ECDA6 /* CMPOSLoggerInterval.m in Sources */ = {isa = PBXBuildFile; fileRef = EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */; }; + EAC703E72B8C826E001ECDA6 /* CMPAccessibilityContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = EA70A7E92B27106100300068 /* CMPAccessibilityContainer.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -70,6 +75,7 @@ EA82F4F82B86144E00465418 /* CMPOSLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPOSLogger.m; sourceTree = ""; }; EA82F4FA2B86184F00465418 /* CMPOSLoggerInterval.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPOSLoggerInterval.h; sourceTree = ""; }; EA82F4FB2B86184F00465418 /* CMPOSLoggerInterval.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPOSLoggerInterval.m; sourceTree = ""; }; + EAC703DF2B8C8154001ECDA6 /* CMPUIKitUtilsTestApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CMPUIKitUtilsTestApp-Bridging-Header.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -160,6 +166,7 @@ isa = PBXGroup; children = ( 997DFCFC2B18E5D3000B56B5 /* CMPUIKitUtilsTestApp.swift */, + EAC703DF2B8C8154001ECDA6 /* CMPUIKitUtilsTestApp-Bridging-Header.h */, ); path = CMPUIKitUtilsTestApp; sourceTree = ""; @@ -239,6 +246,7 @@ }; 997DFCF92B18E5D3000B56B5 = { CreatedOnToolsVersion = 15.0; + LastSwiftMigration = 1500; }; }; }; @@ -307,7 +315,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAC703E32B8C826E001ECDA6 /* CMPAccessibilityElement.m in Sources */, + EAC703E42B8C826E001ECDA6 /* CMPViewController.m in Sources */, + EAC703E52B8C826E001ECDA6 /* CMPOSLogger.m in Sources */, + EAC703E72B8C826E001ECDA6 /* CMPAccessibilityContainer.m in Sources */, 997DFCFD2B18E5D3000B56B5 /* CMPUIKitUtilsTestApp.swift in Sources */, + EAC703E62B8C826E001ECDA6 /* CMPOSLoggerInterval.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -530,6 +543,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 45226JTYHN; @@ -550,6 +564,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -561,6 +576,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 45226JTYHN; @@ -581,6 +597,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m index 3195a25e91583..4fad4cb37c708 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m @@ -40,6 +40,7 @@ - (CMPOSLoggerInterval *)beginIntervalNamed:(NSString *)name { [_poolLock unlock]; if (interval) { + [interval beginWithName:name]; return interval; } else { interval = [[CMPOSLoggerInterval alloc] initWithLog:_log]; diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m index bc36d114d3710..4356a42d01a85 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -30,11 +30,11 @@ - (instancetype)initWithLog:(os_log_t)log { - (void)beginWithName:(NSString *)name { _name = name; - os_signpost_interval_begin(_log, _signpostId, "interval", "%{public}s", [name UTF8String]); + os_signpost_interval_begin(_log, _signpostId, "CMPInterval", "%{public}s", [name UTF8String]); } - (void)end { - os_signpost_interval_end(_log, _signpostId, "interval"); + os_signpost_interval_end(_log, _signpostId, "CMPInterval"); } @end diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h new file mode 100644 index 0000000000000..517fddfec8540 --- /dev/null +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "CMPUIKitUtils.h" diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift index de46d4e975e55..aeb4d2627ef6c 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift @@ -8,10 +8,26 @@ import SwiftUI @main -struct CMPUIKitUtilsTestApp: App { +struct CMPUIKitUtilsTestApp: App { + let uiLogger = CMPOSLogger(categoryName: "androidx.compose.ui") + let runtimeLogger = CMPOSLogger(categoryName: "androidx.compose.runtime") var body: some Scene { WindowGroup { Color.black + .onAppear { + Task { + if #available(iOS 16.0, *) { + for i in 0..<100 { + let uiInterval = uiLogger.beginIntervalNamed("\(i)") + let runtimeInterval = runtimeLogger.beginIntervalNamed("\(i)") + try await Task.sleep(for: Duration.milliseconds(4)) + uiLogger.end(uiInterval) + runtimeLogger.end(runtimeInterval) + try await Task.sleep(for: Duration.milliseconds(4)) + } + } + } + } } } } From efdc56f61d11c8e3aa8ab3ab49e1dd7de9f03b5f Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 09:41:18 +0100 Subject: [PATCH 13/36] Add todo --- .../ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt index 93c5cf91b4654..cbc4feabc755b 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt @@ -20,6 +20,9 @@ import androidx.compose.runtime.ExperimentalComposeApi import androidx.compose.ui.uikit.utils.CMPOSLogger import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval +// TODO: implement within source set hierarchy of ui-utils: +// compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt + @ExperimentalComposeApi fun enableTraceOSLog() { if (traceImpl == null) { From 42cf27046c2d93bcc6bd19ab869a0c875015bb25 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 09:56:45 +0100 Subject: [PATCH 14/36] Add trace to skikoMain --- .../compose/ui/Trace.skikoMain.desktop.kt | 21 +++++++++++++++++++ .../compose/ui/Trace.skikoMain.jsWasm.kt | 21 +++++++++++++++++++ .../compose/ui/Trace.skikoMain.macos.kt | 21 +++++++++++++++++++ .../androidx/compose/ui/Trace.skikoMain.kt | 21 +++++++++++++++++++ .../ui/scene/BaseComposeScene.skiko.kt | 2 +- .../scene/ComposeSceneInputHandler.skiko.kt | 2 +- .../ui/scene/ComposeSceneRecomposer.skiko.kt | 2 +- .../ui/scene/SingleLayerComposeScene.skiko.kt | 2 +- .../kotlin/androidx/compose/ui/Trace.uikit.kt | 5 +---- .../compose/ui/window/MetalRedrawer.uikit.kt | 2 +- 10 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt create mode 100644 compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt create mode 100644 compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt create mode 100644 compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt new file mode 100644 index 0000000000000..c37db837d1827 --- /dev/null +++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui + +internal actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt b/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt new file mode 100644 index 0000000000000..c37db837d1827 --- /dev/null +++ b/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui + +internal actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt b/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt new file mode 100644 index 0000000000000..c37db837d1827 --- /dev/null +++ b/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui + +internal actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt new file mode 100644 index 0000000000000..6276527f09420 --- /dev/null +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui + +// TODO: move to `ui-util` once it's sliced into source sets + +internal expect inline fun trace(sectionName: String, block: () -> T): T \ No newline at end of file diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 5a91e516f07a2..f19fa1b815755 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -38,7 +38,7 @@ import androidx.compose.ui.input.pointer.PointerType import androidx.compose.ui.node.SnapshotInvalidationTracker import androidx.compose.ui.platform.GlobalSnapshotManager import androidx.compose.ui.platform.PlatformContext -import androidx.compose.ui.util.trace +import androidx.compose.ui.trace import kotlin.coroutines.CoroutineContext import kotlin.concurrent.Volatile diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt index 5e9e962308f52..655bc01885544 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.input.pointer.SyntheticEventSender import androidx.compose.ui.input.pointer.areAnyPressed import androidx.compose.ui.input.pointer.copyFor import androidx.compose.ui.node.RootNodeOwner -import androidx.compose.ui.util.trace +import androidx.compose.ui.trace import org.jetbrains.skiko.currentNanoTime /** diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt index 5aa082f683c5d..421d291d1a892 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composition import androidx.compose.runtime.CompositionContext import androidx.compose.runtime.Recomposer import androidx.compose.ui.platform.FlushCoroutineDispatcher -import androidx.compose.ui.util.trace +import androidx.compose.ui.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt index 603d21c6899b2..1ab3d7dd3d09c 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.util.trace +import androidx.compose.ui.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.Dispatchers diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt index cbc4feabc755b..04c0cb68e34c5 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt @@ -20,9 +20,6 @@ import androidx.compose.runtime.ExperimentalComposeApi import androidx.compose.ui.uikit.utils.CMPOSLogger import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval -// TODO: implement within source set hierarchy of ui-utils: -// compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt - @ExperimentalComposeApi fun enableTraceOSLog() { if (traceImpl == null) { @@ -63,7 +60,7 @@ internal object Trace { * Wrap the specified [block] in calls to [Trace.beginSection] (with the supplied [sectionName]) * and [Trace.endSection]. */ -internal inline fun trace(sectionName: String, block: () -> T): T { +internal actual inline fun trace(sectionName: String, block: () -> T): T { val token = Trace.beginSection(sectionName) try { return block() diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index fc6ec4b9fda32..ce0990fb5f1ad 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.interop.UIKitInteropTransaction import androidx.compose.ui.interop.doLocked import androidx.compose.ui.interop.isNotEmpty import androidx.compose.ui.util.fastForEach -import androidx.compose.ui.util.trace +import androidx.compose.ui.trace import kotlin.math.roundToInt import kotlinx.cinterop.* import org.jetbrains.skia.* From 0fc7c345f91a001aceec63f259ab0d02c9d832eb Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:27:18 +0100 Subject: [PATCH 15/36] Move to ui-utils existing func --- .../compose/ui/util/Trace.desktop.kt} | 8 +-- .../androidx/compose/ui/util/Trace.jb.kt | 6 +- .../androidx/compose/ui/util/Trace.js.kt | 21 ++++++ .../androidx/compose/ui/util/Trace.macos.kt | 21 ++++++ .../androidx/compose/ui/util/Trace.uikit.kt | 37 ++++++++++ .../androidx/compose/ui/util/Trace.wasmJs.kt | 21 ++++++ .../kotlin/androidx/compose/ui/Trace.uikit.kt | 72 ------------------- 7 files changed, 107 insertions(+), 79 deletions(-) rename compose/ui/{ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt => ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt} (78%) create mode 100644 compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt create mode 100644 compose/ui/ui-util/src/macosMain/kotlin/androidx/compose/ui/util/Trace.macos.kt create mode 100644 compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt create mode 100644 compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt delete mode 100644 compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt b/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt similarity index 78% rename from compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt rename to compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt index 6276527f09420..0c399c4d18533 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/Trace.skikoMain.kt +++ b/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt @@ -14,8 +14,8 @@ * limitations under the License. */ -package androidx.compose.ui +package androidx.compose.ui.util -// TODO: move to `ui-util` once it's sliced into source sets - -internal expect inline fun trace(sectionName: String, block: () -> T): T \ No newline at end of file +actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt b/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt index 640590fb8b0a4..b2cb529c7b617 100644 --- a/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt +++ b/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt @@ -16,6 +16,6 @@ package androidx.compose.ui.util -actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} +//actual inline fun trace(sectionName: String, block: () -> T): T { +// return block() +//} diff --git a/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt b/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt new file mode 100644 index 0000000000000..0c399c4d18533 --- /dev/null +++ b/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui.util + +actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui-util/src/macosMain/kotlin/androidx/compose/ui/util/Trace.macos.kt b/compose/ui/ui-util/src/macosMain/kotlin/androidx/compose/ui/util/Trace.macos.kt new file mode 100644 index 0000000000000..0c399c4d18533 --- /dev/null +++ b/compose/ui/ui-util/src/macosMain/kotlin/androidx/compose/ui/util/Trace.macos.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui.util + +actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt b/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt new file mode 100644 index 0000000000000..b793dc6447dd5 --- /dev/null +++ b/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui.util + +@ExperimentalComposeApi +fun enableTraceOSLog() { + if (traceImpl == null) { + traceImpl = CMPOSLogger(categoryName = "androidx.compose.ui") + } +} + +private var traceImpl: CMPOSLogger? = null + +actual inline fun trace(sectionName: String, block: () -> T): T { + val interval = traceImpl?.beginIntervalNamed(sectionName) + try { + return block() + } finally { + interval?.let { + traceImpl?.endInterval(it) + } + } +} \ No newline at end of file diff --git a/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt b/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt new file mode 100644 index 0000000000000..0c399c4d18533 --- /dev/null +++ b/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui.util + +actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt deleted file mode 100644 index 04c0cb68e34c5..0000000000000 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/Trace.uikit.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui - -import androidx.compose.runtime.ExperimentalComposeApi -import androidx.compose.ui.uikit.utils.CMPOSLogger -import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval - -@ExperimentalComposeApi -fun enableTraceOSLog() { - if (traceImpl == null) { - traceImpl = CMPOSLogger(categoryName = "androidx.compose.ui") - } -} - -private var traceImpl: CMPOSLogger? = null - -// Verbatim of androidx.compose.runtime.Trace -internal object Trace { - /** - * Writes a trace message to indicate that a given section of code has begun. - * This call must be followed by a corresponding call to [endSection] on the same thread. - * - * @return An arbitrary token which will be supplied to the corresponding call - * to [endSection]. May be null. - */ - fun beginSection(name: String): CMPOSLoggerInterval? { - return traceImpl?.beginIntervalNamed(name) - } - - /** - * Writes a trace message to indicate that a given section of code has ended. - * This call must be preceded by a corresponding call to [beginSection]. - * Calling this method will mark the end of the most recently begun section of code, so care - * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and - * called from the same thread. - * - * @param interval The instance returned from the corresponding call to [beginSection]. - */ - fun endSection(interval: CMPOSLoggerInterval) { - traceImpl?.endInterval(interval) - } -} - -/** - * Wrap the specified [block] in calls to [Trace.beginSection] (with the supplied [sectionName]) - * and [Trace.endSection]. - */ -internal actual inline fun trace(sectionName: String, block: () -> T): T { - val token = Trace.beginSection(sectionName) - try { - return block() - } finally { - token?.let { - Trace.endSection(it) - } - } -} \ No newline at end of file From bebcfc4760b989826096e6acf76f7f538a2ec210 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:30:44 +0100 Subject: [PATCH 16/36] Remove test class --- .../compose/runtime/UIKitAccessTest.kt | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt b/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt deleted file mode 100644 index 367c1be0722b2..0000000000000 --- a/compose/runtime/runtime/src/uikitMain/kotlin/android/compose/runtime/UIKitAccessTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.compose.runtime - -import androidx.compose.ui.uikit.utils.CMPAccessibilityElement - -class UIKitAccessTest { - init { - println(">> Access ${CMPAccessibilityElement()}") - } -} \ No newline at end of file From 8af1ac57f62e3490f818cc42964710671fca2229 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:31:56 +0100 Subject: [PATCH 17/36] Remove Trace.jb.kt --- .../androidx/compose/ui/util/Trace.jb.kt | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt diff --git a/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt b/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt deleted file mode 100644 index b2cb529c7b617..0000000000000 --- a/compose/ui/ui-util/src/jbMain/kotlin/androidx/compose/ui/util/Trace.jb.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui.util - -//actual inline fun trace(sectionName: String, block: () -> T): T { -// return block() -//} From 0a8999ab9887f2ab83e1c520d08ce679fde90a4a Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:35:19 +0100 Subject: [PATCH 18/36] Remove unneeded files, import trace from other package --- .../compose/ui/Trace.skikoMain.desktop.kt | 21 ------------------- .../compose/ui/Trace.skikoMain.jsWasm.kt | 21 ------------------- .../compose/ui/Trace.skikoMain.macos.kt | 21 ------------------- .../ui/scene/BaseComposeScene.skiko.kt | 2 +- .../scene/ComposeSceneInputHandler.skiko.kt | 2 +- .../ui/scene/ComposeSceneRecomposer.skiko.kt | 2 +- .../ui/scene/SingleLayerComposeScene.skiko.kt | 2 +- .../compose/ui/window/MetalRedrawer.uikit.kt | 2 +- 8 files changed, 5 insertions(+), 68 deletions(-) delete mode 100644 compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt delete mode 100644 compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt delete mode 100644 compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt deleted file mode 100644 index c37db837d1827..0000000000000 --- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/Trace.skikoMain.desktop.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui - -internal actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} \ No newline at end of file diff --git a/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt b/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt deleted file mode 100644 index c37db837d1827..0000000000000 --- a/compose/ui/ui/src/jsWasmMain/kotlin/androidx/compose/ui/Trace.skikoMain.jsWasm.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui - -internal actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} \ No newline at end of file diff --git a/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt b/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt deleted file mode 100644 index c37db837d1827..0000000000000 --- a/compose/ui/ui/src/macosMain/kotlin/androidx/compose/ui/Trace.skikoMain.macos.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui - -internal actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} \ No newline at end of file diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index f19fa1b815755..5a91e516f07a2 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -38,7 +38,7 @@ import androidx.compose.ui.input.pointer.PointerType import androidx.compose.ui.node.SnapshotInvalidationTracker import androidx.compose.ui.platform.GlobalSnapshotManager import androidx.compose.ui.platform.PlatformContext -import androidx.compose.ui.trace +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlin.concurrent.Volatile diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt index 655bc01885544..5e9e962308f52 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneInputHandler.skiko.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.input.pointer.SyntheticEventSender import androidx.compose.ui.input.pointer.areAnyPressed import androidx.compose.ui.input.pointer.copyFor import androidx.compose.ui.node.RootNodeOwner -import androidx.compose.ui.trace +import androidx.compose.ui.util.trace import org.jetbrains.skiko.currentNanoTime /** diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt index 421d291d1a892..5aa082f683c5d 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeSceneRecomposer.skiko.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composition import androidx.compose.runtime.CompositionContext import androidx.compose.runtime.Recomposer import androidx.compose.ui.platform.FlushCoroutineDispatcher -import androidx.compose.ui.trace +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt index 1ab3d7dd3d09c..603d21c6899b2 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.trace +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.Dispatchers diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index ce0990fb5f1ad..fc6ec4b9fda32 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.interop.UIKitInteropTransaction import androidx.compose.ui.interop.doLocked import androidx.compose.ui.interop.isNotEmpty import androidx.compose.ui.util.fastForEach -import androidx.compose.ui.trace +import androidx.compose.ui.util.trace import kotlin.math.roundToInt import kotlinx.cinterop.* import org.jetbrains.skia.* From 9695ea14826b3d9f60062c89fa06cf8ea4de9e4a Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:40:10 +0100 Subject: [PATCH 19/36] Add dependency on objc module to ui-utils --- compose/ui/ui-util/build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compose/ui/ui-util/build.gradle b/compose/ui/ui-util/build.gradle index 9ca0d2f28e48f..b9f8d55a9ba54 100644 --- a/compose/ui/ui-util/build.gradle +++ b/compose/ui/ui-util/build.gradle @@ -78,6 +78,13 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { implementation(libs.kotlinStdlib) } } + + uikitMain { + dependencies { + api project(":compose:ui:ui-uikit") + } + } + wasmJsMain.dependsOn(jbMain) commonTest.dependencies { From 02f7be70909565059cd186e5e4a8af11c6ef2b83 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 12:54:40 +0100 Subject: [PATCH 20/36] Add proper annotations --- .../androidx/compose/ui/util/Trace.uikit.kt | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt b/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt index b793dc6447dd5..68ea4102ed996 100644 --- a/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt +++ b/compose/ui/ui-util/src/uikitMain/kotlin/androidx/compose/ui/util/Trace.uikit.kt @@ -16,15 +16,36 @@ package androidx.compose.ui.util -@ExperimentalComposeApi +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.InternalComposeUiApi +import androidx.compose.ui.uikit.utils.CMPOSLogger + +/** + * Enables iOS OS logging for the `androidx.compose.ui` APIs. + * + * Tracing allows logging detailed information about the Compose UI framework, which can be further + * analyzed using the XCode Instruments tool. + * + * This method is an [ExperimentalComposeUiApi], which means it is subject to change without notice in major, minor, or patch releases. + * + * @see ExperimentalComposeUiApi + */ +@OptIn(InternalComposeUiApi::class) +@ExperimentalComposeUiApi fun enableTraceOSLog() { if (traceImpl == null) { traceImpl = CMPOSLogger(categoryName = "androidx.compose.ui") } } -private var traceImpl: CMPOSLogger? = null +/** + * Instance of the [CMPOSLogger] used for tracing. Public due to `inline` requirement of [trace]. + * Intended for internal use only. + */ +@InternalComposeUiApi +var traceImpl: CMPOSLogger? = null +@OptIn(InternalComposeUiApi::class) actual inline fun trace(sectionName: String, block: () -> T): T { val interval = traceImpl?.beginIntervalNamed(sectionName) try { From ba137e1c2746feebcc44d09144c5d71db83b1602 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 13:00:43 +0100 Subject: [PATCH 21/36] Fix compilation error --- .../kotlin/androidx/compose/mpp/demo/main.uikit.kt | 5 +++-- .../kotlin/androidx/compose/runtime/Trace.uikit.kt | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt index bc14ca33436fe..a0be289d8ef0a 100644 --- a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt +++ b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.ExperimentalComposeApi import androidx.compose.runtime.ExperimentalComposeRuntimeApi import androidx.compose.runtime.remember +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.main.defaultUIKitMain import androidx.compose.ui.platform.AccessibilityDebugLogger import androidx.compose.ui.platform.AccessibilitySyncOptions @@ -19,10 +20,10 @@ import bugs.StartRecompositionCheck import platform.UIKit.UIViewController -@OptIn(ExperimentalComposeApi::class) +@OptIn(ExperimentalComposeApi::class, ExperimentalComposeUiApi::class) fun main(vararg args: String) { androidx.compose.runtime.enableTraceOSLog() - androidx.compose.ui.enableTraceOSLog() + androidx.compose.ui.util.enableTraceOSLog() val arg = args.firstOrNull() ?: "" defaultUIKitMain("ComposeDemo", ComposeUIViewController(configure = { diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index 486058ae88bc1..2669791658435 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -20,6 +20,16 @@ import androidx.compose.ui.uikit.utils.CMPOSLogger import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval +/** + * Enables iOS OS logging for the `androidx.compose.runtime` APIs. + * + * Tracing allows logging detailed information about the Compose UI framework, which can be further + * analyzed using the XCode Instruments tool. + * + * This method is an [ExperimentalComposeApi], which means it is subject to change without notice in major, minor, or patch releases. + * + * @see ExperimentalComposeApi + */ @ExperimentalComposeApi fun enableTraceOSLog() { if (traceImpl == null) { From 9a75279a97c1ed26389956e4b9554027a84777b0 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 14:25:45 +0100 Subject: [PATCH 22/36] Add trace for wait signal --- .../kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index fc6ec4b9fda32..40214880bc7da 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -361,7 +361,9 @@ internal class MetalRedrawer( pictureRecorder.finishRecordingAsPicture() } - dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER) + trace("MetalRedrawer:draw:waitInflightSemaphore") { + dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER) + } val metalDrawable = metalLayer.nextDrawable() From 96ea8ee8b2a830f24692f45b5a78ec66f43b7f5f Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 14:47:47 +0100 Subject: [PATCH 23/36] Add extra traces --- .../kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt index 40214880bc7da..c296462cb8925 100644 --- a/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt +++ b/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/MetalRedrawer.uikit.kt @@ -365,7 +365,9 @@ internal class MetalRedrawer( dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER) } - val metalDrawable = metalLayer.nextDrawable() + val metalDrawable = trace("MetalRedrawer:draw:nextDrawable") { + metalLayer.nextDrawable() + } if (metalDrawable == null) { // TODO: anomaly, log From 806d73e9d9756ed74262209d427b2e54d814610b Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Mon, 26 Feb 2024 14:49:30 +0100 Subject: [PATCH 24/36] Fix bin compat issue --- .../desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt b/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt index 0c399c4d18533..372685cb0ac96 100644 --- a/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt +++ b/compose/ui/ui-util/src/desktopMain/kotlin/androidx/compose/ui/util/Trace.desktop.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@file:JvmName("Trace_jbKt") package androidx.compose.ui.util From 5fa15f688854f2dfeda0e4549b471dce237cbcda Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 09:24:04 +0100 Subject: [PATCH 25/36] Add trace --- .../kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 5a91e516f07a2..0a3748c18ea30 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -75,7 +75,7 @@ internal abstract class BaseComposeScene( private set private var isInvalidationDisabled = false - private inline fun postponeInvalidation(crossinline block: () -> T): T { + private inline fun postponeInvalidation(crossinline block: () -> T): T = trace("BaseComposeScene:postponeInvalidation") { check(!isClosed) { "ComposeScene is closed" } isInvalidationDisabled = true return try { From d9df692322231f2d07839f249b56be2f7c547f82 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 09:25:06 +0100 Subject: [PATCH 26/36] Move trace --- .../kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt | 3 ++- .../androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt index c0992a61e2c76..c839b4913135a 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt @@ -75,6 +75,7 @@ import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.toIntRect import androidx.compose.ui.unit.toRect import androidx.compose.ui.util.fastAll +import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlin.math.max import kotlin.math.min @@ -192,7 +193,7 @@ internal class RootNodeOwner( measureAndLayoutDelegate.dispatchOnPositionedCallbacks(forceDispatch = true) } - fun draw(canvas: Canvas) { + fun draw(canvas: Canvas) = trace("RootNodeOwner:draw"){ owner.root.draw(canvas) clearInvalidObservations() } diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt index 603d21c6899b2..6731a6ef27bdd 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/SingleLayerComposeScene.skiko.kt @@ -35,7 +35,6 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.util.trace import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.Dispatchers @@ -172,7 +171,7 @@ private class SingleLayerComposeSceneImpl( mainOwner.measureAndLayout() } - override fun draw(canvas: Canvas) = trace("SingleLayerComposeSceneImpl:draw") { + override fun draw(canvas: Canvas) { mainOwner.draw(canvas) } From ee4adeb963ae3be3f1e0cabf84ff228a750f53d3 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 09:52:53 +0100 Subject: [PATCH 27/36] Unify linux source sets in `runtime` --- compose/runtime/runtime/build.gradle | 17 ++++++-- .../androidx/compose/runtime/Trace.linux.kt} | 1 + .../compose/runtime/Trace.linuxX64.kt | 42 ------------------- 3 files changed, 14 insertions(+), 46 deletions(-) rename compose/runtime/runtime/src/{linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt => linuxMain/kotlin/androidx/compose/runtime/Trace.linux.kt} (99%) delete mode 100644 compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle index b1fc617e39369..7900323625eff 100644 --- a/compose/runtime/runtime/build.gradle +++ b/compose/runtime/runtime/build.gradle @@ -185,10 +185,19 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { desktopMain.dependsOn(jbMain) jsNativeMain.dependsOn(jbMain) - linuxArm64Main.dependsOn(nativeMain) - linuxArm64Test.dependsOn(nativeTest) - linuxX64Main.dependsOn(nativeMain) - linuxX64Test.dependsOn(nativeTest) + linuxMain { + dependsOn(nativeMain) + } + + linuxTest { + dependsOn(nativeTest) + } + + linuxArm64Main.dependsOn(linuxMain) + linuxArm64Test.dependsOn(linuxTest) + linuxX64Main.dependsOn(linuxMain) + linuxX64Test.dependsOn(linuxTest) + mingwX64Main.dependsOn(nativeMain) mingwX64Test.dependsOn(nativeTest) diff --git a/compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt b/compose/runtime/runtime/src/linuxMain/kotlin/androidx/compose/runtime/Trace.linux.kt similarity index 99% rename from compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt rename to compose/runtime/runtime/src/linuxMain/kotlin/androidx/compose/runtime/Trace.linux.kt index b3815dc46efb7..0f74a51e7e4c7 100644 --- a/compose/runtime/runtime/src/linuxArm64Main/kotlin/androidx/compose/runtime/Trace.linuxArm64.kt +++ b/compose/runtime/runtime/src/linuxMain/kotlin/androidx/compose/runtime/Trace.linux.kt @@ -39,4 +39,5 @@ internal actual object Trace { */ actual fun endSection(token: Any?) { } + } \ No newline at end of file diff --git a/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt b/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt deleted file mode 100644 index b3815dc46efb7..0000000000000 --- a/compose/runtime/runtime/src/linuxX64Main/kotlin/androidx/compose/runtime/Trace.linuxX64.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.runtime - -internal actual object Trace { - /** - * Writes a trace message to indicate that a given section of code has begun. - * This call must be followed by a corresponding call to [endSection] on the same thread. - * - * @return An arbitrary token which will be supplied to the corresponding call - * to [endSection]. May be null. - */ - actual fun beginSection(name: String): Any? { - return null - } - - /** - * Writes a trace message to indicate that a given section of code has ended. - * This call must be preceded by a corresponding call to [beginSection]. - * Calling this method will mark the end of the most recently begun section of code, so care - * must be taken to ensure that `beginSection` / `endSection` pairs are properly nested and - * called from the same thread. - * - * @param token The instance returned from the corresponding call to [beginSection]. - */ - actual fun endSection(token: Any?) { - } -} \ No newline at end of file From 1cbaaa8de3a4393b120ac6708cf560aac277ee01 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 09:59:40 +0100 Subject: [PATCH 28/36] Unify web targets --- compose/ui/ui-util/build.gradle | 8 +++++-- .../androidx/compose/ui/util/Trace.web.kt | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 compose/ui/ui-util/src/webMain/kotlin/androidx/compose/ui/util/Trace.web.kt diff --git a/compose/ui/ui-util/build.gradle b/compose/ui/ui-util/build.gradle index b9f8d55a9ba54..4af09f66977df 100644 --- a/compose/ui/ui-util/build.gradle +++ b/compose/ui/ui-util/build.gradle @@ -70,7 +70,6 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { jbMain.dependsOn(commonMain) nativeMain.dependsOn(jbMain) - jsMain.dependsOn(jbMain) desktopMain.dependsOn(jbMain) wasmJsMain { @@ -85,7 +84,12 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { } } - wasmJsMain.dependsOn(jbMain) + webMain { + dependsOn(jbMain) + } + + jsMain.dependsOn(webMain) + wasmJsMain.dependsOn(webMain) commonTest.dependencies { implementation(kotlin("test-junit")) diff --git a/compose/ui/ui-util/src/webMain/kotlin/androidx/compose/ui/util/Trace.web.kt b/compose/ui/ui-util/src/webMain/kotlin/androidx/compose/ui/util/Trace.web.kt new file mode 100644 index 0000000000000..0c399c4d18533 --- /dev/null +++ b/compose/ui/ui-util/src/webMain/kotlin/androidx/compose/ui/util/Trace.web.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.ui.util + +actual inline fun trace(sectionName: String, block: () -> T): T { + return block() +} \ No newline at end of file From b2951f5665862a1a8f74df03dd08c6c873e34c99 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 10:02:42 +0100 Subject: [PATCH 29/36] Remove files --- .../androidx/compose/ui/util/Trace.js.kt | 21 ------------------- .../androidx/compose/ui/util/Trace.wasmJs.kt | 21 ------------------- 2 files changed, 42 deletions(-) delete mode 100644 compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt delete mode 100644 compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt diff --git a/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt b/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt deleted file mode 100644 index 0c399c4d18533..0000000000000 --- a/compose/ui/ui-util/src/jsMain/kotlin/androidx/compose/ui/util/Trace.js.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui.util - -actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} \ No newline at end of file diff --git a/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt b/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt deleted file mode 100644 index 0c399c4d18533..0000000000000 --- a/compose/ui/ui-util/src/wasmJsMain/kotlin/androidx/compose/ui/util/Trace.wasmJs.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.compose.ui.util - -actual inline fun trace(sectionName: String, block: () -> T): T { - return block() -} \ No newline at end of file From 7f279e95c29b4efb25f9ae08fdab917506dd8b59 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 10:03:14 +0100 Subject: [PATCH 30/36] Add space --- .../kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt index c839b4913135a..5a93a153cb41b 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt @@ -193,7 +193,7 @@ internal class RootNodeOwner( measureAndLayoutDelegate.dispatchOnPositionedCallbacks(forceDispatch = true) } - fun draw(canvas: Canvas) = trace("RootNodeOwner:draw"){ + fun draw(canvas: Canvas) = trace("RootNodeOwner:draw") { owner.root.draw(canvas) clearInvalidObservations() } From 93cd6e737a6aa34bd0feec7ec15e1658d51555cc Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 10:40:12 +0100 Subject: [PATCH 31/36] Update license header --- .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h | 21 +++++++++++++------ .../CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m | 21 +++++++++++++------ .../CMPUIKitUtils/CMPOSLoggerInterval.h | 21 +++++++++++++------ .../CMPUIKitUtils/CMPOSLoggerInterval.m | 21 +++++++++++++------ .../CMPUIKitUtilsTestApp-Bridging-Header.h | 18 +++++++++++++--- .../CMPUIKitUtilsTestApp.swift | 21 +++++++++++++------ 6 files changed, 90 insertions(+), 33 deletions(-) diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h index 454e3c37b0ebe..83a0aee3076de 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.h @@ -1,9 +1,18 @@ -// -// CMPOSLogger.h -// CMPUIKitUtils -// -// Created by Ilia.Semenov on 21/02/2024. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #import diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m index 4fad4cb37c708..28c9dba90a888 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLogger.m @@ -1,9 +1,18 @@ -// -// CMPOSLogger.m -// CMPUIKitUtils -// -// Created by Ilia.Semenov on 21/02/2024. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #import "CMPOSLogger.h" diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h index faa619a7f7341..e35ff58fa9193 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.h @@ -1,9 +1,18 @@ -// -// CMPOSLoggerInterval.h -// CMPUIKitUtils -// -// Created by Ilia.Semenov on 21/02/2024. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #import #import diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m index 4356a42d01a85..4a4453c28bdc3 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -1,9 +1,18 @@ -// -// CMPOSLoggerInterval.m -// CMPUIKitUtils -// -// Created by Ilia.Semenov on 21/02/2024. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #import "CMPOSLoggerInterval.h" diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h index 517fddfec8540..eb3f9ac9fb037 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp-Bridging-Header.h @@ -1,5 +1,17 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #import "CMPUIKitUtils.h" diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift index aeb4d2627ef6c..34f0c091fdb19 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtilsTestApp/CMPUIKitUtilsTestApp.swift @@ -1,9 +1,18 @@ -// -// CMPUIKitUtilsTestAppApp.swift -// CMPUIKitUtilsTestApp -// -// Created by Andrei.Salavei on 30.11.23. -// +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import SwiftUI From 5d703c9ca584e87b9d4a28d27753029a3c225321 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Tue, 27 Feb 2024 13:11:06 +0100 Subject: [PATCH 32/36] Add tags --- .../compose/ui/scene/BaseComposeScene.skiko.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 0a3748c18ea30..0d604b6400fc2 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -75,7 +75,7 @@ internal abstract class BaseComposeScene( private set private var isInvalidationDisabled = false - private inline fun postponeInvalidation(crossinline block: () -> T): T = trace("BaseComposeScene:postponeInvalidation") { + private inline fun postponeInvalidation(tag: String, crossinline block: () -> T): T = trace("BaseComposeScene:postponeInvalidation($tag)") { check(!isClosed) { "ComposeScene is closed" } isInvalidationDisabled = true return try { @@ -125,7 +125,7 @@ internal abstract class BaseComposeScene( override fun hasInvalidations(): Boolean = hasPendingDraws || recomposer.hasPendingWork - override fun setContent(content: @Composable () -> Unit) = postponeInvalidation { + override fun setContent(content: @Composable () -> Unit) = postponeInvalidation("setContent") { check(!isClosed) { "ComposeScene is closed" } inputHandler.onChangeContent() @@ -148,7 +148,7 @@ internal abstract class BaseComposeScene( override fun render(canvas: Canvas, nanoTime: Long) { return trace("BaseComposeScene:render") { - postponeInvalidation { + postponeInvalidation("render") { // Note that on Android the order is slightly different: // - Recomposition // - Layout @@ -183,7 +183,7 @@ internal abstract class BaseComposeScene( keyboardModifiers: PointerKeyboardModifiers?, nativeEvent: Any?, button: PointerButton? - ) = postponeInvalidation { + ) = postponeInvalidation("sendPointerEvent") { inputHandler.onPointerEvent( eventType = eventType, position = position, @@ -208,7 +208,7 @@ internal abstract class BaseComposeScene( timeMillis: Long, nativeEvent: Any?, button: PointerButton?, - ) = postponeInvalidation { + ) = postponeInvalidation("sendPointerEvent") { inputHandler.onPointerEvent( eventType = eventType, pointers = pointers, @@ -221,7 +221,7 @@ internal abstract class BaseComposeScene( ) } - override fun sendKeyEvent(keyEvent: KeyEvent): Boolean = postponeInvalidation { + override fun sendKeyEvent(keyEvent: KeyEvent): Boolean = postponeInvalidation("sendKeyEvent") { inputHandler.onKeyEvent(keyEvent) } From 5f26c26e3ea11a0481f759be22eae24067413281 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 28 Feb 2024 12:35:56 +0100 Subject: [PATCH 33/36] Remove redundant _name variable --- .../objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m index 4a4453c28bdc3..fd70cf4da99f7 100644 --- a/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m +++ b/compose/ui/ui-uikit/src/uikitMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPOSLoggerInterval.m @@ -21,7 +21,6 @@ @implementation CMPOSLoggerInterval { os_log_t _log; os_signpost_id_t _signpostId; - NSString *_name; } - (instancetype)initWithLog:(os_log_t)log { @@ -30,15 +29,12 @@ - (instancetype)initWithLog:(os_log_t)log { if (self) { _log = log; _signpostId = os_signpost_id_generate(_log); - _name = nil; } return self; } -- (void)beginWithName:(NSString *)name { - _name = name; - +- (void)beginWithName:(NSString *)name { os_signpost_interval_begin(_log, _signpostId, "CMPInterval", "%{public}s", [name UTF8String]); } From af98cefc2b5e3afcc07fa0d975dc0964387c9b7a Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 28 Feb 2024 12:37:59 +0100 Subject: [PATCH 34/36] Update compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt Co-authored-by: Igor Demin --- .../kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 0d604b6400fc2..67527c74e4445 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -75,7 +75,7 @@ internal abstract class BaseComposeScene( private set private var isInvalidationDisabled = false - private inline fun postponeInvalidation(tag: String, crossinline block: () -> T): T = trace("BaseComposeScene:postponeInvalidation($tag)") { + private inline fun postponeInvalidation(traceTag: String, crossinline block: () -> T): T = trace(traceTag) { check(!isClosed) { "ComposeScene is closed" } isInvalidationDisabled = true return try { From c5735e4533a02b99214251e2ae2ad8ea641e682a Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 28 Feb 2024 12:44:13 +0100 Subject: [PATCH 35/36] Minor refactor --- .../ui/scene/BaseComposeScene.skiko.kt | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt index 67527c74e4445..0b1d401fda4a0 100644 --- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt +++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt @@ -125,7 +125,7 @@ internal abstract class BaseComposeScene( override fun hasInvalidations(): Boolean = hasPendingDraws || recomposer.hasPendingWork - override fun setContent(content: @Composable () -> Unit) = postponeInvalidation("setContent") { + override fun setContent(content: @Composable () -> Unit) = postponeInvalidation("BaseComposeScene:setContent") { check(!isClosed) { "ComposeScene is closed" } inputHandler.onChangeContent() @@ -146,32 +146,29 @@ internal abstract class BaseComposeScene( recomposer.performScheduledTasks() } - override fun render(canvas: Canvas, nanoTime: Long) { - return trace("BaseComposeScene:render") { - postponeInvalidation("render") { - // Note that on Android the order is slightly different: - // - Recomposition - // - Layout - // - Draw - // - Composition effects - // - Synthetic events - // We do this differently in order to be able to observe changes made by synthetic events - // in the drawing phase, thus reducing the time before they are visible on screen. - // - // It is important, however, to run the composition effects before the synthetic events are - // dispatched, in order to allow registering for these events before they are sent. - // Otherwise, events like a synthetic mouse-enter sent due to a new element appearing under - // the pointer would be missed by e.g. InteractionSource.collectHoverAsState - recomposer.performScheduledTasks() - frameClock.sendFrame(nanoTime) // Recomposition - doLayout() // Layout - recomposer.performScheduledEffects() // Composition effects (e.g. LaunchedEffect) - inputHandler.updatePointerPosition() // Synthetic move event - snapshotInvalidationTracker.onDraw() - draw(canvas) // Draw - } + override fun render(canvas: Canvas, nanoTime: Long) = + postponeInvalidation("BaseComposeScene:render") { + // Note that on Android the order is slightly different: + // - Recomposition + // - Layout + // - Draw + // - Composition effects + // - Synthetic events + // We do this differently in order to be able to observe changes made by synthetic events + // in the drawing phase, thus reducing the time before they are visible on screen. + // + // It is important, however, to run the composition effects before the synthetic events are + // dispatched, in order to allow registering for these events before they are sent. + // Otherwise, events like a synthetic mouse-enter sent due to a new element appearing under + // the pointer would be missed by e.g. InteractionSource.collectHoverAsState + recomposer.performScheduledTasks() + frameClock.sendFrame(nanoTime) // Recomposition + doLayout() // Layout + recomposer.performScheduledEffects() // Composition effects (e.g. LaunchedEffect) + inputHandler.updatePointerPosition() // Synthetic move event + snapshotInvalidationTracker.onDraw() + draw(canvas) // Draw } - } override fun sendPointerEvent( eventType: PointerEventType, @@ -183,7 +180,7 @@ internal abstract class BaseComposeScene( keyboardModifiers: PointerKeyboardModifiers?, nativeEvent: Any?, button: PointerButton? - ) = postponeInvalidation("sendPointerEvent") { + ) = postponeInvalidation("BaseComposeScene:sendPointerEvent") { inputHandler.onPointerEvent( eventType = eventType, position = position, @@ -208,7 +205,7 @@ internal abstract class BaseComposeScene( timeMillis: Long, nativeEvent: Any?, button: PointerButton?, - ) = postponeInvalidation("sendPointerEvent") { + ) = postponeInvalidation("BaseComposeScene:sendPointerEvent") { inputHandler.onPointerEvent( eventType = eventType, pointers = pointers, @@ -221,7 +218,7 @@ internal abstract class BaseComposeScene( ) } - override fun sendKeyEvent(keyEvent: KeyEvent): Boolean = postponeInvalidation("sendKeyEvent") { + override fun sendKeyEvent(keyEvent: KeyEvent): Boolean = postponeInvalidation("BaseComposeScene:sendKeyEvent") { inputHandler.onKeyEvent(keyEvent) } From b345cba2f2e5cbf48c844918b720c474611ac871 Mon Sep 17 00:00:00 2001 From: Elijah Semyonov Date: Wed, 28 Feb 2024 17:01:40 +0100 Subject: [PATCH 36/36] Remove dependency from runtime --- .../androidx/compose/mpp/demo/main.uikit.kt | 1 - compose/runtime/runtime/build.gradle | 5 ---- .../androidx/compose/runtime/Trace.uikit.kt | 29 ++----------------- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt index a0be289d8ef0a..85e37e3672319 100644 --- a/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt +++ b/compose/mpp/demo/src/uikitMain/kotlin/androidx/compose/mpp/demo/main.uikit.kt @@ -22,7 +22,6 @@ import platform.UIKit.UIViewController @OptIn(ExperimentalComposeApi::class, ExperimentalComposeUiApi::class) fun main(vararg args: String) { - androidx.compose.runtime.enableTraceOSLog() androidx.compose.ui.util.enableTraceOSLog() val arg = args.firstOrNull() ?: "" diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle index 7900323625eff..6b7a54a5657ae 100644 --- a/compose/runtime/runtime/build.gradle +++ b/compose/runtime/runtime/build.gradle @@ -126,11 +126,6 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { api("androidx.annotation:annotation:1.1.0") } } - uikitMain { - dependencies { - api project(":compose:ui:ui-uikit") - } - } commonTest.dependencies { implementation kotlin("test") diff --git a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt index 2669791658435..0f74a51e7e4c7 100644 --- a/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt +++ b/compose/runtime/runtime/src/uikitMain/kotlin/androidx/compose/runtime/Trace.uikit.kt @@ -16,29 +16,6 @@ package androidx.compose.runtime -import androidx.compose.ui.uikit.utils.CMPOSLogger -import androidx.compose.ui.uikit.utils.CMPOSLoggerInterval - - -/** - * Enables iOS OS logging for the `androidx.compose.runtime` APIs. - * - * Tracing allows logging detailed information about the Compose UI framework, which can be further - * analyzed using the XCode Instruments tool. - * - * This method is an [ExperimentalComposeApi], which means it is subject to change without notice in major, minor, or patch releases. - * - * @see ExperimentalComposeApi - */ -@ExperimentalComposeApi -fun enableTraceOSLog() { - if (traceImpl == null) { - traceImpl = CMPOSLogger(categoryName = "androidx.compose.runtime") - } -} - -private var traceImpl: CMPOSLogger? = null - internal actual object Trace { /** * Writes a trace message to indicate that a given section of code has begun. @@ -48,7 +25,7 @@ internal actual object Trace { * to [endSection]. May be null. */ actual fun beginSection(name: String): Any? { - return traceImpl?.beginIntervalNamed(name) + return null } /** @@ -61,8 +38,6 @@ internal actual object Trace { * @param token The instance returned from the corresponding call to [beginSection]. */ actual fun endSection(token: Any?) { - token?.let { - traceImpl?.endInterval(it as CMPOSLoggerInterval) - } } + } \ No newline at end of file