| /* | |
| * Copyright 2023 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "gm/gm.h" | |
| #include "include/core/SkCanvas.h" | |
| #include "include/core/SkPaint.h" | |
| #include "include/core/SkRect.h" | |
| #include "include/core/SkString.h" | |
| #include "include/core/SkTypes.h" | |
| #include "src/core/SkRandom.h" | |
| #include "tools/timer/TimeUtils.h" | |
| #include "tools/viewer/Slide.h" | |
| #include <array> | |
| // This slide draws a lot of overlapping rectangles which slide left. | |
| // It's adapted from the performance test at https://benchmarks.slaylines.io/ | |
| static constexpr int kWidth = 1000; | |
| static constexpr int kHeight = 639; | |
| static constexpr int kNumRects = 32000; | |
| class AnimatedRects : public Slide { | |
| public: | |
| AnimatedRects() { | |
| fName = "animated-rects"; | |
| } | |
| protected: | |
| void load(SkScalar, SkScalar) override { | |
| for (int i = 0; i < kNumRects; ++i) { | |
| fRect[i].x = fRand.nextF() * kWidth; | |
| fRect[i].y = fRand.nextF() * kHeight; | |
| fRect[i].size = 10.0 + fRand.nextF() * 40.0; | |
| fRect[i].speed = 1.0 + fRand.nextF(); | |
| } | |
| fStrokePaint.setAntiAlias(true); | |
| fStrokePaint.setColor(SK_ColorBLACK); | |
| fStrokePaint.setStyle(SkPaint::kStroke_Style); | |
| fStrokePaint.setStrokeWidth(2.0); | |
| fFillPaint.setAntiAlias(true); | |
| fFillPaint.setStyle(SkPaint::kFill_Style); | |
| fFillPaint.setColor(SK_ColorWHITE); | |
| } | |
| void draw(SkCanvas* canvas) override { | |
| SkAutoCanvasRestore acr(canvas, /*doSave=*/true); | |
| canvas->clipRect({0, 0, (float)kWidth, (float)kHeight}); | |
| for (int i = 0; i < kNumRects; ++i) { | |
| const AnimatedRect& r = fRect[i]; | |
| canvas->drawRect(SkRect{r.x, r.y, r.x + r.size, r.y + r.size}, fStrokePaint); | |
| canvas->drawRect(SkRect{r.x, r.y, r.x + r.size, r.y + r.size}, fFillPaint); | |
| } | |
| } | |
| bool animate(double nanos) override { | |
| float seconds = 1e-9 * nanos; | |
| if (0.0f != fLastTime) { | |
| float scale = (seconds - fLastTime) * 60; | |
| for (int i = 0; i < kNumRects; ++i) { | |
| AnimatedRect& r = fRect[i]; | |
| r.x -= r.speed * scale; | |
| if (r.x + r.size < 0) { | |
| r.x = kWidth + r.size; | |
| } | |
| } | |
| } | |
| fLastTime = seconds; | |
| return true; | |
| } | |
| private: | |
| struct AnimatedRect { | |
| float x, y, size, speed; | |
| }; | |
| std::array<AnimatedRect, kNumRects> fRect; | |
| SkRandom fRand; | |
| SkPaint fStrokePaint, fFillPaint; | |
| float fLastTime = 0.0f; | |
| }; | |
| ////////////////////////////////////////////////////////////////////////////// | |
| DEF_SLIDE(return new AnimatedRects;) |