Index: ui/aura/painting_window_unittest.cc |
diff --git a/ui/aura/painting_window_unittest.cc b/ui/aura/painting_window_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3792efeb007f1ef59b1471949644e20446e15d81 |
--- /dev/null |
+++ b/ui/aura/painting_window_unittest.cc |
@@ -0,0 +1,217 @@ |
+// Copyright (c) 2016 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 <stddef.h> |
+#include <stdint.h> |
+ |
+#include "base/strings/utf_string_conversions.h" |
+#include "cc/output/copy_output_request.h" |
+#include "cc/output/copy_output_result.h" |
+#include "ui/aura/test/test_windows.h" |
+#include "ui/aura/window.h" |
+#include "ui/compositor/paint_recorder.h" |
+#include "ui/compositor/test/context_factories_for_test.h" |
+#include "ui/compositor/test/draw_waiter_for_test.h" |
+#include "ui/gfx/font_list.h" |
+ |
+namespace aura { |
+namespace { |
+ |
+typedef void(*TestFunction)(gfx::Canvas*, const base::string16&, |
danakj
2016/01/26 19:41:53
using, not typedef
|
+ const gfx::FontList&, const gfx::Rect&); |
+ |
+class FontTextPaintingWindowDelegate : public aura::test::TestWindowDelegate { |
+ public: |
+ FontTextPaintingWindowDelegate(const gfx::Size& window_size, |
+ TestFunction func) |
+ : window_size_(window_size), func_(func) { |
+ } |
+ |
+ ~FontTextPaintingWindowDelegate() override {} |
+ |
+ void OnPaint(const ui::PaintContext& context) override { |
+ ui::PaintRecorder recorder(context, window_size_); |
+ recorder.canvas()->DrawColor(SK_ColorBLUE); |
+ const base::string16 text = base::ASCIIToUTF16("Plz, don't crash!"); |
+ func_(recorder.canvas(), text, font_list_, gfx::Rect(window_size_)); |
+ } |
+ |
+ private: |
+ gfx::Size window_size_; |
+ gfx::FontList font_list_; |
+ TestFunction func_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FontTextPaintingWindowDelegate); |
+}; |
+ |
+} // namespace |
+ |
+class PaintingWindowTest : public testing::Test, |
+ public testing::WithParamInterface<TestFunction> { |
+ public: |
+ PaintingWindowTest() {} |
+ ~PaintingWindowTest() override {} |
+ |
+ void SetUp() override { |
+ testing::Test::SetUp(); |
+ |
+ // The ContextFactory must exist before any Compositors are created. |
+ // 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
|
+ bool enable_pixel_output = true; |
+ ui::ContextFactory* context_factory = |
+ ui::InitializeContextFactoryForTests(enable_pixel_output); |
+ |
+ helper_.reset( |
+ new aura::test::AuraTestHelper(base::MessageLoopForUI::current())); |
+ helper_->SetUp(context_factory); |
+ gfx::FontList::SetDefaultFontDescription("Arial,Times New Roman,13px"); |
+ } |
+ |
+ void TearDown() override { |
+ test_window_.reset(); |
+ delegate_.reset(); |
+ helper_->RunAllPendingInMessageLoop(); |
+ helper_->TearDown(); |
+ ui::TerminateContextFactoryForTests(); |
+ testing::Test::TearDown(); |
+ } |
+ |
+ protected: |
+ aura::Window* test_window() { return test_window_.get(); } |
+ aura::Window* root_window() { return helper_->root_window(); } |
+ aura::TestScreen* test_screen() { return helper_->test_screen(); } |
+ |
+ void WaitForDraw() { |
+ helper_->host()->compositor()->ScheduleDraw(); |
+ ui::DrawWaiterForTest::WaitForCompositingEnded( |
+ helper_->host()->compositor()); |
+ } |
+ |
+ void SetupTestWindow(const gfx::Rect& window_bounds) { |
+ delegate_.reset( |
+ new FontTextPaintingWindowDelegate(window_bounds.size(), GetParam())); |
+ test_window_.reset(aura::test::CreateTestWindowWithDelegate( |
+ delegate_.get(), 0, window_bounds, root_window())); |
+ } |
+ |
+ void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { |
+ scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); |
+ scoped_ptr<cc::CopyOutputRequest> request = |
+ cc::CopyOutputRequest::CreateBitmapRequest( |
+ base::Bind(&ReadbackHolder::OutputRequestCallback, holder)); |
+ request->set_area(source_rect); |
+ |
+ helper_->host()->compositor()->root_layer()->RequestCopyOfOutput( |
+ std::move(request)); |
+ |
+ // Wait for copy response. This needs to wait as the compositor could |
+ // be in the middle of a draw right now, and the commit with the |
+ // copy output request may not be done on the first draw. |
+ for (int i = 0; i < 2; i++) { |
+ helper_->host()->compositor()->ScheduleFullRedraw(); |
+ WaitForDraw(); |
+ } |
+ |
+ // Waits for the callback to finish run and return result. |
+ holder->WaitForReadback(); |
+ |
+ *bitmap = holder->result(); |
+ } |
+ |
+ private: |
+ class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { |
+ public: |
+ ReadbackHolder() : run_loop_(new base::RunLoop) {} |
+ |
+ void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) { |
+ result_ = result->TakeBitmap(); |
+ run_loop_->Quit(); |
+ } |
+ |
+ void WaitForReadback() { run_loop_->Run(); } |
+ |
+ const SkBitmap& result() const { return *result_; } |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<ReadbackHolder>; |
+ |
+ virtual ~ReadbackHolder() {} |
+ |
+ scoped_ptr<SkBitmap> result_; |
+ scoped_ptr<base::RunLoop> run_loop_; |
+ }; |
+ |
+ scoped_ptr<aura::test::AuraTestHelper> helper_; |
+ scoped_ptr<aura::Window> test_window_; |
+ scoped_ptr<FontTextPaintingWindowDelegate> delegate_; |
+ std::vector<unsigned char> png_representation_; |
+ base::MessageLoopForUI message_loop_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PaintingWindowTest); |
+}; |
+ |
+TEST_P(PaintingWindowTest, DrawString) { |
+ SetupTestWindow(root_window()->bounds()); |
+ WaitForDraw(); |
danakj
2016/01/26 19:41:53
why wait for draw? SetupTestWindow already did?
|
+ |
+ SkBitmap bitmap; |
+ ReadPixels(&bitmap, root_window()->bounds()); |
+ ASSERT_FALSE(bitmap.empty()); |
+ |
+ size_t count_red = 0; |
+ size_t count_blue = 0; |
+ |
+ SkAutoLockPixels lock(bitmap); |
+ for (int x = 0; x < bitmap.width(); x++) { |
+ for (int y = 0; y < bitmap.height(); y++) { |
+ SkColor actual_color = bitmap.getColor(x, y); |
+ if (actual_color == SK_ColorRED) { |
+ ++count_red; |
+ } else if (actual_color == SK_ColorBLUE) { |
+ ++count_blue; |
+ } else { |
+ EXPECT_EQ(0, SkColorGetG(actual_color)); |
+ } |
+ } |
+ } |
+ |
+ EXPECT_NE(0u, count_blue); |
danakj
2016/01/26 19:41:53
Few things about these tests..
1) I'm not a big f
|
+ EXPECT_NE(0u, count_red); |
+ EXPECT_GT(count_blue, count_red); |
+} |
+ |
+INSTANTIATE_TEST_CASE_P(DrawString, |
+ PaintingWindowTest, |
+ testing::Values( |
+ [](gfx::Canvas* canvas, |
+ const base::string16& text, |
+ const gfx::FontList& font_list, |
+ const gfx::Rect& rect) { |
+ canvas->DrawStringRectWithHalo( |
+ text, font_list, SK_ColorRED, |
+ SK_ColorBLUE, rect, 0); |
+ }, |
+ [](gfx::Canvas* canvas, |
+ const base::string16& text, |
+ const gfx::FontList& font_list, |
+ const gfx::Rect& rect) { |
+ canvas->DrawFadedString( |
+ text, font_list, SK_ColorRED, rect, 0); |
+ }, |
+ [](gfx::Canvas* canvas, |
+ const base::string16& text, |
+ const gfx::FontList& font_list, |
+ const gfx::Rect& rect) { |
+ gfx::ShadowValues shadows; |
+ shadows.push_back( |
+ gfx::ShadowValue(gfx::Vector2d(1, 1), |
+ 0, SK_ColorRED)); |
+ canvas->DrawStringRectWithShadows( |
+ text, font_list, SK_ColorRED, |
+ rect, 0, 0, shadows); |
+ } |
+ )); |
+ |
+ |
+} // namespace aura |