skia学习记录

windows编译

  1. 需要有python3环境
  2. git代理配置:
1
2
git config --global http.proxy 127.0.0.1:55664
git config --global https.proxy 127.0.0.1:55664
  1. 安装depot_tools到某一目录
1
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

并配置depot_tools目录为环境变量

  1. 安装LLVM,如15.0.7。
  2. 下载skia源码,并切到一个chrome下分支
1
git clone https://skia.googlesource.com/skia.git
  1. 下载skia依赖库源码,跳转到别的分支编译,一直到 The changes made to environment variables only apply to the currently running shell instance...
1
2
3
cd skia
git checkout chrome/m125
python tools/git-sync-deps
  1. 下载 ninja
1
python bin/fetch-ninja
  1. PowerShell生成make文件(可选):
1
bin/gn gen out/debug --args/'clang_win=\"D:\LLVM\" cc=\"clang\" cxx=\"clang++\" extra_cflags=[\"/MTd\"] is_official_build=true is_debug=false skia_use_system_expat=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_system_harfbuzz=false skia_use_system_icu=false skia_use_icu=false'
  1. 编译静态库(可选):
1
ninja -C out/debug

用于验证所有步骤是否正确,成功则在debug目录下出现.lib文件

  1. PowerShell生成sln工程:
1
bin/gn gen build/sln --args'clang_win=\"D:\LLVM\"' --ide=vs

在skia中使用vertex shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
void HelloWorld::onPaint(SkSurface* surface) {
auto canvas = surface->getCanvas();
canvas->save();
// Clear background
canvas->clear(SK_ColorWHITE);

SkPaint paint;
paint.setColor(SK_ColorRED);

static constexpr auto kRect = SkRect::MakeLTRB(20, 20, 120, 120);
static constexpr auto kUV = SkRect::MakeLTRB(0, 0, 20, 20);

static constexpr ColorVertex kColorQuad[]{
{0, 0x00FFFF00, {kRect.left(), kUV.left(), kRect.top(), kUV.top()}},
{0, 0x00FFFFFF, {kRect.right(), kUV.right(), kRect.top(), kUV.top()}},
{0, 0xFFFF00FF, {kRect.left(), kUV.left(), kRect.bottom(), kUV.bottom()}},
{0, 0xFFFFFF00, {kRect.right(), kUV.right(), kRect.bottom(), kUV.bottom()}},
};
static constexpr ColorVertex kColorIndexedQuad[]{
{0, 0x00FFFF00, {kRect.left(), kUV.left(), kRect.top(), kUV.top()}},
{0, 0x00000000, {100.f, 0.f, 100.f, 5.f}}, // unused
{0, 0x00FFFFFF, {kRect.right(), kUV.right(), kRect.top(), kUV.top()}},
{0, 0x00000000, {200.f, 10.f, 200.f, 10.f}}, // unused
{0, 0xFFFF00FF, {kRect.left(), kUV.left(), kRect.bottom(), kUV.bottom()}},
{0, 0xFFFFFF00, {kRect.right(), kUV.right(), kRect.bottom(), kUV.bottom()}},
};
static constexpr size_t kColorIndexedOffset = 2 * sizeof(ColorVertex);
static constexpr uint16_t kIndices[]{0, 2, 4, 2, 5, 4};
static constexpr size_t kIndexOffset = 6;

sk_sp<SkMesh::VertexBuffer> fColorVB =
SkMeshes::MakeVertexBuffer(kColorQuad, sizeof(kColorQuad));

auto data = SkData::MakeUninitialized(sizeof(kColorIndexedQuad) + kColorIndexedOffset);
sk_sp<SkMesh::VertexBuffer> fColorIndexedVB =
SkMeshes::MakeVertexBuffer(data->data(), data->size());

static constexpr SkColor kColors[] = {SK_ColorTRANSPARENT, SK_ColorWHITE};

static const Attribute kAttributes[]{
{Attribute::Type::kFloat4, 8, SkString{"xuyv"}},
{Attribute::Type::kUByte4_unorm, 4, SkString{"brag"}},
};
static const Varying kVaryings[]{
{Varying::Type::kHalf4, SkString{"color"}},
{Varying::Type::kFloat2, SkString{"uv"}},
};
static constexpr char kVS[] = R"(
half4 unswizzle_color(half4 color) { return color.garb; }

Varyings main(const in Attributes attributes) {
Varyings varyings;
varyings.color = unswizzle_color(attributes.brag);
varyings.uv = attributes.xuyv.yw;
varyings.position = attributes.xuyv.xz;
varyings.position.x += 500.0;
return varyings;
}
)";
static constexpr char kFS[] = R"(
uniform colorFilter filter;

float2 main(const in Varyings varyings, out float4 color) {
color = filter.eval(varyings.color);
return varyings.uv;
}
)";
auto [spec, error] = SkMeshSpecification::Make(
kAttributes, sizeof(ColorVertex), kVaryings, SkString(kVS), SkString(kFS));

if (!spec) {
SkDebugf("%s\n", error.c_str());
}
sk_sp<SkMeshSpecification> fSpecWithColor = std::move(spec);

sk_sp<SkShader> fShader =
SkGradientShader::MakeRadial({10, 10}, 3, kColors, nullptr, 2, SkTileMode::kMirror);
SkRuntimeEffect::ChildPtr nullChild[1] = {};
SkMesh::Result result = SkMesh::Make(fSpecWithColor,
SkMesh::Mode::kTriangleStrip,
fColorVB,
/*vertexCount=*/4,
/*vertexOffset=*/0,
/*uniforms=*/nullptr,
/*children=*/nullChild,
kRect);

if (!result.mesh.isValid()) {
SkDebugf("Mesh creation failed: %s\n", result.error.c_str());
}

paint.setAlpha(0x40);
canvas->drawMesh(result.mesh, SkBlender::Mode(SkBlendMode::kDst), paint);
canvas->translate(0, 150);
canvas->restore();
}