c80ee456ad
This reverts commit 046c2b7d90
.
Reason for revert: need to update/guard flutter
Original change's description:
> move onto new factories for SkMatrix
>
> Just rename, no functional changes expected.
>
> Change-Id: Id77ab1cf6b1cab35087a7c56000750912cf47383
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290831
> Commit-Queue: Mike Reed <reed@google.com>
> Reviewed-by: Florin Malita <fmalita@chromium.org>
TBR=fmalita@chromium.org,reed@google.com
Change-Id: Ic74f177128913374b8c60b4df88f04cf72fbacb3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291359
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
203 lines
8.0 KiB
C++
203 lines
8.0 KiB
C++
/*
|
|
* Copyright 2020 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/gpu/GrContext.h"
|
|
#include "src/core/SkPathPriv.h"
|
|
#include "src/gpu/GrContextPriv.h"
|
|
#include "src/gpu/GrOpFlushState.h"
|
|
#include "src/gpu/tessellate/GrTessellatePathOp.h"
|
|
#include "src/gpu/tessellate/GrWangsFormula.h"
|
|
#include "tools/ToolUtils.h"
|
|
|
|
// This is the number of cubics in desk_chalkboard.skp. (There are no quadratics in the chalkboard.)
|
|
constexpr static int kNumCubicsInChalkboard = 47182;
|
|
|
|
static SkPath make_cubic_path() {
|
|
SkRandom rand;
|
|
SkPath path;
|
|
for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
|
|
float x = std::ldexp(rand.nextF(), (i % 18)) / 1e3f;
|
|
path.cubicTo(111.625f*x, 308.188f*x, 764.62f*x, -435.688f*x, 742.63f*x, 85.187f*x);
|
|
path.cubicTo(764.62f*x, -435.688f*x, 111.625f*x, 308.188f*x, 0, 0);
|
|
}
|
|
return path;
|
|
}
|
|
|
|
// This is a dummy GrMeshDrawOp::Target implementation that just gives back pointers into
|
|
// pre-allocated CPU buffers, rather than allocating and mapping GPU buffers.
|
|
class BenchmarkTarget : public GrMeshDrawOp::Target {
|
|
public:
|
|
void resetAllocator() { fAllocator.reset(); }
|
|
SkArenaAlloc* allocator() override { return &fAllocator; }
|
|
void putBackVertices(int vertices, size_t vertexStride) override { /* no-op */ }
|
|
|
|
void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
|
|
int* startVertex) override {
|
|
if (vertexSize * vertexCount > sizeof(fStaticVertexData)) {
|
|
SK_ABORT(SkStringPrintf(
|
|
"FATAL: wanted %zu bytes of static vertex data; only have %zu.\n",
|
|
vertexSize * vertexCount, SK_ARRAY_COUNT(fStaticVertexData)).c_str());
|
|
}
|
|
return fStaticVertexData;
|
|
}
|
|
|
|
GrDrawIndexedIndirectCommand* makeDrawIndexedIndirectSpace(
|
|
int drawCount, sk_sp<const GrBuffer>* buffer, size_t* offsetInBytes) override {
|
|
int staticBufferCount = (int)SK_ARRAY_COUNT(fStaticDrawIndexedIndirectData);
|
|
if (drawCount > staticBufferCount) {
|
|
SK_ABORT(SkStringPrintf(
|
|
"FATAL: wanted %i static drawIndexedIndirect elements; only have %i.\n",
|
|
drawCount, staticBufferCount).c_str());
|
|
}
|
|
return fStaticDrawIndexedIndirectData;
|
|
}
|
|
|
|
#define UNIMPL(...) __VA_ARGS__ override { SK_ABORT("unimplemented."); }
|
|
UNIMPL(void recordDraw(const GrGeometryProcessor*, const GrSimpleMesh[], int,
|
|
const GrSurfaceProxy* const[], GrPrimitiveType))
|
|
UNIMPL(uint16_t* makeIndexSpace(int, sk_sp<const GrBuffer>*, int*))
|
|
UNIMPL(void* makeVertexSpaceAtLeast(size_t, int, int, sk_sp<const GrBuffer>*, int*, int*))
|
|
UNIMPL(uint16_t* makeIndexSpaceAtLeast(int, int, sk_sp<const GrBuffer>*, int*, int*))
|
|
UNIMPL(GrDrawIndirectCommand* makeDrawIndirectSpace(int, sk_sp<const GrBuffer>*, size_t*))
|
|
UNIMPL(void putBackIndices(int))
|
|
UNIMPL(GrRenderTargetProxy* proxy() const)
|
|
UNIMPL(const GrSurfaceProxyView* writeView() const)
|
|
UNIMPL(const GrAppliedClip* appliedClip() const)
|
|
UNIMPL(GrAppliedClip detachAppliedClip())
|
|
UNIMPL(const GrXferProcessor::DstProxyView& dstProxyView() const)
|
|
UNIMPL(GrResourceProvider* resourceProvider() const)
|
|
UNIMPL(GrStrikeCache* strikeCache() const)
|
|
UNIMPL(GrAtlasManager* atlasManager() const)
|
|
UNIMPL(SkTArray<GrSurfaceProxy*, true>* sampledProxyArray())
|
|
UNIMPL(const GrCaps& caps() const)
|
|
UNIMPL(GrDeferredUploadTarget* deferredUploadTarget())
|
|
#undef UNIMPL
|
|
|
|
private:
|
|
SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 5];
|
|
GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32];
|
|
SkSTArenaAlloc<1024 * 1024> fAllocator;
|
|
};
|
|
|
|
// This serves as a base class for benchmarking individual methods on GrTessellatePathOp.
|
|
class GrTessellatePathOp::TestingOnly_Benchmark : public Benchmark {
|
|
public:
|
|
TestingOnly_Benchmark(const char* subName, SkPath path, const SkMatrix& m)
|
|
: fOp(m, path, GrPaint(), GrAAType::kMSAA) {
|
|
fName.printf("tessellate_%s", subName);
|
|
}
|
|
|
|
const char* onGetName() override { return fName.c_str(); }
|
|
bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
|
|
|
|
class MiddleOutInnerTrianglesBench;
|
|
class OuterCubicsBench;
|
|
class CubicWedgesBench;
|
|
class WangsFormulaBench;
|
|
|
|
private:
|
|
void onDraw(int loops, SkCanvas*) final {
|
|
for (int i = 0; i < loops; ++i) {
|
|
fOp.fTriangleBuffer.reset();
|
|
fOp.fDoStencilTriangleBuffer = false;
|
|
fOp.fDoFillTriangleBuffer = false;
|
|
fOp.fCubicBuffer.reset();
|
|
fOp.fStencilCubicsShader = nullptr;
|
|
this->runBench(&fTarget, &fOp);
|
|
fTarget.resetAllocator();
|
|
}
|
|
}
|
|
|
|
virtual void runBench(GrMeshDrawOp::Target*, GrTessellatePathOp*) = 0;
|
|
|
|
GrTessellatePathOp fOp;
|
|
BenchmarkTarget fTarget;
|
|
SkString fName;
|
|
};
|
|
|
|
class GrTessellatePathOp::TestingOnly_Benchmark::MiddleOutInnerTrianglesBench
|
|
: public GrTessellatePathOp::TestingOnly_Benchmark {
|
|
public:
|
|
MiddleOutInnerTrianglesBench()
|
|
: TestingOnly_Benchmark("prepareMiddleOutInnerTriangles",
|
|
ToolUtils::make_star(SkRect::MakeWH(100, 100),
|
|
kNumCubicsInChalkboard),
|
|
SkMatrix::I()) {
|
|
}
|
|
void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override {
|
|
int numBeziers;
|
|
op->prepareMiddleOutInnerTriangles(target, &numBeziers);
|
|
}
|
|
};
|
|
|
|
DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::MiddleOutInnerTrianglesBench(); );
|
|
|
|
class GrTessellatePathOp::TestingOnly_Benchmark::OuterCubicsBench
|
|
: public GrTessellatePathOp::TestingOnly_Benchmark {
|
|
public:
|
|
OuterCubicsBench()
|
|
: TestingOnly_Benchmark("prepareOuterCubics", make_cubic_path(), SkMatrix::I()) {
|
|
}
|
|
void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override {
|
|
op->prepareOuterCubics(target, kNumCubicsInChalkboard,
|
|
CubicDataAlignment::kVertexBoundary);
|
|
}
|
|
};
|
|
|
|
DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::OuterCubicsBench(); );
|
|
|
|
class GrTessellatePathOp::TestingOnly_Benchmark::CubicWedgesBench
|
|
: public GrTessellatePathOp::TestingOnly_Benchmark {
|
|
public:
|
|
CubicWedgesBench()
|
|
: TestingOnly_Benchmark("prepareCubicWedges", make_cubic_path(), SkMatrix::I()) {
|
|
}
|
|
void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override {
|
|
op->prepareCubicWedges(target);
|
|
}
|
|
};
|
|
|
|
DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::CubicWedgesBench(););
|
|
|
|
class GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench
|
|
: public GrTessellatePathOp::TestingOnly_Benchmark {
|
|
public:
|
|
WangsFormulaBench(const char* suffix, const SkMatrix& matrix)
|
|
: TestingOnly_Benchmark(SkStringPrintf("wangs_formula_cubic_log2%s", suffix).c_str(),
|
|
make_cubic_path(), SkMatrix::I())
|
|
, fMatrix(matrix) {
|
|
}
|
|
void runBench(GrMeshDrawOp::Target*, GrTessellatePathOp* op) override {
|
|
int sum = 0;
|
|
GrVectorXform xform(fMatrix);
|
|
for (auto [verb, pts, w] : SkPathPriv::Iterate(op->fPath)) {
|
|
if (verb == SkPathVerb::kCubic) {
|
|
sum += GrWangsFormula::cubic_log2(4, pts, xform);
|
|
}
|
|
}
|
|
// Don't let the compiler optimize away GrWangsFormula::cubic_log2.
|
|
if (sum <= 0) {
|
|
SK_ABORT("sum should be > 0.");
|
|
}
|
|
}
|
|
private:
|
|
SkMatrix fMatrix;
|
|
};
|
|
|
|
DEF_BENCH(
|
|
return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench("", SkMatrix::I());
|
|
);
|
|
DEF_BENCH(
|
|
return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench(
|
|
"_scale", SkMatrix::MakeScale(1.1f, 0.9f));
|
|
);
|
|
DEF_BENCH(
|
|
return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench(
|
|
"_affine", SkMatrix::MakeAll(.9f,0.9f,0, 1.1f,1.1f,0, 0,0,1));
|
|
);
|