blob: 44a1b131e4a0a4f088d5d9ce0dc1e072c37c79f6 [file] [log] [blame]
Ruiqi Maob609e6d2018-07-17 10:19:38 -04001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkVertices.h"
11#include "SkPoint.h"
12#include <iostream>
13#include <vector>
14
15using namespace skiagm;
16
17static const int kCellSize = 60;
18static const int kColumnSize = 36;
19
20static const int kBoneCount = 7;
Ruiqi Maoc97a3392018-08-15 10:44:19 -040021static const SkVertices::Bone kBones[] = {
22 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}, // SkMatrix::I()
23 {{ 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f }}, // SkMatrix::MakeTrans(10, 0)
24 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f }}, // SkMatrix::MakeTrans(0, 10)
25 {{ 1.0f, 0.0f, 0.0f, 1.0f, -10.0f, 0.0f }}, // SkMatrix::MakeTrans(-10, 0)
26 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -10.0f }}, // SkMatrix::MakeTrans(0, -10)
27 {{ 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(0.5)
28 {{ 1.5f, 0.0f, 0.0f, 1.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(1.5)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040029};
30
31static const int kVertexCount = 4;
32static const SkPoint kPositions[] = {
33 { 0, 0 },
34 { 0, 30 },
35 { 30, 30 },
36 { 30, 0 },
37};
38static const SkColor kColors[] = {
39 0xFFFF0000,
40 0xFF00FF00,
41 0xFF0000FF,
42 0xFFFFFF00,
43};
44static const SkVertices::BoneIndices kBoneIndices[] = {
45 {{ 1, 0, 0, 0 }},
46 {{ 2, 1, 0, 0 }},
47 {{ 3, 2, 1, 0 }},
48 {{ 4, 3, 2, 1 }},
49};
50static const SkVertices::BoneWeights kBoneWeights[] = {
51 {{ 1.0f, 0.0f, 0.0f, 0.0f }},
52 {{ 0.5f, 0.5f, 0.0f, 0.0f }},
53 {{ 0.34f, 0.33f, 0.33f, 0.0f }},
54 {{ 0.25f, 0.25f, 0.25f, 0.25f }},
55};
56
57static const int kIndexCount = 6;
58static const uint16_t kIndices[] = {
59 0, 1, 2,
60 2, 3, 0,
61};
62
Ruiqi Maoc97a3392018-08-15 10:44:19 -040063// Swap two SkVertices::Bone pointers in place.
64static void swap(const SkVertices::Bone** x, const SkVertices::Bone** y) {
65 const SkVertices::Bone* temp = *x;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040066 *x = *y;
67 *y = temp;
68}
69
70class SkinningGM : public GM {
71
72public:
Ruiqi Mao363402d2018-07-18 10:53:44 -040073 SkinningGM(bool deformUsingCPU, bool cache)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040074 : fPaint()
75 , fVertices(nullptr)
76 , fDeformUsingCPU(deformUsingCPU)
Ruiqi Mao363402d2018-07-18 10:53:44 -040077 , fCache(cache)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040078 {}
79
80protected:
81 bool runAsBench() const override {
82 return true;
83 }
84
85 SkString onShortName() override {
86 SkString name("skinning");
87 if (fDeformUsingCPU) {
88 name.append("_cpu");
89 }
Ruiqi Mao363402d2018-07-18 10:53:44 -040090 if (fCache) {
91 name.append("_cached");
92 }
Ruiqi Maob609e6d2018-07-17 10:19:38 -040093 return name;
94 }
95
96 SkISize onISize() override {
97 return SkISize::Make(2400, 2400);
98 }
99
100 void onOnceBeforeDraw() override {
101 fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
102 kVertexCount,
103 kPositions,
104 nullptr,
105 kColors,
106 kBoneIndices,
107 kBoneWeights,
108 kIndexCount,
109 kIndices,
Ruiqi Mao363402d2018-07-18 10:53:44 -0400110 !fCache);
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400111 }
112
113 void onDraw(SkCanvas* canvas) override {
114 // Set the initial position.
115 int xpos = kCellSize;
116 int ypos = kCellSize;
117
118 // Create the mutable set of bones.
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400119 const SkVertices::Bone* bones[kBoneCount];
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400120 for (int i = 0; i < kBoneCount; i ++) {
121 bones[i] = &kBones[i];
122 }
123
124 // Draw the vertices.
125 drawPermutations(canvas, xpos, ypos, bones, 1);
126 }
127
128private:
129 void drawPermutations(SkCanvas* canvas,
130 int& xpos,
131 int& ypos,
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400132 const SkVertices::Bone** bones,
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400133 int start) {
134 if (start == kBoneCount) {
135 // Reached the end of the permutations, so draw.
136 canvas->save();
137
138 // Copy the bones.
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400139 SkVertices::Bone copiedBones[kBoneCount];
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400140 for (int i = 0; i < kBoneCount; i ++) {
141 copiedBones[i] = *bones[i];
142 }
143
144 // Set the position.
145 canvas->translate(xpos, ypos);
146
147 // Draw the vertices.
148 if (fDeformUsingCPU) {
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400149 // Apply the bones.
150 sk_sp<SkVertices> vertices = fVertices->applyBones(copiedBones,
151 kBoneCount);
152
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400153 // Deform with CPU.
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400154 canvas->drawVertices(vertices.get(),
155 SkBlendMode::kSrc,
156 fPaint);
157 } else {
158 // Deform with GPU.
159 canvas->drawVertices(fVertices.get(),
160 copiedBones,
161 kBoneCount,
162 SkBlendMode::kSrc,
163 fPaint);
164 }
165
166 canvas->restore();
167
168 // Get a new position to draw the vertices.
169 xpos += kCellSize;
170 if (xpos > kCellSize * kColumnSize) {
171 xpos = kCellSize;
172 ypos += kCellSize;
173 }
174
175 return;
176 }
177
178 // Find all possible permutations within the given range.
179 for (int i = start; i < kBoneCount; i ++) {
180 // Swap the start and i-th elements.
181 swap(bones + start, bones + i);
182
183 // Find permutations of the sub array.
184 drawPermutations(canvas, xpos, ypos, bones, start + 1);
185
186 // Swap the elements back.
187 swap(bones + i, bones + start);
188 }
189 }
190
191private:
192 SkPaint fPaint;
193 sk_sp<SkVertices> fVertices;
194 bool fDeformUsingCPU;
Ruiqi Mao363402d2018-07-18 10:53:44 -0400195 bool fCache;
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400196
197 typedef GM INHERITED;
198};
199
200/////////////////////////////////////////////////////////////////////////////////////
201
Ruiqi Mao363402d2018-07-18 10:53:44 -0400202DEF_GM(return new SkinningGM(true, true);)
203DEF_GM(return new SkinningGM(false, true);)
204DEF_GM(return new SkinningGM(true, false);)
205DEF_GM(return new SkinningGM(false, false);)