| /* | |
| * Copyright 2014 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/SkBitmap.h" | |
| #include "include/core/SkCanvas.h" | |
| #include "include/core/SkPaint.h" | |
| #include "include/core/SkPath.h" | |
| #include "include/core/SkPathBuilder.h" | |
| #include "include/core/SkString.h" | |
| #include "include/effects/SkGradient.h" | |
| #include <array> | |
| enum ColorPattern { | |
| kWhite_ColorPattern, | |
| kBlue_ColorPattern, | |
| kOpaqueBitmap_ColorPattern, | |
| kAlphaBitmap_ColorPattern, | |
| }; | |
| struct ColorPatternData { | |
| SkColor fColor; | |
| bool fIsBitmap; | |
| const char* fName; | |
| }; | |
| static constexpr auto gColorPatterns = std::to_array<ColorPatternData>({ | |
| // Keep this in same order as ColorPattern enum | |
| ColorPatternData{ SK_ColorWHITE, false, "white" }, // kWhite_ColorPattern | |
| ColorPatternData{ SK_ColorBLUE, false, "blue" }, // kBlue_ColorPattern | |
| ColorPatternData{ SK_ColorWHITE, true, "obaqueBitMap" }, // kOpaqueBitmap_ColorPattern | |
| ColorPatternData{ 0x10000000, true, "alphaBitmap" }, // kAlphaBitmap_ColorPattern | |
| }); | |
| enum DrawType { | |
| kRect_DrawType, | |
| kPath_DrawType, | |
| }; | |
| static void makebm(SkBitmap* bm, int w, int h) { | |
| bm->allocN32Pixels(w, h); | |
| bm->eraseColor(SK_ColorTRANSPARENT); | |
| SkCanvas canvas(*bm); | |
| SkScalar s = SkIntToScalar(std::min(w, h)); | |
| static const SkPoint kPts0[] = { { 0, 0 }, { s, s } }; | |
| static const SkPoint kPts1[] = { { s/2, 0 }, { s/2, s } }; | |
| static const SkScalar kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; | |
| static const SkColor4f kColors0[] = { SkColor4f::FromColor(0x80F00080), | |
| SkColor4f::FromColor(0xF0F08000), | |
| SkColor4f::FromColor(0x800080F0) }; | |
| static const SkColor4f kColors1[] = { SkColor4f::FromColor(0xF08000F0), | |
| SkColor4f::FromColor(0x8080F000), | |
| SkColor4f::FromColor(0xF000F080) }; | |
| SkPaint paint; | |
| paint.setShader(SkShaders::LinearGradient(kPts0, {{kColors0, kPos, SkTileMode::kClamp}, {}})); | |
| canvas.drawPaint(paint); | |
| paint.setShader(SkShaders::LinearGradient(kPts1, {{kColors1, kPos, SkTileMode::kClamp}, {}})); | |
| canvas.drawPaint(paint); | |
| } | |
| /** | |
| * This bench draws a grid of either rects or filled paths, with two alternating color patterns. | |
| * This color patterns are passed in as enums to the class. The options are: | |
| * 1) solid white color | |
| * 2) solid blue color | |
| * 3) opaque bitmap | |
| * 4) partial alpha bitmap | |
| * The same color pattern can be set for both arguments to create a uniform pattern on all draws. | |
| * | |
| * The bench is used to test a few things. First it can test any optimizations made for a specific | |
| * color pattern (for example drawing an opaque bitmap versus one with partial alpha). Also it can | |
| * be used to test the cost of program switching and/or GrDrawOp combining when alternating between | |
| * different patterns when on the gpu. | |
| */ | |
| class AlternatingColorPatternBench : public Benchmark { | |
| public: | |
| enum { | |
| NX = 5, | |
| NY = 5, | |
| NUM_DRAWS = NX * NY, | |
| }; | |
| sk_sp<SkShader> fBmShader; | |
| std::array<SkPath, NUM_DRAWS> fPaths; | |
| std::array<SkRect, NUM_DRAWS> fRects; | |
| std::array<SkColor, NUM_DRAWS> fColors; | |
| std::array<sk_sp<SkShader>, NUM_DRAWS> fShaders; | |
| SkString fName; | |
| ColorPatternData fPattern1; | |
| ColorPatternData fPattern2; | |
| DrawType fDrawType; | |
| SkBitmap fBmp; | |
| AlternatingColorPatternBench(ColorPattern pattern1, ColorPattern pattern2, DrawType drawType) { | |
| fPattern1 = gColorPatterns[pattern1]; | |
| fPattern2 = gColorPatterns[pattern2]; | |
| fName.printf("colorPattern_%s_%s_%s", | |
| fPattern1.fName, fPattern2.fName, | |
| kRect_DrawType == drawType ? "rect" : "path"); | |
| fDrawType = drawType; | |
| } | |
| protected: | |
| const char* onGetName() override { | |
| return fName.c_str(); | |
| } | |
| void onDelayedSetup() override { | |
| int w = 40; | |
| int h = 40; | |
| makebm(&fBmp, w, h); | |
| fBmShader = fBmp.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, | |
| SkSamplingOptions(SkFilterMode::kLinear)); | |
| int offset = 2; | |
| int count = 0; | |
| for (int j = 0; j < NY; ++j) { | |
| for (int i = 0; i < NX; ++i) { | |
| int x = (w + offset) * i; | |
| int y = (h * offset) * j; | |
| if (kRect_DrawType == fDrawType) { | |
| fRects[count].setXYWH(SkIntToScalar(x), SkIntToScalar(y), | |
| SkIntToScalar(w), SkIntToScalar(h)); | |
| } else { | |
| SkPathBuilder builder; | |
| builder.moveTo(SkIntToScalar(x), SkIntToScalar(y)); | |
| builder.rLineTo(SkIntToScalar(w), 0); | |
| builder.rLineTo(0, SkIntToScalar(h)); | |
| builder.rLineTo(SkIntToScalar(-w + 1), 0); | |
| fPaths[count] = builder.detach(); | |
| } | |
| if (0 == count % 2) { | |
| fColors[count] = fPattern1.fColor; | |
| fShaders[count] = fPattern1.fIsBitmap ? fBmShader : nullptr; | |
| } else { | |
| fColors[count] = fPattern2.fColor; | |
| fShaders[count] = fPattern2.fIsBitmap ? fBmShader : nullptr; | |
| } | |
| ++count; | |
| } | |
| } | |
| } | |
| void onDraw(int loops, SkCanvas* canvas) override { | |
| SkPaint paint; | |
| paint.setAntiAlias(false); | |
| for (int i = 0; i < loops; ++i) { | |
| for (int j = 0; j < NUM_DRAWS; ++j) { | |
| paint.setColor(fColors[j]); | |
| paint.setShader(fShaders[j]); | |
| if (kRect_DrawType == fDrawType) { | |
| canvas->drawRect(fRects[j], paint); | |
| } else { | |
| canvas->drawPath(fPaths[j], paint); | |
| } | |
| } | |
| } | |
| } | |
| private: | |
| using INHERITED = Benchmark; | |
| }; | |
| DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern, | |
| kWhite_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kBlue_ColorPattern, | |
| kBlue_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern, | |
| kBlue_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, | |
| kOpaqueBitmap_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern, | |
| kAlphaBitmap_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, | |
| kAlphaBitmap_ColorPattern, | |
| kPath_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, | |
| kOpaqueBitmap_ColorPattern, | |
| kRect_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern, | |
| kAlphaBitmap_ColorPattern, | |
| kRect_DrawType);) | |
| DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern, | |
| kAlphaBitmap_ColorPattern, | |
| kRect_DrawType);) |