Skip to content

Move SkiaSharp C API (src/c) out of upstream :core into libSkiaSharp - #251

Open
mattleibow wants to merge 4 commits into
skiasharpfrom
dev/move-capi-to-libskiasharp
Open

Move SkiaSharp C API (src/c) out of upstream :core into libSkiaSharp#251
mattleibow wants to merge 4 commits into
skiasharpfrom
dev/move-capi-to-libskiasharp

Conversation

@mattleibow

@mattleibow mattleibow commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Moves SkiaSharp's fork-owned C API shim (src/c/*.cpp + include/c/*.h) out of upstream Skia's :core GN target and into the skiasharp_build("SkiaSharp") target (libSkiaSharp). This cleanly separates "Skia stuff" (upstream) from "SkiaSharp stuff" (our shim), shrinks the fork diff in upstream-owned files, and permanently fixes a class of "lost public_define when upstream reshuffles :core deps" bugs.

Companion parent-repo PR: mono/SkiaSharp#4131 (bumps this submodule + updates the non-GN Apple/Tizen builds).

Motivation

In the m148 update, upstream commit 029229d8be ("Simplify gn typeface related deps") moved the :fontmgr_* targets off :core and onto :skia. Our src/c/sk_typeface.cpp selects the Linux default font manager behind #elif defined(SK_FONTMGR_FONTCONFIG_AVAILABLE) — a public_define emitted by :fontmgr_fontconfig. Because src/c was injected into :core (via skia_core_sources += [...] in gn/core.gni) and upstream dropped :fontmgr_fontconfig from :core's deps, the define vanished from our compile → sk_fontmgr_create_default() silently returned an empty font manager → 0 fonts on Linux.

skiasharp_build("SkiaSharp") already deps on :skia, which lists :fontmgr_fontconfig in its public_deps. GN propagates a dependency's public_config (carrying public_defines) transitively through public_deps. So compiling src/c in libSkiaSharp makes it automatically see SK_FONTMGR_FONTCONFIG_AVAILABLE, the fontconfig include path, and SkFontMgr_New_FontConfig — via one existing edge, with no :core patch.

Changes

gn/core.gni

  • Removed the fork block skia_core_sources += [ "$_src/c/*.cpp" ... ] (all 40 src/c sources + sk_types_priv.h).
  • Removed the matching skia_core_public_headers += [ "$_include/c/*.h" ] block.
  • Result: :core no longer compiles or references any of our shim.

BUILD.gn

  • skiasharp_build("SkiaSharp") now owns the src/c/*.cpp sources (alongside the existing src/xamarin/*.cpp), the include/c/*.h public headers, and explicit deps/public_deps for everything those files need to compile that previously arrived transitively via :core:
    • fontmgr targets via optional() (fontconfig/CoreText/DirectWrite/Android/FCI) so the right SK_FONTMGR_*_AVAILABLE defines reach sk_typeface.cpp per platform,
    • module deps modules/skottie, modules/skresources, modules/sksg for skottie_animation.cpp / skresources_resource_provider.cpp / sksg_invalidation_controller.cpp,
    • GPU headers for gr_context.cpp.
  • Completed the C API public header list. The original gn/core.gni fork block never listed sk_linker.h, skottie_animation.h, skresources_resource_provider.h, or sksg_invalidation_controller.h, even though their .cpp are compiled. Now that :SkiaSharp is the GN owner of the C API surface, these four are added to public so the target metadata (and gn check) sees the full surface.
  • Removed the two m148 :core fork workarounds that only existed because src/c compiled in :core: the GPU-defines block and the if (skia_enable_fontmgr_fontconfig) { deps += [ ":fontmgr_fontconfig" ] } block (the 029229d8be workaround). After the move :core no longer compiles sk_typeface.cpp, so it no longer needs the define.
  • Added a warnings/deprecation guardrail to the SkiaSharp target. The skiasharp_build template bypasses Skia's skia_target_default_configs, so //gn/skia:warnings (and thus -Wall/-Wextra) never reached our sources — deprecated-API usage compiled silently on every GN platform and only surfaced on Tizen's hand-written -Werror build. Now the target adds //gn/skia:warnings for parity, plus a new :skiasharp_strict config (listed last so it wins over :warnings' -Wno-deprecated-declarations) that forces -Werror=deprecated-declarations (/we4996 on MSVC). Any future deprecated-Skia-API use in src/c now fails the build on every platform.

src/c/sk_path.cpp — deprecation fixes

  • sk_pathop_tight_bounds: was calling the [[deprecated]] SkPathOps::TightBounds; now calls SkPath::computeTightBounds() directly (identical semantics).
  • Migrated the four // DEPRECATED bool/out-param overloads to the new std::optional<SkPath> API, preserving the C API's write-to-result + return-bool contract: Op, Simplify, AsWinding, and SkOpBuilder::resolve.

Validation

  • macOS arm64 (native): builds clean; real 7.3 MB dylib, 820 sk_* C API symbols, Metal symbols present.
  • Linux x64 (Docker emulated): builds clean; fontconfig regression guard confirmed — non-empty default typeface, Fc* undefined symbols present in the .so (was 0 when broken).
  • Deprecation guardrail proven: reverting the TightBounds fix makes the build fail with error: 'TightBounds' is deprecated [-Werror,-Wdeprecated-declarations]; restoring it builds clean.
  • Tests: SkiaSharp.Tests.Console pass (the Linux font tests — SKTypefaceTest.DefaultIsNotEmpty, SKFontManagerTest, text measurement — are the key regression guard).

Notes

  • No C API signature changes; no binding regeneration needed.
  • This is the proper architectural fix that lets us drop the temporary m148 :core workarounds (done here).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR moves SkiaSharp’s fork-owned C API shim (src/c/*.cpp and include/c/*.h) out of upstream Skia’s :core target and into the skiasharp_build("SkiaSharp") target (libSkiaSharp), so the shim’s build inputs/defines come from SkiaSharp’s own GN dependency graph instead of upstream :core.

Changes:

  • Removed SkiaSharp C API sources/headers from gn/core.gni so upstream :core no longer compiles or exports the shim.
  • Updated BUILD.gn so skiasharp_build("SkiaSharp") owns the shim sources/headers, adds the needed deps, and adds a strict deprecation-as-error warnings config.
  • Updated src/c/sk_path.cpp to use the newer std::optional pathops APIs and avoid deprecated SkPathOps::TightBounds.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/c/sk_path.cpp Replaces deprecated pathops calls with std::optional-based APIs and computeTightBounds() logic.
gn/core.gni Removes the fork block that injected SkiaSharp C shim headers/sources into upstream :core.
BUILD.gn Moves shim sources/headers into skiasharp_build("SkiaSharp"), adds deps, and enforces deprecation warnings as errors for the shim.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread BUILD.gn
Comment on lines +4042 to +4046
"modules/jsonreader",
"modules/skottie",
"modules/skresources",
"modules/sksg",
]
Comment thread BUILD.gn
Comment on lines +4125 to +4129
"src/c/gr_context.cpp",
"src/c/sk_linker.cpp",
"src/c/skottie_animation.cpp",
"src/c/skresources_resource_provider.cpp",
"src/c/sksg_invalidation_controller.cpp",
mattleibow and others added 4 commits June 13, 2026 00:30
Compile the fork-owned C API shim (src/c/*.cpp) and its public headers
(include/c/*.h) in skiasharp_build("SkiaSharp") instead of injecting them
into upstream :core via gn/core.gni. libSkiaSharp deps directly on the
font-manager optional() targets and the modules the shim needs, so the
shim sees its public_defines (e.g. SK_FONTMGR_FONTCONFIG_AVAILABLE) and
GPU backend defines from its own dependency graph rather than riding on
:core's milestone-churning transitive deps.

Now that src/c no longer compiles in :core, remove the two fork
workarounds that only existed to feed it: the manual GPU defines block
(SK_VULKAN/SK_METAL/SK_DIRECT3D + use_skia_vulkan_headers) and the m148
fontconfig dep block (commit 029229d). Upstream :core's own sources
do not need these.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…SkiaSharp sources

sk_path.cpp called the [[deprecated]] SkPathOps TightBounds() helper, which
m148 marked deprecated. Inline its exact computeTightBounds() body instead so
the C API shim no longer consumes a deprecated Skia API.

The deprecation only failed Tizen's hand-written -Werror makefile build because
the skiasharp_build GN template bypasses Skia's skia_target_default_configs, so
//gn/skia:warnings (and thus -Wall/-Wextra) never reached our sources. Add
:warnings for parity and a new :skiasharp_strict config (listed last) that
forces -Werror=deprecated-declarations over the :warnings suppression, so any
future deprecated-API use in src/c fails on every platform, not just Tizen.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sk_path.cpp also used the // DEPRECATED bool/out-param overloads of Op,
Simplify, AsWinding and SkOpBuilder::resolve. Unlike TightBounds these are only
comment-deprecated (no [[deprecated]] attribute) so the compiler did not flag
them, but upstream wants callers off them. Migrate all four to the
std::optional<SkPath> returning forms, preserving the existing
write-to-result + return-bool C API semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sk_linker.h, skottie_animation.h, skresources_resource_provider.h, and
sksg_invalidation_controller.h were never in the C API public header list
(carried over from the original gn/core.gni fork block). Now that
:SkiaSharp owns the C API surface, complete the public header metadata so
GN consumers and gn check see the full surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow
mattleibow force-pushed the dev/move-capi-to-libskiasharp branch from 4f9d7c6 to db4f1e9 Compare June 12, 2026 22:33
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.

2 participants