diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 11251d2098309..3ae421ecf59f3 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -846,6 +846,8 @@ ORIGIN: ../../../flutter/flow/raster_cache_util.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/skia_gpu_object.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/stopwatch.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/stopwatch.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/flow/stopwatch_sk.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/flow/stopwatch_sk.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface_frame.cc + ../../../flutter/LICENSE @@ -3592,6 +3594,8 @@ FILE: ../../../flutter/flow/raster_cache_util.h FILE: ../../../flutter/flow/skia_gpu_object.h FILE: ../../../flutter/flow/stopwatch.cc FILE: ../../../flutter/flow/stopwatch.h +FILE: ../../../flutter/flow/stopwatch_sk.cc +FILE: ../../../flutter/flow/stopwatch_sk.h FILE: ../../../flutter/flow/surface.cc FILE: ../../../flutter/flow/surface.h FILE: ../../../flutter/flow/surface_frame.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index f52d3251c45d8..5d69ae2e166fa 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -77,6 +77,8 @@ source_set("flow") { "skia_gpu_object.h", "stopwatch.cc", "stopwatch.h", + "stopwatch_sk.cc", + "stopwatch_sk.h", "surface.cc", "surface.h", "surface_frame.cc", diff --git a/flow/layers/performance_overlay_layer.cc b/flow/layers/performance_overlay_layer.cc index 2b693b270033c..4275a996fdb35 100644 --- a/flow/layers/performance_overlay_layer.cc +++ b/flow/layers/performance_overlay_layer.cc @@ -8,6 +8,7 @@ #include #include +#include "flow/stopwatch_sk.h" #include "third_party/skia/include/core/SkFont.h" #include "third_party/skia/include/core/SkTextBlob.h" @@ -29,7 +30,11 @@ void VisualizeStopWatch(DlCanvas* canvas, if (show_graph) { SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height); - stopwatch.Visualize(canvas, visualization_rect); + + // TODO(matanlurey): Select a visualizer based on the current backend. + // https://github.com/flutter/flutter/issues/126009 + SkStopwatchVisualizer visualizer = SkStopwatchVisualizer(stopwatch); + visualizer.Visualize(canvas, visualization_rect); } if (show_labels) { diff --git a/flow/stopwatch.cc b/flow/stopwatch.cc index 4d28f375a4479..b8e8d3007a6cd 100644 --- a/flow/stopwatch.cc +++ b/flow/stopwatch.cc @@ -4,14 +4,9 @@ #include "flutter/flow/stopwatch.h" -#include "include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkPath.h" -#include "third_party/skia/include/core/SkSurface.h" - namespace flutter { static const size_t kMaxSamples = 120; -static const size_t kMaxFrameMarkers = 8; Stopwatch::Stopwatch(const RefreshRateUpdater& updater) : refresh_rate_updater_(updater), @@ -19,8 +14,6 @@ Stopwatch::Stopwatch(const RefreshRateUpdater& updater) current_sample_(0) { const fml::TimeDelta delta = fml::TimeDelta::Zero(); laps_.resize(kMaxSamples, delta); - cache_dirty_ = true; - prev_drawn_sample_index_ = 0; } Stopwatch::~Stopwatch() = default; @@ -51,12 +44,20 @@ const fml::TimeDelta& Stopwatch::LastLap() const { return laps_[(current_sample_ - 1) % kMaxSamples]; } -double Stopwatch::UnitFrameInterval(double raster_time_ms) const { - return raster_time_ms / GetFrameBudget().count(); +const fml::TimeDelta& Stopwatch::GetLap(size_t index) const { + return laps_[index]; +} + +size_t Stopwatch::GetCurrentSample() const { + return current_sample_; +} + +double StopwatchVisualizer::UnitFrameInterval(double raster_time_ms) const { + return raster_time_ms / stopwatch_.GetFrameBudget().count(); } -double Stopwatch::UnitHeight(double raster_time_ms, - double max_unit_interval) const { +double StopwatchVisualizer::UnitHeight(double raster_time_ms, + double max_unit_interval) const { double unit_height = UnitFrameInterval(raster_time_ms) / max_unit_interval; if (unit_height > 1.0) { unit_height = 1.0; @@ -82,169 +83,6 @@ fml::TimeDelta Stopwatch::AverageDelta() const { return sum / kMaxSamples; } -// Initialize the SkSurface for drawing into. Draws the base background and any -// timing data from before the initial Visualize() call. -void Stopwatch::InitVisualizeSurface(SkISize size) const { - // Mark as dirty if the size has changed. - if (visualize_cache_surface_) { - if (size.width() != visualize_cache_surface_->width() || - size.height() != visualize_cache_surface_->height()) { - cache_dirty_ = true; - }; - } - - if (!cache_dirty_) { - return; - } - cache_dirty_ = false; - - // TODO(garyq): Use a GPU surface instead of a CPU surface. - visualize_cache_surface_ = - SkSurfaces::Raster(SkImageInfo::MakeN32Premul(size)); - - SkCanvas* cache_canvas = visualize_cache_surface_->getCanvas(); - - // Establish the graph position. - const SkScalar x = 0; - const SkScalar y = 0; - const SkScalar width = size.width(); - const SkScalar height = size.height(); - - SkPaint paint; - paint.setColor(0x99FFFFFF); - cache_canvas->drawRect(SkRect::MakeXYWH(x, y, width, height), paint); - - // Scale the graph to show frame times up to those that are 3 times the frame - // time. - const double one_frame_ms = GetFrameBudget().count(); - const double max_interval = one_frame_ms * 3.0; - const double max_unit_interval = UnitFrameInterval(max_interval); - - // Draw the old data to initially populate the graph. - // Prepare a path for the data. We start at the height of the last point, so - // it looks like we wrap around - SkPath path; - path.setIsVolatile(true); - path.moveTo(x, height); - path.lineTo(x, y + height * (1.0 - UnitHeight(laps_[0].ToMillisecondsF(), - max_unit_interval))); - double unit_x; - double unit_next_x = 0.0; - for (size_t i = 0; i < kMaxSamples; i += 1) { - unit_x = unit_next_x; - unit_next_x = (static_cast(i + 1) / kMaxSamples); - const double sample_y = - y + height * (1.0 - UnitHeight(laps_[i].ToMillisecondsF(), - max_unit_interval)); - path.lineTo(x + width * unit_x, sample_y); - path.lineTo(x + width * unit_next_x, sample_y); - } - path.lineTo( - width, - y + height * (1.0 - UnitHeight(laps_[kMaxSamples - 1].ToMillisecondsF(), - max_unit_interval))); - path.lineTo(width, height); - path.close(); - - // Draw the graph. - paint.setColor(0xAA0000FF); - cache_canvas->drawPath(path, paint); -} - -void Stopwatch::Visualize(DlCanvas* canvas, const SkRect& rect) const { - // Initialize visualize cache if it has not yet been initialized. - InitVisualizeSurface(SkISize::Make(rect.width(), rect.height())); - - SkCanvas* cache_canvas = visualize_cache_surface_->getCanvas(); - SkPaint paint; - - // Establish the graph position. - const SkScalar x = 0; - const SkScalar y = 0; - const SkScalar width = visualize_cache_surface_->width(); - const SkScalar height = visualize_cache_surface_->height(); - - // Scale the graph to show frame times up to those that are 3 times the frame - // time. - const double one_frame_ms = GetFrameBudget().count(); - const double max_interval = one_frame_ms * 3.0; - const double max_unit_interval = UnitFrameInterval(max_interval); - - const double sample_unit_width = (1.0 / kMaxSamples); - - // Draw vertical replacement bar to erase old/stale pixels. - paint.setColor(0x99FFFFFF); - paint.setStyle(SkPaint::Style::kFill_Style); - paint.setBlendMode(SkBlendMode::kSrc); - double sample_x = - x + width * (static_cast(prev_drawn_sample_index_) / kMaxSamples); - const auto eraser_rect = SkRect::MakeLTRB( - sample_x, y, sample_x + width * sample_unit_width, height); - cache_canvas->drawRect(eraser_rect, paint); - - // Draws blue timing bar for new data. - paint.setColor(0xAA0000FF); - paint.setBlendMode(SkBlendMode::kSrcOver); - const auto bar_rect = SkRect::MakeLTRB( - sample_x, - y + height * (1.0 - - UnitHeight(laps_[current_sample_ == 0 ? kMaxSamples - 1 - : current_sample_ - 1] - .ToMillisecondsF(), - max_unit_interval)), - sample_x + width * sample_unit_width, height); - cache_canvas->drawRect(bar_rect, paint); - - // Draw horizontal frame markers. - paint.setStrokeWidth(0); // hairline - paint.setStyle(SkPaint::Style::kStroke_Style); - paint.setColor(0xCC000000); - - if (max_interval > one_frame_ms) { - // Paint the horizontal markers - size_t frame_marker_count = - static_cast(max_interval / one_frame_ms); - - // Limit the number of markers displayed. After a certain point, the graph - // becomes crowded - if (frame_marker_count > kMaxFrameMarkers) { - frame_marker_count = 1; - } - - for (size_t frame_index = 0; frame_index < frame_marker_count; - frame_index++) { - const double frame_height = - height * (1.0 - (UnitFrameInterval((frame_index + 1) * one_frame_ms) / - max_unit_interval)); - cache_canvas->drawLine(x, y + frame_height, width, y + frame_height, - paint); - } - } - - // Paint the vertical marker for the current frame. - // We paint it over the current frame, not after it, because when we - // paint this we don't yet have all the times for the current frame. - paint.setStyle(SkPaint::Style::kFill_Style); - paint.setBlendMode(SkBlendMode::kSrcOver); - if (UnitFrameInterval(LastLap().ToMillisecondsF()) > 1.0) { - // budget exceeded - paint.setColor(SK_ColorRED); - } else { - // within budget - paint.setColor(SK_ColorGREEN); - } - sample_x = x + width * (static_cast(current_sample_) / kMaxSamples); - const auto marker_rect = SkRect::MakeLTRB( - sample_x, y, sample_x + width * sample_unit_width, height); - cache_canvas->drawRect(marker_rect, paint); - prev_drawn_sample_index_ = current_sample_; - - // Draw the cached surface onto the output canvas. - auto image = DlImage::Make(visualize_cache_surface_->makeImageSnapshot()); - canvas->DrawImage(image, {rect.x(), rect.y()}, - DlImageSampling::kNearestNeighbor); -} - fml::Milliseconds Stopwatch::GetFrameBudget() const { return refresh_rate_updater_.GetFrameBudget(); } diff --git a/flow/stopwatch.h b/flow/stopwatch.h index 005697dd9a164..d6e8f0da7fbcc 100644 --- a/flow/stopwatch.h +++ b/flow/stopwatch.h @@ -12,8 +12,6 @@ #include "flutter/fml/time/time_delta.h" #include "flutter/fml/time/time_point.h" -#include "third_party/skia/include/core/SkSurface.h" - namespace flutter { class Stopwatch { @@ -32,16 +30,16 @@ class Stopwatch { ~Stopwatch(); + const fml::TimeDelta& GetLap(size_t index) const; + + size_t GetCurrentSample() const; + const fml::TimeDelta& LastLap() const; fml::TimeDelta MaxDelta() const; fml::TimeDelta AverageDelta() const; - void InitVisualizeSurface(SkISize size) const; - - void Visualize(DlCanvas* canvas, const SkRect& rect) const; - void Start(); void Stop(); @@ -52,20 +50,11 @@ class Stopwatch { fml::Milliseconds GetFrameBudget() const; private: - inline double UnitFrameInterval(double time_ms) const; - inline double UnitHeight(double time_ms, double max_height) const; - const RefreshRateUpdater& refresh_rate_updater_; fml::TimePoint start_; std::vector laps_; size_t current_sample_; - // Mutable data cache for performance optimization of the graphs. Prevents - // expensive redrawing of old data. - mutable bool cache_dirty_; - mutable sk_sp visualize_cache_surface_; - mutable size_t prev_drawn_sample_index_; - FML_DISALLOW_COPY_AND_ASSIGN(Stopwatch); }; @@ -91,6 +80,38 @@ class FixedRefreshRateStopwatch : public Stopwatch { FixedRefreshRateUpdater fixed_delegate_; }; +//------------------------------------------------------------------------------ +/// @brief Abstract class for visualizing (i.e. drawing) a stopwatch. +/// +/// @note This was originally folded into the |Stopwatch| class, but +/// was separated out to make it easier to change the underlying +/// implementation (which relied directly on Skia, not showing on +/// Impeller: https://github.com/flutter/flutter/issues/126009). +class StopwatchVisualizer { + public: + explicit StopwatchVisualizer(const Stopwatch& stopwatch) + : stopwatch_(stopwatch) {} + + virtual ~StopwatchVisualizer() = default; + + /// @brief Renders the stopwatch as a graph. + /// + /// @param canvas The canvas to draw on. + /// @param[in] rect The rectangle to draw in. + virtual void Visualize(DlCanvas* canvas, const SkRect& rect) const = 0; + + FML_DISALLOW_COPY_AND_ASSIGN(StopwatchVisualizer); + + protected: + /// @brief Converts a raster time to a unit interval. + double UnitFrameInterval(double time_ms) const; + + /// @brief Converts a raster time to a unit height. + double UnitHeight(double time_ms, double max_height) const; + + const Stopwatch& stopwatch_; +}; + } // namespace flutter #endif // FLUTTER_FLOW_INSTRUMENTATION_H_ diff --git a/flow/stopwatch_sk.cc b/flow/stopwatch_sk.cc new file mode 100644 index 0000000000000..16a3411fdf9cc --- /dev/null +++ b/flow/stopwatch_sk.cc @@ -0,0 +1,187 @@ +// 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_sk.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkImageInfo.h" +#include "include/core/SkPaint.h" +#include "include/core/SkPath.h" +#include "include/core/SkSize.h" +#include "include/core/SkSurface.h" + +namespace flutter { + +static const size_t kMaxSamples = 120; +static const size_t kMaxFrameMarkers = 8; + +void SkStopwatchVisualizer::InitVisualizeSurface(SkISize size) const { + // Mark as dirty if the size has changed. + if (visualize_cache_surface_) { + if (size.width() != visualize_cache_surface_->width() || + size.height() != visualize_cache_surface_->height()) { + cache_dirty_ = true; + }; + } + + if (!cache_dirty_) { + return; + } + cache_dirty_ = false; + + // TODO(garyq): Use a GPU surface instead of a CPU surface. + visualize_cache_surface_ = + SkSurfaces::Raster(SkImageInfo::MakeN32Premul(size)); + + SkCanvas* cache_canvas = visualize_cache_surface_->getCanvas(); + + // Establish the graph position. + const SkScalar x = 0; + const SkScalar y = 0; + const SkScalar width = size.width(); + const SkScalar height = size.height(); + + SkPaint paint; + paint.setColor(0x99FFFFFF); + cache_canvas->drawRect(SkRect::MakeXYWH(x, y, width, height), paint); + + // Scale the graph to show frame times up to those that are 3 times the frame + // time. + const double one_frame_ms = stopwatch_.GetFrameBudget().count(); + const double max_interval = one_frame_ms * 3.0; + const double max_unit_interval = UnitFrameInterval(max_interval); + + // Draw the old data to initially populate the graph. + // Prepare a path for the data. We start at the height of the last point, so + // it looks like we wrap around + SkPath path; + path.setIsVolatile(true); + path.moveTo(x, height); + path.lineTo( + x, y + height * (1.0 - UnitHeight(stopwatch_.GetLap(0).ToMillisecondsF(), + max_unit_interval))); + double unit_x; + double unit_next_x = 0.0; + for (size_t i = 0; i < kMaxSamples; i += 1) { + unit_x = unit_next_x; + unit_next_x = (static_cast(i + 1) / kMaxSamples); + const double sample_y = + y + height * (1.0 - UnitHeight(stopwatch_.GetLap(i).ToMillisecondsF(), + max_unit_interval)); + path.lineTo(x + width * unit_x, sample_y); + path.lineTo(x + width * unit_next_x, sample_y); + } + path.lineTo( + width, + y + height * + (1.0 - + UnitHeight(stopwatch_.GetLap(kMaxSamples - 1).ToMillisecondsF(), + max_unit_interval))); + path.lineTo(width, height); + path.close(); + + // Draw the graph. + paint.setColor(0xAA0000FF); + cache_canvas->drawPath(path, paint); +} + +void SkStopwatchVisualizer::Visualize(DlCanvas* canvas, + const SkRect& rect) const { + // Initialize visualize cache if it has not yet been initialized. + InitVisualizeSurface(SkISize::Make(rect.width(), rect.height())); + + SkCanvas* cache_canvas = visualize_cache_surface_->getCanvas(); + SkPaint paint; + + // Establish the graph position. + const SkScalar x = 0; + const SkScalar y = 0; + const SkScalar width = visualize_cache_surface_->width(); + const SkScalar height = visualize_cache_surface_->height(); + + // Scale the graph to show frame times up to those that are 3 times the frame + // time. + const double one_frame_ms = stopwatch_.GetFrameBudget().count(); + const double max_interval = one_frame_ms * 3.0; + const double max_unit_interval = UnitFrameInterval(max_interval); + + const double sample_unit_width = (1.0 / kMaxSamples); + + // Draw vertical replacement bar to erase old/stale pixels. + paint.setColor(0x99FFFFFF); + paint.setStyle(SkPaint::Style::kFill_Style); + paint.setBlendMode(SkBlendMode::kSrc); + double sample_x = + x + width * (static_cast(prev_drawn_sample_index_) / kMaxSamples); + const auto eraser_rect = SkRect::MakeLTRB( + sample_x, y, sample_x + width * sample_unit_width, height); + cache_canvas->drawRect(eraser_rect, paint); + + // Draws blue timing bar for new data. + paint.setColor(0xAA0000FF); + paint.setBlendMode(SkBlendMode::kSrcOver); + const auto bar_rect = SkRect::MakeLTRB( + sample_x, + y + height * + (1.0 - + UnitHeight(stopwatch_ + .GetLap(stopwatch_.GetCurrentSample() == 0 + ? kMaxSamples - 1 + : stopwatch_.GetCurrentSample() - 1) + .ToMillisecondsF(), + max_unit_interval)), + sample_x + width * sample_unit_width, height); + cache_canvas->drawRect(bar_rect, paint); + + // Draw horizontal frame markers. + paint.setStrokeWidth(0); // hairline + paint.setStyle(SkPaint::Style::kStroke_Style); + paint.setColor(0xCC000000); + + if (max_interval > one_frame_ms) { + // Paint the horizontal markers + size_t frame_marker_count = + static_cast(max_interval / one_frame_ms); + + // Limit the number of markers displayed. After a certain point, the graph + // becomes crowded + if (frame_marker_count > kMaxFrameMarkers) { + frame_marker_count = 1; + } + + for (size_t frame_index = 0; frame_index < frame_marker_count; + frame_index++) { + const double frame_height = + height * (1.0 - (UnitFrameInterval((frame_index + 1) * one_frame_ms) / + max_unit_interval)); + cache_canvas->drawLine(x, y + frame_height, width, y + frame_height, + paint); + } + } + + // Paint the vertical marker for the current frame. + // We paint it over the current frame, not after it, because when we + // paint this we don't yet have all the times for the current frame. + paint.setStyle(SkPaint::Style::kFill_Style); + paint.setBlendMode(SkBlendMode::kSrcOver); + if (UnitFrameInterval(stopwatch_.LastLap().ToMillisecondsF()) > 1.0) { + // budget exceeded + paint.setColor(SK_ColorRED); + } else { + // within budget + paint.setColor(SK_ColorGREEN); + } + sample_x = x + width * (static_cast(stopwatch_.GetCurrentSample()) / + kMaxSamples); + const auto marker_rect = SkRect::MakeLTRB( + sample_x, y, sample_x + width * sample_unit_width, height); + cache_canvas->drawRect(marker_rect, paint); + prev_drawn_sample_index_ = stopwatch_.GetCurrentSample(); + + // Draw the cached surface onto the output canvas. + auto image = DlImage::Make(visualize_cache_surface_->makeImageSnapshot()); + canvas->DrawImage(image, {rect.x(), rect.y()}, + DlImageSampling::kNearestNeighbor); +} + +} // namespace flutter diff --git a/flow/stopwatch_sk.h b/flow/stopwatch_sk.h new file mode 100644 index 0000000000000..c1dfb24307d33 --- /dev/null +++ b/flow/stopwatch_sk.h @@ -0,0 +1,40 @@ +// 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_SK_H_ +#define FLUTTER_FLOW_STOPWATCH_SK_H_ + +#include "flow/stopwatch.h" +#include "include/core/SkSurface.h" + +namespace flutter { + +//------------------------------------------------------------------------------ +/// A stopwatch visualizer that uses Skia (|SkCanvas|) to draw the stopwatch. +/// +/// @see DlStopwatchVisualizer for the newer non-backend specific version. +class SkStopwatchVisualizer : public StopwatchVisualizer { + public: + explicit SkStopwatchVisualizer(const Stopwatch& stopwatch) + : StopwatchVisualizer(stopwatch) {} + + void Visualize(DlCanvas* canvas, const SkRect& rect) const override; + + private: + /// Initializes the |SkSurface| used for drawing the stopwatch. + /// + /// Draws the base background and any timing data from before the initial + /// call to |Visualize|. + void InitVisualizeSurface(SkISize size) const; + + // Mutable data cache for performance optimization of the graphs. + // Prevents expensive redrawing of old data. + mutable bool cache_dirty_ = true; + mutable sk_sp visualize_cache_surface_; + mutable size_t prev_drawn_sample_index_ = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_FLOW_STOPWATCH_SK_H_ diff --git a/flow/stopwatch_unittests.cc b/flow/stopwatch_unittests.cc index 76893c7089333..3ded5142a9fbb 100644 --- a/flow/stopwatch_unittests.cc +++ b/flow/stopwatch_unittests.cc @@ -42,5 +42,20 @@ TEST(Instrumentation, GetFrameBudgetFromUpdaterTest) { EXPECT_EQ(frame_budget_90fps, actual_frame_budget); } +TEST(Instrumentation, GetLapByIndexTest) { + fml::Milliseconds frame_budget_90fps = fml::RefreshRateToFrameBudget(90); + FixedRefreshRateStopwatch stopwatch(frame_budget_90fps); + stopwatch.SetLapTime(fml::TimeDelta::FromMilliseconds(10)); + EXPECT_EQ(stopwatch.GetLap(1), fml::TimeDelta::FromMilliseconds(10)); +} + +TEST(Instrumentation, GetCurrentSampleTest) { + fml::Milliseconds frame_budget_90fps = fml::RefreshRateToFrameBudget(90); + FixedRefreshRateStopwatch stopwatch(frame_budget_90fps); + stopwatch.Start(); + stopwatch.Stop(); + EXPECT_EQ(stopwatch.GetCurrentSample(), size_t(1)); +} + } // namespace testing } // namespace flutter diff --git a/testing/resources/performance_overlay_gold_120fps.png b/testing/resources/performance_overlay_gold_120fps.png index c19d1eb7208e1..9677724230ad2 100644 Binary files a/testing/resources/performance_overlay_gold_120fps.png and b/testing/resources/performance_overlay_gold_120fps.png differ diff --git a/testing/resources/performance_overlay_gold_60fps.png b/testing/resources/performance_overlay_gold_60fps.png index 4e18fa15e9436..0d45210c56e40 100644 Binary files a/testing/resources/performance_overlay_gold_60fps.png and b/testing/resources/performance_overlay_gold_60fps.png differ diff --git a/testing/resources/performance_overlay_gold_90fps.png b/testing/resources/performance_overlay_gold_90fps.png index 962e2875d4fde..d6fb7e8e0d7a1 100644 Binary files a/testing/resources/performance_overlay_gold_90fps.png and b/testing/resources/performance_overlay_gold_90fps.png differ