Skip to content

Prepare ui-graphics/ui-text for future upstreaming: extract skiko implementation into separate module#3126

Open
Ivan Matkov (MatkovIvan) wants to merge 7 commits into
jb-mainfrom
ivan.matkov/ui-skiko
Open

Prepare ui-graphics/ui-text for future upstreaming: extract skiko implementation into separate module#3126
Ivan Matkov (MatkovIvan) wants to merge 7 commits into
jb-mainfrom
ivan.matkov/ui-skiko

Conversation

@MatkovIvan

@MatkovIvan Ivan Matkov (MatkovIvan) commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

CMP-9813 Extract ui-graphics/ui-text skiko implementation into ui-skiko module
CMP-9814 Runtime registration of ui-skiko

Release Notes

N/A

Comment thread compose/ui/ui/build.gradle Outdated
@@ -222,6 +223,7 @@ androidXMultiplatform {
// TODO: Move to commonTest?
implementation(project(":compose:material:material"))
implementation(project(":compose:foundation:foundation"))
implementation(project(":compose:ui:ui-skiko"))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
implementation(project(":compose:ui:ui-skiko"))

skikoMain already contains it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -1,88 +0,0 @@
/*

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please separate moving files and changing them into separate commits? Without doing so, it is difficult to review.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the specific shape you are requesting here.
This PR is not just about renaming but about extracting the logic into a new module and converting previous classes/functions to wrappers.

What moving do you mean? And despite of the answer - do you really want to have a separate commit with inconsistent/not-compilable state?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Add the empty :compose:ui:ui-skiko Gradle module (settings include and
build script) that the following commits populate with the relocated
Skiko graphics and text backends. No source code yet.
Pure relocation: every change is a rename of byte-identical content from
ui-graphics into the new ui-skiko module. No build-script or logic
changes here, so the follow-up commit's diff shows only the new bindings
and delegation rather than the ~3k-line relocation.

Relocated as-is: Canvas/Paint/Path/PathEffect/PathMeasure/PathIterator/
ImageBitmap/GraphicsLayer/Blur/Rects impls, the matrix helpers, the
Skia-interop Desktop*/Native*/Actuals sources, and the Skiko graphics
tests. Does not build on its own; completed by the next commit.
Make ui-graphics' nonAndroidMain Skia-free by resolving Skia through
runtime-registered @InternalComposeUiApi Platform* bindings, completing
the relocation from the previous commit. Also reconfigures
ui-graphics/build.gradle for the Skia-free source-set topology.

- ui-graphics keeps thin expect/actual delegators that resolve a
  registered PlatformGraphics implementation at runtime.
- The Skia-holding expect-class actuals (Shader, ColorFilter,
  BlurEffect/OffsetEffect/RenderEffect) become Skiko-free via the
  PlatformBindings pattern: an opaque Platform* binding in ui-graphics,
  implemented in ui-skiko.
- Public Skia-interop extensions (skiaPaint, skiaImageFilter,
  asComposePath, ...) are published from ui-skiko keeping their original
  package and @file:JvmName facade anchors, preserving desktop binary
  compatibility. Deprecated Skia-returning members that cannot be
  extensions delegate through a temporary SkikoGraphicsCompat registry.
- BlendMode/SkiaVertexMode conversion helpers are gathered into the new
  SkiaConversions.nonAndroid.kt.

API baselines are regenerated in a later commit.
Pure relocation: every change is a rename of byte-identical content from
ui-text into ui-skiko, mirroring the graphics move. No build-script or
logic changes here.

Relocated as-is: paragraph building/intrinsics/layout, char helpers, the
font subsystem (FontFamilyResolver, font loading, PlatformFont), locale
and text-paint impls, and the Skiko text tests. Does not build on its
own; completed by the next commit.
Make ui-text's nonAndroidMain Skia-free by resolving Skia through a
runtime-registered text implementation, completing the relocation from
the previous commit. Also extends ui-skiko/build.gradle with the text
source sets and reconfigures ui-text/build.gradle.

- ui-text keeps expect/actual delegators; the org.jetbrains.skia
  paragraph, font and text-paint code lives in ui-skiko.
- The font subsystem is ui-text's own public API with per-platform
  loadTypeface actuals, so the unavoidable public Skia-typed surface
  stays in ui-text's skikoMain compat layer (Skia-free nonAndroidMain ->
  Skia skikoMain -> platform leaves); only the implementation moves.
- ComposeUiSkikoRuntime.registerSkikoComposeImplementation() now wires
  both the graphics and text implementations (plus the temporary
  SkikoGraphicsCompat bridge).

API baselines are regenerated in a later commit.
Wire registerSkikoComposeImplementation() into the Skiko-backed Compose
entry points so the ui-graphics/ui-text registries are populated before
any scene is created: desktop ComposePanel/ComposeWindowPanel, macOS
ComposeWindow, iOS ComposeContainer, web ComposeWindowInternal,
ImageComposeScene, and the ui-test rules. Adds the :compose:ui:ui-skiko
dependency to the modules that rely on the Skiko backend transitively
(ui, ui-test, ui-test-junit4, foundation).

Tests reach the backend through a SkikoComposeTestBase per affected test
source set, which registers the implementation in its init block so that
it is available to subclass field initializers. The base class is
duplicated per module because those test source sets share no test-scoped
module: ui-text and ui-skiko tests cannot depend on ui-test without a
dependency cycle, and a single shared class in a main source set would
ship test support code in a production artifact.
Record the post-extraction public API. ui-graphics/ui-text baselines
shrink by the relocation-only removals (the Skia-interop extensions and
helpers now published from ui-skiko under identical package + facade
names); no other public declarations change. Desktop binary
compatibility is preserved through the @file:JvmName facade anchors and
the HIDDEN split-facade shims in ui-skiko.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants