Commit 7d66f340 authored by Alexander Alekseev's avatar Alexander Alekseev Committed by Commit Bot

Ash HUD: Add graph legend.

This adds legend to the graphs.

CPU tab legend: https://screenshot.googleplex.com/BSEafb7msokFohF.png
RAM tab legend: https://screenshot.googleplex.com/7KZWaGYP5NNjkR7.png
Folded legend: https://screenshot.googleplex.com/6g9U2v4CEjgKhPq.png

Bug: 1121868
Change-Id: I9c093f4d3ef886b6aba659497a56d766eb8cb2eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2380268
Commit-Queue: Alexander Alekseev <alemate@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804256}
parent d93811a3
...@@ -492,10 +492,14 @@ component("ash") { ...@@ -492,10 +492,14 @@ component("ash") {
"hud_display/hud_properties.h", "hud_display/hud_properties.h",
"hud_display/hud_settings_view.cc", "hud_display/hud_settings_view.cc",
"hud_display/hud_settings_view.h", "hud_display/hud_settings_view.h",
"hud_display/legend.cc",
"hud_display/legend.h",
"hud_display/memory_graph_page_view.cc", "hud_display/memory_graph_page_view.cc",
"hud_display/memory_graph_page_view.h", "hud_display/memory_graph_page_view.h",
"hud_display/memory_status.cc", "hud_display/memory_status.cc",
"hud_display/memory_status.h", "hud_display/memory_status.h",
"hud_display/solid_source_background.cc",
"hud_display/solid_source_background.h",
"hud_display/tab_strip.cc", "hud_display/tab_strip.cc",
"hud_display/tab_strip.h", "hud_display/tab_strip.h",
"ime/ime_controller_impl.cc", "ime/ime_controller_impl.cc",
......
...@@ -6,10 +6,8 @@ ...@@ -6,10 +6,8 @@
#include <numeric> #include <numeric>
#include "ash/hud_display/grid.h"
#include "ash/hud_display/hud_constants.h" #include "ash/hud_display/hud_constants.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/views/layout/fill_layout.h"
namespace ash { namespace ash {
namespace hud_display { namespace hud_display {
...@@ -33,18 +31,30 @@ CpuGraphPageView::CpuGraphPageView(const base::TimeDelta refresh_interval) ...@@ -33,18 +31,30 @@ CpuGraphPageView::CpuGraphPageView(const base::TimeDelta refresh_interval)
cpu_idle_(Graph::Baseline::BASELINE_BOTTOM, cpu_idle_(Graph::Baseline::BASELINE_BOTTOM,
Graph::Fill::SOLID, Graph::Fill::SOLID,
SkColorSetA(SK_ColorDKGRAY, kHUDAlpha)) { SkColorSetA(SK_ColorDKGRAY, kHUDAlpha)) {
// There is only one child which shoule be overlayed.
SetLayoutManager(std::make_unique<views::FillLayout>());
const int data_width = cpu_other_.GetDataBufferSize(); const int data_width = cpu_other_.GetDataBufferSize();
// -XX seconds on the left, 100% top, 0 seconds on the right, 0% on the // -XX seconds on the left, 100% top, 0 seconds on the right, 0% on the
// bottom. Seconds and Gigabytes are dimentions. Number of data points is // bottom. Seconds and Gigabytes are dimentions. Number of data points is
// cpu_other_.GetDataBufferSize(), horizontal grid ticks are drawn every 10 // cpu_other_.GetDataBufferSize(), horizontal grid ticks are drawn every 10
// seconds. // seconds.
grid_ = AddChildView(std::make_unique<Grid>( CreateGrid(
/*left=*/static_cast<int>(-data_width * refresh_interval.InSecondsF()), /*left=*/static_cast<int>(-data_width * refresh_interval.InSecondsF()),
/*top=*/100, /*right=*/0, /*bottom=*/0, base::ASCIIToUTF16("s"), /*top=*/100, /*right=*/0, /*bottom=*/0, base::ASCIIToUTF16("s"),
base::ASCIIToUTF16("%"), data_width, 10 / refresh_interval.InSecondsF())); base::ASCIIToUTF16("%"), data_width, 10 / refresh_interval.InSecondsF());
const std::vector<Legend::Entry> legend(
{{cpu_idle_.color(), base::ASCIIToUTF16("Idle"),
base::ASCIIToUTF16("Total amount of CPU time spent\nin idle mode.")},
{cpu_user_.color(), base::ASCIIToUTF16("User"),
base::ASCIIToUTF16(
"Total amount of CPU time spent\n running user processes.")},
{cpu_system_.color(), base::ASCIIToUTF16("System"),
base::ASCIIToUTF16(
"Total amount of CPU time spent\nrunning system processes.")},
{cpu_other_.color(), base::ASCIIToUTF16("Other"),
base::ASCIIToUTF16(
"Total amount of CPU time spent\nrunning other tasks.\nThis "
"includes IO wait, IRQ, guest OS, etc.")}});
CreateLegend(legend);
} }
CpuGraphPageView::~CpuGraphPageView() = default; CpuGraphPageView::~CpuGraphPageView() = default;
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
namespace ash { namespace ash {
namespace hud_display { namespace hud_display {
class Grid;
// Draws CPU graphs; // Draws CPU graphs;
class CpuGraphPageView : public GraphPageViewBase { class CpuGraphPageView : public GraphPageViewBase {
public: public:
...@@ -23,7 +21,7 @@ class CpuGraphPageView : public GraphPageViewBase { ...@@ -23,7 +21,7 @@ class CpuGraphPageView : public GraphPageViewBase {
CpuGraphPageView& operator=(const CpuGraphPageView&) = delete; CpuGraphPageView& operator=(const CpuGraphPageView&) = delete;
~CpuGraphPageView() override; ~CpuGraphPageView() override;
// view:: // views::View
void OnPaint(gfx::Canvas* canvas) override; void OnPaint(gfx::Canvas* canvas) override;
// Update page data from the new snapshot. // Update page data from the new snapshot.
...@@ -35,8 +33,6 @@ class CpuGraphPageView : public GraphPageViewBase { ...@@ -35,8 +33,6 @@ class CpuGraphPageView : public GraphPageViewBase {
Graph cpu_system_; Graph cpu_system_;
Graph cpu_user_; Graph cpu_user_;
Graph cpu_idle_; Graph cpu_idle_;
Grid* grid_ = nullptr; // not owned.
}; };
} // namespace hud_display } // namespace hud_display
......
...@@ -55,6 +55,8 @@ class Graph { ...@@ -55,6 +55,8 @@ class Graph {
size_t GetDataBufferSize() const { return data_.BufferSize(); } size_t GetDataBufferSize() const { return data_.BufferSize(); }
SkColor color() const { return color_; }
#if !defined(NDEBUG) #if !defined(NDEBUG)
// Returns string representation os this object for debug. // Returns string representation os this object for debug.
std::string DebugDump(const std::string& name) const; std::string DebugDump(const std::string& name) const;
......
...@@ -4,19 +4,150 @@ ...@@ -4,19 +4,150 @@
#include "ash/hud_display/graph_page_view_base.h" #include "ash/hud_display/graph_page_view_base.h"
#include "ash/hud_display/grid.h"
#include "ash/hud_display/hud_constants.h"
#include "ash/hud_display/hud_properties.h"
#include "ash/hud_display/legend.h"
#include "ash/hud_display/solid_source_background.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/window/vector_icons/vector_icons.h"
namespace ash { namespace ash {
namespace hud_display { namespace hud_display {
namespace {
constexpr int kMinMaxButtonIconSize = 10;
constexpr int kMinMaxButtonBorder = 5;
// ImageButton with underline
class MinMaxButton : public views::ImageButton {
public:
METADATA_HEADER(MinMaxButton);
explicit MinMaxButton(views::ButtonListener* listener)
: views::ImageButton(listener) {
SetBorder(views::CreateEmptyBorder(gfx::Insets(kMinMaxButtonBorder)));
SetBackground(std::make_unique<SolidSourceBackground>(kHUDLegendBackground,
/*radius=*/0));
SetProperty(kHUDClickHandler, HTCLIENT);
}
MinMaxButton(const MinMaxButton&) = delete;
MinMaxButton& operator=(const MinMaxButton&) = delete;
~MinMaxButton() override = default;
protected:
// ImageButton
void PaintButtonContents(gfx::Canvas* canvas) override {
views::ImageButton::PaintButtonContents(canvas);
SkPath path;
path.moveTo(0, height());
path.lineTo(height(), width());
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setBlendMode(SkBlendMode::kSrc);
flags.setStyle(cc::PaintFlags::kStroke_Style);
flags.setStrokeWidth(1);
flags.setColor(kHUDDefaultColor);
canvas->DrawPath(path, flags);
}
};
BEGIN_METADATA(MinMaxButton, ImageButton)
END_METADATA
void SetMinimizeIconToButton(views::ImageButton* button) {
button->SetImage(
views::Button::ButtonState::STATE_NORMAL,
gfx::CreateVectorIcon(views::kWindowControlMinimizeIcon,
kMinMaxButtonIconSize, kHUDDefaultColor));
}
void SetRestoreIconToButton(views::ImageButton* button) {
button->SetImage(
views::Button::ButtonState::STATE_NORMAL,
gfx::CreateVectorIcon(views::kWindowControlRestoreIcon,
kMinMaxButtonIconSize, kHUDDefaultColor));
}
} // namespace
BEGIN_METADATA(GraphPageViewBase, View) BEGIN_METADATA(GraphPageViewBase, View)
END_METADATA END_METADATA
GraphPageViewBase::GraphPageViewBase() { GraphPageViewBase::GraphPageViewBase() {
DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_);
// There are two overlaid children: grid and container for the legend.
SetLayoutManager(std::make_unique<views::FillLayout>());
// Grid is added after this object is fully initialized, but it should be
// located under control elements (or they will never receive events). This
// way we need to create a separate container for it.
grid_container_ = AddChildView(std::make_unique<views::View>());
grid_container_->SetLayoutManager(std::make_unique<views::FillLayout>());
// Legend is floating in its own container. Invisible border of
// kLegendPositionOffset makes it float on top of the graph.
constexpr int kLegendPositionOffset = 20;
legend_container_ = AddChildView(std::make_unique<views::View>());
legend_container_
->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical))
->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kStart);
legend_container_->SetBorder(
views::CreateEmptyBorder(gfx::Insets(kLegendPositionOffset)));
legend_container_->SetVisible(false);
legend_min_max_button_ =
legend_container_->AddChildView(std::make_unique<MinMaxButton>(this));
SetMinimizeIconToButton(legend_min_max_button_);
} }
GraphPageViewBase::~GraphPageViewBase() { GraphPageViewBase::~GraphPageViewBase() {
DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_);
} }
void GraphPageViewBase::ButtonPressed(views::Button*, ui::Event const&) {
if (legend_->GetVisible()) {
legend_->SetVisible(false);
SetRestoreIconToButton(legend_min_max_button_);
} else {
legend_->SetVisible(true);
SetMinimizeIconToButton(legend_min_max_button_);
}
}
void GraphPageViewBase::CreateLegend(
const std::vector<Legend::Entry>& entries) {
DCHECK(!legend_);
legend_ = legend_container_->AddChildView(std::make_unique<Legend>(entries));
legend_container_->SetVisible(true);
}
// Put grid in its dedicated container.
Grid* GraphPageViewBase::CreateGrid(float left,
float top,
float right,
float bottom,
const base::string16& x_unit,
const base::string16& y_unit,
int horizontal_points_number,
int horizontal_ticks_interval) {
DCHECK(grid_container_->children().empty());
return grid_container_->AddChildView(std::make_unique<Grid>(
left, top, right, bottom, x_unit, y_unit, horizontal_points_number,
horizontal_ticks_interval));
}
} // namespace hud_display } // namespace hud_display
} // namespace ash } // namespace ash
...@@ -6,14 +6,22 @@ ...@@ -6,14 +6,22 @@
#define ASH_HUD_DISPLAY_GRAPH_PAGE_VIEW_BASE_H_ #define ASH_HUD_DISPLAY_GRAPH_PAGE_VIEW_BASE_H_
#include "ash/hud_display/data_source.h" #include "ash/hud_display/data_source.h"
#include "ash/hud_display/legend.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h" #include "ui/views/view.h"
namespace views {
class ImageButton;
}
namespace ash { namespace ash {
namespace hud_display { namespace hud_display {
class Grid;
// Interface for a single graph page. // Interface for a single graph page.
class GraphPageViewBase : public views::View { class GraphPageViewBase : public views::View, public views::ButtonListener {
public: public:
METADATA_HEADER(GraphPageViewBase); METADATA_HEADER(GraphPageViewBase);
...@@ -22,10 +30,34 @@ class GraphPageViewBase : public views::View { ...@@ -22,10 +30,34 @@ class GraphPageViewBase : public views::View {
GraphPageViewBase& operator=(const GraphPageViewBase&) = delete; GraphPageViewBase& operator=(const GraphPageViewBase&) = delete;
~GraphPageViewBase() override; ~GraphPageViewBase() override;
// views::ButtonListener
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// Update page data from the new snapshot. // Update page data from the new snapshot.
virtual void UpdateData(const DataSource::Snapshot& snapshot) = 0; virtual void UpdateData(const DataSource::Snapshot& snapshot) = 0;
// Adds default legend.
void CreateLegend(const std::vector<Legend::Entry>& entries);
// Put grid in its dedicated container.
Grid* CreateGrid(float left,
float top,
float right,
float bottom,
const base::string16& x_unit,
const base::string16& y_unit,
int horizontal_points_number,
int horizontal_ticks_interval);
private: private:
// Container for the Grid object.
views::View* grid_container_ = nullptr; // not owned
// Container for the legend object.
views::View* legend_container_ = nullptr; // not owned
views::ImageButton* legend_min_max_button_ = nullptr; // not owned
views::View* legend_ = nullptr; // not owned
SEQUENCE_CHECKER(ui_sequence_checker_); SEQUENCE_CHECKER(ui_sequence_checker_);
}; };
......
...@@ -17,6 +17,7 @@ constexpr SkColor kHUDDefaultColor = ...@@ -17,6 +17,7 @@ constexpr SkColor kHUDDefaultColor =
SkColorSetARGB(kHUDAlpha, 0xFF, 0xB2, 0x66); SkColorSetARGB(kHUDAlpha, 0xFF, 0xB2, 0x66);
constexpr SkColor kHUDBackground = SkColorSetARGB(kHUDAlpha, 17, 17, 17); constexpr SkColor kHUDBackground = SkColorSetARGB(kHUDAlpha, 17, 17, 17);
constexpr SkColor kHUDLegendBackground = kHUDBackground;
// Radius of rounded corners for tabs. // Radius of rounded corners for tabs.
// Must be be divisible by 3 to make kTabOverlayWidth integer. // Must be be divisible by 3 to make kTabOverlayWidth integer.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "ash/hud_display/hud_constants.h" #include "ash/hud_display/hud_constants.h"
#include "ash/hud_display/hud_display.h" #include "ash/hud_display/hud_display.h"
#include "ash/hud_display/hud_properties.h" #include "ash/hud_display/hud_properties.h"
#include "ash/hud_display/solid_source_background.h"
#include "ash/hud_display/tab_strip.h" #include "ash/hud_display/tab_strip.h"
#include "components/vector_icons/vector_icons.h" #include "components/vector_icons/vector_icons.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
...@@ -22,52 +23,6 @@ namespace ash { ...@@ -22,52 +23,6 @@ namespace ash {
namespace hud_display { namespace hud_display {
namespace { namespace {
// Basically views::SolidBackground with SkBlendMode::kSrc paint mode.
class SolidSourceBackground : public views::Background {
public:
// Background will have top rounded corners with |top_rounding_radius|.
SolidSourceBackground(SkColor color, SkScalar top_rounding_radius)
: top_rounding_radius_(top_rounding_radius) {
SetNativeControlColor(color);
}
SolidSourceBackground(const SolidSourceBackground&) = delete;
SolidSourceBackground& operator=(const SolidSourceBackground&) = delete;
~SolidSourceBackground() override = default;
// views::Background
void Paint(gfx::Canvas* canvas, views::View* view) const override {
if (top_rounding_radius_ == 0) {
// Fill the background. Note that we don't constrain to the bounds as
// canvas is already clipped for us.
canvas->DrawColor(get_color(), SkBlendMode::kSrc);
} else {
const SkScalar circle_size = top_rounding_radius_ * 2;
const int right_edge = view->width();
const int bottom_edge = view->height();
SkPath path;
path.moveTo(0, bottom_edge);
/* |false| will draw straight line to the start of the arc */
path.arcTo({0, 0, circle_size, circle_size}, -180, 90, false);
path.arcTo({right_edge - circle_size, 0, right_edge, circle_size}, -90,
90, false);
path.lineTo(right_edge, bottom_edge);
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setBlendMode(SkBlendMode::kSrc);
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(get_color());
canvas->DrawPath(path, flags);
}
}
private:
SkScalar top_rounding_radius_;
};
// Draws bottom left rounded background triangle. // Draws bottom left rounded background triangle.
class BottomLeftOuterBackground : public views::Background { class BottomLeftOuterBackground : public views::Background {
public: public:
......
// Copyright 2020 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 "ash/hud_display/legend.h"
#include "ash/hud_display/hud_constants.h"
#include "ash/hud_display/solid_source_background.h"
#include "cc/paint/paint_flags.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
namespace hud_display {
namespace {
class LegendEntry : public views::View {
public:
METADATA_HEADER(LegendEntry);
explicit LegendEntry(const Legend::Entry& data);
LegendEntry(const LegendEntry&) = delete;
LegendEntry& operator=(const LegendEntry&) = delete;
~LegendEntry() override;
// views::View:
void OnPaint(gfx::Canvas* canvas) override;
private:
const SkColor color_;
};
BEGIN_METADATA(LegendEntry, View)
END_METADATA
LegendEntry::LegendEntry(const Legend::Entry& data) : color_(data.color) {
views::BoxLayout* layout_manager =
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
layout_manager->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
// We need to allocate space for the colorpicker. It should be square with
// edge size matching default views::Label height. This is not known until
// layout runs, so just hard code it.
constexpr int kColorpickerAreaWidth = 20;
SetBorder(views::CreateEmptyBorder(0, kColorpickerAreaWidth, 0, 0));
views::Label* label = AddChildView(
std::make_unique<views::Label>(data.label, views::style::CONTEXT_LABEL));
label->SetEnabledColor(kHUDDefaultColor);
if (!data.tooltip.empty())
label->SetTooltipText(data.tooltip);
}
LegendEntry::~LegendEntry() = default;
void LegendEntry::OnPaint(gfx::Canvas* canvas) {
// Draw 10x10 sold color rectangle in the middle of the left border.
// (We used border to allocate space for the colorpicker above.)
constexpr int kBoxSize = 10;
const gfx::Rect bounds(border()->GetInsets().left(), height());
constexpr int kBoxBorderWidth = 1;
gfx::Rect box = bounds;
box.ClampToCenteredSize(gfx::Size(kBoxSize, kBoxSize));
const SkRect border =
SkRect::MakeXYWH(box.x(), box.y(), box.width(), box.height());
SkPath box_border;
box_border.addRect(border);
SkPath box_filled;
box_filled.addRect(border.makeInset(kBoxBorderWidth, kBoxBorderWidth));
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setBlendMode(SkBlendMode::kSrc);
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(color_);
canvas->DrawPath(box_filled, flags);
flags.setStyle(cc::PaintFlags::kStroke_Style);
flags.setStrokeWidth(kBoxBorderWidth);
flags.setColor(kHUDDefaultColor);
canvas->DrawPath(box_border, flags);
views::View::OnPaint(canvas);
}
} // namespace
BEGIN_METADATA(Legend, View)
END_METADATA
Legend::Legend(const std::vector<Legend::Entry>& contents) {
views::BoxLayout* layout_manager =
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
layout_manager->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kStretch);
SetBackground(std::make_unique<SolidSourceBackground>(kHUDLegendBackground,
/*radius=*/0));
SetBorder(views::CreateEmptyBorder(gfx::Insets(kHUDInset)));
for (const auto& entry : contents)
AddChildView(std::make_unique<LegendEntry>(entry));
}
Legend::~Legend() = default;
} // namespace hud_display
} // namespace ash
// Copyright 2020 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.
#ifndef ASH_HUD_DISPLAY_LEGEND_H_
#define ASH_HUD_DISPLAY_LEGEND_H_
#include <vector>
#include "base/strings/string16.h"
#include "ui/views/view.h"
namespace ash {
namespace hud_display {
// Draws legend view.
class Legend : public views::View {
public:
METADATA_HEADER(Legend);
struct Entry {
SkColor color;
base::string16 label;
base::string16 tooltip;
};
Legend(const std::vector<Entry>& contents);
Legend(const Legend&) = delete;
Legend& operator=(const Legend&) = delete;
~Legend() override;
};
} // namespace hud_display
} // namespace ash
#endif // ASH_HUD_DISPLAY_LEGEND_H_
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/views/layout/fill_layout.h"
namespace ash { namespace ash {
namespace hud_display { namespace hud_display {
...@@ -47,21 +46,40 @@ MemoryGraphPageView::MemoryGraphPageView(const base::TimeDelta refresh_interval) ...@@ -47,21 +46,40 @@ MemoryGraphPageView::MemoryGraphPageView(const base::TimeDelta refresh_interval)
graph_chrome_rss_shared_(Graph::Baseline::BASELINE_BOTTOM, graph_chrome_rss_shared_(Graph::Baseline::BASELINE_BOTTOM,
Graph::Fill::NONE, Graph::Fill::NONE,
SkColorSetA(SK_ColorBLUE, kHUDAlpha)) { SkColorSetA(SK_ColorBLUE, kHUDAlpha)) {
// There is only one child which shoule be overlayed.
SetLayoutManager(std::make_unique<views::FillLayout>());
const int data_width = graph_arc_rss_private_.GetDataBufferSize(); const int data_width = graph_arc_rss_private_.GetDataBufferSize();
// -XX seconds on the left, 0Gb top (will be updated later), 0 seconds on the // -XX seconds on the left, 0Gb top (will be updated later), 0 seconds on the
// right, 0 Gb on the bottom. Seconds and Gigabytes are dimentions. Number of // right, 0 Gb on the bottom. Seconds and Gigabytes are dimentions. Number of
// data points is data_width. horizontal grid ticks are drawn every 10 // data points is data_width. horizontal grid ticks are drawn every 10
// seconds. // seconds.
grid_ = AddChildView(std::make_unique<Grid>( grid_ = CreateGrid(
static_cast<int>(/*left=*/-data_width * refresh_interval.InSecondsF()), static_cast<int>(/*left=*/-data_width * refresh_interval.InSecondsF()),
/*top=*/0, /*right=*/0, /*bottom=*/0, base::ASCIIToUTF16("s"), /*top=*/0, /*right=*/0, /*bottom=*/0, base::ASCIIToUTF16("s"),
base::ASCIIToUTF16("Gb"), data_width, base::ASCIIToUTF16("Gb"), data_width, 10 / refresh_interval.InSecondsF());
10 / refresh_interval.InSecondsF()));
// Hide grid until we know total memory size. // Hide grid until we know total memory size.
grid_->SetVisible(false); grid_->SetVisible(false);
const std::vector<Legend::Entry> legend({
{graph_gpu_kernel_.color(), base::ASCIIToUTF16("GPU Driver"),
base::ASCIIToUTF16("Kernel GPU buffers as reported\nby "
"base::SystemMemoryInfo::gem_size.")},
{graph_gpu_rss_private_.color(), base::ASCIIToUTF16("Chrome GPU"),
base::ASCIIToUTF16(
"RSS private memory of\n --type=gpu-process Chrome process.")},
// ARC memory is not usually visible (skipped)
{graph_renderers_rss_private_.color(),
base::ASCIIToUTF16("Chrome Renderer"),
base::ASCIIToUTF16(
"Sum of RSS private memory of\n--type=renderer Chrome process.")},
{graph_mem_used_unknown_.color(), base::ASCIIToUTF16("Other"),
base::ASCIIToUTF16(
"Amount of other used memory.\nEquals to total used minus known.")},
{graph_mem_free_.color(), base::ASCIIToUTF16("Free"),
base::ASCIIToUTF16("Free memory as reported by kernel.")},
{graph_chrome_rss_private_.color(), base::ASCIIToUTF16("Browser"),
base::ASCIIToUTF16("RSS private memory of the\nmain Chrome process.")}
// Browser RSS hairline skipped.
});
CreateLegend(legend);
} }
MemoryGraphPageView::~MemoryGraphPageView() = default; MemoryGraphPageView::~MemoryGraphPageView() = default;
......
// Copyright 2020 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 "ash/hud_display/solid_source_background.h"
#include "cc/paint/paint_flags.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/gfx/canvas.h"
#include "ui/views/view.h"
namespace ash {
namespace hud_display {
SolidSourceBackground::SolidSourceBackground(SkColor color,
SkScalar top_rounding_radius)
: top_rounding_radius_(top_rounding_radius) {
SetNativeControlColor(color);
}
void SolidSourceBackground::Paint(gfx::Canvas* canvas,
views::View* view) const {
if (top_rounding_radius_ == 0) {
// Fill the background. Note that we don't constrain to the bounds as
// canvas is already clipped for us.
canvas->DrawColor(get_color(), SkBlendMode::kSrc);
} else {
const SkScalar circle_size = top_rounding_radius_ * 2;
const int right_edge = view->width();
const int bottom_edge = view->height();
SkPath path;
path.moveTo(0, bottom_edge);
// |false| will draw straight line to the start of the arc.
path.arcTo({0, 0, circle_size, circle_size}, -180, 90, false);
path.arcTo({right_edge - circle_size, 0, right_edge, circle_size}, -90, 90,
false);
path.lineTo(right_edge, bottom_edge);
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setBlendMode(SkBlendMode::kSrc);
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(get_color());
canvas->DrawPath(path, flags);
}
}
} // namespace hud_display
} // namespace ash
// Copyright 2020 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.
#ifndef ASH_HUD_DISPLAY_SOLID_SOURCE_BACKGROUND_H_
#define ASH_HUD_DISPLAY_SOLID_SOURCE_BACKGROUND_H_
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "ui/views/background.h"
namespace gfx {
class Canvas;
}
namespace views {
class View;
}
namespace ash {
namespace hud_display {
// Basically views::SolidBackground with SkBlendMode::kSrc paint mode.
class SolidSourceBackground : public views::Background {
public:
// Background will have top rounded corners with |top_rounding_radius|.
SolidSourceBackground(SkColor color, SkScalar top_rounding_radius);
SolidSourceBackground(const SolidSourceBackground&) = delete;
SolidSourceBackground& operator=(const SolidSourceBackground&) = delete;
~SolidSourceBackground() override = default;
// views::Background
void Paint(gfx::Canvas* canvas, views::View* view) const override;
private:
SkScalar top_rounding_radius_;
};
} // namespace hud_display
} // namespace ash
#endif // ASH_HUD_DISPLAY_SOLID_SOURCE_BACKGROUND_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment