summaryrefslogtreecommitdiffstats
path: root/cc/quads/draw_polygon.cc
diff options
context:
space:
mode:
authorawoloszyn <awoloszyn@chromium.org>2015-03-12 07:38:32 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-12 14:39:32 +0000
commit3d8eb1d841ec1ea36906d351bc65af4d7d27718a (patch)
treec5bdd8bbc4df5a7080973ba2c6c03efce11077d9 /cc/quads/draw_polygon.cc
parent884896c72542201a64c42ad20048e5b321ec3b81 (diff)
downloadchromium_src-3d8eb1d841ec1ea36906d351bc65af4d7d27718a.zip
chromium_src-3d8eb1d841ec1ea36906d351bc65af4d7d27718a.tar.gz
chromium_src-3d8eb1d841ec1ea36906d351bc65af4d7d27718a.tar.bz2
Splitting of layers for correct intersections
Sorting 3d-sorted layers and rendering them in that order causes issues when layers intersect. Instead place 3d-sorted layers in a bsp tree and fragment any intersecting layers into non-rectangular quads. We can then render the fragments in the correct sorted order regardless of intersections. BUG=455918,159225,132122,230833 Review URL: https://codereview.chromium.org/595593002 Cr-Commit-Position: refs/heads/master@{#320276}
Diffstat (limited to 'cc/quads/draw_polygon.cc')
-rw-r--r--cc/quads/draw_polygon.cc33
1 files changed, 22 insertions, 11 deletions
diff --git a/cc/quads/draw_polygon.cc b/cc/quads/draw_polygon.cc
index 026be2c..6544b64 100644
--- a/cc/quads/draw_polygon.cc
+++ b/cc/quads/draw_polygon.cc
@@ -12,7 +12,7 @@
namespace {
// This allows for some imperfection in the normal comparison when checking if
// two pieces of geometry are coplanar.
-static const float coplanar_dot_epsilon = 0.01f;
+static const float coplanar_dot_epsilon = 0.001f;
// This threshold controls how "thick" a plane is. If a point's distance is
// <= |compare_threshold|, then it is considered on the plane. Only when this
// boundary is crossed do we consider doing splitting.
@@ -25,21 +25,23 @@ static const float compare_threshold = 1.0f;
// points that SHOULD be intersecting the "thick plane", but actually fail to
// test positively for it because |split_threshold| allowed them to be outside
// this range.
+// This is really supposd to be compare_threshold / 2.0f, but that would
+// create another static initializer.
static const float split_threshold = 0.5f;
+
+static const float normalized_threshold = 0.001f;
} // namespace
namespace cc {
-gfx::Vector3dF DrawPolygon::default_normal = gfx::Vector3dF(0.0f, 0.0f, -1.0f);
-
DrawPolygon::DrawPolygon() {
}
-DrawPolygon::DrawPolygon(DrawQuad* original,
+DrawPolygon::DrawPolygon(const DrawQuad* original,
const std::vector<gfx::Point3F>& in_points,
const gfx::Vector3dF& normal,
int draw_order_index)
- : order_index_(draw_order_index), original_ref_(original) {
+ : order_index_(draw_order_index), original_ref_(original), is_split_(true) {
for (size_t i = 0; i < in_points.size(); i++) {
points_.push_back(in_points[i]);
}
@@ -49,12 +51,14 @@ DrawPolygon::DrawPolygon(DrawQuad* original,
// This takes the original DrawQuad that this polygon should be based on,
// a visible content rect to make the 4 corner points from, and a transformation
// to move it and its normal into screen space.
-DrawPolygon::DrawPolygon(DrawQuad* original_ref,
+DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
const gfx::RectF& visible_content_rect,
const gfx::Transform& transform,
int draw_order_index)
- : order_index_(draw_order_index), original_ref_(original_ref) {
- normal_ = default_normal;
+ : normal_(0.0f, 0.0f, 1.0f),
+ order_index_(draw_order_index),
+ original_ref_(original_ref),
+ is_split_(false) {
gfx::Point3F points[8];
int num_vertices_in_clipped_quad;
gfx::QuadF send_quad(visible_content_rect);
@@ -97,6 +101,9 @@ float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const {
// Assumes that layers are split and there are no intersecting planes.
BspCompareResult DrawPolygon::SideCompare(const DrawPolygon& a,
const DrawPolygon& b) {
+ // Let's make sure that both of these are normalized.
+ DCHECK_GE(normalized_threshold, std::abs(a.normal_.LengthSquared() - 1.0f));
+ DCHECK_GE(normalized_threshold, std::abs(b.normal_.LengthSquared() - 1.0f));
// Right away let's check if they're coplanar
double dot = gfx::DotProduct(a.normal_, b.normal_);
float sign = 0.0f;
@@ -105,7 +112,7 @@ BspCompareResult DrawPolygon::SideCompare(const DrawPolygon& a,
if (std::abs(dot) >= 1.0f - coplanar_dot_epsilon) {
normal_match = true;
// The normals are matching enough that we only have to test one point.
- sign = gfx::DotProduct(a.points_[0] - b.points_[0], b.normal_);
+ sign = b.SignedPointDistance(a.points_[0]);
// Is it on either side of the splitter?
if (sign < -compare_threshold) {
return BSP_BACK;
@@ -168,7 +175,7 @@ static bool LineIntersectPlane(const gfx::Point3F& line_start,
// The case where one vertex lies on the thick-plane and the other
// is outside of it.
- if (std::abs(start_distance) < distance_threshold &&
+ if (std::abs(start_distance) <= distance_threshold &&
std::abs(end_distance) > distance_threshold) {
intersection->SetPoint(line_start.x(), line_start.y(), line_start.z());
return true;
@@ -270,7 +277,7 @@ bool DrawPolygon::Split(const DrawPolygon& splitter,
break;
}
}
- if (current_vertex++ > points_size) {
+ if (current_vertex++ > (points_size)) {
break;
}
}
@@ -284,6 +291,7 @@ bool DrawPolygon::Split(const DrawPolygon& splitter,
// First polygon.
out_points[0].push_back(intersections[0]);
+ DCHECK_GE(vertex_before[1], start1);
for (size_t i = start1; i <= vertex_before[1]; i++) {
out_points[0].push_back(points_[i]);
--points_remaining;
@@ -306,6 +314,9 @@ bool DrawPolygon::Split(const DrawPolygon& splitter,
scoped_ptr<DrawPolygon> poly2(
new DrawPolygon(original_ref_, out_points[1], normal_, order_index_));
+ DCHECK_GE(poly1->points().size(), 3u);
+ DCHECK_GE(poly2->points().size(), 3u);
+
if (SideCompare(*poly1, splitter) == BSP_FRONT) {
*front = poly1.Pass();
*back = poly2.Pass();