e4b79699ef
This fixes the perf bot crashes from https://skia-review.googlesource.com/c/skia/+/317209 and removes a few other instances of kReplace_ClipOp that are equivalent to the still supported SkClipOp::kIntersect op. Other than the benchmark case, the GPU clip stack wasn't hitting these cases but they do need to be updated when the deprecated ops are fully removed. At this point, the remaining uses of deprecated clip ops are all in unit tests that specifically test a clip stack (raster, conservative, or skclipstack) that specifically supports expanded clip ops and the tests are testing those operations. They can remain until we remove full support. Bug: skia:10208 Change-Id: I5703bf43fd41b6addf329190a70c5429d5971240 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317380 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
254 lines
7.7 KiB
C++
254 lines
7.7 KiB
C++
/*
|
|
* Copyright 2011 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/SkPath.h"
|
|
#include "include/core/SkRegion.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/utils/SkRandom.h"
|
|
#include "src/core/SkAAClip.h"
|
|
#include "src/core/SkClipOpPriv.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// This bench tests out AA/BW clipping via canvas' clipPath and clipRect calls
|
|
class AAClipBench : public Benchmark {
|
|
SkString fName;
|
|
SkPath fClipPath;
|
|
SkRect fClipRect;
|
|
SkRect fDrawRect;
|
|
bool fDoPath;
|
|
bool fDoAA;
|
|
|
|
public:
|
|
AAClipBench(bool doPath, bool doAA)
|
|
: fDoPath(doPath)
|
|
, fDoAA(doAA) {
|
|
|
|
fName.printf("aaclip_%s_%s",
|
|
doPath ? "path" : "rect",
|
|
doAA ? "AA" : "BW");
|
|
|
|
fClipRect.setLTRB(10.5f, 10.5f, 50.5f, 50.5f);
|
|
fClipPath.addRoundRect(fClipRect, SkIntToScalar(10), SkIntToScalar(10));
|
|
fDrawRect.setWH(100, 100);
|
|
|
|
SkASSERT(fClipPath.isConvex());
|
|
}
|
|
|
|
protected:
|
|
const char* onGetName() override { return fName.c_str(); }
|
|
void onDraw(int loops, SkCanvas* canvas) override {
|
|
|
|
SkPaint paint;
|
|
this->setupPaint(&paint);
|
|
|
|
for (int i = 0; i < loops; ++i) {
|
|
// jostle the clip regions each time to prevent caching
|
|
fClipRect.offset((i % 2) == 0 ? SkIntToScalar(10) : SkIntToScalar(-10), 0);
|
|
fClipPath.reset();
|
|
fClipPath.addRoundRect(fClipRect,
|
|
SkIntToScalar(5), SkIntToScalar(5));
|
|
SkASSERT(fClipPath.isConvex());
|
|
|
|
canvas->save();
|
|
#if 1
|
|
if (fDoPath) {
|
|
canvas->clipPath(fClipPath, SkClipOp::kIntersect, fDoAA);
|
|
} else {
|
|
canvas->clipRect(fClipRect, SkClipOp::kIntersect, fDoAA);
|
|
}
|
|
|
|
canvas->drawRect(fDrawRect, paint);
|
|
#else
|
|
// this path tests out directly draw the clip primitive
|
|
// use it to comparing just drawing the clip vs. drawing using
|
|
// the clip
|
|
if (fDoPath) {
|
|
canvas->drawPath(fClipPath, paint);
|
|
} else {
|
|
canvas->drawRect(fClipRect, paint);
|
|
}
|
|
#endif
|
|
canvas->restore();
|
|
}
|
|
}
|
|
private:
|
|
using INHERITED = Benchmark;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// This bench tests out nested clip stacks. It is intended to simulate
|
|
// how WebKit nests clips.
|
|
class NestedAAClipBench : public Benchmark {
|
|
SkString fName;
|
|
bool fDoAA;
|
|
SkRect fDrawRect;
|
|
SkRandom fRandom;
|
|
|
|
static const int kNestingDepth = 3;
|
|
static const int kImageSize = 400;
|
|
|
|
SkPoint fSizes[kNestingDepth+1];
|
|
|
|
public:
|
|
NestedAAClipBench(bool doAA) : fDoAA(doAA) {
|
|
fName.printf("nested_aaclip_%s", doAA ? "AA" : "BW");
|
|
|
|
fDrawRect = SkRect::MakeLTRB(0, 0,
|
|
SkIntToScalar(kImageSize),
|
|
SkIntToScalar(kImageSize));
|
|
|
|
fSizes[0].set(SkIntToScalar(kImageSize), SkIntToScalar(kImageSize));
|
|
|
|
for (int i = 1; i < kNestingDepth+1; ++i) {
|
|
fSizes[i].set(fSizes[i-1].fX/2, fSizes[i-1].fY/2);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
const char* onGetName() override { return fName.c_str(); }
|
|
|
|
|
|
void recurse(SkCanvas* canvas,
|
|
int depth,
|
|
const SkPoint& offset) {
|
|
|
|
canvas->save();
|
|
|
|
SkRect temp = SkRect::MakeLTRB(0, 0,
|
|
fSizes[depth].fX, fSizes[depth].fY);
|
|
temp.offset(offset);
|
|
|
|
SkPath path;
|
|
path.addRoundRect(temp, SkIntToScalar(3), SkIntToScalar(3));
|
|
SkASSERT(path.isConvex());
|
|
|
|
canvas->clipPath(path, SkClipOp::kIntersect, fDoAA);
|
|
|
|
if (kNestingDepth == depth) {
|
|
// we only draw the draw rect at the lowest nesting level
|
|
SkPaint paint;
|
|
paint.setColor(0xff000000 | fRandom.nextU());
|
|
canvas->drawRect(fDrawRect, paint);
|
|
} else {
|
|
SkPoint childOffset = offset;
|
|
this->recurse(canvas, depth+1, childOffset);
|
|
|
|
childOffset += fSizes[depth+1];
|
|
this->recurse(canvas, depth+1, childOffset);
|
|
|
|
childOffset.fX = offset.fX + fSizes[depth+1].fX;
|
|
childOffset.fY = offset.fY;
|
|
this->recurse(canvas, depth+1, childOffset);
|
|
|
|
childOffset.fX = offset.fX;
|
|
childOffset.fY = offset.fY + fSizes[depth+1].fY;
|
|
this->recurse(canvas, depth+1, childOffset);
|
|
}
|
|
|
|
canvas->restore();
|
|
}
|
|
|
|
void onDraw(int loops, SkCanvas* canvas) override {
|
|
|
|
for (int i = 0; i < loops; ++i) {
|
|
SkPoint offset = SkPoint::Make(0, 0);
|
|
this->recurse(canvas, 0, offset);
|
|
}
|
|
}
|
|
|
|
private:
|
|
using INHERITED = Benchmark;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
class AAClipBuilderBench : public Benchmark {
|
|
SkString fName;
|
|
SkPath fPath;
|
|
SkRect fRect;
|
|
SkRegion fRegion;
|
|
bool fDoPath;
|
|
bool fDoAA;
|
|
|
|
public:
|
|
AAClipBuilderBench(bool doPath, bool doAA) {
|
|
fDoPath = doPath;
|
|
fDoAA = doAA;
|
|
|
|
fName.printf("aaclip_build_%s_%s", doPath ? "path" : "rect",
|
|
doAA ? "AA" : "BW");
|
|
|
|
fRegion.setRect({0, 0, 640, 480});
|
|
fRect.set(fRegion.getBounds());
|
|
fRect.inset(SK_Scalar1/4, SK_Scalar1/4);
|
|
fPath.addRoundRect(fRect, SkIntToScalar(20), SkIntToScalar(20));
|
|
}
|
|
|
|
protected:
|
|
const char* onGetName() override { return fName.c_str(); }
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
SkPaint paint;
|
|
this->setupPaint(&paint);
|
|
|
|
for (int i = 0; i < loops; ++i) {
|
|
SkAAClip clip;
|
|
if (fDoPath) {
|
|
clip.setPath(fPath, &fRegion, fDoAA);
|
|
} else {
|
|
clip.setRect(fRect, fDoAA);
|
|
}
|
|
}
|
|
}
|
|
private:
|
|
using INHERITED = Benchmark;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
class AAClipRegionBench : public Benchmark {
|
|
public:
|
|
AAClipRegionBench() {
|
|
SkPath path;
|
|
// test conversion of a complex clip to a aaclip
|
|
path.addCircle(0, 0, SkIntToScalar(200));
|
|
path.addCircle(0, 0, SkIntToScalar(180));
|
|
// evenodd means we've constructed basically a stroked circle
|
|
path.setFillType(SkPathFillType::kEvenOdd);
|
|
|
|
SkIRect bounds;
|
|
path.getBounds().roundOut(&bounds);
|
|
fRegion.setPath(path, SkRegion(bounds));
|
|
}
|
|
|
|
protected:
|
|
const char* onGetName() override { return "aaclip_setregion"; }
|
|
void onDraw(int loops, SkCanvas*) override {
|
|
for (int i = 0; i < loops; ++i) {
|
|
SkAAClip clip;
|
|
clip.setRegion(fRegion);
|
|
}
|
|
}
|
|
|
|
private:
|
|
SkRegion fRegion;
|
|
using INHERITED = Benchmark;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DEF_BENCH(return new AAClipBuilderBench(false, false);)
|
|
DEF_BENCH(return new AAClipBuilderBench(false, true);)
|
|
DEF_BENCH(return new AAClipBuilderBench(true, false);)
|
|
DEF_BENCH(return new AAClipBuilderBench(true, true);)
|
|
DEF_BENCH(return new AAClipRegionBench();)
|
|
DEF_BENCH(return new AAClipBench(false, false);)
|
|
DEF_BENCH(return new AAClipBench(false, true);)
|
|
DEF_BENCH(return new AAClipBench(true, false);)
|
|
DEF_BENCH(return new AAClipBench(true, true);)
|
|
DEF_BENCH(return new NestedAAClipBench(false);)
|
|
DEF_BENCH(return new NestedAAClipBench(true);)
|