OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 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 <stddef.h> | |
6 #include <stdint.h> | |
7 | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "cc/output/copy_output_request.h" | |
10 #include "cc/output/copy_output_result.h" | |
11 #include "ui/aura/test/test_windows.h" | |
12 #include "ui/aura/window.h" | |
13 #include "ui/compositor/paint_recorder.h" | |
14 #include "ui/compositor/test/context_factories_for_test.h" | |
15 #include "ui/compositor/test/draw_waiter_for_test.h" | |
16 #include "ui/gfx/font_list.h" | |
17 | |
18 namespace aura { | |
19 namespace { | |
20 | |
21 typedef void(*TestFunction)(gfx::Canvas*, const base::string16&, | |
danakj
2016/01/26 19:41:53
using, not typedef
| |
22 const gfx::FontList&, const gfx::Rect&); | |
23 | |
24 class FontTextPaintingWindowDelegate : public aura::test::TestWindowDelegate { | |
25 public: | |
26 FontTextPaintingWindowDelegate(const gfx::Size& window_size, | |
27 TestFunction func) | |
28 : window_size_(window_size), func_(func) { | |
29 } | |
30 | |
31 ~FontTextPaintingWindowDelegate() override {} | |
32 | |
33 void OnPaint(const ui::PaintContext& context) override { | |
34 ui::PaintRecorder recorder(context, window_size_); | |
35 recorder.canvas()->DrawColor(SK_ColorBLUE); | |
36 const base::string16 text = base::ASCIIToUTF16("Plz, don't crash!"); | |
37 func_(recorder.canvas(), text, font_list_, gfx::Rect(window_size_)); | |
38 } | |
39 | |
40 private: | |
41 gfx::Size window_size_; | |
42 gfx::FontList font_list_; | |
43 TestFunction func_; | |
44 | |
45 DISALLOW_COPY_AND_ASSIGN(FontTextPaintingWindowDelegate); | |
46 }; | |
47 | |
48 } // namespace | |
49 | |
50 class PaintingWindowTest : public testing::Test, | |
51 public testing::WithParamInterface<TestFunction> { | |
52 public: | |
53 PaintingWindowTest() {} | |
54 ~PaintingWindowTest() override {} | |
55 | |
56 void SetUp() override { | |
57 testing::Test::SetUp(); | |
58 | |
59 // The ContextFactory must exist before any Compositors are created. | |
60 // Snapshot test tests real drawing and readback, so needs pixel output. | |
danakj
2016/01/26 19:41:53
"Snapshot test tests"? I see no Snapshot tests/cla
| |
61 bool enable_pixel_output = true; | |
62 ui::ContextFactory* context_factory = | |
63 ui::InitializeContextFactoryForTests(enable_pixel_output); | |
64 | |
65 helper_.reset( | |
66 new aura::test::AuraTestHelper(base::MessageLoopForUI::current())); | |
67 helper_->SetUp(context_factory); | |
68 gfx::FontList::SetDefaultFontDescription("Arial,Times New Roman,13px"); | |
69 } | |
70 | |
71 void TearDown() override { | |
72 test_window_.reset(); | |
73 delegate_.reset(); | |
74 helper_->RunAllPendingInMessageLoop(); | |
75 helper_->TearDown(); | |
76 ui::TerminateContextFactoryForTests(); | |
77 testing::Test::TearDown(); | |
78 } | |
79 | |
80 protected: | |
81 aura::Window* test_window() { return test_window_.get(); } | |
82 aura::Window* root_window() { return helper_->root_window(); } | |
83 aura::TestScreen* test_screen() { return helper_->test_screen(); } | |
84 | |
85 void WaitForDraw() { | |
86 helper_->host()->compositor()->ScheduleDraw(); | |
87 ui::DrawWaiterForTest::WaitForCompositingEnded( | |
88 helper_->host()->compositor()); | |
89 } | |
90 | |
91 void SetupTestWindow(const gfx::Rect& window_bounds) { | |
92 delegate_.reset( | |
93 new FontTextPaintingWindowDelegate(window_bounds.size(), GetParam())); | |
94 test_window_.reset(aura::test::CreateTestWindowWithDelegate( | |
95 delegate_.get(), 0, window_bounds, root_window())); | |
96 } | |
97 | |
98 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { | |
99 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); | |
100 scoped_ptr<cc::CopyOutputRequest> request = | |
101 cc::CopyOutputRequest::CreateBitmapRequest( | |
102 base::Bind(&ReadbackHolder::OutputRequestCallback, holder)); | |
103 request->set_area(source_rect); | |
104 | |
105 helper_->host()->compositor()->root_layer()->RequestCopyOfOutput( | |
106 std::move(request)); | |
107 | |
108 // Wait for copy response. This needs to wait as the compositor could | |
109 // be in the middle of a draw right now, and the commit with the | |
110 // copy output request may not be done on the first draw. | |
111 for (int i = 0; i < 2; i++) { | |
112 helper_->host()->compositor()->ScheduleFullRedraw(); | |
113 WaitForDraw(); | |
114 } | |
115 | |
116 // Waits for the callback to finish run and return result. | |
117 holder->WaitForReadback(); | |
118 | |
119 *bitmap = holder->result(); | |
120 } | |
121 | |
122 private: | |
123 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { | |
124 public: | |
125 ReadbackHolder() : run_loop_(new base::RunLoop) {} | |
126 | |
127 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) { | |
128 result_ = result->TakeBitmap(); | |
129 run_loop_->Quit(); | |
130 } | |
131 | |
132 void WaitForReadback() { run_loop_->Run(); } | |
133 | |
134 const SkBitmap& result() const { return *result_; } | |
135 | |
136 private: | |
137 friend class base::RefCountedThreadSafe<ReadbackHolder>; | |
138 | |
139 virtual ~ReadbackHolder() {} | |
140 | |
141 scoped_ptr<SkBitmap> result_; | |
142 scoped_ptr<base::RunLoop> run_loop_; | |
143 }; | |
144 | |
145 scoped_ptr<aura::test::AuraTestHelper> helper_; | |
146 scoped_ptr<aura::Window> test_window_; | |
147 scoped_ptr<FontTextPaintingWindowDelegate> delegate_; | |
148 std::vector<unsigned char> png_representation_; | |
149 base::MessageLoopForUI message_loop_; | |
150 | |
151 DISALLOW_COPY_AND_ASSIGN(PaintingWindowTest); | |
152 }; | |
153 | |
154 TEST_P(PaintingWindowTest, DrawString) { | |
155 SetupTestWindow(root_window()->bounds()); | |
156 WaitForDraw(); | |
danakj
2016/01/26 19:41:53
why wait for draw? SetupTestWindow already did?
| |
157 | |
158 SkBitmap bitmap; | |
159 ReadPixels(&bitmap, root_window()->bounds()); | |
160 ASSERT_FALSE(bitmap.empty()); | |
161 | |
162 size_t count_red = 0; | |
163 size_t count_blue = 0; | |
164 | |
165 SkAutoLockPixels lock(bitmap); | |
166 for (int x = 0; x < bitmap.width(); x++) { | |
167 for (int y = 0; y < bitmap.height(); y++) { | |
168 SkColor actual_color = bitmap.getColor(x, y); | |
169 if (actual_color == SK_ColorRED) { | |
170 ++count_red; | |
171 } else if (actual_color == SK_ColorBLUE) { | |
172 ++count_blue; | |
173 } else { | |
174 EXPECT_EQ(0, SkColorGetG(actual_color)); | |
175 } | |
176 } | |
177 } | |
178 | |
179 EXPECT_NE(0u, count_blue); | |
danakj
2016/01/26 19:41:53
Few things about these tests..
1) I'm not a big f
| |
180 EXPECT_NE(0u, count_red); | |
181 EXPECT_GT(count_blue, count_red); | |
182 } | |
183 | |
184 INSTANTIATE_TEST_CASE_P(DrawString, | |
185 PaintingWindowTest, | |
186 testing::Values( | |
187 [](gfx::Canvas* canvas, | |
188 const base::string16& text, | |
189 const gfx::FontList& font_list, | |
190 const gfx::Rect& rect) { | |
191 canvas->DrawStringRectWithHalo( | |
192 text, font_list, SK_ColorRED, | |
193 SK_ColorBLUE, rect, 0); | |
194 }, | |
195 [](gfx::Canvas* canvas, | |
196 const base::string16& text, | |
197 const gfx::FontList& font_list, | |
198 const gfx::Rect& rect) { | |
199 canvas->DrawFadedString( | |
200 text, font_list, SK_ColorRED, rect, 0); | |
201 }, | |
202 [](gfx::Canvas* canvas, | |
203 const base::string16& text, | |
204 const gfx::FontList& font_list, | |
205 const gfx::Rect& rect) { | |
206 gfx::ShadowValues shadows; | |
207 shadows.push_back( | |
208 gfx::ShadowValue(gfx::Vector2d(1, 1), | |
209 0, SK_ColorRED)); | |
210 canvas->DrawStringRectWithShadows( | |
211 text, font_list, SK_ColorRED, | |
212 rect, 0, 0, shadows); | |
213 } | |
214 )); | |
215 | |
216 | |
217 } // namespace aura | |
OLD | NEW |