Reland "Add variety of bulk API benchmarks"
This reverts commit659b21d480
. Reason for revert: Fixed skipping nonrendering benchmark Original change's description: > Revert "Add variety of bulk API benchmarks" > > This reverts commite63595dd85
. > > Reason for revert: Breaking the Perf tests: > > ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] > Command exited with code 139 > ####################################### > symbolized stacktrace follows > ####################################### > build/nanobench BulkRectBench<1000, (RectangleLayout)1, (ImageMode)2, (DrawMode)2>::onPerCanvasPreDraw(SkCanvas*) at skia/bench/BulkRectBench.cpp:218 > build/nanobench main at skia/bench/nanobench.cpp:1277 > /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f1213dad2e1] > build/nanobench _start at ??:? > > > > > > Original change's description: > > Add variety of bulk API benchmarks > > > > Covers drawing 1000 anti-aliased rectangles, either sharing 1 image, using > > a unique image, or as a solid color. Tests using the bulk APIs and regular > > one-at-a-time drawing. > > > > Change-Id: Icdf5a1f6df229aed785212d0941b89c11aa785c0 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251003 > > Commit-Queue: Michael Ludwig <michaelludwig@google.com> > > Reviewed-by: Robert Phillips <robertphillips@google.com> > > TBR=robertphillips@google.com,egdaniel@chromium.org,michaelludwig@google.com > > Change-Id: I3b26d5a04c472993585242a108c2764ea2b96940 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251213 > Reviewed-by: Joe Gregorio <jcgregorio@google.com> > Commit-Queue: Joe Gregorio <jcgregorio@google.com> Change-Id: I83538faa29ada5ab1b02ff07ae9fe90734ed198e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251238 Auto-Submit: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Joe Gregorio <jcgregorio@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
4ac37632a8
commit
1beb8ae9a2
271
bench/BulkRectBench.cpp
Normal file
271
bench/BulkRectBench.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* 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/SkImage.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/gpu/GrContext.h"
|
||||
#include "include/utils/SkRandom.h"
|
||||
|
||||
#include "src/gpu/GrClip.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
|
||||
// Benchmarks that exercise the bulk image and solid color quad APIs, under a variety of patterns:
|
||||
enum class ImageMode {
|
||||
kShared, // 1. One shared image referenced by every rectangle
|
||||
kUnique, // 2. Unique image for every rectangle
|
||||
kNone // 3. No image, solid color shading per rectangle
|
||||
};
|
||||
// X
|
||||
enum class DrawMode {
|
||||
kBatch, // Bulk API submission, one call to draw every rectangle
|
||||
kRef, // One standard SkCanvas draw call per rectangle
|
||||
kQuad // One experimental draw call per rectangle, only for solid color draws
|
||||
};
|
||||
// X
|
||||
enum class RectangleLayout {
|
||||
kRandom, // Random overlapping rectangles
|
||||
kGrid // Small, non-overlapping rectangles in a grid covering the output surface
|
||||
};
|
||||
|
||||
// Benchmark runner that can be configured by template arguments.
|
||||
template<int kRectCount, RectangleLayout kLayout, ImageMode kImageMode, DrawMode kDrawMode>
|
||||
class BulkRectBench : public Benchmark {
|
||||
public:
|
||||
static_assert(kImageMode == ImageMode::kNone || kDrawMode != DrawMode::kQuad,
|
||||
"kQuad only supported for solid color draws");
|
||||
|
||||
static constexpr int kWidth = 1024;
|
||||
static constexpr int kHeight = 1024;
|
||||
|
||||
// There will either be 0 images, 1 image, or 1 image per rect
|
||||
static constexpr int kImageCount = kImageMode == ImageMode::kShared ?
|
||||
1 : (kImageMode == ImageMode::kNone ? 0 : kRectCount);
|
||||
|
||||
bool isSuitableFor(Backend backend) override {
|
||||
if (kDrawMode == DrawMode::kBatch && kImageMode == ImageMode::kNone) {
|
||||
// Currently the bulk color quad API is only available on GrRenderTargetContext
|
||||
return backend == kGPU_Backend;
|
||||
} else {
|
||||
return this->INHERITED::isSuitableFor(backend);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SkRect fRects[kRectCount];
|
||||
sk_sp<SkImage> fImages[kImageCount];
|
||||
SkColor4f fColors[kRectCount];
|
||||
SkString fName;
|
||||
|
||||
void computeName() {
|
||||
fName = "bulkrect";
|
||||
fName.appendf("_%d", kRectCount);
|
||||
if (kLayout == RectangleLayout::kRandom) {
|
||||
fName.append("_random");
|
||||
} else {
|
||||
fName.append("_grid");
|
||||
}
|
||||
if (kImageMode == ImageMode::kShared) {
|
||||
fName.append("_sharedimage");
|
||||
} else if (kImageMode == ImageMode::kUnique) {
|
||||
fName.append("_uniqueimages");
|
||||
} else {
|
||||
fName.append("_solidcolor");
|
||||
}
|
||||
if (kDrawMode == DrawMode::kBatch) {
|
||||
fName.append("_batch");
|
||||
} else if (kDrawMode == DrawMode::kRef) {
|
||||
fName.append("_ref");
|
||||
} else {
|
||||
fName.append("_quad");
|
||||
}
|
||||
}
|
||||
|
||||
void drawImagesBatch(SkCanvas* canvas) const {
|
||||
SkASSERT(kImageMode != ImageMode::kNone);
|
||||
SkASSERT(kDrawMode == DrawMode::kBatch);
|
||||
|
||||
SkCanvas::ImageSetEntry batch[kRectCount];
|
||||
for (int i = 0; i < kRectCount; ++i) {
|
||||
int imageIndex = kImageMode == ImageMode::kShared ? 0 : i;
|
||||
batch[i].fImage = fImages[imageIndex];
|
||||
batch[i].fSrcRect = SkRect::MakeIWH(fImages[imageIndex]->width(),
|
||||
fImages[imageIndex]->height());
|
||||
batch[i].fDstRect = fRects[i];
|
||||
batch[i].fAAFlags = SkCanvas::kAll_QuadAAFlags;
|
||||
}
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
|
||||
canvas->experimental_DrawEdgeAAImageSet(batch, kRectCount, nullptr, nullptr, &paint,
|
||||
SkCanvas::kFast_SrcRectConstraint);
|
||||
}
|
||||
|
||||
void drawImagesRef(SkCanvas* canvas) const {
|
||||
SkASSERT(kImageMode != ImageMode::kNone);
|
||||
SkASSERT(kDrawMode == DrawMode::kRef);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
|
||||
for (int i = 0; i < kRectCount; ++i) {
|
||||
int imageIndex = kImageMode == ImageMode::kShared ? 0 : i;
|
||||
SkIRect srcRect = SkIRect::MakeWH(fImages[imageIndex]->width(),
|
||||
fImages[imageIndex]->height());
|
||||
canvas->drawImageRect(fImages[imageIndex].get(), srcRect, fRects[i], &paint,
|
||||
SkCanvas::kFast_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSolidColorsBatch(SkCanvas* canvas) const {
|
||||
SkASSERT(kImageMode == ImageMode::kNone);
|
||||
SkASSERT(kDrawMode == DrawMode::kBatch);
|
||||
|
||||
GrContext* context = canvas->getGrContext();
|
||||
SkASSERT(context);
|
||||
|
||||
GrRenderTargetContext::QuadSetEntry batch[kRectCount];
|
||||
for (int i = 0; i < kRectCount; ++i) {
|
||||
batch[i].fRect = fRects[i];
|
||||
batch[i].fColor = fColors[i].premul();
|
||||
batch[i].fLocalMatrix = SkMatrix::I();
|
||||
batch[i].fAAFlags = GrQuadAAFlags::kAll;
|
||||
}
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorWHITE);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext();
|
||||
SkMatrix view = canvas->getTotalMatrix();
|
||||
GrPaint grPaint;
|
||||
SkPaintToGrPaint(context, rtc->colorInfo(), paint, view, &grPaint);
|
||||
rtc->drawQuadSet(GrNoClip(), std::move(grPaint), GrAA::kYes, view, batch, kRectCount);
|
||||
}
|
||||
|
||||
void drawSolidColorsRef(SkCanvas* canvas) const {
|
||||
SkASSERT(kImageMode == ImageMode::kNone);
|
||||
SkASSERT(kDrawMode == DrawMode::kRef || kDrawMode == DrawMode::kQuad);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
for (int i = 0; i < kRectCount; ++i) {
|
||||
if (kDrawMode == DrawMode::kRef) {
|
||||
paint.setColor4f(fColors[i]);
|
||||
canvas->drawRect(fRects[i], paint);
|
||||
} else {
|
||||
canvas->experimental_DrawEdgeAAQuad(fRects[i], nullptr, SkCanvas::kAll_QuadAAFlags,
|
||||
fColors[i], SkBlendMode::kSrcOver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* onGetName() override {
|
||||
if (fName.isEmpty()) {
|
||||
this->computeName();
|
||||
}
|
||||
return fName.c_str();
|
||||
}
|
||||
|
||||
void onDelayedSetup() override {
|
||||
static constexpr SkScalar kMinRectSize = 0.2f;
|
||||
static constexpr SkScalar kMaxRectSize = 300.f;
|
||||
|
||||
SkRandom rand;
|
||||
for (int i = 0; i < kRectCount; i++) {
|
||||
if (kLayout == RectangleLayout::kRandom) {
|
||||
SkScalar w = rand.nextF() * (kMaxRectSize - kMinRectSize) + kMinRectSize;
|
||||
SkScalar h = rand.nextF() * (kMaxRectSize - kMinRectSize) + kMinRectSize;
|
||||
|
||||
SkScalar x = rand.nextF() * (kWidth - w);
|
||||
SkScalar y = rand.nextF() * (kHeight - h);
|
||||
|
||||
fRects[i].setXYWH(x, y, w, h);
|
||||
} else {
|
||||
int gridSize = SkScalarCeilToInt(SkScalarSqrt(kRectCount));
|
||||
SkASSERT(gridSize * gridSize >= kRectCount);
|
||||
|
||||
SkScalar w = (kWidth - 1.f) / gridSize;
|
||||
SkScalar h = (kHeight - 1.f) / gridSize;
|
||||
|
||||
SkScalar x = (i % gridSize) * w + 0.5f; // Offset to ensure AA doesn't get disabled
|
||||
SkScalar y = (i / gridSize) * h + 0.5f;
|
||||
|
||||
fRects[i].setXYWH(x, y, w, h);
|
||||
}
|
||||
|
||||
// Make sure we don't extend outside the render target, don't want to include clipping
|
||||
// in the benchmark.
|
||||
SkASSERT(SkRect::MakeWH(kWidth, kHeight).contains(fRects[i]));
|
||||
|
||||
fColors[i] = {rand.nextF(), rand.nextF(), rand.nextF(), 1.f};
|
||||
}
|
||||
}
|
||||
|
||||
void onPerCanvasPreDraw(SkCanvas* canvas) override {
|
||||
// Push the skimages to the GPU when using the GPU backend so that the texture creation is
|
||||
// not part of the bench measurements. Always remake the images since they are so simple,
|
||||
// and since they are context-specific, this works when the bench runs multiple GPU backends
|
||||
GrContext* context = canvas->getGrContext();
|
||||
for (int i = 0; i < kImageCount; ++i) {
|
||||
SkBitmap bm;
|
||||
bm.allocN32Pixels(256, 256);
|
||||
bm.eraseColor(fColors[i].toSkColor());
|
||||
auto image = SkImage::MakeFromBitmap(bm);
|
||||
|
||||
fImages[i] = context ? image->makeTextureImage(context) : std::move(image);
|
||||
}
|
||||
}
|
||||
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
for (int i = 0; i < loops; i++) {
|
||||
if (kImageMode == ImageMode::kNone) {
|
||||
if (kDrawMode == DrawMode::kBatch) {
|
||||
this->drawSolidColorsBatch(canvas);
|
||||
} else {
|
||||
this->drawSolidColorsRef(canvas);
|
||||
}
|
||||
} else {
|
||||
if (kDrawMode == DrawMode::kBatch) {
|
||||
this->drawImagesBatch(canvas);
|
||||
} else {
|
||||
this->drawImagesRef(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SkIPoint onGetSize() override {
|
||||
return { kWidth, kHeight };
|
||||
}
|
||||
|
||||
typedef Benchmark INHERITED;
|
||||
};
|
||||
|
||||
// constructor call is wrapped in () so the macro doesn't break parsing the commas in the template
|
||||
#define ADD_BENCH(n, layout, imageMode, drawMode) \
|
||||
DEF_BENCH( return (new BulkRectBench<n, layout, imageMode, drawMode>()); )
|
||||
|
||||
#define ADD_BENCH_FAMILY(n, layout) \
|
||||
ADD_BENCH(n, layout, ImageMode::kShared, DrawMode::kBatch) \
|
||||
ADD_BENCH(n, layout, ImageMode::kShared, DrawMode::kRef) \
|
||||
ADD_BENCH(n, layout, ImageMode::kUnique, DrawMode::kBatch) \
|
||||
ADD_BENCH(n, layout, ImageMode::kUnique, DrawMode::kRef) \
|
||||
ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kBatch) \
|
||||
ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kRef) \
|
||||
ADD_BENCH(n, layout, ImageMode::kNone, DrawMode::kQuad)
|
||||
|
||||
ADD_BENCH_FAMILY(1000, RectangleLayout::kRandom)
|
||||
ADD_BENCH_FAMILY(1000, RectangleLayout::kGrid)
|
||||
|
||||
#undef ADD_BENCH_FAMILY
|
||||
#undef ADD_BENCH
|
@ -22,6 +22,7 @@ bench_sources = [
|
||||
"$_bench/BlurImageFilterBench.cpp",
|
||||
"$_bench/BlurRectBench.cpp",
|
||||
"$_bench/BlurRectsBench.cpp",
|
||||
"$_bench/BulkRectBench.cpp",
|
||||
"$_bench/CTConvertBench.cpp",
|
||||
"$_bench/ChartBench.cpp",
|
||||
"$_bench/ChecksumBench.cpp",
|
||||
|
Loading…
Reference in New Issue
Block a user