flutter_flutter/flow/layers/performance_overlay_layer.cc
liyuqian d0dc9b94d4
Rename frame_time and engine_time (#8952)
At a quick glance, one could easily think of the "engine_time" as the
GPU thread time and the "frame_time" as the UI thread time because the
GPU thread time is mainly spent on the engine while the UI thread time
is mainly spent on the Dart framework to generate the frame.

But it's actually the other way. The "engine_time" is UI thread time and
the "frame_time" is the GPU thread time.

To avoid the confusion, rename them to "ui_time" and "raster_time"
respectively. I avoided the "gpu_time" because the rasterization may be
purely on a CPU backed software Skia backend.
2019-05-14 14:29:27 -07:00

98 lines
3.3 KiB
C++

// 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 <iomanip>
#include <iostream>
#include <string>
#include "flutter/flow/layers/performance_overlay_layer.h"
#include "third_party/skia/include/core/SkFont.h"
namespace flutter {
namespace {
void DrawStatisticsText(SkCanvas& canvas,
const std::string& string,
int x,
int y,
const std::string& font_path) {
SkFont font;
if (font_path != "") {
font = SkFont(SkTypeface::MakeFromFile(font_path.c_str()));
}
font.setSize(15);
SkPaint paint;
paint.setColor(SK_ColorGRAY);
canvas.drawSimpleText(string.c_str(), string.size(), SkTextEncoding::kUTF8, x,
y, font, paint);
}
void VisualizeStopWatch(SkCanvas& canvas,
const Stopwatch& stopwatch,
SkScalar x,
SkScalar y,
SkScalar width,
SkScalar height,
bool show_graph,
bool show_labels,
const std::string& label_prefix,
const std::string& font_path) {
const int label_x = 8; // distance from x
const int label_y = -10; // distance from y+height
if (show_graph) {
SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height);
stopwatch.Visualize(canvas, visualization_rect);
}
if (show_labels) {
double max_ms_per_frame = stopwatch.MaxDelta().ToMillisecondsF();
double average_ms_per_frame = stopwatch.AverageDelta().ToMillisecondsF();
std::stringstream stream;
stream.setf(std::ios::fixed | std::ios::showpoint);
stream << std::setprecision(1);
stream << label_prefix << " "
<< "max " << max_ms_per_frame << " ms/frame, "
<< "avg " << average_ms_per_frame << " ms/frame";
DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y,
font_path);
}
}
} // namespace
PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options,
const char* font_path)
: options_(options) {
if (font_path != nullptr) {
font_path_ = font_path;
}
}
void PerformanceOverlayLayer::Paint(PaintContext& context) const {
const int padding = 8;
if (!options_)
return;
TRACE_EVENT0("flutter", "PerformanceOverlayLayer::Paint");
SkScalar x = paint_bounds().x() + padding;
SkScalar y = paint_bounds().y() + padding;
SkScalar width = paint_bounds().width() - (padding * 2);
SkScalar height = paint_bounds().height() / 2;
SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
VisualizeStopWatch(
*context.leaf_nodes_canvas, context.raster_time, x, y, width,
height - padding, options_ & kVisualizeRasterizerStatistics,
options_ & kDisplayRasterizerStatistics, "GPU", font_path_);
VisualizeStopWatch(*context.leaf_nodes_canvas, context.ui_time, x, y + height,
width, height - padding,
options_ & kVisualizeEngineStatistics,
options_ & kDisplayEngineStatistics, "UI", font_path_);
}
} // namespace flutter