/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "Benchmark.h" #include "GrContextOptions.h" #include "SkCanvas.h" #include "SkImage.h" #include "SkRandom.h" #include "SkSurface.h" class MultitextureImages : public Benchmark { public: MultitextureImages(int imageSize, int dstRectSize, bool disableMultitexturing, bool aa) : fImageSize(imageSize) , fDstRectSize(dstRectSize) , fDisableMultitexturing(disableMultitexturing) , fAA(aa) { fName.appendf("multitexture_images_%dx%d_image_%dx%d_rect", imageSize, imageSize, dstRectSize, dstRectSize); if (aa) { fName.append("_aa"); } if (disableMultitexturing) { fName.append("_disable_multitexturing"); } } bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; } protected: const char* onGetName() override { return fName.c_str(); } void onPerCanvasPreDraw(SkCanvas* canvas) override { auto ii = SkImageInfo::Make(fImageSize, fImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr); SkRandom random; for (int i = 0; i < kNumImages; ++i) { auto surf = canvas->makeSurface(ii); SkColor color = random.nextU(); surf->getCanvas()->clear(color); SkPaint paint; paint.setColor(~color); paint.setBlendMode(SkBlendMode::kSrc); surf->getCanvas()->drawRect(SkRect::MakeLTRB(3, 3, fImageSize - 3, fImageSize - 3), paint); fImages[i] = surf->makeImageSnapshot(); } } void onPerCanvasPostDraw(SkCanvas*) override { for (int i = 0; i < kNumImages; ++i) { fImages[i].reset(); } } void onDraw(int loops, SkCanvas* canvas) override { SkRect rect = SkRect::MakeWH(fDstRectSize, fDstRectSize); SkPaint paint; paint.setAlpha(0x40); paint.setFilterQuality(kLow_SkFilterQuality); paint.setAntiAlias(fAA); for (int i = 0; i < loops; i++) { for (int j = 0; j < kNumImages; ++j) { SkVector translate = this->translation(i * kNumImages + j); canvas->drawImageRect(fImages[j].get(), rect.makeOffset(translate.fX, translate.fY), &paint); } // Prevent any batching except without multitexturing since we're trying to measure // drawing distinct images and just repeating images here to increase the workload for // timing reasons. canvas->flush(); } } void modifyGrContextOptions(GrContextOptions* options) override { options->fDisableImageMultitexturing = fDisableMultitexturing; } private: SkIPoint onGetSize() override { // The rows and columns are spaced by kTranslate, but the images may overlap if they are // larger than kTranslate and extend beyond the last row/column. return SkIPoint::Make(kTranslate * (kNumColumns - 1) + fDstRectSize, kTranslate * (kNumRows - 1) + fDstRectSize); } SkVector translation(int i) const { SkVector offset; // Fractional offsets to ensure we can't ignore antialiasing. offset.fX = i % kNumColumns * kTranslate + 0.1f; offset.fY = (i / kNumColumns) % kNumRows * kTranslate + 0.1f; return offset; } static const int kTranslate = 200; static const int kNumColumns = 5; static const int kNumRows = 5; static const int kNumImages = 8; sk_sp fImages[kNumImages]; SkString fName; int fImageSize; int fDstRectSize; bool fDisableMultitexturing; bool fAA; typedef Benchmark INHERITED; }; // Non-AA DEF_BENCH(return new MultitextureImages(128, 32, false, false)); DEF_BENCH(return new MultitextureImages(128, 32, true, false)); DEF_BENCH(return new MultitextureImages(128, 128, false, false)); DEF_BENCH(return new MultitextureImages(128, 128, true, false)); DEF_BENCH(return new MultitextureImages(128, 256, false, false)); DEF_BENCH(return new MultitextureImages(128, 256, true, false)); DEF_BENCH(return new MultitextureImages(512, 32, false, false)); DEF_BENCH(return new MultitextureImages(512, 32, true, false)); DEF_BENCH(return new MultitextureImages(512, 128, false, false)); DEF_BENCH(return new MultitextureImages(512, 128, true, false)); DEF_BENCH(return new MultitextureImages(512, 256, false, false)); DEF_BENCH(return new MultitextureImages(512, 256, true, false)); DEF_BENCH(return new MultitextureImages(512, 512, false, false)); DEF_BENCH(return new MultitextureImages(512, 512, true, false)); // AA DEF_BENCH(return new MultitextureImages(512, 512, true, true)); DEF_BENCH(return new MultitextureImages(512, 512, false, true)); DEF_BENCH(return new MultitextureImages(128, 32, true, true)); DEF_BENCH(return new MultitextureImages(128, 32, false, true));