Skip to content

Commit

Permalink
Build Skiko with Clang-CL (#1020)
Browse files Browse the repository at this point in the history
Official Skia documentation suggests that it's [_highly
recommended_](https://skia.org/docs/user/build/#highly-recommended-build-with-clang-cl)
to build Skia with Clang-CL on Windows, and that this dramatically
improves Skia performance with Software rendering and in other areas.
This corresponds with my experience, so here it is.

Related Skia-pack PR: JetBrains/skia-pack#64

Prerequisite: #1024
  • Loading branch information
Alovchin91 authored Feb 12, 2025
1 parent 3f95f4e commit 60f1df8
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 40 deletions.
17 changes: 9 additions & 8 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
* `Windows`
1. Download [Visual Studio Build Tools 2019](https://learn.microsoft.com/en-us/visualstudio/releases/2019/history) (search "BuildTools" on the page).
2. During the installation, select "Desktop development with C++"
3. Add an environment variable SKIKO_VSBT_PATH=C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools
```
Control Panel|All Control Panel Items|System|Advanced system settings|Environment variables
```
or by running `cmd` as administrator:
```
setx /M SKIKO_VSBT_PATH "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
```
3. Add an environment variable SKIKO_VSBT_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
```
Control Panel|All Control Panel Items|System|Advanced system settings|Environment variables
```
or by running `cmd` as administrator:
```
setx /M SKIKO_VSBT_PATH "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
```
4. Skiko is built using Clang-cl. Clang-cl is a part of LLVM and can be downloaded from the [LLVM project's website](https://releases.llvm.org/). Please also make sure that Clang-cl.exe is available in %PATH%.
* Install Emscripten
* Set `JAVA_HOME` to location of JDK, at least version 11
Expand Down
7 changes: 6 additions & 1 deletion skiko/buildSrc/src/main/kotlin/CompileSkikoCppTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ abstract class CompileSkikoCppTask() : AbstractSkikoNativeToolTask() {
arg("-o", outputFile.absolutePath.replace("\\", "/"))
arg(value = sourceFile.absolutePath.replace("\\", "/"))
if (compiler.get().startsWith("clang")) {
arg("-MJ", outputFile.absolutePath + ".json")
// We use Clang-CL on Windows which doesn't directly support the -MJ flag.
// We have to use the /clang:-MJ"path" form instead.
when {
buildTargetOS.get().isWindows -> rawArg("/clang:-MJ\"" + outputFile.absolutePath + ".json\"")
else -> arg("-MJ", outputFile.absolutePath + ".json")
}
}
}

Expand Down
18 changes: 9 additions & 9 deletions skiko/buildSrc/src/main/kotlin/properties.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ fun compilerForTarget(os: OS, arch: Arch): String =
Arch.Wasm -> "Unexpected combination: $os & $arch"
}
OS.Android -> "clang++"
OS.Windows -> "cl.exe"
OS.Windows -> "clang-cl.exe"
OS.MacOS, OS.IOS, OS.TVOS -> "clang++"
OS.Wasm -> "emcc"
}

fun linkerForTarget(os: OS, arch: Arch): String =
if (os.isWindows) "link.exe" else compilerForTarget(os, arch)
if (os.isWindows) "lld-link.exe" else compilerForTarget(os, arch)

val OS.dynamicLibExt: String
get() = when (this) {
Expand All @@ -74,22 +74,22 @@ enum class SkiaBuildType(
val id: String,
val flags: Array<String>,
val clangFlags: Array<String>,
val msvcCompilerFlags: Array<String>,
val msvcLinkerFlags: Array<String>
val winCompilerFlags: Array<String>,
val winLinkerFlags: Array<String>
) {
DEBUG(
"Debug",
id = "Debug",
flags = arrayOf("-DSK_DEBUG"),
clangFlags = arrayOf("-std=c++17", "-g", "-DSK_TRIVIAL_ABI=[[clang::trivial_abi]]"),
msvcCompilerFlags = arrayOf("/Zi /std:c++17"),
msvcLinkerFlags = arrayOf("/DEBUG"),
winCompilerFlags = arrayOf("/Zi", "/std:c++17"),
winLinkerFlags = arrayOf("/DEBUG"),
),
RELEASE(
id = "Release",
flags = arrayOf("-DNDEBUG"),
clangFlags = arrayOf("-std=c++17", "-O3"),
msvcCompilerFlags = arrayOf("/O2 /std:c++17"),
msvcLinkerFlags = arrayOf("/DEBUG"),
winCompilerFlags = arrayOf("/O2", "/std:c++17"),
winLinkerFlags = arrayOf("/DEBUG"),
);
override fun toString() = id
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fun SkikoProjectContext.createCompileJvmBindingsTask(
includeHeadersNonRecursive(skiaHeadersDirs(skiaJvmBindingsDir.get()))
val projectDir = project.projectDir
includeHeadersNonRecursive(projectDir.resolve("src/awtMain/cpp/include"))
includeHeadersNonRecursive(projectDir.resolve("src/jvmMain/cpp/common"))
includeHeadersNonRecursive(projectDir.resolve("src/jvmMain/cpp/include"))
includeHeadersNonRecursive(projectDir.resolve("src/commonMain/cpp/common/include"))

Expand Down Expand Up @@ -95,16 +96,17 @@ fun SkikoProjectContext.createCompileJvmBindingsTask(
)
}
OS.Windows -> {
compiler.set(windowsSdkPaths.compiler.absolutePath)
includeHeadersNonRecursive(windowsSdkPaths.includeDirs)
includeHeadersNonRecursive(jdkHome.resolve("include/win32"))
val targetArgs = if (targetArch == Arch.Arm64) arrayOf("/clang:--target=arm64-windows") else arrayOf()
osFlags = arrayOf(
"/nologo",
*buildType.msvcCompilerFlags,
*buildType.winCompilerFlags,
"/utf-8",
"/GR-", // no-RTTI.
"/FS", // Due to an error when building in Teamcity. https://docs.microsoft.com/en-us/cpp/build/reference/fs-force-synchronous-pdb-writes
// LATER. Ange rendering arguments:
*targetArgs,
// LATER. Angle rendering arguments:
// "-I$skiaDir/third_party/externals/angle2/include",
// "-I$skiaDir/src/gpu",
// "-DSK_ANGLE",
Expand Down Expand Up @@ -287,27 +289,16 @@ fun SkikoProjectContext.createLinkJvmBindings(
)
}
OS.Windows -> {
linker.set(windowsSdkPaths.linker.absolutePath)
libDirs.set(windowsSdkPaths.libDirs)
osFlags = mutableListOf<String>().apply {
addAll(buildType.msvcLinkerFlags)
addAll(buildType.winLinkerFlags)
addAll(
arrayOf(
// ignore https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-warning-lnk4217
// because we link OpenGl dynamically, defining functions in our own file in OpenGLLibrary.cc
"/ignore:4217"
)
)
// workaround for VS Build Tools 2022 (17.2+) change
// https://developercommunity.visualstudio.com/t/-imp-std-init-once-complete-unresolved-external-sy/1684365#T-N10041864
if (windowsSdkPaths.toolchainVersion >= VersionNumber.parse("14.32")) {
addAll(
arrayOf(
"/ALTERNATENAME:__imp___std_init_once_begin_initialize=__imp_InitOnceBeginInitialize",
"/ALTERNATENAME:__imp___std_init_once_complete=__imp_InitOnceComplete"
)
)
}
addAll(
arrayOf(
"/NOLOGO",
Expand Down
2 changes: 1 addition & 1 deletion skiko/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ kotlin.code.style=official
deploy.version=0.0.0


dependencies.skia=m132-9b3c42e2f9-1
dependencies.skia=m132-9b3c42e2f9-2

# you can override general skia dependencies by passing platform-specific property:
# dependencies.skia.android-arm64
Expand Down
5 changes: 2 additions & 3 deletions skiko/src/awtMain/cpp/windows/InternalDirectXApi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "ganesh/GrBackendSurface.h"
#include "ganesh/GrDirectContext.h"
#include "SkSurface.h"
#include "../common/interop.hh"

#include "ganesh/d3d/GrD3DTypes.h"
#include "ganesh/d3d/GrD3DBackendContext.h"
Expand Down Expand Up @@ -351,7 +350,7 @@ extern "C"
dst.PlacedFootprint.Footprint.Depth = 1;
dst.PlacedFootprint.Footprint.RowPitch = calculateRowPitch(texture->width);

D3D12_BOX srcBox = {0, 0, 0, texture->width, texture->height, 1};
D3D12_BOX srcBox = {0, 0, 0, static_cast<UINT>(texture->width), static_cast<UINT>(texture->height), 1};

commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &srcBox);

Expand Down Expand Up @@ -381,7 +380,7 @@ extern "C"
DirectXOffScreenTexture *texture = fromJavaPointer<DirectXOffScreenTexture *>(texturePtr);

auto rangeLength = texture->readbackBufferWidth();
D3D12_RANGE readbackBufferRange{ 0, rangeLength };
D3D12_RANGE readbackBufferRange{ 0, static_cast<SIZE_T>(rangeLength) };

/*
* TODO: memcpy from unaligned texture is not supported, line by line copy is very slow,
Expand Down
2 changes: 1 addition & 1 deletion skiko/src/awtMain/cpp/windows/SoftwareRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "SkColorSpace.h"
#include "SkSurface.h"
#include "src/base/SkAutoMalloc.h"
#include "../common/interop.hh"
#include "interop.hh"

class SoftwareDevice
{
Expand Down
2 changes: 1 addition & 1 deletion skiko/src/awtMain/cpp/windows/directXRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "ganesh/GrDirectContext.h"
#include "SkSurface.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "../common/interop.hh"
#include "interop.hh"
#include "DCompLibrary.h"

#include "ganesh/d3d/GrD3DTypes.h"
Expand Down
1 change: 0 additions & 1 deletion skiko/src/awtMain/cpp/windows/exceptions_handler.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "exceptions_handler.h"
#include "../common/interop.hh"

const char *getDescription(DWORD code) {
switch (code) {
Expand Down

0 comments on commit 60f1df8

Please sign in to comment.