summaryrefslogtreecommitdiffstats
path: root/cc/quads/draw_polygon.cc
diff options
context:
space:
mode:
authorpetermayo <petermayo@chromium.org>2015-12-10 07:42:05 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-10 15:42:56 +0000
commit5240189cba88ed90ef654310c064d588c022f837 (patch)
tree831e35e47ac508f3ec9906f6653ac954f7bad6e7 /cc/quads/draw_polygon.cc
parent096b91575a69187a3f9e7b6484db5ac8ee9ed452 (diff)
downloadchromium_src-5240189cba88ed90ef654310c064d588c022f837.zip
chromium_src-5240189cba88ed90ef654310c064d588c022f837.tar.gz
chromium_src-5240189cba88ed90ef654310c064d588c022f837.tar.bz2
Replace inverse transform with Cross-product computation.
This changes how we compute the 3d normals for quads moved into a 3d context. The inverse transform approach seems to suffer numeric instability around small Y rotations that invert the normal, causing artifacts during rotation animations. BUG=565758 TEST=observe 565758#2 html, and see no flicker at the start of the twist. R=vollick@chromium.org CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1497153002 Cr-Commit-Position: refs/heads/master@{#364367}
Diffstat (limited to 'cc/quads/draw_polygon.cc')
-rw-r--r--cc/quads/draw_polygon.cc35
1 files changed, 33 insertions, 2 deletions
diff --git a/cc/quads/draw_polygon.cc b/cc/quads/draw_polygon.cc
index b4f132a..b279fe6 100644
--- a/cc/quads/draw_polygon.cc
+++ b/cc/quads/draw_polygon.cc
@@ -70,7 +70,7 @@ DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
for (int i = 0; i < num_vertices_in_clipped_quad; i++) {
points_.push_back(points[i]);
}
- ApplyTransformToNormal(transform);
+ ConstructNormal();
}
DrawPolygon::~DrawPolygon() {
@@ -88,6 +88,37 @@ scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() {
return new_polygon;
}
+//
+// If this were to be more generally used and expected to be applicable
+// replacing this with Newell's algorithm (or an improvement thereof)
+// would be preferable, but usually this is coming in from a rectangle
+// that has been transformed to screen space and clipped.
+// Averaging a few near diagonal cross products is pretty good in that case.
+//
+void DrawPolygon::ConstructNormal() {
+ normal_.set_x(0.0f);
+ normal_.set_y(0.0f);
+ normal_.set_z(0.0f);
+ int delta = points_.size() / 2;
+ for (size_t i = 1; i + delta < points_.size(); i++) {
+ normal_ +=
+ CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]);
+ }
+ float normal_magnitude = normal_.Length();
+ if (normal_magnitude != 0 && normal_magnitude != 1) {
+ normal_.Scale(1.0f / normal_magnitude);
+ }
+}
+
+#if defined(OS_WIN)
+//
+// Allows the unittest to invoke this for the more general constructor.
+//
+void DrawPolygon::RecomputeNormalForTesting() {
+ ConstructNormal();
+}
+#endif
+
float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const {
return gfx::DotProduct(point - points_[0], normal_);
}
@@ -210,7 +241,7 @@ void DrawPolygon::ApplyTransform(const gfx::Transform& transform) {
// be transformed along with the vertices.
void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) {
ApplyTransform(transform);
- ApplyTransformToNormal(transform);
+ ConstructNormal();
}
// In the case of TransformToLayerSpace, we assume that we are giving the