| Index: ui/views/controls/button/label_button_perftest.cc
|
| diff --git a/ui/views/controls/button/label_button_perftest.cc b/ui/views/controls/button/label_button_perftest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..186ab997e6a2a167f19cd70370a46bf69297bb28
|
| --- /dev/null
|
| +++ b/ui/views/controls/button/label_button_perftest.cc
|
| @@ -0,0 +1,147 @@
|
| +// Copyright 2015 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 "ui/views/controls/button/label_button.h"
|
| +
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "base/test/perf_time_logger.h"
|
| +#include "cc/playback/display_item_list.h"
|
| +#include "cc/playback/display_item_list_settings.h"
|
| +#include "ui/compositor/paint_context.h"
|
| +#include "ui/views/test/widget_test.h"
|
| +
|
| +namespace views {
|
| +namespace {
|
| +
|
| +const int kWarmupIterations = 20;
|
| +const int kScaleFactor = 2.0f; // Test HiDPI.
|
| +
|
| +class LabelButtonPerfTest : public test::WidgetTest {
|
| + public:
|
| + LabelButtonPerfTest() {}
|
| +
|
| + // Body of the test after a button has been created. Goal is to simulate the
|
| + // impact of adding one additional button on the time to first paint a dialog.
|
| + void PostCreateTestBody(const ui::PaintContext& paint_context, View* view) {
|
| + view->SizeToPreferredSize();
|
| + widget_->GetContentsView()->AddChildView(view);
|
| + widget_->GetContentsView()->Layout();
|
| + // Paint into a new canvas. This gets adopted by the View's PaintCache to
|
| + // emulate a "first" paint scenario. Paints the root view, so that the
|
| + // PaintContext can be reused.
|
| + widget_->GetRootView()->Paint(paint_context);
|
| + }
|
| +
|
| + void RunViewInitPaintTest(const char* test_name,
|
| + const base::Callback<View*()>& factory,
|
| + int perf_test_iterations) {
|
| + // Create a template view to determine size and ensure resources are loaded
|
| + // for the given scale factor.
|
| + gfx::Rect canvas_rect;
|
| + {
|
| + const gfx::Rect template_rect(100, 100);
|
| + scoped_refptr<cc::DisplayItemList> list = cc::DisplayItemList::Create(
|
| + template_rect, cc::DisplayItemListSettings());
|
| + ui::PaintContext paint_context(list.get(), kScaleFactor, template_rect,
|
| + template_rect);
|
| + scoped_ptr<View> template_view(factory.Run());
|
| + PostCreateTestBody(paint_context, template_view.get());
|
| + canvas_rect = template_view->bounds();
|
| + }
|
| +
|
| + // Sanity check to ensure something is happening.
|
| + EXPECT_LT(10, canvas_rect.width());
|
| + EXPECT_LT(10, canvas_rect.height());
|
| +
|
| + // Repaint with the same PaintContext each time.
|
| + scoped_refptr<cc::DisplayItemList> list =
|
| + cc::DisplayItemList::Create(canvas_rect, cc::DisplayItemListSettings());
|
| + ui::PaintContext paint_context(list.get(), kScaleFactor, canvas_rect,
|
| + canvas_rect);
|
| +
|
| + for (int iteration = 0; iteration < kWarmupIterations; ++iteration) {
|
| + scoped_ptr<View> view(factory.Run());
|
| + PostCreateTestBody(paint_context, view.get());
|
| + }
|
| +
|
| + base::PerfTimeLogger timer(test_name);
|
| + for (int iteration = 0; iteration < perf_test_iterations; ++iteration) {
|
| + scoped_ptr<View> view(factory.Run());
|
| + PostCreateTestBody(paint_context, view.get());
|
| + // scoped_ptr destructor removes the button from the hierarchy.
|
| + }
|
| + // PerfTimeLogger destructor logs duration.
|
| + }
|
| +
|
| + // testing::Test:
|
| + void SetUp() override {
|
| + ViewsTestBase::SetUp();
|
| + // Some initialization (e.g. for theming) does not occur until a view is
|
| + // actually added to a widget. Create a widget for that, but don't ever show
|
| + // it nor paint it.
|
| + widget_ = CreateTopLevelPlatformWidget();
|
| + widget_->SetSize(gfx::Size(200, 200));
|
| + widget_->Show();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + widget_->CloseNow();
|
| + ViewsTestBase::TearDown();
|
| + }
|
| +
|
| + protected:
|
| + Widget* widget_ = nullptr;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(LabelButtonPerfTest);
|
| +};
|
| +
|
| +// Factory functions for the test. Try to mimic the manner by which Views are
|
| +// are typically created in client code.
|
| +View* CreateTextbutton(const base::string16& text) {
|
| + return new LabelButton(nullptr, text);
|
| +}
|
| +
|
| +View* CreateButton(const base::string16& text) {
|
| + LabelButton* button = new LabelButton(nullptr, text);
|
| + button->SetStyle(Button::STYLE_BUTTON);
|
| + return button;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Performance tests for initializing a LabelButton, adding it to a View
|
| +// hierarchy, then performing a "first" paint. Ballpark figures are given for
|
| +// the duration of a single iteration on a z620 running Linux.
|
| +
|
| +// Test STYLE_TEXTBUTTON with no text. Ballpark: 1ms debug 0.3ms release.
|
| +TEST_F(LabelButtonPerfTest, InitAndPaintTextbuttonNoText) {
|
| + RunViewInitPaintTest("views_label_button_text_button_no_text_1000",
|
| + base::Bind(&CreateTextbutton, base::string16()),
|
| + 1000);
|
| +}
|
| +
|
| +// Test STYLE_TEXTBUTTON with the label "abc". Ballpark: 8ms debug, 7ms release.
|
| +TEST_F(LabelButtonPerfTest, InitAndPaintTextbuttonAbcText) {
|
| + RunViewInitPaintTest(
|
| + "views_label_button_text_button_abc_text_100",
|
| + base::Bind(&CreateTextbutton, base::ASCIIToUTF16("abc")),
|
| + 100);
|
| +}
|
| +
|
| +// Test STYLE_BUTTON with no text. Ballpark: 2.5ms debug 1ms release.
|
| +TEST_F(LabelButtonPerfTest, InitAndPaintButtonNoText) {
|
| + RunViewInitPaintTest("views_label_button_button_no_text_1000",
|
| + base::Bind(&CreateButton, base::string16()),
|
| + 1000);
|
| +}
|
| +
|
| +// Test STYLE_BUTTON with the label "abc". Ballpark: 12ms debug, 9ms release.
|
| +TEST_F(LabelButtonPerfTest, InitAndPaintButtonAbcText) {
|
| + RunViewInitPaintTest("views_label_button_button_abc_text_100",
|
| + base::Bind(&CreateButton, base::ASCIIToUTF16("abc")),
|
| + 100);
|
| +}
|
| +
|
| +} // namespace views
|
|
|