diff options
Diffstat (limited to 'cc')
-rw-r--r-- | cc/base/math_util.cc | 13 | ||||
-rw-r--r-- | cc/base/math_util.h | 7 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 2 | ||||
-rw-r--r-- | cc/output/overlay_candidate.cc | 56 | ||||
-rw-r--r-- | cc/output/overlay_candidate.h | 2 | ||||
-rw-r--r-- | cc/output/overlay_strategy_common.cc | 3 | ||||
-rw-r--r-- | cc/output/overlay_unittest.cc | 100 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 2 | ||||
-rw-r--r-- | cc/quads/draw_quad_unittest.cc | 14 | ||||
-rw-r--r-- | cc/quads/texture_draw_quad.cc | 12 | ||||
-rw-r--r-- | cc/quads/texture_draw_quad.h | 6 |
11 files changed, 183 insertions, 34 deletions
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc index e2fd565..969e52a 100644 --- a/cc/base/math_util.cc +++ b/cc/base/math_util.cc @@ -15,6 +15,7 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/vector2d_f.h" +#include "ui/gfx/geometry/vector3d_f.h" #include "ui/gfx/transform.h" namespace cc { @@ -867,4 +868,16 @@ float MathUtil::AsFloatSafely(float value) { return std::min(value, std::numeric_limits<float>::max()); } +gfx::Vector3dF MathUtil::GetXAxis(const gfx::Transform& transform) { + return gfx::Vector3dF(transform.matrix().getFloat(0, 0), + transform.matrix().getFloat(1, 0), + transform.matrix().getFloat(2, 0)); +} + +gfx::Vector3dF MathUtil::GetYAxis(const gfx::Transform& transform) { + return gfx::Vector3dF(transform.matrix().getFloat(0, 1), + transform.matrix().getFloat(1, 1), + transform.matrix().getFloat(2, 1)); +} + } // namespace cc diff --git a/cc/base/math_util.h b/cc/base/math_util.h index 56fdd17..749b9bd 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h @@ -33,6 +33,7 @@ class RectF; class Transform; class Vector2dF; class Vector2d; +class Vector3dF; } namespace cc { @@ -240,6 +241,12 @@ class CC_EXPORT MathUtil { // If the value is inf, returns max double/float representation. static double AsDoubleSafely(double value); static float AsFloatSafely(float value); + + // Returns vector that x axis (1,0,0) transforms to under given transform. + static gfx::Vector3dF GetXAxis(const gfx::Transform& transform); + + // Returns vector that y axis (0,1,0) transforms to under given transform. + static gfx::Vector3dF GetYAxis(const gfx::Transform& transform); }; } // namespace cc diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index cfe319b..bdb537a 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -72,7 +72,7 @@ Float4 UVTransform(const TextureDrawQuad* quad) { gfx::PointF uv0 = quad->uv_top_left; gfx::PointF uv1 = quad->uv_bottom_right; Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}}; - if (quad->flipped) { + if (quad->y_flipped) { xform.data[1] = 1.0f - xform.data[1]; xform.data[3] = -xform.data[3]; } diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc index 0cbd3de..7a82570 100644 --- a/cc/output/overlay_candidate.cc +++ b/cc/output/overlay_candidate.cc @@ -5,11 +5,35 @@ #include "cc/output/overlay_candidate.h" #include <algorithm> +#include <limits> #include "base/logging.h" +#include "cc/base/math_util.h" #include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/geometry/vector3d_f.h" namespace cc { +namespace { +// Tolerance for considering axis vector elements to be zero. +const SkMScalar kEpsilon = std::numeric_limits<float>::epsilon(); + +enum Axis { NONE, AXIS_POS_X, AXIS_NEG_X, AXIS_POS_Y, AXIS_NEG_Y }; + +Axis VectorToAxis(const gfx::Vector3dF& vec) { + if (std::abs(vec.z()) > kEpsilon) + return NONE; + const bool x_zero = (std::abs(vec.x()) <= kEpsilon); + const bool y_zero = (std::abs(vec.y()) <= kEpsilon); + if (x_zero && !y_zero) + return (vec.y() > 0) ? AXIS_POS_Y : AXIS_NEG_Y; + else if (y_zero && !x_zero) + return (vec.x() > 0) ? AXIS_POS_X : AXIS_NEG_X; + else + return NONE; +} + +} // namespace + OverlayCandidate::OverlayCandidate() : transform(gfx::OVERLAY_TRANSFORM_NONE), format(RGBA_8888), @@ -23,12 +47,34 @@ OverlayCandidate::~OverlayCandidate() {} // static gfx::OverlayTransform OverlayCandidate::GetOverlayTransform( const gfx::Transform& quad_transform, - bool flipped) { - if (!quad_transform.IsPositiveScaleOrTranslation()) + bool y_flipped) { + if (!quad_transform.Preserves2dAxisAlignment()) { return gfx::OVERLAY_TRANSFORM_INVALID; + } + + gfx::Vector3dF x_axis = MathUtil::GetXAxis(quad_transform); + gfx::Vector3dF y_axis = MathUtil::GetYAxis(quad_transform); + if (y_flipped) { + y_axis.Scale(-1); + } - return flipped ? gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL - : gfx::OVERLAY_TRANSFORM_NONE; + Axis x_to = VectorToAxis(x_axis); + Axis y_to = VectorToAxis(y_axis); + + if (x_to == AXIS_POS_X && y_to == AXIS_POS_Y) + return gfx::OVERLAY_TRANSFORM_NONE; + else if (x_to == AXIS_NEG_X && y_to == AXIS_POS_Y) + return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + else if (x_to == AXIS_POS_X && y_to == AXIS_NEG_Y) + return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL; + else if (x_to == AXIS_NEG_Y && y_to == AXIS_POS_X) + return gfx::OVERLAY_TRANSFORM_ROTATE_270; + else if (x_to == AXIS_NEG_X && y_to == AXIS_NEG_Y) + return gfx::OVERLAY_TRANSFORM_ROTATE_180; + else if (x_to == AXIS_POS_Y && y_to == AXIS_NEG_X) + return gfx::OVERLAY_TRANSFORM_ROTATE_90; + else + return gfx::OVERLAY_TRANSFORM_INVALID; } // static @@ -131,7 +177,7 @@ gfx::OverlayTransform OverlayCandidate::ModifyTransform( gfx::RectF OverlayCandidate::GetOverlayRect( const gfx::Transform& quad_transform, const gfx::Rect& rect) { - DCHECK(quad_transform.IsPositiveScaleOrTranslation()); + DCHECK(quad_transform.Preserves2dAxisAlignment()); gfx::RectF float_rect(rect); quad_transform.TransformRect(&float_rect); diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h index c6bb22a..3639635 100644 --- a/cc/output/overlay_candidate.h +++ b/cc/output/overlay_candidate.h @@ -19,7 +19,7 @@ class CC_EXPORT OverlayCandidate { public: static gfx::OverlayTransform GetOverlayTransform( const gfx::Transform& quad_transform, - bool flipped); + bool y_flipped); // Apply transform |delta| to |in| and return the resulting transform, // or OVERLAY_TRANSFORM_INVALID. static gfx::OverlayTransform ModifyTransform(gfx::OverlayTransform in, diff --git a/cc/output/overlay_strategy_common.cc b/cc/output/overlay_strategy_common.cc index b03fbba5..be352a5 100644 --- a/cc/output/overlay_strategy_common.cc +++ b/cc/output/overlay_strategy_common.cc @@ -56,7 +56,8 @@ bool OverlayStrategyCommon::IsInvisibleQuad(const DrawQuad* draw_quad) { bool OverlayStrategyCommon::GetTextureQuadInfo(const TextureDrawQuad& quad, OverlayCandidate* quad_info) { gfx::OverlayTransform overlay_transform = - OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped); + OverlayCandidate::GetOverlayTransform(quad.quadTransform(), + quad.y_flipped); if (quad.background_color != SK_ColorTRANSPARENT || quad.premultiplied_alpha || overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID) diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 5694762..c9a2ae0 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc @@ -61,10 +61,14 @@ void SingleOverlayValidator::CheckOverlaySupport( ASSERT_EQ(2U, surfaces->size()); OverlayCandidate& candidate = surfaces->back(); - if (candidate.display_rect.width() == 64) + if (candidate.display_rect.width() == 64) { EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect); - else - EXPECT_EQ(kOverlayRect, candidate.display_rect); + } else { + EXPECT_NEAR(kOverlayRect.x(), candidate.display_rect.x(), 0.01f); + EXPECT_NEAR(kOverlayRect.y(), candidate.display_rect.y(), 0.01f); + EXPECT_NEAR(kOverlayRect.width(), candidate.display_rect.width(), 0.01f); + EXPECT_NEAR(kOverlayRect.height(), candidate.display_rect.height(), 0.01f); + } EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(), candidate.uv_rect.ToString()); candidate.overlay_handled = true; @@ -540,7 +544,7 @@ TEST_F(SingleOverlayOnTopTest, RejectOpacity) { EXPECT_EQ(0U, candidate_list.size()); } -TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) { +TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), @@ -556,11 +560,13 @@ TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) { EXPECT_EQ(0U, candidate_list.size()); } -TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) { +TEST_F(SingleOverlayOnTopTest, AllowVerticalFlip) { + gfx::Rect rect = kOverlayRect; + rect.set_width(rect.width() / 2); + rect.Offset(0, -rect.height()); scoped_ptr<RenderPass> pass = CreateRenderPass(); - CreateFullscreenCandidateQuad(resource_provider_.get(), - pass->shared_quad_state_list.back(), - pass.get()); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f, -1.0f); @@ -569,7 +575,29 @@ TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) { OverlayCandidateList candidate_list; overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); ASSERT_EQ(1U, pass_list.size()); - EXPECT_EQ(0U, candidate_list.size()); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL, + candidate_list.back().transform); +} + +TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) { + gfx::Rect rect = kOverlayRect; + rect.set_height(rect.height() / 2); + rect.Offset(-rect.width(), 0); + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); + pass->shared_quad_state_list.back()->content_to_target_transform.Scale(-1.0f, + 2.0f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL, + candidate_list.back().transform); } TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) { @@ -589,6 +617,60 @@ TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) { EXPECT_EQ(2U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) { + gfx::Rect rect = kOverlayRect; + rect.Offset(0, -rect.height()); + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); + pass->shared_quad_state_list.back() + ->content_to_target_transform.RotateAboutZAxis(90.f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90, candidate_list.back().transform); +} + +TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) { + gfx::Rect rect = kOverlayRect; + rect.Offset(-rect.width(), -rect.height()); + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); + pass->shared_quad_state_list.back() + ->content_to_target_transform.RotateAboutZAxis(180.f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180, candidate_list.back().transform); +} + +TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) { + gfx::Rect rect = kOverlayRect; + rect.Offset(-rect.width(), 0); + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); + pass->shared_quad_state_list.back() + ->content_to_target_transform.RotateAboutZAxis(270.f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + ASSERT_EQ(2U, candidate_list.size()); + EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270, candidate_list.back().transform); +} + TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateCheckeredQuadAt(resource_provider_.get(), diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 3520176..2013e03 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -438,7 +438,7 @@ void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame, QuadVertexRect(), quad->rect, quad->visible_rect); SkRect quad_rect = gfx::RectFToSkRect(visible_quad_vertex_rect); - if (quad->flipped) + if (quad->y_flipped) current_canvas_->scale(1, -1); bool blend_background = quad->background_color != SK_ColorTRANSPARENT && diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc index 02d57ba..968a1d0 100644 --- a/cc/quads/draw_quad_unittest.cc +++ b/cc/quads/draw_quad_unittest.cc @@ -549,7 +549,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { gfx::PointF uv_top_left(0.5f, 224.f); gfx::PointF uv_bottom_right(51.5f, 260.f); const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - bool flipped = true; + bool y_flipped = true; bool nearest_neighbor = true; CREATE_SHARED_STATE(); @@ -562,7 +562,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, - flipped, + y_flipped, nearest_neighbor); EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); EXPECT_EQ(visible_rect, copy_quad->visible_rect); @@ -572,7 +572,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { EXPECT_EQ(uv_top_left, copy_quad->uv_top_left); EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right); EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); - EXPECT_EQ(flipped, copy_quad->flipped); + EXPECT_EQ(y_flipped, copy_quad->y_flipped); EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor); CREATE_QUAD_8_ALL(TextureDrawQuad, @@ -582,7 +582,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, - flipped, + y_flipped, nearest_neighbor); EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material); EXPECT_EQ(resource_id, copy_quad->resource_id); @@ -590,7 +590,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) { EXPECT_EQ(uv_top_left, copy_quad->uv_top_left); EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right); EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4); - EXPECT_EQ(flipped, copy_quad->flipped); + EXPECT_EQ(y_flipped, copy_quad->y_flipped); EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor); } @@ -857,7 +857,7 @@ TEST_F(DrawQuadIteratorTest, TextureDrawQuad) { gfx::PointF uv_top_left(0.5f, 224.f); gfx::PointF uv_bottom_right(51.5f, 260.f); const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - bool flipped = true; + bool y_flipped = true; bool nearest_neighbor = true; CREATE_SHARED_STATE(); @@ -870,7 +870,7 @@ TEST_F(DrawQuadIteratorTest, TextureDrawQuad) { uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, - flipped, + y_flipped, nearest_neighbor); EXPECT_EQ(resource_id, quad_new->resource_id); EXPECT_EQ(1, IterateAndCount(quad_new)); diff --git a/cc/quads/texture_draw_quad.cc b/cc/quads/texture_draw_quad.cc index 318d4f8..4b8720a 100644 --- a/cc/quads/texture_draw_quad.cc +++ b/cc/quads/texture_draw_quad.cc @@ -16,7 +16,7 @@ TextureDrawQuad::TextureDrawQuad() : resource_id(0), premultiplied_alpha(false), background_color(SK_ColorTRANSPARENT), - flipped(false), + y_flipped(false), nearest_neighbor(false) { this->vertex_opacity[0] = 0.f; this->vertex_opacity[1] = 0.f; @@ -34,7 +34,7 @@ void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state, const gfx::PointF& uv_bottom_right, SkColor background_color, const float vertex_opacity[4], - bool flipped, + bool y_flipped, bool nearest_neighbor) { bool needs_blending = vertex_opacity[0] != 1.0f || vertex_opacity[1] != 1.0f || vertex_opacity[2] != 1.0f || vertex_opacity[3] != 1.0f; @@ -49,7 +49,7 @@ void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state, this->vertex_opacity[1] = vertex_opacity[1]; this->vertex_opacity[2] = vertex_opacity[2]; this->vertex_opacity[3] = vertex_opacity[3]; - this->flipped = flipped; + this->y_flipped = y_flipped; this->nearest_neighbor = nearest_neighbor; } @@ -64,7 +64,7 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state, const gfx::PointF& uv_bottom_right, SkColor background_color, const float vertex_opacity[4], - bool flipped, + bool y_flipped, bool nearest_neighbor) { DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect, opaque_rect, visible_rect, needs_blending); @@ -77,7 +77,7 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state, this->vertex_opacity[1] = vertex_opacity[1]; this->vertex_opacity[2] = vertex_opacity[2]; this->vertex_opacity[3] = vertex_opacity[3]; - this->flipped = flipped; + this->y_flipped = y_flipped; this->nearest_neighbor = nearest_neighbor; } @@ -105,7 +105,7 @@ void TextureDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const { value->AppendDouble(vertex_opacity[i]); value->EndArray(); - value->SetBoolean("flipped", flipped); + value->SetBoolean("y_flipped", y_flipped); value->SetBoolean("nearest_neighbor", nearest_neighbor); } diff --git a/cc/quads/texture_draw_quad.h b/cc/quads/texture_draw_quad.h index afac6bf..7064149 100644 --- a/cc/quads/texture_draw_quad.h +++ b/cc/quads/texture_draw_quad.h @@ -26,7 +26,7 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { const gfx::PointF& uv_bottom_right, SkColor background_color, const float vertex_opacity[4], - bool flipped, + bool y_flipped, bool nearest_neighbor); void SetAll(const SharedQuadState* shared_quad_state, @@ -40,7 +40,7 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { const gfx::PointF& uv_bottom_right, SkColor background_color, const float vertex_opacity[4], - bool flipped, + bool y_flipped, bool nearest_neighbor); unsigned resource_id; @@ -49,7 +49,7 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { gfx::PointF uv_bottom_right; SkColor background_color; float vertex_opacity[4]; - bool flipped; + bool y_flipped; bool nearest_neighbor; void IterateResources(const ResourceIteratorCallback& callback) override; |