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

Unified Diff: ui/compositor/paint_context_unittest.cc

Issue 2877483003: Implements core logic for Pixel Canvas (Closed)
Patch Set: Resolving comments Created 3 years, 5 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 side-by-side diff with in-line comments
Download patch
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..526855adab66145c73c799ce5911033caf1fd1e1
--- /dev/null
+++ b/ui/compositor/paint_context_unittest.cc
@@ -0,0 +1,232 @@
+// 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/compositor/compositor_switches.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);
+
+// ___________
+// | 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) {
+ ui::SetPixelCanvasForTesting(pixel_canvas_enabled);
+ std::vector<PaintContext*> contexts(9);
+ contexts[0] = new PaintContext(nullptr, dsf, invd_rect, kLayerSize);
+
+ contexts[1] = new PaintContext(*contexts[0], r_0_1, invd_rect,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+
+ contexts[2] = new PaintContext(*contexts[0], r_0_2, invd_rect,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+ contexts[3] = new PaintContext(*contexts[2], r_2_3, r_0_2,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+ contexts[4] = new PaintContext(*contexts[2], r_2_4, r_0_2,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+ contexts[5] = new PaintContext(*contexts[2], r_2_5, r_0_2,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+
+ contexts[6] = new PaintContext(*contexts[0], r_0_6, invd_rect,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+ contexts[7] = new PaintContext(*contexts[6], r_6_7, r_0_6,
+ PaintContext::ScaleType::SCALE_TO_FIT);
+ contexts[8] = new PaintContext(*contexts[6], r_6_8, r_0_6,
+ PaintContext::ScaleType::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->paint_recording_size()));
+ int times_empty = 0;
+ for (auto* context : contexts) {
+ const gfx::Rect& child_context_bounds =
+ context->paint_recording_bounds() -
+ parent_context->paint_recording_bounds().OffsetFromOrigin();
+ 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]->paint_recording_size(), r_0.size());
+
+ EXPECT_EQ(contexts[1]->paint_recording_size(), r_0_1.size());
+
+ EXPECT_EQ(contexts[2]->paint_recording_size(), r_0_2.size());
+ EXPECT_EQ(contexts[3]->paint_recording_size(), r_2_3.size());
+ EXPECT_EQ(contexts[4]->paint_recording_size(), r_2_4.size());
+ EXPECT_EQ(contexts[5]->paint_recording_size(), r_2_5.size());
+
+ EXPECT_EQ(contexts[6]->paint_recording_size(), r_0_6.size());
+ EXPECT_EQ(contexts[7]->paint_recording_size(), r_6_7.size());
+ EXPECT_EQ(contexts[8]->paint_recording_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]->paint_recording_size(), gfx::Size(154, 570));
+
+ EXPECT_EQ(contexts[1]->paint_recording_size(), gfx::Size(154, 190));
+
+ EXPECT_EQ(contexts[2]->paint_recording_bounds(), gfx::Rect(0, 190, 154, 190));
+ EXPECT_EQ(contexts[3]->paint_recording_size(), gfx::Size(51, 190));
+ EXPECT_EQ(contexts[4]->paint_recording_bounds(), gfx::Rect(51, 190, 52, 190));
+ EXPECT_EQ(contexts[5]->paint_recording_bounds(),
+ gfx::Rect(103, 190, 51, 190));
+
+ EXPECT_EQ(contexts[6]->paint_recording_bounds(), gfx::Rect(0, 380, 154, 190));
+ EXPECT_EQ(contexts[7]->paint_recording_size(), gfx::Size(103, 190));
+ EXPECT_EQ(contexts[8]->paint_recording_bounds(),
+ gfx::Rect(103, 380, 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

Powered by Google App Engine
This is Rietveld 408576698