This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Add a DlStopwatchVisualizer
and conditionally use it for Impeller
#45259
Merged
auto-submit
merged 17 commits into
flutter:main
from
matanlurey:impeller-performance-overlay-impl
Aug 30, 2023
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
4743eb3
Add a DlStopwatchVisualizer, and use it if Impeller is enabled.
matanlurey 4bf4178
Mostly working, still debugging.
matanlurey 74e142d
The graph is now complete.
matanlurey 78c2820
Merge branch 'main' into impeller-performance-overlay-impl
matanlurey 41428f3
Stop for tonight, mostly working, needs TLC.
matanlurey d14392e
Merge remote-tracking branch 'upstream/main' into impeller-performanc…
matanlurey c12e1da
Fix bar height.
matanlurey 2030333
Only make a single DrawVertices call.
matanlurey dc2cb79
Add stopwatch_dl_unittests and write a test.
matanlurey dc164d2
Merge remote-tracking branch 'upstream/main' into impeller-performanc…
matanlurey 7943593
Remove dead code.
matanlurey 3d90d4a
Merge branch 'main' into impeller-performance-overlay-impl
matanlurey 77a4b78
Remove dead code.
matanlurey 3fcbe00
Remove FIXME.
matanlurey d5df176
Merge branch 'main' into impeller-performance-overlay-impl
matanlurey f85ee9e
kSrcOut.
matanlurey 99d0cd1
Fix type.
matanlurey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Copyright 2013 The Flutter 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 "flutter/flow/stopwatch_dl.h" | ||
#include <memory> | ||
#include <vector> | ||
#include "display_list/dl_blend_mode.h" | ||
#include "display_list/dl_canvas.h" | ||
#include "display_list/dl_color.h" | ||
#include "display_list/dl_paint.h" | ||
#include "display_list/dl_vertices.h" | ||
#include "include/core/SkRect.h" | ||
|
||
namespace flutter { | ||
|
||
static const size_t kMaxSamples = 120; | ||
static const size_t kMaxFrameMarkers = 8; | ||
|
||
void DlStopwatchVisualizer::Visualize(DlCanvas* canvas, | ||
const SkRect& rect) const { | ||
auto painter = DlVertexPainter(); | ||
DlPaint paint; | ||
|
||
// Establish the graph position. | ||
auto const x = rect.x(); | ||
auto const y = rect.y(); | ||
auto const width = rect.width(); | ||
auto const height = rect.height(); | ||
auto const bottom = rect.bottom(); | ||
|
||
// Scale the graph to show time frames up to those that are 3x the frame time. | ||
auto const one_frame_ms = stopwatch_.GetFrameBudget().count(); | ||
auto const max_interval = one_frame_ms * 3.0; | ||
auto const max_unit_interval = UnitFrameInterval(max_interval); | ||
auto const sample_unit_width = (1.0 / kMaxSamples); | ||
|
||
// Provide a semi-transparent background for the graph. | ||
painter.DrawRect(rect, 0x99FFFFFF); | ||
|
||
// Prepare a path for the data; we start at the height of the last point so | ||
// it looks like we wrap around. | ||
{ | ||
for (auto i = size_t(0); i < stopwatch_.GetLapsCount(); i++) { | ||
auto const sample_unit_height = | ||
(1.0 - UnitHeight(stopwatch_.GetLap(i).ToMillisecondsF(), | ||
max_unit_interval)); | ||
|
||
auto const bar_width = width * sample_unit_width; | ||
auto const bar_height = height * sample_unit_height; | ||
auto const bar_left = x + width * sample_unit_width * i; | ||
|
||
painter.DrawRect(SkRect::MakeLTRB(/*left=*/bar_left, | ||
/*top=*/y + bar_height, | ||
/*right=*/bar_left + bar_width, | ||
/*bottom=*/bottom), | ||
0xAA0000FF); | ||
} | ||
} | ||
|
||
// Draw horizontal frame markers. | ||
{ | ||
if (max_interval > one_frame_ms) { | ||
// Paint the horizontal markers. | ||
auto count = static_cast<size_t>(max_interval / one_frame_ms); | ||
|
||
// Limit the number of markers to a reasonable amount. | ||
if (count > kMaxFrameMarkers) { | ||
count = 1; | ||
} | ||
|
||
for (auto i = size_t(0); i < count; i++) { | ||
auto const frame_height = | ||
height * (1.0 - (UnitFrameInterval(i + 1) * one_frame_ms) / | ||
max_unit_interval); | ||
|
||
// Draw a skinny rectangle (i.e. a line). | ||
painter.DrawRect(SkRect::MakeLTRB(/*left=*/x, | ||
/*top=*/y + frame_height, | ||
/*right=*/width, | ||
/*bottom=*/y + frame_height + 1), | ||
0xCC000000); | ||
} | ||
} | ||
} | ||
|
||
// Paint the vertical marker for the current frame. | ||
{ | ||
DlColor color = DlColor::kGreen(); | ||
if (UnitFrameInterval(stopwatch_.LastLap().ToMillisecondsF()) > 1.0) { | ||
// budget exceeded. | ||
color = DlColor::kRed(); | ||
} | ||
auto const l = | ||
x + width * (static_cast<double>(stopwatch_.GetCurrentSample()) / | ||
kMaxSamples); | ||
auto const t = y; | ||
auto const r = l + width * sample_unit_width; | ||
auto const b = rect.bottom(); | ||
painter.DrawRect(SkRect::MakeLTRB(l, t, r, b), color); | ||
} | ||
|
||
// Actually draw. | ||
// Note we use kSrcOver, because some of the colors above have opacity < 1.0. | ||
canvas->DrawVertices(painter.IntoVertices(), DlBlendMode::kSrcOver, paint); | ||
} | ||
|
||
void DlVertexPainter::DrawRect(const SkRect& rect, const DlColor& color) { | ||
// Draw 6 vertices representing 2 triangles. | ||
auto const left = rect.x(); | ||
auto const top = rect.y(); | ||
auto const right = rect.right(); | ||
auto const bottom = rect.bottom(); | ||
|
||
auto const vertices = std::array<SkPoint, 6>{ | ||
SkPoint::Make(left, top), // tl tr | ||
SkPoint::Make(right, top), // br | ||
SkPoint::Make(right, bottom), // | ||
SkPoint::Make(right, bottom), // tl | ||
SkPoint::Make(left, bottom), // bl br | ||
SkPoint::Make(left, top) // | ||
}; | ||
|
||
auto const colors = std::array<DlColor, 6>{ | ||
color, // tl tr | ||
color, // br | ||
color, // | ||
color, // tl | ||
color, // bl br | ||
color // | ||
}; | ||
|
||
vertices_.insert(vertices_.end(), vertices.begin(), vertices.end()); | ||
colors_.insert(colors_.end(), colors.begin(), colors.end()); | ||
} | ||
|
||
std::shared_ptr<DlVertices> DlVertexPainter::IntoVertices() { | ||
auto const result = DlVertices::Make( | ||
/*mode=*/DlVertexMode::kTriangles, | ||
/*vertex_count=*/vertices_.size(), | ||
/*vertices=*/vertices_.data(), | ||
/*texture_coordinates=*/nullptr, | ||
/*colors=*/colors_.data()); | ||
vertices_.clear(); | ||
colors_.clear(); | ||
return result; | ||
} | ||
|
||
} // namespace flutter |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2013 The Flutter 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 FLUTTER_FLOW_STOPWATCH_DL_H_ | ||
#define FLUTTER_FLOW_STOPWATCH_DL_H_ | ||
|
||
#include "flow/stopwatch.h" | ||
|
||
namespace flutter { | ||
|
||
//------------------------------------------------------------------------------ | ||
/// A stopwatch visualizer that uses DisplayList (|DlCanvas|) to draw. | ||
/// | ||
/// @note This is the newer non-backend specific version, that works in both | ||
/// Skia and Impeller. The older Skia-specific version is | ||
/// |SkStopwatchVisualizer|, which still should be used for Skia-specific | ||
/// optimizations. | ||
class DlStopwatchVisualizer : public StopwatchVisualizer { | ||
public: | ||
explicit DlStopwatchVisualizer(const Stopwatch& stopwatch) | ||
: StopwatchVisualizer(stopwatch) {} | ||
|
||
void Visualize(DlCanvas* canvas, const SkRect& rect) const override; | ||
}; | ||
|
||
/// @brief Provides canvas-like painting methods that actually build vertices. | ||
/// | ||
/// The goal is minimally invasive rendering for the performance monitor. | ||
/// | ||
/// The methods in this class are intended to be used by |DlStopwatchVisualizer| | ||
/// only. The rationale is the creating lines, rectangles, and paths (while OK | ||
/// for general apps) would cause non-trivial work for the performance monitor | ||
/// due to tessellation per-frame. | ||
/// | ||
/// @note A goal of this class was to make updating the performance monitor | ||
/// (and keeping it in sync with the |SkStopwatchVisualizer|) as easy as | ||
/// possible (i.e. not having to do triangle-math). | ||
class DlVertexPainter final { | ||
public: | ||
/// Draws a rectangle with the given color to a buffer. | ||
void DrawRect(const SkRect& rect, const DlColor& color); | ||
|
||
/// Converts the buffered vertices into a |DlVertices| object. | ||
/// | ||
/// @note This method clears the buffer. | ||
std::shared_ptr<DlVertices> IntoVertices(); | ||
|
||
private: | ||
std::vector<SkPoint> vertices_; | ||
std::vector<DlColor> colors_; | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // FLUTTER_FLOW_STOPWATCH_DL_H_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.