blob: ac030cebf72398405ad886c119ec76963448daeb [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:
23 SkString onShortName() override {
24 return SkString("crbug_224618");
25 }
26
27 SkISize onISize() override {
28 return SkISize::Make(kMaxVW, kMaxVW);
29 }
30
31 // This animates the FOV in viewer, to ensure the panorama covering rects are stable across
32 // a variety of perspective matrices
33 bool onAnimate(double nanos) override {
34 fTime = TimeUtils::Scaled(1e-9f * nanos, 0.5f);
35 return true;
36 }
37
Michael Ludwig949ceb22020-02-07 10:14:45 -050038 void onOnceBeforeDraw() override {
39 static const SkColor kColors[2] = {SK_ColorTRANSPARENT, SkColorSetARGB(128, 255, 255, 255)};
40 sk_sp<SkShader> gradient = SkGradientShader::MakeRadial(
41 {200.f, 200.f}, 25.f, kColors, nullptr, 2, SkTileMode::kMirror,
42 SkGradientShader::kInterpolateColorsInPremul_Flag, nullptr);
43
44 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(400, 400);
45
46 SkPaint bgPaint;
47 bgPaint.setShader(gradient);
48 surface->getCanvas()->drawPaint(bgPaint);
49
50 fCubeImage = surface->makeImageSnapshot();
51 }
52
Michael Ludwig08f1a252020-01-22 14:32:11 -050053 void onDraw(SkCanvas* canvas) override {
54 SkScalar viewportWidth = SkScalarMod(fTime, 10.f) / 10.f * (kMaxVW - kMinVW) + kMinVW;
55 SkScalar radius = viewportWidth / 2.f; // round?
56 // See https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/perspective
57 SkM44 proj{1.f, 0.f, 0.f, 0.f,
58 0.f, 1.f, 0.f, 0.f,
59 0.f, 0.f, 1.f, 0.f,
60 0.f, 0.f, -1.f / radius, 1.f};
61 SkM44 zoom = SkM44::Translate(0.f, 0.f, radius);
62 SkM44 postZoom = SkM44::Translate(0.f, 0.f, -radius - 1.f);
Mike Reed2a7c6192020-02-21 11:19:20 -050063 SkM44 rotateHorizontal = SkM44::Rotate({0, 1, 0}, 2.356194490192345f);
Michael Ludwig08f1a252020-01-22 14:32:11 -050064
65 // w in degrees will need to be converted to radians
66 SkV4 axisAngles[6] = {
67 {0.f, 1.f, 0.f, -90.f}, // rotateY(-90deg)
68 {1.f, 0.f, 0.f, 0.f}, // <none>
69 {0.f, 1.f, 0.f, 90.f}, // rotateY(90deg)
70 {0.f, 1.f, 0.f, 180.f}, // rotateY(180deg)
71 {1.f, 0.f, 0.f, -90.f}, // rotateX(-90deg)
72 {1.f, 0.f, 0.f, 90.f}, // rotateX(90deg)
73 };
74 SkColor faceColors[6] = {
75 SK_ColorRED,
76 SK_ColorGREEN,
77 SK_ColorBLUE,
78 SK_ColorYELLOW,
79 SkColorSetARGB(0xFF, 0xFF, 0xA5, 0x00), // orange css
80 SkColorSetARGB(0xFF, 0x80, 0x00, 0x80) // purple css
81 };
Michael Ludwig949ceb22020-02-07 10:14:45 -050082
Michael Ludwig08f1a252020-01-22 14:32:11 -050083 for (int i = 0; i < 6; ++i) {
Mike Reed2a7c6192020-02-21 11:19:20 -050084 SkM44 model = SkM44::Rotate({axisAngles[i].x, axisAngles[i].y, axisAngles[i].z},
Michael Ludwig08f1a252020-01-22 14:32:11 -050085 SkDegreesToRadians(axisAngles[i].w));
86 model = SkM44::Translate(radius, radius) * proj * // project and place content
87 zoom * rotateHorizontal * model * postZoom * // main model matrix
88 SkM44::Translate(-radius, -radius); // center content
89
90 canvas->save();
Mike Reed3ef77dd2020-04-06 10:41:09 -040091 canvas->concat(model);
Michael Ludwig08f1a252020-01-22 14:32:11 -050092
93 SkPaint fillPaint;
94 fillPaint.setAntiAlias(true);
Michael Ludwig949ceb22020-02-07 10:14:45 -050095 fillPaint.setFilterQuality(kLow_SkFilterQuality);
Michael Ludwig08f1a252020-01-22 14:32:11 -050096 fillPaint.setColor(faceColors[i]);
97
Michael Ludwig949ceb22020-02-07 10:14:45 -050098 // Leverages GrFillRectOp on GPU backend
Michael Ludwig08f1a252020-01-22 14:32:11 -050099 canvas->drawRect(SkRect::MakeWH(viewportWidth, viewportWidth), fillPaint);
Michael Ludwig949ceb22020-02-07 10:14:45 -0500100
101 // Leverages GrTextureOp on GPU backend, to ensure sure both quad paths handle clipping
102 canvas->drawImageRect(fCubeImage.get(),
103 SkRect::MakeWH(fCubeImage->width(), fCubeImage->height()),
104 SkRect::MakeWH(viewportWidth, viewportWidth), &fillPaint,
105 SkCanvas::kFast_SrcRectConstraint);
106
Michael Ludwig08f1a252020-01-22 14:32:11 -0500107 canvas->restore();
108 }
109 }
110private:
111 static const int kMaxVW = 800;
112 static const int kMinVW = 300;
Michael Ludwig949ceb22020-02-07 10:14:45 -0500113
Michael Ludwig08f1a252020-01-22 14:32:11 -0500114 SkScalar fTime;
Michael Ludwig949ceb22020-02-07 10:14:45 -0500115 sk_sp<SkImage> fCubeImage;
Michael Ludwig08f1a252020-01-22 14:32:11 -0500116};
117
118DEF_GM(return new CrBug224618GM();)