PatchBench.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Copyright 2014 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. #include "bench/Benchmark.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkPaint.h"
  10. #include "include/core/SkString.h"
  11. #include "include/effects/SkGradientShader.h"
  12. #include "src/utils/SkPatchUtils.h"
  13. /**
  14. * This bench measures the rendering time of the call SkCanvas::drawPatch with different types of
  15. * input patches (regular case, with loops, a square, with a big difference between "parallel"
  16. * sides). This bench also tests the different combination of optional parameters for the function
  17. * (passing texture coordinates and colors, only textures coordinates, only colors or none).
  18. * Finally, it applies a scale to test if the size affects the rendering time.
  19. */
  20. class PatchBench : public Benchmark {
  21. public:
  22. enum VertexMode {
  23. kNone_VertexMode,
  24. kColors_VertexMode,
  25. kTexCoords_VertexMode,
  26. kBoth_VertexMode
  27. };
  28. PatchBench(SkPoint scale, VertexMode vertexMode)
  29. : fScale(scale)
  30. , fVertexMode(vertexMode) { }
  31. // to add name of specific class override this method
  32. virtual void appendName(SkString* name) {
  33. name->append("normal");
  34. }
  35. // to make other type of patches override this method
  36. virtual void setCubics() {
  37. const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
  38. //top points
  39. {100,100},{150,50},{250,150}, {300,100},
  40. //right points
  41. {350, 150},{250,200},
  42. //bottom points
  43. {300,300},{250,250},{150,350},{100,300},
  44. //left points
  45. {50,250},{150,50}
  46. };
  47. memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
  48. }
  49. virtual void setColors() {
  50. const SkColor colors[SkPatchUtils::kNumCorners] = {
  51. SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
  52. };
  53. memcpy(fColors, colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
  54. }
  55. virtual void setTexCoords() {
  56. const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
  57. {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f,1.0f}, {0.0f, 1.0f}
  58. };
  59. memcpy(fTexCoords, texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
  60. }
  61. // override this method to change the shader
  62. virtual sk_sp<SkShader> createShader() {
  63. const SkColor colors[] = {
  64. SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
  65. SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
  66. };
  67. const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } };
  68. return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
  69. SkTileMode::kMirror);
  70. }
  71. protected:
  72. const char* onGetName() override {
  73. SkString vertexMode;
  74. switch (fVertexMode) {
  75. case kNone_VertexMode:
  76. vertexMode.set("meshlines");
  77. break;
  78. case kColors_VertexMode:
  79. vertexMode.set("colors");
  80. break;
  81. case kTexCoords_VertexMode:
  82. vertexMode.set("texs");
  83. break;
  84. case kBoth_VertexMode:
  85. vertexMode.set("colors_texs");
  86. break;
  87. default:
  88. break;
  89. }
  90. SkString type;
  91. this->appendName(&type);
  92. fName.printf("patch_%s_%s_%fx%f", type.c_str(), vertexMode.c_str(),
  93. fScale.x(), fScale.y());
  94. return fName.c_str();
  95. }
  96. void onDelayedSetup() override {
  97. this->setCubics();
  98. this->setColors();
  99. this->setTexCoords();
  100. this->setupPaint(&fPaint);
  101. switch (fVertexMode) {
  102. case kTexCoords_VertexMode:
  103. case kBoth_VertexMode:
  104. fPaint.setShader(this->createShader());
  105. break;
  106. default:
  107. fPaint.setShader(nullptr);
  108. break;
  109. }
  110. }
  111. void onDraw(int loops, SkCanvas* canvas) override {
  112. canvas->scale(fScale.x(), fScale.y());
  113. for (int i = 0; i < loops; i++) {
  114. switch (fVertexMode) {
  115. case kNone_VertexMode:
  116. canvas->drawPatch(fCubics, nullptr, nullptr, fPaint);
  117. break;
  118. case kColors_VertexMode:
  119. canvas->drawPatch(fCubics, fColors, nullptr, fPaint);
  120. break;
  121. case kTexCoords_VertexMode:
  122. canvas->drawPatch(fCubics, nullptr, fTexCoords, fPaint);
  123. break;
  124. case kBoth_VertexMode:
  125. canvas->drawPatch(fCubics, fColors, fTexCoords, fPaint);
  126. break;
  127. default:
  128. break;
  129. }
  130. }
  131. }
  132. SkPaint fPaint;
  133. SkString fName;
  134. SkVector fScale;
  135. SkPoint fCubics[12];
  136. SkPoint fTexCoords[4];
  137. SkColor fColors[4];
  138. VertexMode fVertexMode;
  139. typedef Benchmark INHERITED;
  140. };
  141. class SquarePatchBench : public PatchBench {
  142. public:
  143. SquarePatchBench(SkPoint scale, VertexMode vertexMode)
  144. : INHERITED(scale, vertexMode) { }
  145. void appendName(SkString* name) override {
  146. name->append("square");
  147. }
  148. void setCubics() override {
  149. const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
  150. //top points
  151. {100,100},{150,100},{250,100}, {300,100},
  152. //right points
  153. {300, 150},{300,250},
  154. //bottom points
  155. {300,300},{250,300},{150,300},{100,300},
  156. //left points
  157. {100,250},{100,150}
  158. };
  159. memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
  160. }
  161. private:
  162. typedef PatchBench INHERITED;
  163. };
  164. class LODDiffPatchBench : public PatchBench {
  165. public:
  166. LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
  167. : INHERITED(scale, vertexMode) { }
  168. void appendName(SkString* name) override {
  169. name->append("LOD_Diff");
  170. }
  171. void setCubics() override {
  172. const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
  173. //top points
  174. {100,175},{150,100},{250,100}, {300,0},
  175. //right points
  176. {300, 150},{300,250},
  177. //bottom points
  178. {300,400},{250,300},{150,300},{100,225},
  179. //left points
  180. {100,215},{100,185}
  181. };
  182. memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
  183. }
  184. private:
  185. typedef PatchBench INHERITED;
  186. };
  187. class LoopPatchBench : public PatchBench {
  188. public:
  189. LoopPatchBench(SkPoint scale, VertexMode vertexMode)
  190. : INHERITED(scale, vertexMode) { }
  191. void appendName(SkString* name) override {
  192. name->append("loop");
  193. }
  194. void setCubics() override {
  195. const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
  196. //top points
  197. {100,100},{300,200},{100,200}, {300,100},
  198. //right points
  199. {380, 400},{380,0},
  200. //bottom points
  201. {300,300},{250,250},{30,200},{100,300},
  202. //left points
  203. {140,325},{150,150}
  204. };
  205. memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
  206. }
  207. private:
  208. typedef PatchBench INHERITED;
  209. };
  210. ///////////////////////////////////////////////////////////////////////////////
  211. DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kNone_VertexMode); )
  212. DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kColors_VertexMode); )
  213. DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kTexCoords_VertexMode); )
  214. DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kBoth_VertexMode); )
  215. DEF_BENCH( return new PatchBench(SkVector::Make(1.f, 1.0f), PatchBench::kNone_VertexMode); )
  216. DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kColors_VertexMode); )
  217. DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kTexCoords_VertexMode); )
  218. DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kBoth_VertexMode); )
  219. DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kNone_VertexMode); )
  220. DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kColors_VertexMode); )
  221. DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kTexCoords_VertexMode); )
  222. DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kBoth_VertexMode); )
  223. DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
  224. PatchBench::kNone_VertexMode); )
  225. DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
  226. PatchBench::kColors_VertexMode); )
  227. DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
  228. PatchBench::kTexCoords_VertexMode); )
  229. DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
  230. PatchBench::kBoth_VertexMode); )
  231. DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.f, 1.0f),
  232. PatchBench::kNone_VertexMode); )
  233. DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
  234. PatchBench::kColors_VertexMode); )
  235. DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
  236. PatchBench::kTexCoords_VertexMode); )
  237. DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
  238. PatchBench::kBoth_VertexMode); )
  239. DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
  240. PatchBench::kNone_VertexMode); )
  241. DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
  242. PatchBench::kColors_VertexMode); )
  243. DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
  244. PatchBench::kTexCoords_VertexMode); )
  245. DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
  246. PatchBench::kBoth_VertexMode); )
  247. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
  248. PatchBench::kNone_VertexMode); )
  249. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
  250. PatchBench::kColors_VertexMode); )
  251. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
  252. PatchBench::kTexCoords_VertexMode); )
  253. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
  254. PatchBench::kBoth_VertexMode); )
  255. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.f, 1.0f),
  256. PatchBench::kNone_VertexMode); )
  257. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
  258. PatchBench::kColors_VertexMode); )
  259. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
  260. PatchBench::kTexCoords_VertexMode); )
  261. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
  262. PatchBench::kBoth_VertexMode); )
  263. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
  264. PatchBench::kNone_VertexMode); )
  265. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
  266. PatchBench::kColors_VertexMode); )
  267. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
  268. PatchBench::kTexCoords_VertexMode); )
  269. DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
  270. PatchBench::kBoth_VertexMode); )
  271. DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
  272. PatchBench::kNone_VertexMode); )
  273. DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
  274. PatchBench::kColors_VertexMode); )
  275. DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
  276. PatchBench::kTexCoords_VertexMode); )
  277. DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
  278. PatchBench::kBoth_VertexMode); )
  279. DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.f, 1.0f),
  280. PatchBench::kNone_VertexMode); )
  281. DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
  282. PatchBench::kColors_VertexMode); )
  283. DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
  284. PatchBench::kTexCoords_VertexMode); )
  285. DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
  286. PatchBench::kBoth_VertexMode); )
  287. DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
  288. PatchBench::kNone_VertexMode); )
  289. DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
  290. PatchBench::kColors_VertexMode); )
  291. DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
  292. PatchBench::kTexCoords_VertexMode); )
  293. DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
  294. PatchBench::kBoth_VertexMode); )
  295. //////////////////////////////////////////////
  296. #include "src/utils/SkPatchUtils.h"
  297. class PatchUtilsBench : public Benchmark {
  298. SkString fName;
  299. const bool fLinearInterp;
  300. public:
  301. PatchUtilsBench(bool linearInterp) : fLinearInterp(linearInterp) {
  302. fName.printf("patchutils_%s", linearInterp ? "linear" : "legacy");
  303. }
  304. const char* onGetName() override { return fName.c_str(); }
  305. bool isSuitableFor(Backend backend) override {
  306. return backend == kNonRendering_Backend;
  307. }
  308. void onDraw(int loops, SkCanvas*) override {
  309. const SkColor colors[] = { 0xFF000000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 };
  310. const SkPoint pts[] = {
  311. { 0, 0 }, { 10, 0 }, { 20, 0 }, { 30, 0 },
  312. { 30,10}, { 30,20 }, { 30,30 }, { 20,30 },
  313. { 10,30}, { 0, 30 }, { 0, 20 }, { 0, 10 },
  314. };
  315. const SkPoint tex[] = {
  316. { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 },
  317. };
  318. auto cs = fLinearInterp ? SkColorSpace::MakeSRGBLinear() : nullptr;
  319. for (int i = 0; i < 100*loops; ++i) {
  320. SkPatchUtils::MakeVertices(pts, colors, tex, 20, 20, cs.get());
  321. }
  322. }
  323. };
  324. DEF_BENCH( return new PatchUtilsBench(false); )
  325. DEF_BENCH( return new PatchUtilsBench(true); )