Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "cc/layer_sorter.h" | 7 #include "cc/layer_sorter.h" |
| 8 | 8 |
| 9 #include <deque> | 9 #include <deque> |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "cc/math_util.h" | 14 #include "cc/math_util.h" |
| 15 #include "cc/render_surface_impl.h" | 15 #include "cc/render_surface_impl.h" |
| 16 #include <public/WebTransformationMatrix.h> | 16 #include <public/WebTransformationMatrix.h> |
| 17 | 17 |
| 18 using namespace std; | 18 using namespace std; |
| 19 using WebKit::WebTransformationMatrix; | 19 using WebKit::WebTransformationMatrix; |
| 20 | 20 |
| 21 namespace cc { | 21 namespace cc { |
| 22 | 22 |
| 23 // This epsilon is used to determine if two layers are too close to each other | |
| 24 // to be able to tell which is in front of the other. It's a relative epsilon | |
| 25 // so it is robust to changes in scene scale. This value was chosen by picking | |
| 26 // a value near machine epsilon and then increasing it until the flickering on | |
| 27 // the test scene went away. | |
| 28 const float LAYER_EPSILON = 1e-4f; | |
|
enne (OOO)
2012/11/01 22:55:23
style nit: kLayerEpsilon
| |
| 29 | |
| 23 inline static float perpProduct(const gfx::Vector2dF& u, const gfx::Vector2dF& v ) | 30 inline static float perpProduct(const gfx::Vector2dF& u, const gfx::Vector2dF& v ) |
| 24 { | 31 { |
| 25 return u.x() * v.y() - u.y() * v.x(); | 32 return u.x() * v.y() - u.y() * v.x(); |
| 26 } | 33 } |
| 27 | 34 |
| 28 // Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Retu rns true and the | 35 // Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Retu rns true and the |
| 29 // point of intersection if they do and false otherwise. | 36 // point of intersection if they do and false otherwise. |
| 30 static bool edgeEdgeTest(const gfx::PointF& a, const gfx::PointF& b, const gfx:: PointF& c, const gfx::PointF& d, gfx::PointF& r) | 37 static bool edgeEdgeTest(const gfx::PointF& a, const gfx::PointF& b, const gfx:: PointF& c, const gfx::PointF& d, gfx::PointF& r) |
| 31 { | 38 { |
| 32 gfx::Vector2dF u = b - a; | 39 gfx::Vector2dF u = b - a; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 r)) | 114 r)) |
| 108 overlapPoints.push_back(r); | 115 overlapPoints.push_back(r); |
| 109 | 116 |
| 110 if (overlapPoints.empty()) | 117 if (overlapPoints.empty()) |
| 111 return None; | 118 return None; |
| 112 | 119 |
| 113 // Check the corresponding layer depth value for all overlap points to deter mine | 120 // Check the corresponding layer depth value for all overlap points to deter mine |
| 114 // which layer is in front. | 121 // which layer is in front. |
| 115 float maxPositive = 0; | 122 float maxPositive = 0; |
| 116 float maxNegative = 0; | 123 float maxNegative = 0; |
| 124 | |
| 125 // This flag tracks the existance of a numerically accurate seperation | |
| 126 // between two layers. If there is no accurate seperation, the layers | |
| 127 // cannot be effectively sorted. | |
| 128 bool accurate = false; | |
|
shawnsingh
2012/11/01 23:03:57
Could we move the computation of "accurate" and as
| |
| 129 | |
| 117 for (unsigned o = 0; o < overlapPoints.size(); o++) { | 130 for (unsigned o = 0; o < overlapPoints.size(); o++) { |
| 118 float za = a->layerZFromProjectedPoint(overlapPoints[o]); | 131 float za = a->layerZFromProjectedPoint(overlapPoints[o]); |
| 119 float zb = b->layerZFromProjectedPoint(overlapPoints[o]); | 132 float zb = b->layerZFromProjectedPoint(overlapPoints[o]); |
| 120 | 133 |
| 134 // Here we attempt to avoid numeric issues with layers that are too | |
| 135 // close together. If we have 2-sided quads that are very close | |
| 136 // together then we will draw them in document order to avoid | |
| 137 // flickering. The correct solution is for the content maker to turn | |
| 138 // on back-face culling or move the quads apart (if they're not two | |
| 139 // sides of one object). | |
| 140 float absDif = fabsf(zb - za); | |
| 141 float absMax = fmax(fabs(zb), fabs(za)); | |
|
shawnsingh
2012/11/01 23:03:57
We probably should be consistent in our usage of f
danakj
2012/11/01 23:06:34
Why aren't we using std::abs() from <cmath> ?
| |
| 142 // Check to see if we've got a result with a reasonable amount of error. | |
| 143 if (absDif > LAYER_EPSILON * absMax) | |
|
shawnsingh
2012/11/01 23:03:57
I'm still not understanding exactly how this check
| |
| 144 accurate = true; | |
| 145 | |
| 121 float diff = za - zb; | 146 float diff = za - zb; |
| 122 if (diff > maxPositive) | 147 if (diff > maxPositive) |
| 123 maxPositive = diff; | 148 maxPositive = diff; |
| 124 if (diff < maxNegative) | 149 if (diff < maxNegative) |
| 125 maxNegative = diff; | 150 maxNegative = diff; |
| 126 } | 151 } |
| 127 | 152 |
| 153 // If we can't tell which should come first, we use document order. | |
| 154 if (!accurate) | |
| 155 return ABeforeB; | |
| 156 | |
| 128 float maxDiff = (fabsf(maxPositive) > fabsf(maxNegative) ? maxPositive : max Negative); | 157 float maxDiff = (fabsf(maxPositive) > fabsf(maxNegative) ? maxPositive : max Negative); |
| 129 | 158 |
| 130 // If the results are inconsistent (and the z difference substantial to rule out | 159 // If the results are inconsistent (and the z difference substantial to rule out |
| 131 // numerical errors) then the layers are intersecting. We will still return an | 160 // numerical errors) then the layers are intersecting. We will still return an |
| 132 // order based on the maximum depth difference but with an edge weight of ze ro | 161 // order based on the maximum depth difference but with an edge weight of ze ro |
| 133 // these layers will get priority if a graph cycle is present and needs to b e broken. | 162 // these layers will get priority if a graph cycle is present and needs to b e broken. |
| 134 if (maxPositive > zThreshold && maxNegative < -zThreshold) | 163 if (maxPositive > zThreshold && maxNegative < -zThreshold) |
| 135 weight = 0; | 164 weight = 0; |
| 136 else | 165 else |
| 137 weight = fabsf(maxDiff); | 166 weight = fabsf(maxDiff); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 *it = sortedList[count++]->layer; | 436 *it = sortedList[count++]->layer; |
| 408 | 437 |
| 409 DVLOG(2) << "Sorting end ----"; | 438 DVLOG(2) << "Sorting end ----"; |
| 410 | 439 |
| 411 m_nodes.clear(); | 440 m_nodes.clear(); |
| 412 m_edges.clear(); | 441 m_edges.clear(); |
| 413 m_activeEdges.clear(); | 442 m_activeEdges.clear(); |
| 414 } | 443 } |
| 415 | 444 |
| 416 } | 445 } |
| OLD | NEW |