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

Side by Side Diff: ui/compositor/layer_unittest.cc

Issue 1634103003: Fix gfx::Canvas::DrawStringRectWithHalo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: small fixes Created 4 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 unified diff | Download patch
« no previous file with comments | « no previous file | ui/gfx/canvas.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/compositor/layer.h" 5 #include "ui/compositor/layer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/json/json_reader.h" 16 #include "base/json/json_reader.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
19 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
23 #include "base/trace_event/trace_event.h" 24 #include "base/trace_event/trace_event.h"
24 #include "cc/layers/layer.h" 25 #include "cc/layers/layer.h"
25 #include "cc/output/copy_output_request.h" 26 #include "cc/output/copy_output_request.h"
26 #include "cc/output/copy_output_result.h" 27 #include "cc/output/copy_output_result.h"
27 #include "cc/surfaces/surface_id.h" 28 #include "cc/surfaces/surface_id.h"
28 #include "cc/surfaces/surface_sequence.h" 29 #include "cc/surfaces/surface_sequence.h"
29 #include "cc/test/pixel_test_utils.h" 30 #include "cc/test/pixel_test_utils.h"
30 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
31 #include "ui/compositor/compositor_observer.h" 32 #include "ui/compositor/compositor_observer.h"
32 #include "ui/compositor/dip_util.h" 33 #include "ui/compositor/dip_util.h"
33 #include "ui/compositor/layer_animation_element.h" 34 #include "ui/compositor/layer_animation_element.h"
34 #include "ui/compositor/layer_animation_observer.h" 35 #include "ui/compositor/layer_animation_observer.h"
35 #include "ui/compositor/layer_animation_sequence.h" 36 #include "ui/compositor/layer_animation_sequence.h"
36 #include "ui/compositor/layer_animator.h" 37 #include "ui/compositor/layer_animator.h"
37 #include "ui/compositor/paint_context.h" 38 #include "ui/compositor/paint_context.h"
38 #include "ui/compositor/paint_recorder.h" 39 #include "ui/compositor/paint_recorder.h"
39 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 40 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
40 #include "ui/compositor/scoped_layer_animation_settings.h" 41 #include "ui/compositor/scoped_layer_animation_settings.h"
41 #include "ui/compositor/test/context_factories_for_test.h" 42 #include "ui/compositor/test/context_factories_for_test.h"
42 #include "ui/compositor/test/draw_waiter_for_test.h" 43 #include "ui/compositor/test/draw_waiter_for_test.h"
43 #include "ui/compositor/test/test_compositor_host.h" 44 #include "ui/compositor/test/test_compositor_host.h"
44 #include "ui/compositor/test/test_layers.h" 45 #include "ui/compositor/test/test_layers.h"
45 #include "ui/gfx/canvas.h" 46 #include "ui/gfx/canvas.h"
46 #include "ui/gfx/codec/png_codec.h" 47 #include "ui/gfx/codec/png_codec.h"
48 #include "ui/gfx/font_list.h"
47 #include "ui/gfx/gfx_paths.h" 49 #include "ui/gfx/gfx_paths.h"
48 #include "ui/gfx/skia_util.h" 50 #include "ui/gfx/skia_util.h"
49 51
50 using cc::MatchesPNGFile; 52 using cc::MatchesPNGFile;
53 using cc::WritePNGFile;
51 54
52 namespace ui { 55 namespace ui {
53 56
54 namespace { 57 namespace {
55 58
56 // There are three test classes in here that configure the Compositor and 59 // There are three test classes in here that configure the Compositor and
57 // Layer's slightly differently: 60 // Layer's slightly differently:
58 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This 61 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
59 // is typically the base class you want to use. 62 // is typically the base class you want to use.
60 // - LayerWithDelegateTest uses LayerDelegate on the delegates. 63 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
(...skipping 22 matching lines...) Expand all
83 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} 86 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
84 87
85 base::Closure PrepareForLayerBoundsChange() override { 88 base::Closure PrepareForLayerBoundsChange() override {
86 return base::Closure(); 89 return base::Closure();
87 } 90 }
88 91
89 private: 92 private:
90 SkColor color_; 93 SkColor color_;
91 }; 94 };
92 95
96 // Layer delegate for painting text with effects on canvas.
97 class DrawStringLayerDelegate : public LayerDelegate {
98 public:
99 enum DrawFunction {
100 STRING_WITH_HALO,
101 STRING_FADED,
102 STRING_WITH_SHADOWS
103 };
104
105 DrawStringLayerDelegate(
106 SkColor back_color, SkColor halo_color,
107 DrawFunction func, const gfx::Size& layer_size)
108 : background_color_(back_color),
109 halo_color_(halo_color),
110 func_(func),
111 layer_size_(layer_size) {
112 }
113
114 ~DrawStringLayerDelegate() override {}
115
116 // Overridden from LayerDelegate:
117 void OnPaintLayer(const ui::PaintContext& context) override {
118 ui::PaintRecorder recorder(context, layer_size_);
119 gfx::Rect bounds(layer_size_);
120 recorder.canvas()->DrawColor(background_color_);
121 const base::string16 text = base::ASCIIToUTF16("Tests!");
122 switch (func_) {
123 case STRING_WITH_HALO:
124 recorder.canvas()->DrawStringRectWithHalo(
125 text, font_list_, SK_ColorRED, halo_color_, bounds, 0);
126 break;
127 case STRING_FADED:
128 recorder.canvas()->DrawFadedString(
129 text, font_list_, SK_ColorRED, bounds, 0);
130 break;
131 case STRING_WITH_SHADOWS: {
132 gfx::ShadowValues shadows;
133 shadows.push_back(
134 gfx::ShadowValue(gfx::Vector2d(2, 2), 2, SK_ColorRED));
135 recorder.canvas()->DrawStringRectWithShadows(
136 text, font_list_, SK_ColorRED, bounds, 0, 0, shadows);
137 break;
138 }
139 default:
140 NOTREACHED();
141 }
142 }
143
144 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
145
146 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
147
148 base::Closure PrepareForLayerBoundsChange() override {
149 return base::Closure();
150 }
151
152 private:
153 const SkColor background_color_;
154 const SkColor halo_color_;
155 const DrawFunction func_;
156 const gfx::FontList font_list_;
157 const gfx::Size layer_size_;
158
159 DISALLOW_COPY_AND_ASSIGN(DrawStringLayerDelegate);
160 };
161
93 class LayerWithRealCompositorTest : public testing::Test { 162 class LayerWithRealCompositorTest : public testing::Test {
94 public: 163 public:
95 LayerWithRealCompositorTest() { 164 LayerWithRealCompositorTest() {
96 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { 165 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
97 test_data_directory_ = test_data_directory_.AppendASCII("compositor"); 166 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
98 } else { 167 } else {
99 LOG(ERROR) << "Could not open test data directory."; 168 LOG(ERROR) << "Could not open test data directory.";
100 } 169 }
170 gfx::FontList::SetDefaultFontDescription("Arial, Times New Roman, 15px");
101 } 171 }
102 ~LayerWithRealCompositorTest() override {} 172 ~LayerWithRealCompositorTest() override {}
103 173
104 // Overridden from testing::Test: 174 // Overridden from testing::Test:
105 void SetUp() override { 175 void SetUp() override {
106 bool enable_pixel_output = true; 176 bool enable_pixel_output = true;
107 ui::ContextFactory* context_factory = 177 ui::ContextFactory* context_factory =
108 InitializeContextFactoryForTests(enable_pixel_output); 178 InitializeContextFactoryForTests(enable_pixel_output);
109 179
110 const gfx::Rect host_bounds(10, 10, 500, 500); 180 const gfx::Rect host_bounds(10, 10, 500, 500);
(...skipping 22 matching lines...) Expand all
133 layer->SetBounds(bounds); 203 layer->SetBounds(bounds);
134 return layer; 204 return layer;
135 } 205 }
136 206
137 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) { 207 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
138 Layer* layer = CreateLayer(LAYER_NOT_DRAWN); 208 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
139 layer->SetBounds(bounds); 209 layer->SetBounds(bounds);
140 return layer; 210 return layer;
141 } 211 }
142 212
213 std::unique_ptr<Layer> CreateDrawStringLayer(
214 const gfx::Rect& bounds, DrawStringLayerDelegate* delegate) {
215 std::unique_ptr<Layer> layer(new Layer(LAYER_TEXTURED));
216 layer->SetBounds(bounds);
217 layer->set_delegate(delegate);
218 return layer;
219 }
220
143 void DrawTree(Layer* root) { 221 void DrawTree(Layer* root) {
144 GetCompositor()->SetRootLayer(root); 222 GetCompositor()->SetRootLayer(root);
145 GetCompositor()->ScheduleDraw(); 223 GetCompositor()->ScheduleDraw();
146 WaitForSwap(); 224 WaitForSwap();
147 } 225 }
148 226
149 void ReadPixels(SkBitmap* bitmap) { 227 void ReadPixels(SkBitmap* bitmap) {
150 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size())); 228 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
151 } 229 }
152 230
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); 1348 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1271 1349
1272 // l11 back to front 1350 // l11 back to front
1273 l0->StackAbove(l11.get(), l12.get()); 1351 l0->StackAbove(l11.get(), l12.get());
1274 DrawTree(l0.get()); 1352 DrawTree(l0.get());
1275 ReadPixels(&bitmap); 1353 ReadPixels(&bitmap);
1276 ASSERT_FALSE(bitmap.empty()); 1354 ASSERT_FALSE(bitmap.empty());
1277 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); 1355 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1278 } 1356 }
1279 1357
1358 // It is really hard to write pixel test on text rendering,
1359 // due to different font appearance.
1360 // So we choose to check result only on Windows.
1361 // See https://codereview.chromium.org/1634103003/#msg41
1362 #if defined(OS_WIN)
1363 TEST_F(LayerWithRealCompositorTest, CanvasDrawStringRectWithHalo) {
1364 gfx::Size size(50, 50);
1365 GetCompositor()->SetScaleAndSize(1.0f, size);
1366 DrawStringLayerDelegate delegate(SK_ColorBLUE, SK_ColorWHITE,
1367 DrawStringLayerDelegate::STRING_WITH_HALO,
1368 size);
1369 std::unique_ptr<Layer> layer(
1370 CreateDrawStringLayer(gfx::Rect(size), &delegate));
1371 DrawTree(layer.get());
1372
1373 SkBitmap bitmap;
1374 ReadPixels(&bitmap);
1375 ASSERT_FALSE(bitmap.empty());
1376
1377 base::FilePath ref_img =
1378 test_data_directory().AppendASCII("string_with_halo.png");
1379 // WritePNGFile(bitmap, ref_img, true);
1380
1381 float percentage_pixels_large_error = 1.0f;
1382 float percentage_pixels_small_error = 0.0f;
1383 float average_error_allowed_in_bad_pixels = 1.f;
1384 int large_error_allowed = 1;
1385 int small_error_allowed = 0;
1386
1387 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img,
1388 cc::FuzzyPixelComparator(
1389 true,
1390 percentage_pixels_large_error,
1391 percentage_pixels_small_error,
1392 average_error_allowed_in_bad_pixels,
1393 large_error_allowed,
1394 small_error_allowed)));
1395 }
1396
1397 TEST_F(LayerWithRealCompositorTest, CanvasDrawFadedString) {
1398 gfx::Size size(50, 50);
1399 GetCompositor()->SetScaleAndSize(1.0f, size);
1400 DrawStringLayerDelegate delegate(SK_ColorBLUE, SK_ColorWHITE,
1401 DrawStringLayerDelegate::STRING_FADED,
1402 size);
1403 std::unique_ptr<Layer> layer(
1404 CreateDrawStringLayer(gfx::Rect(size), &delegate));
1405 DrawTree(layer.get());
1406
1407 SkBitmap bitmap;
1408 ReadPixels(&bitmap);
1409 ASSERT_FALSE(bitmap.empty());
1410
1411 base::FilePath ref_img =
1412 test_data_directory().AppendASCII("string_faded.png");
1413 // WritePNGFile(bitmap, ref_img, true);
1414
1415 float percentage_pixels_large_error = 8.0f; // 200px / (50*50)
1416 float percentage_pixels_small_error = 0.0f;
1417 float average_error_allowed_in_bad_pixels = 80.f;
1418 int large_error_allowed = 255;
1419 int small_error_allowed = 0;
1420
1421 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img,
1422 cc::FuzzyPixelComparator(
1423 true,
1424 percentage_pixels_large_error,
1425 percentage_pixels_small_error,
1426 average_error_allowed_in_bad_pixels,
1427 large_error_allowed,
1428 small_error_allowed)));
1429 }
1430
1431 TEST_F(LayerWithRealCompositorTest, CanvasDrawStringRectWithShadows) {
1432 gfx::Size size(50, 50);
1433 GetCompositor()->SetScaleAndSize(1.0f, size);
1434 DrawStringLayerDelegate delegate(
1435 SK_ColorBLUE, SK_ColorWHITE,
1436 DrawStringLayerDelegate::STRING_WITH_SHADOWS,
1437 size);
1438 std::unique_ptr<Layer> layer(
1439 CreateDrawStringLayer(gfx::Rect(size), &delegate));
1440 DrawTree(layer.get());
1441
1442 SkBitmap bitmap;
1443 ReadPixels(&bitmap);
1444 ASSERT_FALSE(bitmap.empty());
1445
1446 base::FilePath ref_img =
1447 test_data_directory().AppendASCII("string_with_shadows.png");
1448 // WritePNGFile(bitmap, ref_img, true);
1449
1450 float percentage_pixels_large_error = 7.4f; // 185px / (50*50)
1451 float percentage_pixels_small_error = 0.0f;
1452 float average_error_allowed_in_bad_pixels = 60.f;
1453 int large_error_allowed = 246;
1454 int small_error_allowed = 0;
1455
1456 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img,
1457 cc::FuzzyPixelComparator(
1458 true,
1459 percentage_pixels_large_error,
1460 percentage_pixels_small_error,
1461 average_error_allowed_in_bad_pixels,
1462 large_error_allowed,
1463 small_error_allowed)));
1464 }
1465 #endif // defined(OS_WIN)
1466
1280 // Opacity is rendered correctly. 1467 // Opacity is rendered correctly.
1281 // Checks that modifying the hierarchy correctly affects final composite. 1468 // Checks that modifying the hierarchy correctly affects final composite.
1282 TEST_F(LayerWithRealCompositorTest, Opacity) { 1469 TEST_F(LayerWithRealCompositorTest, Opacity) {
1283 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50)); 1470 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1284 1471
1285 // l0 1472 // l0
1286 // +-l11 1473 // +-l11
1287 std::unique_ptr<Layer> l0( 1474 std::unique_ptr<Layer> l0(
1288 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 50, 50))); 1475 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 50, 50)));
1289 std::unique_ptr<Layer> l11( 1476 std::unique_ptr<Layer> l11(
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 root->SetOpacity(0.5f); 2113 root->SetOpacity(0.5f);
1927 WaitForSwap(); 2114 WaitForSwap();
1928 EXPECT_EQ(1u, animation_observer.animation_step_count()); 2115 EXPECT_EQ(1u, animation_observer.animation_step_count());
1929 2116
1930 EXPECT_FALSE(animation_observer.shutdown()); 2117 EXPECT_FALSE(animation_observer.shutdown());
1931 ResetCompositor(); 2118 ResetCompositor();
1932 EXPECT_TRUE(animation_observer.shutdown()); 2119 EXPECT_TRUE(animation_observer.shutdown());
1933 } 2120 }
1934 2121
1935 } // namespace ui 2122 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/canvas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698