blob: a21c38ce3101e3a81a70b0d28f1b5acadcc4e158 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -04009#include "include/core/SkBlendMode.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040011#include "include/core/SkColor.h"
12#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkPoint.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040014#include "include/core/SkRefCnt.h"
15#include "include/core/SkSize.h"
16#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/core/SkVertices.h"
Hal Canary8a001442018-09-19 11:31:27 -040018
Ben Wagner7fde8e12019-05-01 17:28:53 -040019#include <stdint.h>
Ruiqi Maob609e6d2018-07-17 10:19:38 -040020
21using namespace skiagm;
22
23static const int kCellSize = 60;
24static const int kColumnSize = 36;
25
26static const int kBoneCount = 7;
Ruiqi Maoc97a3392018-08-15 10:44:19 -040027static const SkVertices::Bone kBones[] = {
28 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}, // SkMatrix::I()
29 {{ 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f }}, // SkMatrix::MakeTrans(10, 0)
30 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f }}, // SkMatrix::MakeTrans(0, 10)
31 {{ 1.0f, 0.0f, 0.0f, 1.0f, -10.0f, 0.0f }}, // SkMatrix::MakeTrans(-10, 0)
32 {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -10.0f }}, // SkMatrix::MakeTrans(0, -10)
33 {{ 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(0.5)
34 {{ 1.5f, 0.0f, 0.0f, 1.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(1.5)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040035};
36
37static const int kVertexCount = 4;
38static const SkPoint kPositions[] = {
39 { 0, 0 },
40 { 0, 30 },
41 { 30, 30 },
42 { 30, 0 },
43};
44static const SkColor kColors[] = {
45 0xFFFF0000,
46 0xFF00FF00,
47 0xFF0000FF,
48 0xFFFFFF00,
49};
50static const SkVertices::BoneIndices kBoneIndices[] = {
51 {{ 1, 0, 0, 0 }},
52 {{ 2, 1, 0, 0 }},
53 {{ 3, 2, 1, 0 }},
54 {{ 4, 3, 2, 1 }},
55};
56static const SkVertices::BoneWeights kBoneWeights[] = {
57 {{ 1.0f, 0.0f, 0.0f, 0.0f }},
58 {{ 0.5f, 0.5f, 0.0f, 0.0f }},
59 {{ 0.34f, 0.33f, 0.33f, 0.0f }},
60 {{ 0.25f, 0.25f, 0.25f, 0.25f }},
61};
62
63static const int kIndexCount = 6;
64static const uint16_t kIndices[] = {
65 0, 1, 2,
66 2, 3, 0,
67};
68
Ruiqi Maoc97a3392018-08-15 10:44:19 -040069// Swap two SkVertices::Bone pointers in place.
70static void swap(const SkVertices::Bone** x, const SkVertices::Bone** y) {
71 const SkVertices::Bone* temp = *x;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040072 *x = *y;
73 *y = temp;
74}
75
76class SkinningGM : public GM {
77
78public:
Ruiqi Mao363402d2018-07-18 10:53:44 -040079 SkinningGM(bool deformUsingCPU, bool cache)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040080 : fPaint()
81 , fVertices(nullptr)
82 , fDeformUsingCPU(deformUsingCPU)
Ruiqi Mao363402d2018-07-18 10:53:44 -040083 , fCache(cache)
Ruiqi Maob609e6d2018-07-17 10:19:38 -040084 {}
85
86protected:
87 bool runAsBench() const override {
88 return true;
89 }
90
91 SkString onShortName() override {
92 SkString name("skinning");
93 if (fDeformUsingCPU) {
94 name.append("_cpu");
95 }
Ruiqi Mao363402d2018-07-18 10:53:44 -040096 if (fCache) {
97 name.append("_cached");
98 }
Ruiqi Maob609e6d2018-07-17 10:19:38 -040099 return name;
100 }
101
102 SkISize onISize() override {
103 return SkISize::Make(2400, 2400);
104 }
105
106 void onOnceBeforeDraw() override {
107 fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
108 kVertexCount,
109 kPositions,
110 nullptr,
111 kColors,
112 kBoneIndices,
113 kBoneWeights,
114 kIndexCount,
115 kIndices,
Ruiqi Mao363402d2018-07-18 10:53:44 -0400116 !fCache);
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400117 }
118
119 void onDraw(SkCanvas* canvas) override {
120 // Set the initial position.
121 int xpos = kCellSize;
122 int ypos = kCellSize;
123
124 // Create the mutable set of bones.
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400125 const SkVertices::Bone* bones[kBoneCount];
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400126 for (int i = 0; i < kBoneCount; i ++) {
127 bones[i] = &kBones[i];
128 }
129
130 // Draw the vertices.
131 drawPermutations(canvas, xpos, ypos, bones, 1);
132 }
133
134private:
135 void drawPermutations(SkCanvas* canvas,
136 int& xpos,
137 int& ypos,
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400138 const SkVertices::Bone** bones,
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400139 int start) {
140 if (start == kBoneCount) {
141 // Reached the end of the permutations, so draw.
142 canvas->save();
143
144 // Copy the bones.
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400145 SkVertices::Bone copiedBones[kBoneCount];
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400146 for (int i = 0; i < kBoneCount; i ++) {
147 copiedBones[i] = *bones[i];
148 }
149
150 // Set the position.
151 canvas->translate(xpos, ypos);
152
153 // Draw the vertices.
154 if (fDeformUsingCPU) {
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400155 // Apply the bones.
156 sk_sp<SkVertices> vertices = fVertices->applyBones(copiedBones,
157 kBoneCount);
158
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400159 // Deform with CPU.
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400160 canvas->drawVertices(vertices.get(),
161 SkBlendMode::kSrc,
162 fPaint);
163 } else {
164 // Deform with GPU.
165 canvas->drawVertices(fVertices.get(),
166 copiedBones,
167 kBoneCount,
168 SkBlendMode::kSrc,
169 fPaint);
170 }
171
172 canvas->restore();
173
174 // Get a new position to draw the vertices.
175 xpos += kCellSize;
176 if (xpos > kCellSize * kColumnSize) {
177 xpos = kCellSize;
178 ypos += kCellSize;
179 }
180
181 return;
182 }
183
184 // Find all possible permutations within the given range.
185 for (int i = start; i < kBoneCount; i ++) {
186 // Swap the start and i-th elements.
187 swap(bones + start, bones + i);
188
189 // Find permutations of the sub array.
190 drawPermutations(canvas, xpos, ypos, bones, start + 1);
191
192 // Swap the elements back.
193 swap(bones + i, bones + start);
194 }
195 }
196
197private:
198 SkPaint fPaint;
199 sk_sp<SkVertices> fVertices;
200 bool fDeformUsingCPU;
Ruiqi Mao363402d2018-07-18 10:53:44 -0400201 bool fCache;
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400202
203 typedef GM INHERITED;
204};
205
206/////////////////////////////////////////////////////////////////////////////////////
207
Ruiqi Mao363402d2018-07-18 10:53:44 -0400208DEF_GM(return new SkinningGM(true, true);)
209DEF_GM(return new SkinningGM(false, true);)
210DEF_GM(return new SkinningGM(true, false);)
211DEF_GM(return new SkinningGM(false, false);)