diff --git a/ci/builders/mac_host_engine.json b/ci/builders/mac_host_engine.json index 368b3fefc0cfe..ba81406ddf6b9 100644 --- a/ci/builders/mac_host_engine.json +++ b/ci/builders/mac_host_engine.json @@ -52,7 +52,7 @@ "--variant", "host_debug", "--type", - "dart", + "dart,engine", "--engine-capture-core-dump" ], "script": "flutter/testing/run_tests.py" diff --git a/flow/frame_timings.cc b/flow/frame_timings.cc index 7b5c0f908f49a..eed35fd4c755a 100644 --- a/flow/frame_timings.cc +++ b/flow/frame_timings.cc @@ -103,32 +103,75 @@ size_t FrameTimingsRecorder::GetPictureCacheBytes() const { void FrameTimingsRecorder::RecordVsync(fml::TimePoint vsync_start, fml::TimePoint vsync_target) { + fml::Status status = RecordVsyncImpl(vsync_start, vsync_target); + FML_DCHECK(status.ok()); + (void)status; +} + +void FrameTimingsRecorder::RecordBuildStart(fml::TimePoint build_start) { + fml::Status status = RecordBuildStartImpl(build_start); + FML_DCHECK(status.ok()); + (void)status; +} + +void FrameTimingsRecorder::RecordBuildEnd(fml::TimePoint build_end) { + fml::Status status = RecordBuildEndImpl(build_end); + FML_DCHECK(status.ok()); + (void)status; +} + +void FrameTimingsRecorder::RecordRasterStart(fml::TimePoint raster_start) { + fml::Status status = RecordRasterStartImpl(raster_start); + FML_DCHECK(status.ok()); + (void)status; +} + +fml::Status FrameTimingsRecorder::RecordVsyncImpl(fml::TimePoint vsync_start, + fml::TimePoint vsync_target) { std::scoped_lock state_lock(state_mutex_); - FML_DCHECK(state_ == State::kUninitialized); + if (state_ != State::kUninitialized) { + return fml::Status(fml::StatusCode::kFailedPrecondition, + "Check failed: state_ == State::kUninitialized."); + } state_ = State::kVsync; vsync_start_ = vsync_start; vsync_target_ = vsync_target; + return fml::Status(); } -void FrameTimingsRecorder::RecordBuildStart(fml::TimePoint build_start) { +fml::Status FrameTimingsRecorder::RecordBuildStartImpl( + fml::TimePoint build_start) { std::scoped_lock state_lock(state_mutex_); - FML_DCHECK(state_ == State::kVsync); + if (state_ != State::kVsync) { + return fml::Status(fml::StatusCode::kFailedPrecondition, + "Check failed: state_ == State::kVsync."); + } state_ = State::kBuildStart; build_start_ = build_start; + return fml::Status(); } -void FrameTimingsRecorder::RecordBuildEnd(fml::TimePoint build_end) { +fml::Status FrameTimingsRecorder::RecordBuildEndImpl(fml::TimePoint build_end) { std::scoped_lock state_lock(state_mutex_); - FML_DCHECK(state_ == State::kBuildStart); + if (state_ != State::kBuildStart) { + return fml::Status(fml::StatusCode::kFailedPrecondition, + "Check failed: state_ == State::kBuildStart."); + } state_ = State::kBuildEnd; build_end_ = build_end; + return fml::Status(); } -void FrameTimingsRecorder::RecordRasterStart(fml::TimePoint raster_start) { +fml::Status FrameTimingsRecorder::RecordRasterStartImpl( + fml::TimePoint raster_start) { std::scoped_lock state_lock(state_mutex_); - FML_DCHECK(state_ == State::kBuildEnd); + if (state_ != State::kBuildEnd) { + return fml::Status(fml::StatusCode::kFailedPrecondition, + "Check failed: state_ == State::kBuildEnd."); + } state_ = State::kRasterStart; raster_start_ = raster_start; + return fml::Status(); } FrameTiming FrameTimingsRecorder::RecordRasterEnd(const RasterCache* cache) { diff --git a/flow/frame_timings.h b/flow/frame_timings.h index 8d39bb61457d8..39a569c5e79f2 100644 --- a/flow/frame_timings.h +++ b/flow/frame_timings.h @@ -10,6 +10,7 @@ #include "flutter/common/settings.h" #include "flutter/flow/raster_cache.h" #include "flutter/fml/macros.h" +#include "flutter/fml/status.h" #include "flutter/fml/time/time_delta.h" #include "flutter/fml/time/time_point.h" @@ -19,6 +20,10 @@ namespace flutter { +namespace testing { +class FrameTimingsRecorderTest; +} + /// Records timestamps for various phases of a frame rendering process. /// /// Recorder is created on vsync and destroyed after the rasterization of the @@ -114,6 +119,16 @@ class FrameTimingsRecorder { FrameTiming GetRecordedTime() const; private: + FML_FRIEND_TEST(FrameTimingsRecorderTest, ThrowWhenRecordBuildBeforeVsync); + FML_FRIEND_TEST(FrameTimingsRecorderTest, + ThrowWhenRecordRasterBeforeBuildEnd); + + [[nodiscard]] fml::Status RecordVsyncImpl(fml::TimePoint vsync_start, + fml::TimePoint vsync_target); + [[nodiscard]] fml::Status RecordBuildStartImpl(fml::TimePoint build_start); + [[nodiscard]] fml::Status RecordBuildEndImpl(fml::TimePoint build_end); + [[nodiscard]] fml::Status RecordRasterStartImpl(fml::TimePoint raster_start); + static std::atomic frame_number_gen_; mutable std::mutex state_mutex_; diff --git a/flow/frame_timings_recorder_unittests.cc b/flow/frame_timings_recorder_unittests.cc index ab1ef1ebc7eda..db3896cbbc043 100644 --- a/flow/frame_timings_recorder_unittests.cc +++ b/flow/frame_timings_recorder_unittests.cc @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include "flutter/flow/frame_timings.h" #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/flow/testing/mock_raster_cache.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -#include - #include "flutter/fml/time/time_delta.h" #include "flutter/fml/time/time_point.h" #include "gtest/gtest.h" namespace flutter { -namespace testing { + +using testing::MockRasterCache; TEST(FrameTimingsRecorderTest, RecordVsync) { auto recorder = std::make_unique(); @@ -130,9 +130,9 @@ TEST(FrameTimingsRecorderTest, ThrowWhenRecordBuildBeforeVsync) { auto recorder = std::make_unique(); const auto build_start = fml::TimePoint::Now(); - EXPECT_EXIT(recorder->RecordBuildStart(build_start), - ::testing::KilledBySignal(SIGABRT), - "Check failed: state_ == State::kVsync."); + fml::Status status = recorder->RecordBuildStartImpl(build_start); + EXPECT_FALSE(status.ok()); + EXPECT_EQ(status.message(), "Check failed: state_ == State::kVsync."); } TEST(FrameTimingsRecorderTest, ThrowWhenRecordRasterBeforeBuildEnd) { @@ -143,9 +143,9 @@ TEST(FrameTimingsRecorderTest, ThrowWhenRecordRasterBeforeBuildEnd) { recorder->RecordVsync(st, en); const auto raster_start = fml::TimePoint::Now(); - EXPECT_EXIT(recorder->RecordRasterStart(raster_start), - ::testing::KilledBySignal(SIGABRT), - "Check failed: state_ == State::kBuildEnd."); + fml::Status status = recorder->RecordRasterStartImpl(raster_start); + EXPECT_FALSE(status.ok()); + EXPECT_EQ(status.message(), "Check failed: state_ == State::kBuildEnd."); } #endif @@ -297,5 +297,4 @@ TEST(FrameTimingsRecorderTest, FrameNumberTraceArgIsValid) { ASSERT_EQ(actual_arg, expected_arg); } -} // namespace testing } // namespace flutter diff --git a/fml/macros.h b/fml/macros.h index 0158d0e18c73e..7de4ddf1f1f42 100644 --- a/fml/macros.h +++ b/fml/macros.h @@ -38,4 +38,7 @@ TypeName() = delete; \ FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) +#define FML_FRIEND_TEST(test_case_name, test_name) \ + friend class test_case_name##_##test_name##_Test + #endif // FLUTTER_FML_MACROS_H_