OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/compositor/paint_context.h" |
| 6 |
| 7 #include <vector> |
| 8 |
| 9 #include "base/macros.h" |
| 10 #include "base/memory/ref_counted.h" |
| 11 #include "cc/base/region.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/compositor/compositor_switches.h" |
| 14 #include "ui/gfx/geometry/rect.h" |
| 15 #include "ui/gfx/geometry/size.h" |
| 16 |
| 17 namespace ui { |
| 18 namespace { |
| 19 |
| 20 typedef testing::Test PaintContextTest; |
| 21 |
| 22 // Device scale factors |
| 23 constexpr float DSF100 = 1.f; |
| 24 constexpr float DSF125 = 1.25f; |
| 25 constexpr float DSF150 = 1.5f; |
| 26 constexpr float DSF160 = 1.6f; |
| 27 constexpr float DSF166 = 1.66f; |
| 28 |
| 29 const std::vector<float> kDsfList = {DSF100, DSF125, DSF150, DSF160, DSF166}; |
| 30 |
| 31 const gfx::Size kLayerSize(123, 456); |
| 32 |
| 33 // ___________ |
| 34 // | 1 | |
| 35 // |___________| |
| 36 // | 3 | 4 | 5 | <-- 2 |
| 37 // |___|___|___| |
| 38 // | 7 | 8 | <-- 6 |
| 39 // |_______|___| |
| 40 const gfx::Rect r_0(kLayerSize); |
| 41 |
| 42 const gfx::Rect r_0_1(0, 0, 123, 152); |
| 43 |
| 44 const gfx::Rect r_0_2(0, 152, 123, 152); |
| 45 const gfx::Rect r_2_3(0, 0, 41, 152); |
| 46 const gfx::Rect r_2_4(41, 0, 41, 152); |
| 47 const gfx::Rect r_2_5(82, 0, 41, 152); |
| 48 |
| 49 const gfx::Rect r_0_6(0, 304, 123, 152); |
| 50 const gfx::Rect r_6_7(0, 0, 82, 152); |
| 51 const gfx::Rect r_6_8(82, 0, 41, 152); |
| 52 |
| 53 // ___________ |
| 54 // | 1 | |
| 55 // |___________| |
| 56 // | 3 | 4 | 5 | <-- 2 |
| 57 // |___|___|___| |
| 58 // | 7 | 8 | <-- 6 |
| 59 // |_______|___| |
| 60 // Returns the following arrangement of contexts for the given |dsf| |
| 61 std::vector<PaintContext*> GetPaintContextSetup(bool pixel_canvas_enabled, |
| 62 float dsf, |
| 63 const gfx::Rect& invd_rect) { |
| 64 ui::SetPixelCanvasForTesting(pixel_canvas_enabled); |
| 65 std::vector<PaintContext*> contexts(9); |
| 66 contexts[0] = new PaintContext(nullptr, dsf, invd_rect, kLayerSize); |
| 67 |
| 68 contexts[1] = new PaintContext(*contexts[0], r_0_1, invd_rect, |
| 69 PaintContext::ScaleType::SCALE_TO_FIT); |
| 70 |
| 71 contexts[2] = new PaintContext(*contexts[0], r_0_2, invd_rect, |
| 72 PaintContext::ScaleType::SCALE_TO_FIT); |
| 73 contexts[3] = new PaintContext(*contexts[2], r_2_3, r_0_2, |
| 74 PaintContext::ScaleType::SCALE_TO_FIT); |
| 75 contexts[4] = new PaintContext(*contexts[2], r_2_4, r_0_2, |
| 76 PaintContext::ScaleType::SCALE_TO_FIT); |
| 77 contexts[5] = new PaintContext(*contexts[2], r_2_5, r_0_2, |
| 78 PaintContext::ScaleType::SCALE_TO_FIT); |
| 79 |
| 80 contexts[6] = new PaintContext(*contexts[0], r_0_6, invd_rect, |
| 81 PaintContext::ScaleType::SCALE_TO_FIT); |
| 82 contexts[7] = new PaintContext(*contexts[6], r_6_7, r_0_6, |
| 83 PaintContext::ScaleType::SCALE_TO_FIT); |
| 84 contexts[8] = new PaintContext(*contexts[6], r_6_8, r_0_6, |
| 85 PaintContext::ScaleType::SCALE_TO_FIT); |
| 86 |
| 87 return contexts; |
| 88 } |
| 89 |
| 90 // Verifies that the child contexts completely cover the parent context bounds. |
| 91 void VerifyContextCoversParentContext(PaintContext* parent_context, |
| 92 std::vector<PaintContext*> contexts) { |
| 93 cc::Region remaining(gfx::Rect(parent_context->paint_recording_size())); |
| 94 int times_empty = 0; |
| 95 for (auto* context : contexts) { |
| 96 const gfx::Rect& child_context_bounds = |
| 97 context->paint_recording_bounds() - |
| 98 parent_context->paint_recording_bounds().OffsetFromOrigin(); |
| 99 EXPECT_TRUE(remaining.Contains(child_context_bounds)) |
| 100 << "Remaining: " << remaining.ToString() |
| 101 << " context pixel bounds: " << child_context_bounds.ToString(); |
| 102 remaining.Subtract(child_context_bounds); |
| 103 times_empty += remaining.IsEmpty(); |
| 104 } |
| 105 EXPECT_EQ(times_empty, 1); |
| 106 } |
| 107 |
| 108 void VerifyPixelCanvasCornerScaling(std::vector<PaintContext*> contexts) { |
| 109 // context 1, context 2 and context 6 should completely cover context 0. |
| 110 std::vector<PaintContext*> child_contexts; |
| 111 child_contexts.push_back(contexts[1]); |
| 112 child_contexts.push_back(contexts[2]); |
| 113 child_contexts.push_back(contexts[6]); |
| 114 VerifyContextCoversParentContext(contexts[0], child_contexts); |
| 115 child_contexts.clear(); |
| 116 |
| 117 // Context 3,4 and 5 should completely cover context 2. |
| 118 child_contexts.push_back(contexts[3]); |
| 119 child_contexts.push_back(contexts[4]); |
| 120 child_contexts.push_back(contexts[5]); |
| 121 VerifyContextCoversParentContext(contexts[2], child_contexts); |
| 122 child_contexts.clear(); |
| 123 |
| 124 // Context 7 and 8 should completely cover context 6. |
| 125 child_contexts.push_back(contexts[7]); |
| 126 child_contexts.push_back(contexts[8]); |
| 127 VerifyContextCoversParentContext(contexts[6], child_contexts); |
| 128 child_contexts.clear(); |
| 129 } |
| 130 |
| 131 void ClearAllContexts(std::vector<PaintContext*> contexts) { |
| 132 for (auto* context : contexts) |
| 133 delete context; |
| 134 } |
| 135 |
| 136 void VerifyPixelSizesAreSameAsDIPSize(std::vector<PaintContext*> contexts) { |
| 137 EXPECT_EQ(contexts[0]->paint_recording_size(), r_0.size()); |
| 138 |
| 139 EXPECT_EQ(contexts[1]->paint_recording_size(), r_0_1.size()); |
| 140 |
| 141 EXPECT_EQ(contexts[2]->paint_recording_size(), r_0_2.size()); |
| 142 EXPECT_EQ(contexts[3]->paint_recording_size(), r_2_3.size()); |
| 143 EXPECT_EQ(contexts[4]->paint_recording_size(), r_2_4.size()); |
| 144 EXPECT_EQ(contexts[5]->paint_recording_size(), r_2_5.size()); |
| 145 |
| 146 EXPECT_EQ(contexts[6]->paint_recording_size(), r_0_6.size()); |
| 147 EXPECT_EQ(contexts[7]->paint_recording_size(), r_6_7.size()); |
| 148 EXPECT_EQ(contexts[8]->paint_recording_size(), r_6_8.size()); |
| 149 } |
| 150 |
| 151 void VerifyInvalidationRects(float dsf, bool pixel_canvas_enabled) { |
| 152 std::vector<gfx::Rect> invalidation_rects = { |
| 153 gfx::Rect(0, 0, 123, 41), // Intersects with 0 & 1. |
| 154 gfx::Rect(0, 76, 60, 152), // Intersects 0, 1, 2, 3 & 4. |
| 155 gfx::Rect(41, 152, 41, 152), // Intersects with 0, 2 & 4. |
| 156 gfx::Rect(80, 320, 4, 4), // Intersects with 0, 6, 7 & 8. |
| 157 gfx::Rect(40, 151, 43, 154), // Intersects all |
| 158 gfx::Rect(82, 304, 1, 1), // Intersects with 0, 6 & 8. |
| 159 gfx::Rect(81, 303, 2, 2) // Intersects with 0, 2, 4, 5, 6, 7, 8 |
| 160 }; |
| 161 |
| 162 std::vector<std::vector<int>> repaint_context_indices = { |
| 163 std::vector<int>{0, 1}, |
| 164 std::vector<int>{0, 1, 2, 3, 4}, |
| 165 std::vector<int>{0, 2, 4}, |
| 166 std::vector<int>{0, 6, 7, 8}, |
| 167 std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8}, |
| 168 std::vector<int>{0, 6, 8}, |
| 169 std::vector<int>{0, 2, 4, 5, 6, 7, 8}}; |
| 170 |
| 171 std::vector<PaintContext*> contexts; |
| 172 |
| 173 EXPECT_EQ(repaint_context_indices.size(), invalidation_rects.size()); |
| 174 for (size_t i = 0; i < invalidation_rects.size(); i++) { |
| 175 contexts = |
| 176 GetPaintContextSetup(pixel_canvas_enabled, dsf, invalidation_rects[i]); |
| 177 for (size_t j = 0; j < repaint_context_indices[i].size(); j++) |
| 178 EXPECT_TRUE(contexts[repaint_context_indices[i][j]]->ShouldRepaint()); |
| 179 ClearAllContexts(contexts); |
| 180 } |
| 181 } |
| 182 |
| 183 } // namespace |
| 184 |
| 185 TEST_F(PaintContextTest, CornerScalingPixelCanvasEnabled) { |
| 186 std::vector<PaintContext*> contexts; |
| 187 for (float dsf : kDsfList) { |
| 188 contexts = GetPaintContextSetup(true, dsf, gfx::Rect()); |
| 189 VerifyPixelCanvasCornerScaling(contexts); |
| 190 ClearAllContexts(contexts); |
| 191 } |
| 192 |
| 193 // More accurate testing for 1.25 dsf |
| 194 contexts = GetPaintContextSetup(true, DSF125, gfx::Rect()); |
| 195 VerifyPixelCanvasCornerScaling(contexts); |
| 196 EXPECT_EQ(contexts[0]->paint_recording_size(), gfx::Size(154, 570)); |
| 197 |
| 198 EXPECT_EQ(contexts[1]->paint_recording_size(), gfx::Size(154, 190)); |
| 199 |
| 200 EXPECT_EQ(contexts[2]->paint_recording_bounds(), gfx::Rect(0, 190, 154, 190)); |
| 201 EXPECT_EQ(contexts[3]->paint_recording_size(), gfx::Size(51, 190)); |
| 202 EXPECT_EQ(contexts[4]->paint_recording_bounds(), gfx::Rect(51, 190, 52, 190)); |
| 203 EXPECT_EQ(contexts[5]->paint_recording_bounds(), |
| 204 gfx::Rect(103, 190, 51, 190)); |
| 205 |
| 206 EXPECT_EQ(contexts[6]->paint_recording_bounds(), gfx::Rect(0, 380, 154, 190)); |
| 207 EXPECT_EQ(contexts[7]->paint_recording_size(), gfx::Size(103, 190)); |
| 208 EXPECT_EQ(contexts[8]->paint_recording_bounds(), |
| 209 gfx::Rect(103, 380, 51, 190)); |
| 210 ClearAllContexts(contexts); |
| 211 } |
| 212 |
| 213 TEST_F(PaintContextTest, ScalingWithPixelCanvasDisabled) { |
| 214 // With dsf as 1, there should be no scaling and size should be same. |
| 215 std::vector<PaintContext*> contexts = |
| 216 GetPaintContextSetup(false, DSF100, gfx::Rect()); |
| 217 for (float dsf : kDsfList) { |
| 218 contexts = GetPaintContextSetup(false, dsf, gfx::Rect()); |
| 219 VerifyPixelCanvasCornerScaling(contexts); |
| 220 VerifyPixelSizesAreSameAsDIPSize(contexts); |
| 221 ClearAllContexts(contexts); |
| 222 } |
| 223 } |
| 224 |
| 225 TEST_F(PaintContextTest, Invalidation) { |
| 226 for (float dsf : kDsfList) { |
| 227 VerifyInvalidationRects(dsf, false); |
| 228 VerifyInvalidationRects(dsf, true); |
| 229 } |
| 230 } |
| 231 |
| 232 } // namespace ui |
OLD | NEW |