blob: bd42db8cf81e35beeb3e29cb99f051a2bcdde8e6 [file] [log] [blame]
Michael Ludwig08f1a252020-01-22 14:32:11 -05001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "gm/gm.h"
8#include "include/core/SkCanvas.h"
9#include "include/core/SkColor.h"
Michael Ludwig949ceb22020-02-07 10:14:45 -050010#include "include/core/SkImage.h"
Mike Reed2a7c6192020-02-21 11:19:20 -050011#include "include/core/SkM44.h"
Michael Ludwig08f1a252020-01-22 14:32:11 -050012#include "include/core/SkMatrix.h"
Michael Ludwig949ceb22020-02-07 10:14:45 -050013#include "include/core/SkSurface.h"
14#include "include/effects/SkGradientShader.h"
Michael Ludwig08f1a252020-01-22 14:32:11 -050015#include "tools/timer/TimeUtils.h"
16
Michael Ludwig08f1a252020-01-22 14:32:11 -050017// Adapted from https://codepen.io/adamdupuis/pen/qLYzqB
18class CrBug224618GM : public skiagm::GM {
19public:
20 CrBug224618GM() : fTime(0.f) {}
21
22protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000023 SkString getName() const override { return SkString("crbug_224618"); }
Michael Ludwig08f1a252020-01-22 14:32:11 -050024
Leandro Lovisolo8f023882023-08-15 21:13:52 +000025 SkISize getISize() override { return SkISize::Make(kMaxVW, kMaxVW); }
Michael Ludwig08f1a252020-01-22 14:32:11 -050026
27 // This animates the FOV in viewer, to ensure the panorama covering rects are stable across
28 // a variety of perspective matrices
29 bool onAnimate(double nanos) override {
30 fTime = TimeUtils::Scaled(1e-9f * nanos, 0.5f);
31 return true;
32 }
33
Michael Ludwig949ceb22020-02-07 10:14:45 -050034 void onOnceBeforeDraw() override {
35 static const SkColor kColors[2] = {SK_ColorTRANSPARENT, SkColorSetARGB(128, 255, 255, 255)};
36 sk_sp<SkShader> gradient = SkGradientShader::MakeRadial(
37 {200.f, 200.f}, 25.f, kColors, nullptr, 2, SkTileMode::kMirror,
38 SkGradientShader::kInterpolateColorsInPremul_Flag, nullptr);
39
Kevin Lubick5c93acf2023-05-09 12:11:43 -040040 sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(400, 400));
Michael Ludwig949ceb22020-02-07 10:14:45 -050041
42 SkPaint bgPaint;
43 bgPaint.setShader(gradient);
44 surface->getCanvas()->drawPaint(bgPaint);
45
46 fCubeImage = surface->makeImageSnapshot();
47 }
48
Michael Ludwig08f1a252020-01-22 14:32:11 -050049 void onDraw(SkCanvas* canvas) override {
50 SkScalar viewportWidth = SkScalarMod(fTime, 10.f) / 10.f * (kMaxVW - kMinVW) + kMinVW;
51 SkScalar radius = viewportWidth / 2.f; // round?
52 // See https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/perspective
53 SkM44 proj{1.f, 0.f, 0.f, 0.f,
54 0.f, 1.f, 0.f, 0.f,
55 0.f, 0.f, 1.f, 0.f,
56 0.f, 0.f, -1.f / radius, 1.f};
57 SkM44 zoom = SkM44::Translate(0.f, 0.f, radius);
58 SkM44 postZoom = SkM44::Translate(0.f, 0.f, -radius - 1.f);
Mike Reed2a7c6192020-02-21 11:19:20 -050059 SkM44 rotateHorizontal = SkM44::Rotate({0, 1, 0}, 2.356194490192345f);
Michael Ludwig08f1a252020-01-22 14:32:11 -050060
61 // w in degrees will need to be converted to radians
62 SkV4 axisAngles[6] = {
63 {0.f, 1.f, 0.f, -90.f}, // rotateY(-90deg)
64 {1.f, 0.f, 0.f, 0.f}, // <none>
65 {0.f, 1.f, 0.f, 90.f}, // rotateY(90deg)
66 {0.f, 1.f, 0.f, 180.f}, // rotateY(180deg)
67 {1.f, 0.f, 0.f, -90.f}, // rotateX(-90deg)
68 {1.f, 0.f, 0.f, 90.f}, // rotateX(90deg)
69 };
70 SkColor faceColors[6] = {
71 SK_ColorRED,
72 SK_ColorGREEN,
73 SK_ColorBLUE,
74 SK_ColorYELLOW,
75 SkColorSetARGB(0xFF, 0xFF, 0xA5, 0x00), // orange css
76 SkColorSetARGB(0xFF, 0x80, 0x00, 0x80) // purple css
77 };
Michael Ludwig949ceb22020-02-07 10:14:45 -050078
Michael Ludwig08f1a252020-01-22 14:32:11 -050079 for (int i = 0; i < 6; ++i) {
Mike Reed2a7c6192020-02-21 11:19:20 -050080 SkM44 model = SkM44::Rotate({axisAngles[i].x, axisAngles[i].y, axisAngles[i].z},
Michael Ludwig08f1a252020-01-22 14:32:11 -050081 SkDegreesToRadians(axisAngles[i].w));
82 model = SkM44::Translate(radius, radius) * proj * // project and place content
83 zoom * rotateHorizontal * model * postZoom * // main model matrix
84 SkM44::Translate(-radius, -radius); // center content
85
86 canvas->save();
Mike Reed3ef77dd2020-04-06 10:41:09 -040087 canvas->concat(model);
Michael Ludwig08f1a252020-01-22 14:32:11 -050088
89 SkPaint fillPaint;
90 fillPaint.setAntiAlias(true);
91 fillPaint.setColor(faceColors[i]);
92
Robert Phillipsfbf02142021-09-01 16:31:34 -040093 // Leverages FillRectOp on GPU backend
Michael Ludwig08f1a252020-01-22 14:32:11 -050094 canvas->drawRect(SkRect::MakeWH(viewportWidth, viewportWidth), fillPaint);
Michael Ludwig949ceb22020-02-07 10:14:45 -050095
Robert Phillipsfbf02142021-09-01 16:31:34 -040096 // Leverages TextureOp on GPU backend, to ensure sure both quad paths handle clipping
Michael Ludwig949ceb22020-02-07 10:14:45 -050097 canvas->drawImageRect(fCubeImage.get(),
98 SkRect::MakeWH(fCubeImage->width(), fCubeImage->height()),
Mike Reede02d7f82021-01-21 22:25:21 -050099 SkRect::MakeWH(viewportWidth, viewportWidth),
100 SkSamplingOptions(SkFilterMode::kLinear), &fillPaint,
Michael Ludwig949ceb22020-02-07 10:14:45 -0500101 SkCanvas::kFast_SrcRectConstraint);
102
Michael Ludwig08f1a252020-01-22 14:32:11 -0500103 canvas->restore();
104 }
105 }
106private:
107 static const int kMaxVW = 800;
108 static const int kMinVW = 300;
Michael Ludwig949ceb22020-02-07 10:14:45 -0500109
Michael Ludwig08f1a252020-01-22 14:32:11 -0500110 SkScalar fTime;
Michael Ludwig949ceb22020-02-07 10:14:45 -0500111 sk_sp<SkImage> fCubeImage;
Michael Ludwig08f1a252020-01-22 14:32:11 -0500112};
113
114DEF_GM(return new CrBug224618GM();)