8000 chore: cherry-pick b0d3d3e85fa6 from skia by nornagon · Pull Request #27612 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chore: cherry-pick b0d3d3e85fa6 from skia #27612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions patches/skia/.patches
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
backport_1080481.patch
mallocpixelref_should_always_allocate_as_large_as_computebytesize.patch
cherry-pick-6763a713f957.patch
cherry-pick-b0d3d3e85fa6.patch
158 changes: 158 additions & 0 deletions patches/skia/cherry-pick-b0d3d3e85fa6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Salomon <bsalomon@google.com>
Date: Tue, 19 Jan 2021 10:28:15 -0500
Subject: Fix DrawEdgeAAQuad degenerate issue where 3D points don't correctly
project to 2D points.

Bug: chromium:1162942

Change-Id: Idc1dcb725ff9eae651b84de2fe792b188dcd1c1b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354671
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
(cherry picked from commit 7656c4b7e89b4ff00480a6d7a8a19e3fd0e5c86e)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360376
Reviewed-by: Brian Salomon <bsalomon@google.com>

diff --git a/gm/crbug_1162942.cpp b/gm/crbug_1162942.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5d1f6360f3d68e1d3e353752e2e676928c93aef
--- /dev/null
+++ b/gm/crbug_1162942.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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/SkMatrix.h"
+#include "include/core/SkRect.h"
+
+// This tests a scenario where when the 2D projection of a perspective quad is inset we degenerate
+// the inset 2d geometry to a triangle because an inset vertex crosses the opposite edge. When we
+// project back to 3D and try to move the original verts along the original edges so that they
+// project to the 2D points. Whether an edge can be moved along depends on whether the adjacent edge
+// at the vertex is AA. However, in the degenerate triangle case the 2D point may not fall along
+// either of the edges. Thus, if we're constrained to moving along one edge and solve for X or Y the
+// other value may go wildly away from projecting to the 2D value. The current approach is to force
+// AA on at both edges that meet at a vertex whose inset point has been replaced by an off-edge
+// point if either is AA originally. This gives us an additional vector to move along so that we can
+// find a 3D point that projects to the 2D point in both X and Y.
+DEF_SIMPLE_GM(crbug_1162942, canvas, 620, 200) {
+ // Matrix and quad values taken from Chrome repro scenario.
+ SkMatrix ctm = SkMatrix::MakeAll(
+ SkBits2Float(0x3FCC7F75), SkBits2Float(0x3D5784FC), SkBits2Float(0x44C48C99),
+ SkBits2Float(0x3F699F7F), SkBits2Float(0x3E0A0D37), SkBits2Float(0x43908518),
+ SkBits2Float(0x3AA17423), SkBits2Float(0x3A6CCDC3), SkBits2Float(0x3F2EFEEC));
+ ctm.postTranslate(-1500.f, -325.f);
+
+ SkPoint pts[4] = {{SkBits2Float(0x3F39778B), SkBits2Float(0x43FF7FFC)},
+ {SkBits2Float(0x0), SkBits2Float(0x43FF7FFA)},
+ {SkBits2Float(0xB83B055E), SkBits2Float(0x42500003)},
+ {SkBits2Float(0x3F39776F), SkBits2Float(0x4250000D)}};
+ SkRect bounds;
+ bounds.setBounds(pts, 4);
+
+ canvas->clear(SK_ColorWHITE);
+
+ SkCanvas::QuadAAFlags flags[] = {
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag ),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag | SkCanvas::kRight_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kBottom_QuadAAFlag),
+ };
+
+ SkColor color = SK_ColorGREEN;
+ for (auto aaFlags : flags) {
+ canvas->save();
+ canvas->concat(ctm);
+ canvas->experimental_DrawEdgeAAQuad(bounds, pts, aaFlags, color, SkBlendMode::kSrcOver);
+ SkColor rgb = color & 0x00FFFFFF;
+ color = 0xFF000000 | (rgb << 4) | (rgb >> 20);
+ canvas->restore();
+ canvas->translate(0, 25);
+ }
+}
+
diff --git a/gn/gm.gni b/gn/gm.gni
index 83ca03f8e83bd3f809a5eb5df609be2dae793095..be5060443e5975fc085270ee729d6cff28df9840 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -105,6 +105,7 @@ gm_sources = [
"$_gm/convexpolyclip.cpp",
"$_gm/convexpolyeffect.cpp",
"$_gm/copy_to_4444.cpp",
+ "$_gm/crbug_1162942.cpp",
"$_gm/crbug_224618.cpp",
"$_gm/crbug_691386.cpp",
"$_gm/crbug_788500.cpp",
diff --git a/src/gpu/geometry/GrQuadUtils.cpp b/src/gpu/geometry/GrQuadUtils.cpp
index 9650758a87695bec8df342d7d645bf7e71301e23..95442e3f678df42c3b5584c78985aa0df151668e 100644
--- a/src/gpu/geometry/GrQuadUtils.cpp
+++ b/src/gpu/geometry/GrQuadUtils.cpp
@@ -717,7 +717,10 @@ V4f TessellationHelper::EdgeEquations::estimateCoverage(const V4f& x2d, const V4
}

int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEdgeDistances,
- V4f* x2d, V4f* y2d) const {
+ V4f* x2d, V4f* y2d,
+ M4f* aaMask) const {
+ *aaMask = signedEdgeDistances != 0.f;
+
// Move the edge by the signed edge adjustment.
V4f oc = fC + signedEdgeDistances;

@@ -792,10 +795,19 @@ int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEd
if (SkScalarAbs(eDenom[0]) > kTolerance) {
px = if_then_else(d1v0, V4f(ex[0]), px);
py = if_then_else(d1v0, V4f(ey[0]), py);
+ // If we replace a vertex with an intersection then it will not fall along the
+ // edges that intersect at the original vertex. When we apply AA later to the
+ // original points we move along the original 3d edges to move towards the 2d
+ // points we're computing here. If we have an AA edge and a non-AA edge we
+ // can only move along 1 edge, but now the point we're moving toward isn't
+ // on that edge. Thus, we provide an additional degree of freedom by turning
+ // AA on for both edges if either edge is AA.
+ *aaMask = *aaMask | (d1v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
}
if (SkScalarAbs(eDenom[1]) > kTolerance) {
px = if_then_else(d2v0, V4f(ex[1]), px);
py = if_then_else(d2v0, V4f(ey[1]), py);
+ *aaMask = *aaMask | (d2v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
}

*x2d = px;
@@ -1156,9 +1168,11 @@ int TessellationHelper::adjustDegenerateVertices(const skvx::Vec<4, float>& sign
// handles perspective).
V4f x2d = fEdgeVectors.fX2D;
V4f y2d = fEdgeVectors.fY2D;
+
+ M4f aaMask;
int vertexCount = this->getEdgeEquations().computeDegenerateQuad(signedEdgeDistances,
- &x2d, &y2d);
- vertices->moveTo(x2d, y2d, signedEdgeDistances != 0.f);
+ &x2d, &y2d, &aaMask);
+ vertices->moveTo(x2d, y2d, aaMask);
return vertexCount;
}
}
diff --git a/src/gpu/geometry/GrQuadUtils.h b/src/gpu/geometry/GrQuadUtils.h
index dbbc4626e5cfb16db0e832e47477132f410ff13b..50b647bdb9c0efbf6faf8002f706b24ad0f0a2e3 100644
--- a/src/gpu/geometry/GrQuadUtils.h
+++ b/src/gpu/geometry/GrQuadUtils.h
@@ -111,7 +111,8 @@ namespace GrQuadUtils {
// small, edges are near parallel, or edges are very short/zero-length. Returns number
// of effective vertices in the degenerate quad.
int computeDegenerateQuad(const skvx::Vec<4, float>& signedEdgeDistances,
- skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d) const;
+ skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d,
+ skvx::Vec<4, int32_t>* aaMask) const;
};

struct OutsetRequest {
0