90ef83af20
Bug: skia:12662 Change-Id: Ic18220668a4f87e7340a53b3f191887a7a016a04 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473141 Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
363 lines
15 KiB
C++
363 lines
15 KiB
C++
/*
|
|
* 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 "bench/Benchmark.h"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/core/SkVertices.h"
|
|
#include "include/effects/SkGradientShader.h"
|
|
#include "src/utils/SkPatchUtils.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 {
|
|
|
|
public:
|
|
|
|
enum VertexMode {
|
|
kNone_VertexMode,
|
|
kColors_VertexMode,
|
|
kTexCoords_VertexMode,
|
|
kBoth_VertexMode
|
|
};
|
|
|
|
PatchBench(SkPoint scale, VertexMode vertexMode)
|
|
: fScale(scale)
|
|
, fVertexMode(vertexMode) { }
|
|
|
|
// to add name of specific class override this method
|
|
virtual void appendName(SkString* name) {
|
|
name->append("normal");
|
|
}
|
|
|
|
// to make other type of patches override this method
|
|
virtual void setCubics() {
|
|
const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
|
|
//top points
|
|
{100,100},{150,50},{250,150}, {300,100},
|
|
//right points
|
|
{350, 150},{250,200},
|
|
//bottom points
|
|
{300,300},{250,250},{150,350},{100,300},
|
|
//left points
|
|
{50,250},{150,50}
|
|
};
|
|
memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
|
|
}
|
|
|
|
virtual void setColors() {
|
|
const SkColor colors[SkPatchUtils::kNumCorners] = {
|
|
SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
|
|
};
|
|
memcpy(fColors, colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
|
|
}
|
|
|
|
virtual void setTexCoords() {
|
|
const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
|
|
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f,1.0f}, {0.0f, 1.0f}
|
|
};
|
|
memcpy(fTexCoords, texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
|
|
}
|
|
|
|
// override this method to change the shader
|
|
virtual sk_sp<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::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
|
|
SkTileMode::kMirror);
|
|
}
|
|
|
|
protected:
|
|
const char* onGetName() 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 type;
|
|
this->appendName(&type);
|
|
fName.printf("patch_%s_%s_%fx%f", type.c_str(), vertexMode.c_str(),
|
|
fScale.x(), fScale.y());
|
|
return fName.c_str();
|
|
}
|
|
|
|
void onDelayedSetup() override {
|
|
this->setCubics();
|
|
this->setColors();
|
|
this->setTexCoords();
|
|
this->setupPaint(&fPaint);
|
|
switch (fVertexMode) {
|
|
case kTexCoords_VertexMode:
|
|
case kBoth_VertexMode:
|
|
fPaint.setShader(this->createShader());
|
|
break;
|
|
default:
|
|
fPaint.setShader(nullptr);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas* canvas) override {
|
|
canvas->scale(fScale.x(), fScale.y());
|
|
for (int i = 0; i < loops; i++) {
|
|
switch (fVertexMode) {
|
|
case kNone_VertexMode:
|
|
canvas->drawPatch(fCubics, nullptr, nullptr, SkBlendMode::kModulate, fPaint);
|
|
break;
|
|
case kColors_VertexMode:
|
|
canvas->drawPatch(fCubics, fColors, nullptr, SkBlendMode::kModulate, fPaint);
|
|
break;
|
|
case kTexCoords_VertexMode:
|
|
canvas->drawPatch(fCubics, nullptr, fTexCoords, SkBlendMode::kModulate, fPaint);
|
|
break;
|
|
case kBoth_VertexMode:
|
|
canvas->drawPatch(fCubics, fColors, fTexCoords, SkBlendMode::kModulate, fPaint);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SkPaint fPaint;
|
|
SkString fName;
|
|
SkVector fScale;
|
|
SkPoint fCubics[12];
|
|
SkPoint fTexCoords[4];
|
|
SkColor fColors[4];
|
|
VertexMode fVertexMode;
|
|
|
|
using INHERITED = Benchmark;
|
|
};
|
|
|
|
class SquarePatchBench : public PatchBench {
|
|
public:
|
|
SquarePatchBench(SkPoint scale, VertexMode vertexMode)
|
|
: INHERITED(scale, vertexMode) { }
|
|
|
|
void appendName(SkString* name) override {
|
|
name->append("square");
|
|
}
|
|
|
|
void setCubics() override {
|
|
const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
|
|
//top points
|
|
{100,100},{150,100},{250,100}, {300,100},
|
|
//right points
|
|
{300, 150},{300,250},
|
|
//bottom points
|
|
{300,300},{250,300},{150,300},{100,300},
|
|
//left points
|
|
{100,250},{100,150}
|
|
};
|
|
memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
|
|
}
|
|
private:
|
|
using INHERITED = PatchBench;
|
|
};
|
|
|
|
class LODDiffPatchBench : public PatchBench {
|
|
public:
|
|
LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
|
|
: INHERITED(scale, vertexMode) { }
|
|
|
|
void appendName(SkString* name) override {
|
|
name->append("LOD_Diff");
|
|
}
|
|
|
|
void setCubics() override {
|
|
const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
|
|
//top points
|
|
{100,175},{150,100},{250,100}, {300,0},
|
|
//right points
|
|
{300, 150},{300,250},
|
|
//bottom points
|
|
{300,400},{250,300},{150,300},{100,225},
|
|
//left points
|
|
{100,215},{100,185}
|
|
};
|
|
memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
|
|
}
|
|
private:
|
|
using INHERITED = PatchBench;
|
|
};
|
|
|
|
class LoopPatchBench : public PatchBench {
|
|
public:
|
|
LoopPatchBench(SkPoint scale, VertexMode vertexMode)
|
|
: INHERITED(scale, vertexMode) { }
|
|
|
|
void appendName(SkString* name) override {
|
|
name->append("loop");
|
|
}
|
|
|
|
void setCubics() override {
|
|
const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
|
|
//top points
|
|
{100,100},{300,200},{100,200}, {300,100},
|
|
//right points
|
|
{380, 400},{380,0},
|
|
//bottom points
|
|
{300,300},{250,250},{30,200},{100,300},
|
|
//left points
|
|
{140,325},{150,150}
|
|
};
|
|
memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
|
|
}
|
|
private:
|
|
using INHERITED = PatchBench;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(1.f, 1.0f), PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kBoth_VertexMode); )
|
|
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.f, 1.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.f, 1.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.f, 1.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kNone_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kColors_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kTexCoords_VertexMode); )
|
|
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
|
|
PatchBench::kBoth_VertexMode); )
|
|
|
|
//////////////////////////////////////////////
|
|
#include "src/utils/SkPatchUtils.h"
|
|
|
|
class PatchUtilsBench : public Benchmark {
|
|
SkString fName;
|
|
const bool fLinearInterp;
|
|
public:
|
|
PatchUtilsBench(bool linearInterp) : fLinearInterp(linearInterp) {
|
|
fName.printf("patchutils_%s", linearInterp ? "linear" : "legacy");
|
|
}
|
|
|
|
const char* onGetName() override { return fName.c_str(); }
|
|
|
|
bool isSuitableFor(Backend backend) override {
|
|
return backend == kNonRendering_Backend;
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
const SkColor colors[] = { 0xFF000000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 };
|
|
const SkPoint pts[] = {
|
|
{ 0, 0 }, { 10, 0 }, { 20, 0 }, { 30, 0 },
|
|
{ 30,10}, { 30,20 }, { 30,30 }, { 20,30 },
|
|
{ 10,30}, { 0, 30 }, { 0, 20 }, { 0, 10 },
|
|
};
|
|
const SkPoint tex[] = {
|
|
{ 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 },
|
|
};
|
|
|
|
auto cs = fLinearInterp ? SkColorSpace::MakeSRGBLinear() : nullptr;
|
|
for (int i = 0; i < 100*loops; ++i) {
|
|
SkPatchUtils::MakeVertices(pts, colors, tex, 20, 20, cs.get());
|
|
}
|
|
}
|
|
};
|
|
DEF_BENCH( return new PatchUtilsBench(false); )
|
|
DEF_BENCH( return new PatchUtilsBench(true); )
|