Unique frame number for each frame (flutter/engine#26021)
This gets created during vsync and stays for the lifecycle of the frame.
This commit is contained in:
@@ -11,7 +11,10 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
FrameTimingsRecorder::FrameTimingsRecorder() = default;
|
||||
std::atomic_int FrameTimingsRecorder::frame_number_gen_ = {1};
|
||||
|
||||
FrameTimingsRecorder::FrameTimingsRecorder()
|
||||
: frame_number_(frame_number_gen_++) {}
|
||||
|
||||
FrameTimingsRecorder::~FrameTimingsRecorder() = default;
|
||||
|
||||
@@ -132,4 +135,8 @@ std::unique_ptr<FrameTimingsRecorder> FrameTimingsRecorder::CloneUntil(
|
||||
return recorder;
|
||||
}
|
||||
|
||||
uint64_t FrameTimingsRecorder::GetFrameNumber() const {
|
||||
return frame_number_;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -79,10 +79,19 @@ class FrameTimingsRecorder {
|
||||
/// the events. This summary is sent to the framework.
|
||||
FrameTiming RecordRasterEnd(fml::TimePoint raster_end);
|
||||
|
||||
/// Returns the frame number. Frame number is unique per frame and a frame
|
||||
/// built earlier will have a frame number less than a frame that has been
|
||||
/// built at a later point of time.
|
||||
uint64_t GetFrameNumber() const;
|
||||
|
||||
private:
|
||||
static std::atomic_int frame_number_gen_;
|
||||
|
||||
mutable std::mutex state_mutex_;
|
||||
State state_ = State::kUninitialized;
|
||||
|
||||
const uint64_t frame_number_;
|
||||
|
||||
fml::TimePoint vsync_start_;
|
||||
fml::TimePoint vsync_target_;
|
||||
fml::TimePoint build_start_;
|
||||
|
||||
@@ -87,5 +87,22 @@ TEST(FrameTimingsRecorderTest, ThrowWhenRecordRasterBeforeBuildEnd) {
|
||||
|
||||
#endif
|
||||
|
||||
TEST(FrameTimingsRecorderTest, RecordersHaveUniqueFrameNumbers) {
|
||||
auto recorder1 = std::make_unique<FrameTimingsRecorder>();
|
||||
auto recorder2 = std::make_unique<FrameTimingsRecorder>();
|
||||
|
||||
ASSERT_TRUE(recorder2->GetFrameNumber() > recorder1->GetFrameNumber());
|
||||
}
|
||||
|
||||
TEST(FrameTimingsRecorderTest, ClonedHasUniqueFrameNumber) {
|
||||
auto recorder = std::make_unique<FrameTimingsRecorder>();
|
||||
|
||||
const auto now = fml::TimePoint::Now();
|
||||
recorder->RecordVsync(now, now);
|
||||
|
||||
auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kVsync);
|
||||
ASSERT_NE(recorder->GetFrameNumber(), cloned->GetFrameNumber());
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
@@ -41,7 +41,6 @@ Animator::Animator(Delegate& delegate,
|
||||
: 2)),
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
pending_frame_semaphore_(1),
|
||||
frame_number_(1),
|
||||
paused_(false),
|
||||
regenerate_layer_tree_(false),
|
||||
frame_scheduled_(false),
|
||||
@@ -86,7 +85,11 @@ void Animator::EnqueueTraceFlowId(uint64_t trace_flow_id) {
|
||||
// This Parity is used by the timeline component to correctly align
|
||||
// GPU Workloads events with their respective Framework Workload.
|
||||
const char* Animator::FrameParity() {
|
||||
return (frame_number_ % 2) ? "even" : "odd";
|
||||
if (!frame_timings_recorder_) {
|
||||
return "even";
|
||||
}
|
||||
uint64_t frame_number = frame_timings_recorder_->GetFrameNumber();
|
||||
return (frame_number % 2) ? "even" : "odd";
|
||||
}
|
||||
|
||||
static int64_t FxlToDartOrEarlier(fml::TimePoint time) {
|
||||
@@ -97,7 +100,8 @@ static int64_t FxlToDartOrEarlier(fml::TimePoint time) {
|
||||
|
||||
void Animator::BeginFrame(
|
||||
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
|
||||
TRACE_EVENT_ASYNC_END0("flutter", "Frame Request Pending", frame_number_++);
|
||||
TRACE_EVENT_ASYNC_END0("flutter", "Frame Request Pending",
|
||||
frame_timings_recorder->GetFrameNumber());
|
||||
|
||||
frame_timings_recorder_ = std::move(frame_timings_recorder);
|
||||
frame_timings_recorder_->RecordBuildStart(fml::TimePoint::Now());
|
||||
@@ -239,8 +243,13 @@ void Animator::RequestFrame(bool regenerate_layer_tree) {
|
||||
// started an expensive operation right after posting this message however.
|
||||
// To support that, we need edge triggered wakes on VSync.
|
||||
|
||||
uint64_t frame_number = 0;
|
||||
if (frame_timings_recorder_) {
|
||||
frame_number = frame_timings_recorder_->GetFrameNumber();
|
||||
}
|
||||
|
||||
task_runners_.GetUITaskRunner()->PostTask([self = weak_factory_.GetWeakPtr(),
|
||||
frame_number = frame_number_]() {
|
||||
frame_number = frame_number]() {
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ class Animator final {
|
||||
fml::RefPtr<LayerTreePipeline> layer_tree_pipeline_;
|
||||
fml::Semaphore pending_frame_semaphore_;
|
||||
LayerTreePipeline::ProducerContinuation producer_continuation_;
|
||||
int64_t frame_number_;
|
||||
bool paused_;
|
||||
bool regenerate_layer_tree_;
|
||||
bool frame_scheduled_;
|
||||
|
||||
Reference in New Issue
Block a user