Chromium Code Reviews| 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 |