Index: ui/compositor/paint_context_unittest.cc |
diff --git a/ui/compositor/paint_context_unittest.cc b/ui/compositor/paint_context_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5efd7194b294dc756787850b9ec3d7fa14191d11 |
--- /dev/null |
+++ b/ui/compositor/paint_context_unittest.cc |
@@ -0,0 +1,235 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/compositor/paint_context.h" |
+ |
+#include <vector> |
+ |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "cc/base/region.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/gfx/geometry/rect.h" |
+#include "ui/gfx/geometry/size.h" |
+ |
+namespace ui { |
+namespace { |
+ |
+typedef testing::Test PaintContextTest; |
+ |
+// Device scale factors |
+constexpr float DSF100 = 1.f; |
+constexpr float DSF125 = 1.25f; |
+constexpr float DSF150 = 1.5f; |
+constexpr float DSF160 = 1.6f; |
+constexpr float DSF166 = 1.66f; |
+ |
+const std::vector<float> kDsfList = {DSF100, DSF125, DSF150, DSF160, DSF166}; |
+ |
+const gfx::Size kLayerSize(123, 456); |
+ |
+// ___________ |
+// | 1 | |
+// |___________| |
+// | 3 | 4 | 5 | <-- 2 |
+// |___|___|___| |
+// | 7 | 8 | <-- 6 |
+// |_______|___| |
+const gfx::Rect r_0(kLayerSize); |
+ |
+const gfx::Rect r_0_1(0, 0, 123, 152); |
+ |
+const gfx::Rect r_0_2(0, 152, 123, 152); |
+const gfx::Rect r_2_3(0, 0, 41, 152); |
+const gfx::Rect r_2_4(41, 0, 41, 152); |
+const gfx::Rect r_2_5(82, 0, 41, 152); |
+ |
+const gfx::Rect r_0_6(0, 304, 123, 152); |
+const gfx::Rect r_6_7(0, 0, 82, 152); |
+const gfx::Rect r_6_8(82, 0, 41, 152); |
+ |
+// Returns as DisplayItemList with the pixel canvas enabled or disabled based on |
+// |pixel_canvas_enabled|. |
+cc::DisplayItemList* GetDisplayItemList(bool pixel_canvas_enabled) { |
+ cc::DisplayItemList* display_item_list = new cc::DisplayItemList; |
+ display_item_list->set_pixel_canvas_enabled(pixel_canvas_enabled); |
+ return std::move(display_item_list); |
+} |
+ |
+// ___________ |
+// | 1 | |
+// |___________| |
+// | 3 | 4 | 5 | <-- 2 |
+// |___|___|___| |
+// | 7 | 8 | <-- 6 |
+// |_______|___| |
+// Returns the following arrangement of contexts for the given |dsf| |
+std::vector<PaintContext*> GetPaintContextSetup(bool pixel_canvas_enabled, |
+ float dsf, |
+ const gfx::Rect& invd_rect) { |
+ std::vector<PaintContext*> contexts(9); |
+ contexts[0] = new PaintContext(GetDisplayItemList(pixel_canvas_enabled), dsf, |
+ invd_rect, kLayerSize); |
+ |
+ contexts[1] = |
+ new PaintContext(*contexts[0], r_0_1, PaintContext::SCALE_TO_FIT); |
+ |
+ contexts[2] = |
+ new PaintContext(*contexts[0], r_0_2, PaintContext::SCALE_TO_FIT); |
+ contexts[3] = |
+ new PaintContext(*contexts[2], r_2_3, PaintContext::SCALE_TO_FIT); |
+ contexts[4] = |
+ new PaintContext(*contexts[2], r_2_4, PaintContext::SCALE_TO_FIT); |
+ contexts[5] = |
+ new PaintContext(*contexts[2], r_2_5, PaintContext::SCALE_TO_FIT); |
+ |
+ contexts[6] = |
+ new PaintContext(*contexts[0], r_0_6, PaintContext::SCALE_TO_FIT); |
+ contexts[7] = |
+ new PaintContext(*contexts[6], r_6_7, PaintContext::SCALE_TO_FIT); |
+ contexts[8] = |
+ new PaintContext(*contexts[6], r_6_8, PaintContext::SCALE_TO_FIT); |
+ |
+ return contexts; |
+} |
+ |
+// Verifies that the child contexts completely cover the parent context bounds. |
+void VerifyContextCoversParentContext(PaintContext* parent_context, |
+ std::vector<PaintContext*> contexts) { |
+ cc::Region remaining(gfx::Rect(parent_context->pixel_size())); |
+ int times_empty = 0; |
+ for (auto* context : contexts) { |
+ const gfx::Rect& child_context_bounds = context->pixel_bounds(); |
+ EXPECT_TRUE(remaining.Contains(child_context_bounds)) |
+ << "Remaining: " << remaining.ToString() |
+ << " context pixel bounds: " << child_context_bounds.ToString(); |
+ remaining.Subtract(child_context_bounds); |
+ times_empty += remaining.IsEmpty(); |
+ } |
+ EXPECT_EQ(times_empty, 1); |
+} |
+ |
+void VerifyPixelCanvasCornerScaling(std::vector<PaintContext*> contexts) { |
+ // context 1, context 2 and context 6 should completely cover context 0. |
+ std::vector<PaintContext*> child_contexts; |
+ child_contexts.push_back(contexts[1]); |
+ child_contexts.push_back(contexts[2]); |
+ child_contexts.push_back(contexts[6]); |
+ VerifyContextCoversParentContext(contexts[0], child_contexts); |
+ child_contexts.clear(); |
+ |
+ // Context 3,4 and 5 should completely cover context 2. |
+ child_contexts.push_back(contexts[3]); |
+ child_contexts.push_back(contexts[4]); |
+ child_contexts.push_back(contexts[5]); |
+ VerifyContextCoversParentContext(contexts[2], child_contexts); |
+ child_contexts.clear(); |
+ |
+ // Context 7 and 8 should completely cover context 6. |
+ child_contexts.push_back(contexts[7]); |
+ child_contexts.push_back(contexts[8]); |
+ VerifyContextCoversParentContext(contexts[6], child_contexts); |
+ child_contexts.clear(); |
+} |
+ |
+void ClearAllContexts(std::vector<PaintContext*> contexts) { |
+ for (auto* context : contexts) |
+ delete context; |
+} |
+ |
+void VerifyPixelSizesAreSameAsDIPSize(std::vector<PaintContext*> contexts) { |
+ EXPECT_EQ(contexts[0]->pixel_size(), r_0.size()); |
+ |
+ EXPECT_EQ(contexts[1]->pixel_size(), r_0_1.size()); |
+ |
+ EXPECT_EQ(contexts[2]->pixel_size(), r_0_2.size()); |
+ EXPECT_EQ(contexts[3]->pixel_size(), r_2_3.size()); |
+ EXPECT_EQ(contexts[4]->pixel_size(), r_2_4.size()); |
+ EXPECT_EQ(contexts[5]->pixel_size(), r_2_5.size()); |
+ |
+ EXPECT_EQ(contexts[6]->pixel_size(), r_0_6.size()); |
+ EXPECT_EQ(contexts[7]->pixel_size(), r_6_7.size()); |
+ EXPECT_EQ(contexts[8]->pixel_size(), r_6_8.size()); |
+} |
+ |
+void VerifyInvalidationRects(float dsf, bool pixel_canvas_enabled) { |
+ std::vector<gfx::Rect> invalidation_rects = { |
+ gfx::Rect(0, 0, 123, 41), // Intersects with 0 & 1. |
+ gfx::Rect(0, 76, 60, 152), // Intersects 0, 1, 2, 3 & 4. |
+ gfx::Rect(41, 152, 41, 152), // Intersects with 0, 2 & 4. |
+ gfx::Rect(80, 320, 4, 4), // Intersects with 0, 6, 7 & 8. |
+ gfx::Rect(40, 151, 43, 154), // Intersects all |
+ gfx::Rect(82, 304, 1, 1), // Intersects with 0, 6 & 8. |
+ gfx::Rect(81, 303, 2, 2) // Intersects with 0, 2, 4, 5, 6, 7, 8 |
+ }; |
+ |
+ std::vector<std::vector<int>> repaint_context_indices = { |
+ std::vector<int>{0, 1}, |
+ std::vector<int>{0, 1, 2, 3, 4}, |
+ std::vector<int>{0, 2, 4}, |
+ std::vector<int>{0, 6, 7, 8}, |
+ std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8}, |
+ std::vector<int>{0, 6, 8}, |
+ std::vector<int>{0, 2, 4, 5, 6, 7, 8}}; |
+ |
+ std::vector<PaintContext*> contexts; |
+ |
+ EXPECT_EQ(repaint_context_indices.size(), invalidation_rects.size()); |
+ for (size_t i = 0; i < invalidation_rects.size(); i++) { |
+ contexts = |
+ GetPaintContextSetup(pixel_canvas_enabled, dsf, invalidation_rects[i]); |
+ for (size_t j = 0; j < repaint_context_indices[i].size(); j++) |
+ EXPECT_TRUE(contexts[repaint_context_indices[i][j]]->ShouldRepaint()); |
+ ClearAllContexts(contexts); |
+ } |
+} |
+ |
+} // namespace |
+ |
+TEST_F(PaintContextTest, CornerScalingPixelCanvasEnabled) { |
+ std::vector<PaintContext*> contexts; |
+ for (float dsf : kDsfList) { |
+ contexts = GetPaintContextSetup(true, dsf, gfx::Rect()); |
+ VerifyPixelCanvasCornerScaling(contexts); |
+ ClearAllContexts(contexts); |
+ } |
+ |
+ // More accurate testing for 1.25 dsf |
+ contexts = GetPaintContextSetup(true, DSF125, gfx::Rect()); |
+ VerifyPixelCanvasCornerScaling(contexts); |
+ EXPECT_EQ(contexts[0]->pixel_size(), gfx::Size(154, 570)); |
+ |
+ EXPECT_EQ(contexts[1]->pixel_size(), gfx::Size(154, 190)); |
+ |
+ EXPECT_EQ(contexts[2]->pixel_bounds(), gfx::Rect(0, 190, 154, 190)); |
+ EXPECT_EQ(contexts[3]->pixel_size(), gfx::Size(51, 190)); |
+ EXPECT_EQ(contexts[4]->pixel_bounds(), gfx::Rect(51, 0, 52, 190)); |
+ EXPECT_EQ(contexts[5]->pixel_bounds(), gfx::Rect(103, 0, 51, 190)); |
+ |
+ EXPECT_EQ(contexts[6]->pixel_bounds(), gfx::Rect(0, 380, 154, 190)); |
+ EXPECT_EQ(contexts[7]->pixel_size(), gfx::Size(103, 190)); |
+ EXPECT_EQ(contexts[8]->pixel_bounds(), gfx::Rect(103, 0, 51, 190)); |
+ ClearAllContexts(contexts); |
+} |
+ |
+TEST_F(PaintContextTest, ScalingWithPixelCanvasDisabled) { |
+ // With dsf as 1, there should be no scaling and size should be same. |
+ std::vector<PaintContext*> contexts = |
+ GetPaintContextSetup(false, DSF100, gfx::Rect()); |
+ for (float dsf : kDsfList) { |
+ contexts = GetPaintContextSetup(false, dsf, gfx::Rect()); |
+ VerifyPixelCanvasCornerScaling(contexts); |
+ VerifyPixelSizesAreSameAsDIPSize(contexts); |
+ ClearAllContexts(contexts); |
+ } |
+} |
+ |
+TEST_F(PaintContextTest, Invalidation) { |
+ for (float dsf : kDsfList) { |
+ VerifyInvalidationRects(dsf, false); |
+ VerifyInvalidationRects(dsf, true); |
+ } |
+} |
+ |
+} // namespace ui |