Add GM reproducing perspective failures
Modeled on https://codepen.io/adamdupuis/pen/qLYzqB, this GM creates a cube of rectangles with the camera at the center. It animates the FOV since the original chrome issue was most visible when resizing the page (which then updated the fov of the perspective css transform). This draws correctly with the raster backend. There are two issues it causes with Ganesh: 1. The input coordinates of some of the cube faces have 0 or negative ws. - When negative, the current bounds code does not perform clipping and just uses the mirrored point, which leads to misleading bounds. - When 0, the current bounds code produces infinities, and then GrOpsTask discards the op with non-finite bounds. 2. The anti-aliasing code also ignores w <= 0, and so all of its screen space math is incorrect. This causes a mix of completely discarded draws and distorted draws on the GPU backend. Bug: skia:9779, chromium:224618 Change-Id: Ib00b909f51cbf7aaba5b89ed830ddc720ad3c73d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/265763 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
db38022b7c
commit
08f1a25aad
96
gm/crbug_224618.cpp
Normal file
96
gm/crbug_224618.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2020 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/SkColor.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkMatrix44.h"
|
||||
#include "include/private/SkM44.h"
|
||||
#include "tools/timer/TimeUtils.h"
|
||||
|
||||
static SkM44 rotate_axis_angle(SkScalar x, SkScalar y, SkScalar z, SkScalar radians) {
|
||||
// SkM44 doesn't expose any rotation factories yet
|
||||
SkMatrix44 m;
|
||||
m.setRotateAboutUnit(x, y, z, radians);
|
||||
return SkM44(m);
|
||||
}
|
||||
|
||||
// Adapted from https://codepen.io/adamdupuis/pen/qLYzqB
|
||||
class CrBug224618GM : public skiagm::GM {
|
||||
public:
|
||||
CrBug224618GM() : fTime(0.f) {}
|
||||
|
||||
protected:
|
||||
SkString onShortName() override {
|
||||
return SkString("crbug_224618");
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(kMaxVW, kMaxVW);
|
||||
}
|
||||
|
||||
// This animates the FOV in viewer, to ensure the panorama covering rects are stable across
|
||||
// a variety of perspective matrices
|
||||
bool onAnimate(double nanos) override {
|
||||
fTime = TimeUtils::Scaled(1e-9f * nanos, 0.5f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkScalar viewportWidth = SkScalarMod(fTime, 10.f) / 10.f * (kMaxVW - kMinVW) + kMinVW;
|
||||
SkScalar radius = viewportWidth / 2.f; // round?
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/perspective
|
||||
SkM44 proj{1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, -1.f / radius, 1.f};
|
||||
SkM44 zoom = SkM44::Translate(0.f, 0.f, radius);
|
||||
SkM44 postZoom = SkM44::Translate(0.f, 0.f, -radius - 1.f);
|
||||
SkM44 rotateHorizontal = rotate_axis_angle(0.f, 1.f, 0.f, 2.356194490192345f);
|
||||
|
||||
// w in degrees will need to be converted to radians
|
||||
SkV4 axisAngles[6] = {
|
||||
{0.f, 1.f, 0.f, -90.f}, // rotateY(-90deg)
|
||||
{1.f, 0.f, 0.f, 0.f}, // <none>
|
||||
{0.f, 1.f, 0.f, 90.f}, // rotateY(90deg)
|
||||
{0.f, 1.f, 0.f, 180.f}, // rotateY(180deg)
|
||||
{1.f, 0.f, 0.f, -90.f}, // rotateX(-90deg)
|
||||
{1.f, 0.f, 0.f, 90.f}, // rotateX(90deg)
|
||||
};
|
||||
SkColor faceColors[6] = {
|
||||
SK_ColorRED,
|
||||
SK_ColorGREEN,
|
||||
SK_ColorBLUE,
|
||||
SK_ColorYELLOW,
|
||||
SkColorSetARGB(0xFF, 0xFF, 0xA5, 0x00), // orange css
|
||||
SkColorSetARGB(0xFF, 0x80, 0x00, 0x80) // purple css
|
||||
};
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
SkM44 model = rotate_axis_angle(axisAngles[i].x, axisAngles[i].y, axisAngles[i].z,
|
||||
SkDegreesToRadians(axisAngles[i].w));
|
||||
model = SkM44::Translate(radius, radius) * proj * // project and place content
|
||||
zoom * rotateHorizontal * model * postZoom * // main model matrix
|
||||
SkM44::Translate(-radius, -radius); // center content
|
||||
|
||||
canvas->save();
|
||||
canvas->experimental_concat44(model);
|
||||
|
||||
SkPaint fillPaint;
|
||||
fillPaint.setAntiAlias(true);
|
||||
fillPaint.setColor(faceColors[i]);
|
||||
|
||||
canvas->drawRect(SkRect::MakeWH(viewportWidth, viewportWidth), fillPaint);
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
private:
|
||||
static const int kMaxVW = 800;
|
||||
static const int kMinVW = 300;
|
||||
SkScalar fTime;
|
||||
};
|
||||
|
||||
DEF_GM(return new CrBug224618GM();)
|
Loading…
Reference in New Issue
Block a user