From 7e5598a004d0aceb630707053566bee523feea66 Mon Sep 17 00:00:00 2001 From: dandov Date: Fri, 15 Aug 2014 13:30:47 -0700 Subject: [PATCH] Added bench for grid of patches. It is on top of my previous cl to fix the mem leaks of the regular patch bench. NOTREECHECKS=true BUG=skia: R=egdaniel@google.com, bsalomon@google.com Author: dandov@google.com Review URL: https://codereview.chromium.org/470543004 --- bench/PatchBench.cpp | 30 ++--- bench/PatchGridBench.cpp | 259 ++++++++++++++++++++++++++++++++++++++ gyp/bench.gypi | 1 + src/utils/SkPatchGrid.cpp | 15 +-- 4 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 bench/PatchGridBench.cpp diff --git a/bench/PatchBench.cpp b/bench/PatchBench.cpp index 8ce80c4bc5..744141a879 100644 --- a/bench/PatchBench.cpp +++ b/bench/PatchBench.cpp @@ -5,16 +5,19 @@ * found in the LICENSE file. */ #include "Benchmark.h" -#include "SkBitmap.h" #include "SkCanvas.h" -#include "SkColorPriv.h" #include "SkGradientShader.h" #include "SkPaint.h" #include "SkPatchUtils.h" -#include "SkRandom.h" -#include "SkShader.h" #include "SkString.h" -#include "SkTArray.h" + +/** + * This bench measures the rendering time of the call SkCanvas::drawPatch with different types of + * input patches (regular case, with loops, a square, with a big difference between "parallel" + * sides). This bench also tests the different combination of optional parameters for the function + * (passing texture coordinates and colors, only textures coordinates, only colors or none). + * Finally, it applies a scale to test if the size affects the rendering time. + */ class PatchBench : public Benchmark { @@ -92,7 +95,7 @@ protected: vertexMode.set("texs"); break; case kBoth_VertexMode: - vertexMode.set("colors&texs"); + vertexMode.set("colors_texs"); break; default: break; @@ -104,12 +107,7 @@ protected: return fName.c_str(); } - virtual void preDraw() { - - } - - virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { - + virtual void onPreDraw() SK_OVERRIDE { this->setCubics(); this->setColors(); this->setTexCoords(); @@ -123,7 +121,9 @@ protected: fPaint.setShader(NULL); break; } + } + virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { canvas->scale(fScale.x(), fScale.y()); for (int i = 0; i < loops; i++) { switch (fVertexMode) { @@ -165,7 +165,7 @@ public: name->append("square"); } - virtual void setCubics() { + virtual void setCubics() SK_OVERRIDE { const SkPoint points[SkPatchUtils::kNumCtrlPts] = { //top points {100,100},{150,100},{250,100}, {300,100}, @@ -191,7 +191,7 @@ public: name->append("LOD_Diff"); } - virtual void setCubics() { + virtual void setCubics() SK_OVERRIDE { const SkPoint points[SkPatchUtils::kNumCtrlPts] = { //top points {100,175},{150,100},{250,100}, {300,0}, @@ -217,7 +217,7 @@ public: name->append("loop"); } - virtual void setCubics() { + virtual void setCubics() SK_OVERRIDE { const SkPoint points[SkPatchUtils::kNumCtrlPts] = { //top points {100,100},{300,200},{100,200}, {300,100}, diff --git a/bench/PatchGridBench.cpp b/bench/PatchGridBench.cpp new file mode 100644 index 0000000000..c250781893 --- /dev/null +++ b/bench/PatchGridBench.cpp @@ -0,0 +1,259 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkCanvas.h" +#include "SkGradientShader.h" +#include "SkPaint.h" +#include "SkPatchGrid.h" +#include "SkString.h" + + /** + * This bench measures the rendering time of a gridof patches. + * This bench also tests the different combination of optional parameters for the function + * (passing texture coordinates and colors, only textures coordinates, only colors or none). + * Finally, it also has 3 possible sizes small, medium and big to test if the size of the patches + * in the grid affects time. + */ + +class PatchGridBench : public Benchmark { + +public: + + enum Size { + kSmall_Size, + kMedium_Size, + kBig_Size + }; + + enum VertexMode { + kNone_VertexMode, + kColors_VertexMode, + kTexCoords_VertexMode, + kBoth_VertexMode + }; + + PatchGridBench(Size size, VertexMode vertexMode) + : fVertexMode(vertexMode) + , fSize(size) { } + + void setScale(SkCanvas* canvas){ + switch (fSize) { + case kSmall_Size: + canvas->scale(0.1f, 0.1f); + break; + case kMedium_Size: + canvas->scale(1.0f, 1.0f); + break; + case kBig_Size: + canvas->scale(3.0f, 3.0f); + break; + } + } + + void setGrid() { + SkPoint vertices[4][5] = { + {{50,50}, {150,50}, {250,50},{350,50},{450,50}}, + {{50,150}, {120,120}, {250,150},{350,150},{450,150}}, + {{50,250}, {150,250}, {250,250},{350,250},{450,250}}, + {{100,300}, {150,350}, {250,350},{350,350},{450,350}} + }; + + SkColor cornerColors[4][5] = { + {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, + {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, + {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, + {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, + }; + + SkPoint texCoords[4][5] = { + {{0.0f,0.0f}, {1.0f,0.0f}, {2.0f,0.0f}, {3.0f,0.0f}, {4.0f,0.0f}}, + {{0.0f,1.0f}, {1.0f,1.0f}, {2.0f,1.0f}, {3.0f,1.0f}, {4.0f,1.0f}}, + {{0.0f,2.0f}, {1.0f,2.0f}, {2.0f,2.0f}, {3.0f,2.0f}, {4.0f,2.0f}}, + {{0.0f,3.0f}, {1.0f,3.0f}, {2.0f,3.0f}, {3.0f,3.0f}, {4.0f,3.0f}}, + }; + + SkPoint hrzCtrl[4][8] = { + {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}}, + {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}}, + {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}}, + {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}} + }; + + SkPoint vrtCtrl[6][5] = { + {{50,75},{150,75},{250,75},{350,75},{450,75}}, + {{50,125},{150,125},{250,125},{350,125},{450,125}}, + {{50,175},{150,175},{220,225},{350,175},{470,225}}, + {{50,225},{150,225},{220,175},{350,225},{470,155}}, + {{50,275},{150,275},{250,275},{350,275},{400,305}}, + {{50,325},{150,325},{250,325},{350,325},{450,325}} + }; + + static const int kRows = 3; + static const int kCols = 4; + + fGrid.reset(kRows, kCols, SkPatchGrid::kColors_VertexType, NULL); + for (int i = 0; i < kRows; i++) { + for (int j = 0; j < kCols; j++) { + SkPoint points[12]; + + //set corners + points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j]; + points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1]; + points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j]; + points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1]; + + points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2]; + points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1]; + points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2]; + points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1]; + + points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j]; + points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j]; + points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1]; + points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1]; + + SkColor colors[4]; + colors[0] = cornerColors[i][j]; + colors[1] = cornerColors[i][j + 1]; + colors[3] = cornerColors[i + 1][j]; + colors[2] = cornerColors[i + 1][j + 1]; + + SkPoint texs[4]; + texs[0] = texCoords[i][j]; + texs[1] = texCoords[i][j + 1]; + texs[3] = texCoords[i + 1][j]; + texs[2] = texCoords[i + 1][j + 1]; + + switch (fVertexMode) { + case kNone_VertexMode: + fGrid.setPatch(j, i, points, NULL, NULL); + break; + case kColors_VertexMode: + fGrid.setPatch(j, i, points, colors, NULL); + break; + case kTexCoords_VertexMode: + fGrid.setPatch(j, i, points, NULL, texs); + break; + case kBoth_VertexMode: + fGrid.setPatch(j, i, points, colors, texs); + break; + default: + break; + } + } + } + } + + // override this method to change the shader + SkShader* createShader() { + const SkColor colors[] = { + SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, + SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW, + }; + const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } }; + + return SkGradientShader::CreateLinear(pts, colors, NULL, + SK_ARRAY_COUNT(colors), + SkShader::kMirror_TileMode); + } + +protected: + virtual const char* onGetName() SK_OVERRIDE { + SkString vertexMode; + switch (fVertexMode) { + case kNone_VertexMode: + vertexMode.set("meshlines"); + break; + case kColors_VertexMode: + vertexMode.set("colors"); + break; + case kTexCoords_VertexMode: + vertexMode.set("texs"); + break; + case kBoth_VertexMode: + vertexMode.set("colors_texs"); + break; + default: + break; + } + + SkString size; + switch (fSize) { + case kSmall_Size: + size.set("small"); + break; + case kMedium_Size: + size.set("medium"); + break; + case kBig_Size: + size.set("big"); + break; + default: + break; + } + fName.printf("patch_grid_%s_%s", vertexMode.c_str(), size.c_str()); + return fName.c_str(); + } + + virtual void onPreDraw() SK_OVERRIDE { + this->setGrid(); + switch (fVertexMode) { + case kTexCoords_VertexMode: + case kBoth_VertexMode: + fPaint.setShader(createShader())->unref(); + break; + default: + fPaint.setShader(NULL); + break; + } + this->setupPaint(&fPaint); + } + + virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { + this->setScale(canvas); + for (int i = 0; i < loops; i++) { + fGrid.draw(canvas, fPaint); + } + } + + SkPaint fPaint; + SkString fName; + SkPatchGrid fGrid; + VertexMode fVertexMode; + Size fSize; + + typedef Benchmark INHERITED; +}; + + +/////////////////////////////////////////////////////////////////////////////// + +DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, + PatchGridBench::kNone_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, + PatchGridBench::kColors_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, + PatchGridBench::kTexCoords_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, + PatchGridBench::kBoth_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, + PatchGridBench::kNone_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, + PatchGridBench::kColors_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, + PatchGridBench::kTexCoords_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, + PatchGridBench::kBoth_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, + PatchGridBench::kNone_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, + PatchGridBench::kColors_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, + PatchGridBench::kTexCoords_VertexMode); ) +DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, + PatchGridBench::kBoth_VertexMode); ) diff --git a/gyp/bench.gypi b/gyp/bench.gypi index 30f0aa661c..92e0574f2b 100644 --- a/gyp/bench.gypi +++ b/gyp/bench.gypi @@ -70,6 +70,7 @@ '../bench/MorphologyBench.cpp', '../bench/MutexBench.cpp', '../bench/PatchBench.cpp', + '../bench/PatchGridBench.cpp', '../bench/PathBench.cpp', '../bench/PathIterBench.cpp', '../bench/PathUtilsBench.cpp', diff --git a/src/utils/SkPatchGrid.cpp b/src/utils/SkPatchGrid.cpp index b1fea57403..a0809f3594 100644 --- a/src/utils/SkPatchGrid.cpp +++ b/src/utils/SkPatchGrid.cpp @@ -174,13 +174,14 @@ void SkPatchGrid::draw(SkCanvas* canvas, SkPaint& paint) { SkColor colors[4]; this->getPatch(x, y, cubics, colors, texCoords); SkPatchUtils::VertexData data; - SkPatchUtils::getVertexData(&data, cubics, - fModeFlags & kColors_VertexType ? colors : NULL, - fModeFlags & kTexs_VertexType ? texCoords : NULL, - maxCols[x], maxRows[y]); - canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, - data.fPoints, data.fTexCoords, data.fColors, fXferMode, - data.fIndices, data.fIndexCount, paint); + if (SkPatchUtils::getVertexData(&data, cubics, + fModeFlags & kColors_VertexType ? colors : NULL, + fModeFlags & kTexs_VertexType ? texCoords : NULL, + maxCols[x], maxRows[y])) { + canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, + data.fPoints, data.fTexCoords, data.fColors, fXferMode, + data.fIndices, data.fIndexCount, paint); + } } } SkDELETE_ARRAY(maxCols);