Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(839)

Side by Side Diff: cc/layer_sorter.cc

Issue 11362024: added fix that deals with precision in layer sorter (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merging with tip of tree Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | cc/layer_sorter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "cc/layer_sorter.h" 5 #include "cc/layer_sorter.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 #include <limits> 9 #include <limits>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "cc/math_util.h" 13 #include "cc/math_util.h"
14 #include "cc/render_surface_impl.h" 14 #include "cc/render_surface_impl.h"
15 #include "ui/gfx/transform.h" 15 #include "ui/gfx/transform.h"
16 16
17 namespace cc { 17 namespace cc {
18 18
19 // This epsilon is used to determine if two layers are too close to each other
20 // to be able to tell which is in front of the other. It's a relative epsilon
21 // so it is robust to changes in scene scale. This value was chosen by picking
22 // a value near machine epsilon and then increasing it until the flickering on
23 // the test scene went away.
24 const float kLayerEpsilon = 1e-4f;
25
19 inline static float perpProduct(const gfx::Vector2dF& u, const gfx::Vector2dF& v ) 26 inline static float perpProduct(const gfx::Vector2dF& u, const gfx::Vector2dF& v )
20 { 27 {
21 return u.x() * v.y() - u.y() * v.x(); 28 return u.x() * v.y() - u.y() * v.x();
22 } 29 }
23 30
24 // Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Retu rns true and the 31 // Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Retu rns true and the
25 // point of intersection if they do and false otherwise. 32 // point of intersection if they do and false otherwise.
26 static bool edgeEdgeTest(const gfx::PointF& a, const gfx::PointF& b, const gfx:: PointF& c, const gfx::PointF& d, gfx::PointF& r) 33 static bool edgeEdgeTest(const gfx::PointF& a, const gfx::PointF& b, const gfx:: PointF& c, const gfx::PointF& d, gfx::PointF& r)
27 { 34 {
28 gfx::Vector2dF u = b - a; 35 gfx::Vector2dF u = b - a;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 69
63 LayerSorter::LayerSorter() 70 LayerSorter::LayerSorter()
64 : m_zRange(0) 71 : m_zRange(0)
65 { 72 {
66 } 73 }
67 74
68 LayerSorter::~LayerSorter() 75 LayerSorter::~LayerSorter()
69 { 76 {
70 } 77 }
71 78
79 static float const checkFloatingPointNumericAccuracy(float a, float b)
80 {
81 float absDif = std::abs(b - a);
82 float absMax = std::max(std::abs(b), std::abs(a));
83 // Check to see if we've got a result with a reasonable amount of error.
84 return absDif / absMax;
85 }
86
72 // Checks whether layer "a" draws on top of layer "b". The weight value returned is an indication of 87 // Checks whether layer "a" draws on top of layer "b". The weight value returned is an indication of
73 // the maximum z-depth difference between the layers or zero if the layers are f ound to be intesecting 88 // the maximum z-depth difference between the layers or zero if the layers are f ound to be intesecting
74 // (some features are in front and some are behind). 89 // (some features are in front and some are behind).
75 LayerSorter::ABCompareResult LayerSorter::checkOverlap(LayerShape* a, LayerShape * b, float zThreshold, float& weight) 90 LayerSorter::ABCompareResult LayerSorter::checkOverlap(LayerShape* a, LayerShape * b, float zThreshold, float& weight)
76 { 91 {
77 weight = 0; 92 weight = 0;
78 93
79 // Early out if the projected bounds don't overlap. 94 // Early out if the projected bounds don't overlap.
80 if (!a->projectedBounds.Intersects(b->projectedBounds)) 95 if (!a->projectedBounds.Intersects(b->projectedBounds))
81 return None; 96 return None;
(...skipping 21 matching lines...) Expand all
103 r)) 118 r))
104 overlapPoints.push_back(r); 119 overlapPoints.push_back(r);
105 120
106 if (overlapPoints.empty()) 121 if (overlapPoints.empty())
107 return None; 122 return None;
108 123
109 // Check the corresponding layer depth value for all overlap points to deter mine 124 // Check the corresponding layer depth value for all overlap points to deter mine
110 // which layer is in front. 125 // which layer is in front.
111 float maxPositive = 0; 126 float maxPositive = 0;
112 float maxNegative = 0; 127 float maxNegative = 0;
128
129 // This flag tracks the existance of a numerically accurate seperation
130 // between two layers. If there is no accurate seperation, the layers
131 // cannot be effectively sorted.
132 bool accurate = false;
133
113 for (unsigned o = 0; o < overlapPoints.size(); o++) { 134 for (unsigned o = 0; o < overlapPoints.size(); o++) {
114 float za = a->layerZFromProjectedPoint(overlapPoints[o]); 135 float za = a->layerZFromProjectedPoint(overlapPoints[o]);
115 float zb = b->layerZFromProjectedPoint(overlapPoints[o]); 136 float zb = b->layerZFromProjectedPoint(overlapPoints[o]);
116 137
138 // Here we attempt to avoid numeric issues with layers that are too
139 // close together. If we have 2-sided quads that are very close
140 // together then we will draw them in document order to avoid
141 // flickering. The correct solution is for the content maker to turn
142 // on back-face culling or move the quads apart (if they're not two
143 // sides of one object).
144 if (checkFloatingPointNumericAccuracy(za, zb) > kLayerEpsilon)
145 accurate = true;
146
117 float diff = za - zb; 147 float diff = za - zb;
118 if (diff > maxPositive) 148 if (diff > maxPositive)
119 maxPositive = diff; 149 maxPositive = diff;
120 if (diff < maxNegative) 150 if (diff < maxNegative)
121 maxNegative = diff; 151 maxNegative = diff;
122 } 152 }
123 153
154 // If we can't tell which should come first, we use document order.
155 if (!accurate)
156 return ABeforeB;
157
124 float maxDiff = (fabsf(maxPositive) > fabsf(maxNegative) ? maxPositive : max Negative); 158 float maxDiff = (fabsf(maxPositive) > fabsf(maxNegative) ? maxPositive : max Negative);
125 159
126 // If the results are inconsistent (and the z difference substantial to rule out 160 // If the results are inconsistent (and the z difference substantial to rule out
127 // numerical errors) then the layers are intersecting. We will still return an 161 // numerical errors) then the layers are intersecting. We will still return an
128 // order based on the maximum depth difference but with an edge weight of ze ro 162 // order based on the maximum depth difference but with an edge weight of ze ro
129 // these layers will get priority if a graph cycle is present and needs to b e broken. 163 // these layers will get priority if a graph cycle is present and needs to b e broken.
130 if (maxPositive > zThreshold && maxNegative < -zThreshold) 164 if (maxPositive > zThreshold && maxNegative < -zThreshold)
131 weight = 0; 165 weight = 0;
132 else 166 else
133 weight = fabsf(maxDiff); 167 weight = fabsf(maxDiff);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 *it = sortedList[count++]->layer; 437 *it = sortedList[count++]->layer;
404 438
405 DVLOG(2) << "Sorting end ----"; 439 DVLOG(2) << "Sorting end ----";
406 440
407 m_nodes.clear(); 441 m_nodes.clear();
408 m_edges.clear(); 442 m_edges.clear();
409 m_activeEdges.clear(); 443 m_activeEdges.clear();
410 } 444 }
411 445
412 } // namespace cc 446 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/layer_sorter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698