From 0ad3591f3c094a6f6e24cb969849d5ba631db563 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Fri, 17 Mar 2023 00:14:13 -0700 Subject: [PATCH] [Impeller] Add playground flag to render for a specific amount of time. The playgrounds respect the usual GTest flags such as --gtest_filter. Now, specific test harnesses can add their own flags. The playgrounds now respect a --playground_timeout_ms flag that renders a playground for a set amount of time. Setting this to zero will mean that the playgrounds render only a single frame. --- impeller/playground/BUILD.gn | 2 ++ impeller/playground/playground.cc | 8 ++++++++ impeller/playground/playground.h | 5 ++++- impeller/playground/playground_test.cc | 17 ++++++++++++++++- impeller/playground/playground_test.h | 7 +++++++ impeller/playground/switches.cc | 18 ++++++++++++++++++ impeller/playground/switches.h | 24 ++++++++++++++++++++++++ testing/BUILD.gn | 2 ++ testing/run_all_unittests.cc | 10 +++++++--- testing/test_args.cc | 21 +++++++++++++++++++++ testing/test_args.h | 17 +++++++++++++++++ 11 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 impeller/playground/switches.cc create mode 100644 impeller/playground/switches.h create mode 100644 testing/test_args.cc create mode 100644 testing/test_args.h diff --git a/impeller/playground/BUILD.gn b/impeller/playground/BUILD.gn index 623b0d2557b9e..e574e8044594a 100644 --- a/impeller/playground/BUILD.gn +++ b/impeller/playground/BUILD.gn @@ -11,6 +11,8 @@ impeller_component("playground") { "playground.h", "playground_impl.cc", "playground_impl.h", + "switches.cc", + "switches.h", "widgets.cc", "widgets.h", ] diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index 85042638b8044..5080e8842e190 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -300,6 +300,10 @@ bool Playground::OpenPlaygroundHere( VALIDATION_LOG << "Could not render into the surface."; return false; } + + if (!ShouldKeepRendering()) { + break; + } } ::glfwHideWindow(window); @@ -450,4 +454,8 @@ void Playground::SetWindowSize(ISize size) { window_size_ = size; } +bool Playground::ShouldKeepRendering() const { + return true; +} + } // namespace impeller diff --git a/impeller/playground/playground.h b/impeller/playground/playground.h index ac44f19450a6d..f44e36c20b100 100644 --- a/impeller/playground/playground.h +++ b/impeller/playground/playground.h @@ -4,12 +4,12 @@ #pragma once +#include #include #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" #include "flutter/fml/time/time_delta.h" - #include "impeller/geometry/point.h" #include "impeller/image/compressed_image.h" #include "impeller/image/decompressed_image.h" @@ -91,6 +91,9 @@ class Playground { virtual std::string GetWindowTitle() const = 0; + protected: + virtual bool ShouldKeepRendering() const; + private: #if IMPELLER_ENABLE_PLAYGROUND static const bool is_enabled_ = true; diff --git a/impeller/playground/playground_test.cc b/impeller/playground/playground_test.cc index 9db2c3a2eeb21..16f86d282121f 100644 --- a/impeller/playground/playground_test.cc +++ b/impeller/playground/playground_test.cc @@ -4,11 +4,13 @@ #include "flutter/fml/time/time_point.h" +#include "impeller/base/timing.h" #include "impeller/playground/playground_test.h" namespace impeller { -PlaygroundTest::PlaygroundTest() = default; +PlaygroundTest::PlaygroundTest() + : switches_(flutter::testing::GetArgsForProcess()) {} PlaygroundTest::~PlaygroundTest() = default; @@ -61,4 +63,17 @@ std::string PlaygroundTest::GetWindowTitle() const { return FormatWindowTitle(flutter::testing::GetCurrentTestName()); } +// |Playground| +bool PlaygroundTest::ShouldKeepRendering() const { + if (!switches_.timeout.has_value()) { + return true; + } + + if (SecondsF{GetSecondsElapsed()} > switches_.timeout.value()) { + return false; + } + + return true; +} + } // namespace impeller diff --git a/impeller/playground/playground_test.h b/impeller/playground/playground_test.h index 2d01cae7632a0..720623ecda33e 100644 --- a/impeller/playground/playground_test.h +++ b/impeller/playground/playground_test.h @@ -7,9 +7,11 @@ #include #include "flutter/fml/macros.h" +#include "flutter/testing/test_args.h" #include "flutter/testing/testing.h" #include "impeller/geometry/scalar.h" #include "impeller/playground/playground.h" +#include "impeller/playground/switches.h" namespace impeller { @@ -35,6 +37,11 @@ class PlaygroundTest : public Playground, std::string GetWindowTitle() const override; private: + const PlaygroundSwitches switches_; + + // |Playground| + bool ShouldKeepRendering() const; + FML_DISALLOW_COPY_AND_ASSIGN(PlaygroundTest); }; diff --git a/impeller/playground/switches.cc b/impeller/playground/switches.cc new file mode 100644 index 0000000000000..3991e5f9831d5 --- /dev/null +++ b/impeller/playground/switches.cc @@ -0,0 +1,18 @@ +// 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 "impeller/playground/switches.h" + +#include + +namespace impeller { + +PlaygroundSwitches::PlaygroundSwitches(const fml::CommandLine& args) { + std::string timeout_str; + if (args.GetOptionValue("playground_timeout_ms", &timeout_str)) { + timeout = std::chrono::milliseconds(atoi(timeout_str.c_str())); + } +} + +} // namespace impeller diff --git a/impeller/playground/switches.h b/impeller/playground/switches.h new file mode 100644 index 0000000000000..905123b3cc986 --- /dev/null +++ b/impeller/playground/switches.h @@ -0,0 +1,24 @@ +// 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. + +#pragma once + +#include +#include + +#include "flutter/fml/command_line.h" +#include "flutter/fml/macros.h" + +namespace impeller { + +struct PlaygroundSwitches { + // If specified, the playgrounds will render for at least the duration + // specified in the timeout. If the timeout is zero, exactly one frame will be + // rendered in the playground. + std::optional timeout; + + explicit PlaygroundSwitches(const fml::CommandLine& args); +}; + +} // namespace impeller diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 84fab9e41306e..ded94aff3cabe 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -45,6 +45,8 @@ source_set("testing") { "debugger_detection.cc", "debugger_detection.h", "run_all_unittests.cc", + "test_args.cc", + "test_args.h", "test_timeout_listener.cc", "test_timeout_listener.h", ] diff --git a/testing/run_all_unittests.cc b/testing/run_all_unittests.cc index ae5105fc21e72..8d08a3a59ebdb 100644 --- a/testing/run_all_unittests.cc +++ b/testing/run_all_unittests.cc @@ -10,6 +10,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/command_line.h" #include "flutter/testing/debugger_detection.h" +#include "flutter/testing/test_args.h" #include "flutter/testing/test_timeout_listener.h" #include "gtest/gtest.h" @@ -17,8 +18,8 @@ #include #endif // FML_OS_IOS -std::optional GetTestTimeoutFromArgs(int argc, char** argv) { - const auto command_line = fml::CommandLineFromPlatformOrArgcArgv(argc, argv); +std::optional GetTestTimeout() { + const auto& command_line = flutter::testing::GetArgsForProcess(); std::string timeout_seconds; if (!command_line.GetOptionValue("timeout", &timeout_seconds)) { @@ -37,6 +38,9 @@ std::optional GetTestTimeoutFromArgs(int argc, char** argv) { int main(int argc, char** argv) { fml::InstallCrashHandler(); + + flutter::testing::SetArgsForProcess(argc, argv); + #ifdef FML_OS_IOS asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE); @@ -47,7 +51,7 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); // Check if the user has specified a timeout. - const auto timeout = GetTestTimeoutFromArgs(argc, argv); + const auto timeout = GetTestTimeout(); if (!timeout.has_value()) { FML_LOG(INFO) << "Timeouts disabled via a command line flag."; return RUN_ALL_TESTS(); diff --git a/testing/test_args.cc b/testing/test_args.cc new file mode 100644 index 0000000000000..ace858cd64e7f --- /dev/null +++ b/testing/test_args.cc @@ -0,0 +1,21 @@ +// 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/testing/test_args.h" + +namespace flutter { +namespace testing { + +static fml::CommandLine gProcessArgs; + +const fml::CommandLine& GetArgsForProcess() { + return gProcessArgs; +} + +void SetArgsForProcess(int argc, char** argv) { + gProcessArgs = fml::CommandLineFromArgcArgv(argc, argv); +} + +} // namespace testing +} // namespace flutter diff --git a/testing/test_args.h b/testing/test_args.h new file mode 100644 index 0000000000000..0ee5d2a79837a --- /dev/null +++ b/testing/test_args.h @@ -0,0 +1,17 @@ +// 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. + +#pragma once + +#include "flutter/fml/command_line.h" + +namespace flutter { +namespace testing { + +const fml::CommandLine& GetArgsForProcess(); + +void SetArgsForProcess(int argc, char** argv); + +} // namespace testing +} // namespace flutter