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

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: check halo pixels Created 4 years, 10 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') | ui/gfx/render_text.cc » ('J')
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 <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
15 #include "base/json/json_reader.h" 15 #include "base/json/json_reader.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/path_service.h" 19 #include "base/path_service.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
22 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
23 #include "cc/layers/delegated_frame_provider.h" 24 #include "cc/layers/delegated_frame_provider.h"
24 #include "cc/layers/delegated_frame_resource_collection.h" 25 #include "cc/layers/delegated_frame_resource_collection.h"
25 #include "cc/layers/layer.h" 26 #include "cc/layers/layer.h"
26 #include "cc/output/copy_output_request.h" 27 #include "cc/output/copy_output_request.h"
27 #include "cc/output/copy_output_result.h" 28 #include "cc/output/copy_output_result.h"
28 #include "cc/output/delegated_frame_data.h" 29 #include "cc/output/delegated_frame_data.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_sequence.h" 34 #include "ui/compositor/layer_animation_sequence.h"
34 #include "ui/compositor/layer_animator.h" 35 #include "ui/compositor/layer_animator.h"
35 #include "ui/compositor/paint_context.h" 36 #include "ui/compositor/paint_context.h"
36 #include "ui/compositor/paint_recorder.h" 37 #include "ui/compositor/paint_recorder.h"
37 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 38 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
38 #include "ui/compositor/scoped_layer_animation_settings.h" 39 #include "ui/compositor/scoped_layer_animation_settings.h"
39 #include "ui/compositor/test/context_factories_for_test.h" 40 #include "ui/compositor/test/context_factories_for_test.h"
40 #include "ui/compositor/test/draw_waiter_for_test.h" 41 #include "ui/compositor/test/draw_waiter_for_test.h"
41 #include "ui/compositor/test/test_compositor_host.h" 42 #include "ui/compositor/test/test_compositor_host.h"
42 #include "ui/compositor/test/test_layers.h" 43 #include "ui/compositor/test/test_layers.h"
43 #include "ui/gfx/canvas.h" 44 #include "ui/gfx/canvas.h"
44 #include "ui/gfx/codec/png_codec.h" 45 #include "ui/gfx/codec/png_codec.h"
46 #include "ui/gfx/font_list.h"
45 #include "ui/gfx/gfx_paths.h" 47 #include "ui/gfx/gfx_paths.h"
46 #include "ui/gfx/skia_util.h" 48 #include "ui/gfx/skia_util.h"
47 49
48 using cc::MatchesPNGFile; 50 using cc::MatchesPNGFile;
51 using cc::WritePNGFile;
49 52
50 namespace ui { 53 namespace ui {
51 54
52 namespace { 55 namespace {
53 56
54 // There are three test classes in here that configure the Compositor and 57 // There are three test classes in here that configure the Compositor and
55 // Layer's slightly differently: 58 // Layer's slightly differently:
56 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This 59 // - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
57 // is typically the base class you want to use. 60 // is typically the base class you want to use.
58 // - LayerWithDelegateTest uses LayerDelegate on the delegates. 61 // - LayerWithDelegateTest uses LayerDelegate on the delegates.
(...skipping 22 matching lines...) Expand all
81 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} 84 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
82 85
83 base::Closure PrepareForLayerBoundsChange() override { 86 base::Closure PrepareForLayerBoundsChange() override {
84 return base::Closure(); 87 return base::Closure();
85 } 88 }
86 89
87 private: 90 private:
88 SkColor color_; 91 SkColor color_;
89 }; 92 };
90 93
94 class DrawStringLayer : public Layer, public LayerDelegate {
95 public:
96 enum DrawFunction {
97 STRING_WITH_HALO,
98 STRING_FADED,
99 STRING_WITH_SHADOWS
100 };
101
102 DrawStringLayer(SkColor back_color, SkColor halo_color, DrawFunction func)
103 : Layer(LAYER_TEXTURED),
104 background_color_(back_color),
105 halo_color_(halo_color),
106 func_(func) {
107 set_delegate(this);
108 }
109
110 ~DrawStringLayer() override {}
111
112 // Overridden from LayerDelegate:
113 void OnPaintLayer(const ui::PaintContext& context) override {
114 ui::PaintRecorder recorder(context, size());
115 recorder.canvas()->DrawColor(background_color_);
116 const base::string16 text = base::ASCIIToUTF16("Danakj");
117 switch (func_) {
118 case STRING_WITH_HALO:
119 recorder.canvas()->DrawStringRectWithHalo(
120 text, font_list_, SK_ColorRED, halo_color_, gfx::Rect(size()), 0);
121 break;
122 case STRING_FADED:
123 recorder.canvas()->DrawFadedString(
124 text, font_list_, SK_ColorRED, gfx::Rect(size()), 0);
125 break;
126 case STRING_WITH_SHADOWS: {
127 gfx::ShadowValues shadows;
128 shadows.push_back(
129 gfx::ShadowValue(gfx::Vector2d(2, 2), 2, SK_ColorRED));
130 recorder.canvas()->DrawStringRectWithShadows(
131 text, font_list_, SK_ColorRED, gfx::Rect(size()), 0, 0, shadows);
132 break;
133 }
134 default:
135 NOTREACHED();
136 }
137 }
138
139 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
140
141 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
142
143 base::Closure PrepareForLayerBoundsChange() override {
144 return base::Closure();
145 }
146
147 private:
148 SkColor background_color_;
149 SkColor halo_color_;
150 DrawFunction func_;
151 gfx::FontList font_list_;
152 };
153
91 class LayerWithRealCompositorTest : public testing::Test { 154 class LayerWithRealCompositorTest : public testing::Test {
92 public: 155 public:
93 LayerWithRealCompositorTest() { 156 LayerWithRealCompositorTest() {
94 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { 157 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) {
95 test_data_directory_ = test_data_directory_.AppendASCII("compositor"); 158 test_data_directory_ = test_data_directory_.AppendASCII("compositor");
96 } else { 159 } else {
97 LOG(ERROR) << "Could not open test data directory."; 160 LOG(ERROR) << "Could not open test data directory.";
98 } 161 }
162 gfx::FontList::SetDefaultFontDescription("Times New Roman,15px");
99 } 163 }
100 ~LayerWithRealCompositorTest() override {} 164 ~LayerWithRealCompositorTest() override {}
101 165
102 // Overridden from testing::Test: 166 // Overridden from testing::Test:
103 void SetUp() override { 167 void SetUp() override {
104 bool enable_pixel_output = true; 168 bool enable_pixel_output = true;
105 ui::ContextFactory* context_factory = 169 ui::ContextFactory* context_factory =
106 InitializeContextFactoryForTests(enable_pixel_output); 170 InitializeContextFactoryForTests(enable_pixel_output);
107 171
108 const gfx::Rect host_bounds(10, 10, 500, 500); 172 const gfx::Rect host_bounds(10, 10, 500, 500);
(...skipping 22 matching lines...) Expand all
131 layer->SetBounds(bounds); 195 layer->SetBounds(bounds);
132 return layer; 196 return layer;
133 } 197 }
134 198
135 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) { 199 Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
136 Layer* layer = CreateLayer(LAYER_NOT_DRAWN); 200 Layer* layer = CreateLayer(LAYER_NOT_DRAWN);
137 layer->SetBounds(bounds); 201 layer->SetBounds(bounds);
138 return layer; 202 return layer;
139 } 203 }
140 204
205 Layer* CreateDrawStringLayer(const gfx::Rect& bounds,
206 SkColor background_color,
207 SkColor halo_color,
208 DrawStringLayer::DrawFunction func) {
209 Layer* layer = new DrawStringLayer(background_color, halo_color, func);
210 layer->SetBounds(bounds);
211 return layer;
212 }
213
141 void DrawTree(Layer* root) { 214 void DrawTree(Layer* root) {
142 GetCompositor()->SetRootLayer(root); 215 GetCompositor()->SetRootLayer(root);
143 GetCompositor()->ScheduleDraw(); 216 GetCompositor()->ScheduleDraw();
144 WaitForSwap(); 217 WaitForSwap();
145 } 218 }
146 219
147 void ReadPixels(SkBitmap* bitmap) { 220 void ReadPixels(SkBitmap* bitmap) {
148 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size())); 221 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
149 } 222 }
150 223
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // Invalidates the entire contents of the layer. 259 // Invalidates the entire contents of the layer.
187 void SchedulePaintForLayer(Layer* layer) { 260 void SchedulePaintForLayer(Layer* layer) {
188 layer->SchedulePaint( 261 layer->SchedulePaint(
189 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); 262 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
190 } 263 }
191 264
192 const base::FilePath& test_data_directory() const { 265 const base::FilePath& test_data_directory() const {
193 return test_data_directory_; 266 return test_data_directory_;
194 } 267 }
195 268
269 bool CompareColor(const SkBitmap& bmp, const gfx::Size& size, SkColor color) {
270 SkBitmap ref_bmp;
271 ref_bmp.allocPixels(
272 SkImageInfo::MakeN32Premul(size.width(), size.height()));
273 SkCanvas canvas(ref_bmp);
274 canvas.clear(color);
275
276 cc::ExactPixelComparator comparator(true);
277 return comparator.Compare(bmp, ref_bmp);
278 }
279
280 bool HasColor(const SkBitmap& bitmap, const gfx::Size& size, SkColor color) {
281 SkAutoLockPixels lock(bitmap);
282 for (int x = 0; x < bitmap.width(); x++) {
283 for (int y = 0; y < bitmap.height(); y++) {
284 SkColor actual_color = bitmap.getColor(x, y);
285 if (actual_color == color) {
286 return true;
287 }
288 }
289 }
290 return false;
291 }
292
196 private: 293 private:
197 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { 294 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
198 public: 295 public:
199 ReadbackHolder() : run_loop_(new base::RunLoop) {} 296 ReadbackHolder() : run_loop_(new base::RunLoop) {}
200 297
201 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) { 298 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) {
202 result_ = result->TakeBitmap(); 299 result_ = result->TakeBitmap();
203 run_loop_->Quit(); 300 run_loop_->Quit();
204 } 301 }
205 302
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); 1309 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1213 1310
1214 // l11 back to front 1311 // l11 back to front
1215 l0->StackAbove(l11.get(), l12.get()); 1312 l0->StackAbove(l11.get(), l12.get());
1216 DrawTree(l0.get()); 1313 DrawTree(l0.get());
1217 ReadPixels(&bitmap); 1314 ReadPixels(&bitmap);
1218 ASSERT_FALSE(bitmap.empty()); 1315 ASSERT_FALSE(bitmap.empty());
1219 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); 1316 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1220 } 1317 }
1221 1318
1319 TEST_F(LayerWithRealCompositorTest, CanvasDrawStringRectWithHalo) {
1320 gfx::Size size(50, 50);
1321 SkColor check_color = SK_ColorBLUE;
1322 SkColor halo_color = SK_ColorWHITE;
1323 GetCompositor()->SetScaleAndSize(1.0f, size);
1324 scoped_ptr<Layer> layer(CreateDrawStringLayer(
1325 gfx::Rect(size), check_color, halo_color,
1326 DrawStringLayer::STRING_WITH_HALO));
1327 DrawTree(layer.get());
1328
1329 SkBitmap bitmap;
1330 ReadPixels(&bitmap);
1331 ASSERT_FALSE(bitmap.empty());
1332 ASSERT_EQ(50, bitmap.width());
1333 ASSERT_EQ(50, bitmap.height());
1334
1335 EXPECT_FALSE(CompareColor(bitmap, size, check_color));
1336 EXPECT_TRUE(HasColor(bitmap, size, halo_color));
1337 }
1338
1339 TEST_F(LayerWithRealCompositorTest, CanvasDrawFadedString) {
1340 gfx::Size size(50, 50);
1341 SkColor check_color = SK_ColorBLUE;
1342 SkColor halo_color = SK_ColorWHITE;
1343 GetCompositor()->SetScaleAndSize(1.0f, size);
1344 scoped_ptr<Layer> layer(CreateDrawStringLayer(
1345 gfx::Rect(size), check_color, halo_color, DrawStringLayer::STRING_FADED));
1346 DrawTree(layer.get());
1347
1348 SkBitmap bitmap;
1349 ReadPixels(&bitmap);
1350 ASSERT_FALSE(bitmap.empty());
1351
1352 EXPECT_FALSE(CompareColor(bitmap, size, check_color));
1353 EXPECT_FALSE(HasColor(bitmap, size, halo_color));
1354 }
1355
1356 TEST_F(LayerWithRealCompositorTest, CanvasDrawStringRectWithShadows) {
1357 gfx::Size size(50, 50);
1358 SkColor check_color = SK_ColorBLUE;
1359 SkColor halo_color = SK_ColorWHITE;
1360 GetCompositor()->SetScaleAndSize(1.0f, size);
1361 scoped_ptr<Layer> layer(CreateDrawStringLayer(
1362 gfx::Rect(size), check_color, halo_color,
1363 DrawStringLayer::STRING_WITH_SHADOWS));
1364 DrawTree(layer.get());
1365
1366 SkBitmap bitmap;
1367 ReadPixels(&bitmap);
1368 ASSERT_FALSE(bitmap.empty());
1369
1370 EXPECT_FALSE(CompareColor(bitmap, size, check_color));
1371 EXPECT_FALSE(HasColor(bitmap, size, halo_color));
1372 }
1373
1222 // Opacity is rendered correctly. 1374 // Opacity is rendered correctly.
1223 // Checks that modifying the hierarchy correctly affects final composite. 1375 // Checks that modifying the hierarchy correctly affects final composite.
1224 TEST_F(LayerWithRealCompositorTest, Opacity) { 1376 TEST_F(LayerWithRealCompositorTest, Opacity) {
1225 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50)); 1377 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1226 1378
1227 // l0 1379 // l0
1228 // +-l11 1380 // +-l11
1229 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, 1381 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1230 gfx::Rect(0, 0, 50, 50))); 1382 gfx::Rect(0, 0, 50, 50)));
1231 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, 1383 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 root->SetOpacity(0.5f); 2030 root->SetOpacity(0.5f);
1879 WaitForSwap(); 2031 WaitForSwap();
1880 EXPECT_EQ(1u, animation_observer.animation_step_count()); 2032 EXPECT_EQ(1u, animation_observer.animation_step_count());
1881 2033
1882 EXPECT_FALSE(animation_observer.shutdown()); 2034 EXPECT_FALSE(animation_observer.shutdown());
1883 ResetCompositor(); 2035 ResetCompositor();
1884 EXPECT_TRUE(animation_observer.shutdown()); 2036 EXPECT_TRUE(animation_observer.shutdown());
1885 } 2037 }
1886 2038
1887 } // namespace ui 2039 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/canvas.h » ('j') | ui/gfx/render_text.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698