skia2/bench/Matrix44Bench.cpp
Mike Reed 403c807971 Revert "Revert "Extend SkCanvas matrix stack to be 4x4, but with (basically) the same public API.""
The reason for the assert was breaking an assert, that if the CTM was scale/translate, that after
a preTranslate, it should still be that.

This is true... unless the new translate values are non-finite. In that case, we might turn a zero
into a NaN, (0 * non_finite --> nan), so we either have to require finite args (which we don't
at the moment) or we can't make this assert. This re-land removes that assert.

This reverts commit 268ed57d71.

Change-Id: I3c48a0aa17649351a246c1fbab5449f2d59aaf84
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/263023
Commit-Queue: Mike Reed <reed@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: Mike Reed <reed@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-01-08 16:13:51 +00:00

400 lines
9.7 KiB
C++

/*
* Copyright 2012 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/SkMatrix44.h"
#include "include/core/SkString.h"
#include "include/private/SkM44.h"
#include "include/utils/SkRandom.h"
class Matrix44Bench : public Benchmark {
SkString fName;
public:
Matrix44Bench(const char name[]) {
fName.printf("matrix44_%s", name);
}
bool isSuitableFor(Backend backend) override {
return backend == kNonRendering_Backend;
}
virtual void performTest() = 0;
protected:
virtual int mulLoopCount() const { return 1; }
const char* onGetName() override {
return fName.c_str();
}
void onDraw(int loops, SkCanvas*) override {
for (int i = 0; i < loops; i++) {
this->performTest();
}
}
private:
typedef Benchmark INHERITED;
};
class EqualsMatrix44Bench : public Matrix44Bench {
public:
EqualsMatrix44Bench()
: INHERITED("equals")
{
fM1.set(0, 0, 0);
fM2.set(3, 3, 0);
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
(void) (fM0 == fM1);
(void) (fM1 == fM2);
(void) (fM2 == fM0);
}
}
private:
SkMatrix44 fM0, fM1, fM2;
typedef Matrix44Bench INHERITED;
};
class SetIdentityMatrix44Bench : public Matrix44Bench {
public:
SetIdentityMatrix44Bench()
: INHERITED("setidentity")
{
double rowMajor[16] =
{ 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16};
mat.setRowMajord(rowMajor);
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
mat.setIdentity();
}
}
private:
SkMatrix44 mat;
typedef Matrix44Bench INHERITED;
};
class PreScaleMatrix44Bench : public Matrix44Bench {
public:
PreScaleMatrix44Bench()
: INHERITED("prescale")
{
fX = fY = fZ = SkDoubleToMScalar(1.5);
}
protected:
void performTest() override {
fM0.reset();
for (int i = 0; i < 10; ++i) {
fM0.preScale(fX, fY, fZ);
}
}
private:
SkMatrix44 fM0;
SkMScalar fX, fY, fZ;
typedef Matrix44Bench INHERITED;
};
class InvertMatrix44Bench : public Matrix44Bench {
public:
InvertMatrix44Bench()
: INHERITED("invert")
{
fM0.setDouble(0, 0, -1.1);
fM0.setDouble(0, 1, 2.1);
fM0.setDouble(0, 2, -3.1);
fM0.setDouble(0, 3, 4.1);
fM0.setDouble(1, 0, 5.1);
fM0.setDouble(1, 1, -6.1);
fM0.setDouble(1, 2, 7.1);
fM0.setDouble(1, 3, 8.1);
fM0.setDouble(2, 0, -9.1);
fM0.setDouble(2, 1, 10.1);
fM0.setDouble(2, 2, 11.1);
fM0.setDouble(2, 3, -12.1);
fM0.setDouble(3, 0, -13.1);
fM0.setDouble(3, 1, 14.1);
fM0.setDouble(3, 2, -15.1);
fM0.setDouble(3, 3, 16.1);
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
fM0.invert(&fM1);
}
}
private:
SkMatrix44 fM0, fM1;
typedef Matrix44Bench INHERITED;
};
class InvertAffineMatrix44Bench : public Matrix44Bench {
public:
InvertAffineMatrix44Bench()
: INHERITED("invertaffine")
{
fM0.setDouble(0, 0, -1.1);
fM0.setDouble(0, 1, 2.1);
fM0.setDouble(0, 2, -3.1);
fM0.setDouble(0, 3, 4.1);
fM0.setDouble(1, 0, 5.1);
fM0.setDouble(1, 1, -6.1);
fM0.setDouble(1, 2, 7.1);
fM0.setDouble(1, 3, 8.1);
fM0.setDouble(2, 0, -9.1);
fM0.setDouble(2, 1, 10.1);
fM0.setDouble(2, 2, 11.1);
fM0.setDouble(2, 3, -12.1);
// bottom row (perspective component) remains (0, 0, 0, 1).
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
fM0.invert(&fM1);
}
}
private:
SkMatrix44 fM0, fM1;
typedef Matrix44Bench INHERITED;
};
class InvertScaleTranslateMatrix44Bench : public Matrix44Bench {
public:
InvertScaleTranslateMatrix44Bench()
: INHERITED("invertscaletranslate")
{
fM0.setDouble(0, 0, -1.1);
fM0.setDouble(0, 3, 4.1);
fM0.setDouble(1, 1, -6.1);
fM0.setDouble(1, 3, 8.1);
fM0.setDouble(2, 2, 11.1);
fM0.setDouble(2, 3, -12.1);
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
fM0.invert(&fM1);
}
}
private:
SkMatrix44 fM0, fM1;
typedef Matrix44Bench INHERITED;
};
class InvertTranslateMatrix44Bench : public Matrix44Bench {
public:
InvertTranslateMatrix44Bench()
: INHERITED("inverttranslate")
{
fM0.setDouble(0, 3, 4.1);
fM0.setDouble(1, 3, 8.1);
fM0.setDouble(2, 3, -12.1);
}
protected:
void performTest() override {
for (int i = 0; i < 10; ++i) {
fM0.invert(&fM1);
}
}
private:
SkMatrix44 fM0, fM1;
typedef Matrix44Bench INHERITED;
};
class PostScaleMatrix44Bench : public Matrix44Bench {
public:
PostScaleMatrix44Bench()
: INHERITED("postscale")
{
fX = fY = fZ = SkDoubleToMScalar(1.5);
}
protected:
void performTest() override {
fM0.reset();
for (int i = 0; i < 10; ++i) {
fM0.postScale(fX, fY, fZ);
}
}
private:
SkMatrix44 fM0;
SkMScalar fX, fY, fZ;
typedef Matrix44Bench INHERITED;
};
class SetConcatMatrix44Bench : public Matrix44Bench {
public:
// SkMatrix44::setConcat() has a fast path for matrices that are at most scale+translate.
SetConcatMatrix44Bench(bool fastPath)
: INHERITED(fastPath ? "setconcat_fast" : "setconcat_general")
{
if (fastPath) {
const SkMScalar v = SkDoubleToMScalar(1.5);
fM1.setScale(v,v,v);
fM2.setTranslate(v,v,v);
} else {
SkRandom rand;
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
fM1.setFloat(x,y, rand.nextF());
fM2.setFloat(x,y, rand.nextF());
}}
}
}
protected:
void performTest() override {
fM0.reset(); // just to normalize this test with prescale/postscale
for (int i = 0; i < 10000; ++i) {
fM0.setConcat(fM1, fM2);
}
}
private:
SkMatrix44 fM0, fM1, fM2;
typedef Matrix44Bench INHERITED;
};
class GetTypeMatrix44Bench : public Matrix44Bench {
public:
GetTypeMatrix44Bench()
: INHERITED("gettype")
{}
protected:
// Putting random generation of the matrix inside performTest()
// would help us avoid anomalous runs, but takes up 25% or
// more of the function time.
void performTest() override {
for (int i = 0; i < 20; ++i) {
fMatrix.set(1, 2, 1); // to invalidate the type-cache
fMatrix.getType();
}
}
private:
SkMatrix44 fMatrix;
typedef Matrix44Bench INHERITED;
};
DEF_BENCH( return new SetIdentityMatrix44Bench(); )
DEF_BENCH( return new EqualsMatrix44Bench(); )
DEF_BENCH( return new PreScaleMatrix44Bench(); )
DEF_BENCH( return new PostScaleMatrix44Bench(); )
DEF_BENCH( return new InvertMatrix44Bench(); )
DEF_BENCH( return new InvertAffineMatrix44Bench(); )
DEF_BENCH( return new InvertScaleTranslateMatrix44Bench(); )
DEF_BENCH( return new InvertTranslateMatrix44Bench(); )
DEF_BENCH( return new SetConcatMatrix44Bench(true); )
DEF_BENCH( return new SetConcatMatrix44Bench(false); )
DEF_BENCH( return new GetTypeMatrix44Bench(); )
/////////////////////////////////////////////////////////////////////////////////////////////////
class M4Bench : public Benchmark {
SkString fName;
public:
M4Bench(const char name[]) {
fName.printf("m4_%s", name);
SkRandom rand;
float value[32];
for (auto& v : value) {
v = rand.nextF();
}
fM1.setColMajor(value + 0);
fM2.setColMajor(value + 16);
}
bool isSuitableFor(Backend backend) override {
return backend == kNonRendering_Backend;
}
virtual void performTest() = 0;
protected:
SkM44 fM0, fM1, fM2;
virtual int mulLoopCount() const { return 1; }
const char* onGetName() override {
return fName.c_str();
}
void onDraw(int loops, SkCanvas*) override {
for (int i = 0; i < loops; i++) {
this->performTest();
}
}
private:
typedef Benchmark INHERITED;
};
class M4NEQ : public M4Bench {
public:
M4NEQ() : INHERITED("neq") {}
protected:
void performTest() override {
for (int i = 0; i < 10000; ++i) {
fEQ = (fM2 == fM1); // should always be false
}
}
private:
bool fEQ;
typedef M4Bench INHERITED;
};
class M4EQ : public M4Bench {
public:
M4EQ() : INHERITED("eq") {}
protected:
void performTest() override {
fM2 = fM1;
for (int i = 0; i < 10000; ++i) {
fEQ = (fM2 == fM1); // should always be true
}
}
private:
bool fEQ;
typedef M4Bench INHERITED;
};
class M4Concat : public M4Bench {
public:
M4Concat() : INHERITED("op_concat") {}
protected:
void performTest() override {
for (int i = 0; i < 10000; ++i) {
fM0 = SkM44(fM1, fM2);
}
}
private:
typedef M4Bench INHERITED;
};
class M4SetConcat : public M4Bench {
public:
M4SetConcat() : INHERITED("set_concat") {}
protected:
void performTest() override {
for (int i = 0; i < 10000; ++i) {
fM0.setConcat(fM1, fM2);
}
}
private:
typedef M4Bench INHERITED;
};
DEF_BENCH( return new M4EQ(); )
DEF_BENCH( return new M4NEQ(); )
DEF_BENCH( return new M4Concat(); )
DEF_BENCH( return new M4SetConcat(); )