| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/quads/draw_polygon.h" | 5 #include "cc/quads/draw_polygon.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 DrawPolygon::DrawPolygon(const DrawQuad* original, | 39 DrawPolygon::DrawPolygon(const DrawQuad* original, |
| 40 const std::vector<gfx::Point3F>& in_points, | 40 const std::vector<gfx::Point3F>& in_points, |
| 41 const gfx::Vector3dF& normal, | 41 const gfx::Vector3dF& normal, |
| 42 int draw_order_index) | 42 int draw_order_index) |
| 43 : order_index_(draw_order_index), original_ref_(original), is_split_(true) { | 43 : order_index_(draw_order_index), original_ref_(original), is_split_(true) { |
| 44 for (size_t i = 0; i < in_points.size(); i++) { | 44 for (size_t i = 0; i < in_points.size(); i++) { |
| 45 points_.push_back(in_points[i]); | 45 points_.push_back(in_points[i]); |
| 46 } | 46 } |
| 47 normal_ = normal; | 47 normal_ = normal; |
| 48 DCHECK_LE((ConstructNormal(), (normal_ - normal).Length()), |
| 49 normalized_threshold); |
| 48 } | 50 } |
| 49 | 51 |
| 50 // This takes the original DrawQuad that this polygon should be based on, | 52 // This takes the original DrawQuad that this polygon should be based on, |
| 51 // a visible content rect to make the 4 corner points from, and a transformation | 53 // a visible content rect to make the 4 corner points from, and a transformation |
| 52 // to move it and its normal into screen space. | 54 // to move it and its normal into screen space. |
| 53 DrawPolygon::DrawPolygon(const DrawQuad* original_ref, | 55 DrawPolygon::DrawPolygon(const DrawQuad* original_ref, |
| 54 const gfx::RectF& visible_layer_rect, | 56 const gfx::RectF& visible_layer_rect, |
| 55 const gfx::Transform& transform, | 57 const gfx::Transform& transform, |
| 56 int draw_order_index) | 58 int draw_order_index) |
| 57 : normal_(0.0f, 0.0f, 1.0f), | 59 : normal_(0.0f, 0.0f, 1.0f), |
| 58 order_index_(draw_order_index), | 60 order_index_(draw_order_index), |
| 59 original_ref_(original_ref), | 61 original_ref_(original_ref), |
| 60 is_split_(false) { | 62 is_split_(false) { |
| 61 gfx::Point3F points[8]; | 63 gfx::Point3F points[8]; |
| 62 int num_vertices_in_clipped_quad; | 64 int num_vertices_in_clipped_quad; |
| 63 gfx::QuadF send_quad(visible_layer_rect); | 65 gfx::QuadF send_quad(visible_layer_rect); |
| 64 | 66 |
| 65 // Doing this mapping here is very important, since we can't just transform | 67 // Doing this mapping here is very important, since we can't just transform |
| 66 // the points without clipping and not run into strange geometry issues when | 68 // the points without clipping and not run into strange geometry issues when |
| 67 // crossing w = 0. At this point, in the constructor, we know that we're | 69 // crossing w = 0. At this point, in the constructor, we know that we're |
| 68 // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d | 70 // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d |
| 69 // function instead of writing a generic polygon version of it. | 71 // function instead of writing a generic polygon version of it. |
| 70 MathUtil::MapClippedQuad3d( | 72 MathUtil::MapClippedQuad3d( |
| 71 transform, send_quad, points, &num_vertices_in_clipped_quad); | 73 transform, send_quad, points, &num_vertices_in_clipped_quad); |
| 72 for (int i = 0; i < num_vertices_in_clipped_quad; i++) { | 74 for (int i = 0; i < num_vertices_in_clipped_quad; i++) { |
| 73 points_.push_back(points[i]); | 75 points_.push_back(points[i]); |
| 74 } | 76 } |
| 77 transform.TransformVector(&normal_); |
| 75 ConstructNormal(); | 78 ConstructNormal(); |
| 76 } | 79 } |
| 77 | 80 |
| 78 DrawPolygon::~DrawPolygon() { | 81 DrawPolygon::~DrawPolygon() { |
| 79 } | 82 } |
| 80 | 83 |
| 81 std::unique_ptr<DrawPolygon> DrawPolygon::CreateCopy() { | 84 std::unique_ptr<DrawPolygon> DrawPolygon::CreateCopy() { |
| 82 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon()); | 85 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon()); |
| 83 new_polygon->order_index_ = order_index_; | 86 new_polygon->order_index_ = order_index_; |
| 84 new_polygon->original_ref_ = original_ref_; | 87 new_polygon->original_ref_ = original_ref_; |
| 85 new_polygon->points_.reserve(points_.size()); | 88 new_polygon->points_.reserve(points_.size()); |
| 86 new_polygon->points_ = points_; | 89 new_polygon->points_ = points_; |
| 87 new_polygon->normal_.set_x(normal_.x()); | 90 new_polygon->normal_.set_x(normal_.x()); |
| 88 new_polygon->normal_.set_y(normal_.y()); | 91 new_polygon->normal_.set_y(normal_.y()); |
| 89 new_polygon->normal_.set_z(normal_.z()); | 92 new_polygon->normal_.set_z(normal_.z()); |
| 90 return new_polygon; | 93 return new_polygon; |
| 91 } | 94 } |
| 92 | 95 |
| 93 // | 96 // |
| 94 // If this were to be more generally used and expected to be applicable | 97 // If this were to be more generally used and expected to be applicable |
| 95 // replacing this with Newell's algorithm (or an improvement thereof) | 98 // replacing this with Newell's algorithm (or an improvement thereof) |
| 96 // would be preferable, but usually this is coming in from a rectangle | 99 // would be preferable, but usually this is coming in from a rectangle |
| 97 // that has been transformed to screen space and clipped. | 100 // that has been transformed to screen space and clipped. |
| 98 // Averaging a few near diagonal cross products is pretty good in that case. | 101 // Averaging a few near diagonal cross products is pretty good in that case. |
| 99 // | 102 // |
| 100 void DrawPolygon::ConstructNormal() { | 103 void DrawPolygon::ConstructNormal() { |
| 101 normal_.set_x(0.0f); | 104 gfx::Vector3dF new_normal(0.0f, 0.0f, 0.0f); |
| 102 normal_.set_y(0.0f); | |
| 103 normal_.set_z(0.0f); | |
| 104 int delta = points_.size() / 2; | 105 int delta = points_.size() / 2; |
| 105 for (size_t i = 1; i + delta < points_.size(); i++) { | 106 for (size_t i = 1; i + delta < points_.size(); i++) { |
| 106 normal_ += | 107 new_normal += |
| 107 CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]); | 108 CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]); |
| 108 } | 109 } |
| 109 float normal_magnitude = normal_.Length(); | 110 float normal_magnitude = new_normal.Length(); |
| 111 // Here we constrain the new normal to point in the same sense as the old one. |
| 112 // This allows us to handle winding-reversing transforms better. |
| 113 if (gfx::DotProduct(normal_, new_normal) < 0.0) { |
| 114 normal_magnitude *= -1.0; |
| 115 } |
| 110 if (normal_magnitude != 0 && normal_magnitude != 1) { | 116 if (normal_magnitude != 0 && normal_magnitude != 1) { |
| 111 normal_.Scale(1.0f / normal_magnitude); | 117 new_normal.Scale(1.0f / normal_magnitude); |
| 112 } | 118 } |
| 119 normal_ = new_normal; |
| 113 } | 120 } |
| 114 | 121 |
| 115 #if defined(OS_WIN) | 122 #if defined(OS_WIN) |
| 116 // | 123 // |
| 117 // Allows the unittest to invoke this for the more general constructor. | 124 // Allows the unittest to invoke this for the more general constructor. |
| 118 // | 125 // |
| 119 void DrawPolygon::RecomputeNormalForTesting() { | 126 void DrawPolygon::RecomputeNormalForTesting() { |
| 120 ConstructNormal(); | 127 ConstructNormal(); |
| 121 } | 128 } |
| 122 #endif | 129 #endif |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 for (size_t i = 0; i < points_.size(); i++) { | 243 for (size_t i = 0; i < points_.size(); i++) { |
| 237 transform.TransformPoint(&points_[i]); | 244 transform.TransformPoint(&points_[i]); |
| 238 } | 245 } |
| 239 } | 246 } |
| 240 | 247 |
| 241 // TransformToScreenSpace assumes we're moving a layer from its layer space | 248 // TransformToScreenSpace assumes we're moving a layer from its layer space |
| 242 // into 3D screen space, which for sorting purposes requires the normal to | 249 // into 3D screen space, which for sorting purposes requires the normal to |
| 243 // be transformed along with the vertices. | 250 // be transformed along with the vertices. |
| 244 void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) { | 251 void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) { |
| 245 ApplyTransform(transform); | 252 ApplyTransform(transform); |
| 253 transform.TransformVector(&normal_); |
| 246 ConstructNormal(); | 254 ConstructNormal(); |
| 247 } | 255 } |
| 248 | 256 |
| 249 // In the case of TransformToLayerSpace, we assume that we are giving the | 257 // In the case of TransformToLayerSpace, we assume that we are giving the |
| 250 // inverse transformation back to the polygon to move it back into layer space | 258 // inverse transformation back to the polygon to move it back into layer space |
| 251 // but we can ignore the costly process of applying the inverse to the normal | 259 // but we can ignore the costly process of applying the inverse to the normal |
| 252 // since we know the normal will just reset to its original state. | 260 // since we know the normal will just reset to its original state. |
| 253 void DrawPolygon::TransformToLayerSpace( | 261 void DrawPolygon::TransformToLayerSpace( |
| 254 const gfx::Transform& inverse_transform) { | 262 const gfx::Transform& inverse_transform) { |
| 255 ApplyTransform(inverse_transform); | 263 ApplyTransform(inverse_transform); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 quads->push_back( | 371 quads->push_back( |
| 364 gfx::QuadF(first, | 372 gfx::QuadF(first, |
| 365 gfx::PointF(points_[offset].x(), points_[offset].y()), | 373 gfx::PointF(points_[offset].x(), points_[offset].y()), |
| 366 gfx::PointF(points_[op1].x(), points_[op1].y()), | 374 gfx::PointF(points_[op1].x(), points_[op1].y()), |
| 367 gfx::PointF(points_[op2].x(), points_[op2].y()))); | 375 gfx::PointF(points_[op2].x(), points_[op2].y()))); |
| 368 offset = op2; | 376 offset = op2; |
| 369 } | 377 } |
| 370 } | 378 } |
| 371 | 379 |
| 372 } // namespace cc | 380 } // namespace cc |
| OLD | NEW |