910e62b5创建于 1月15日历史提交
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_METRICS_FRAME_INFO_H_
#define CC_METRICS_FRAME_INFO_H_

#include "base/time/time.h"
#include "cc/cc_export.h"

namespace cc {

struct CC_EXPORT FrameInfo {
  FrameInfo();
  FrameInfo(const FrameInfo& other);
  ~FrameInfo();

  enum class FrameFinalState {
    kNoUpdateDesired,
    kDropped,

    // A `presented all` frame contains all the desired update for this vsync.
    // Note that this doesn't necessarily mean the frame included updates from
    // both the main and the compositor thread. For example, if there's only a
    // main-thread animation running, and the animation update was included in
    // the frame produced, then it's `presented all`, although the compositor
    // thread did not have any updates for this frame.
    kPresentedAll,

    // A `partial update` frame contains updates from a compositor frame, but
    // misses the update from the main-thread for the same vsync. However, it is
    // still possible for such a `partial update` frame to contain new update
    // from an earlier main-thread.
    //
    // `kPresentedPartialOldMain` represents a partial update frame without any
    //     new update from the main-thread.
    // `kPresentedPartialNewMain` represents a partial update frame with some
    //     new update from the main-thread.
    kPresentedPartialOldMain,
    kPresentedPartialNewMain,
    kPresentedPartialWithoutWaiting,
  };
  FrameFinalState final_state = FrameFinalState::kNoUpdateDesired;
  FrameFinalState final_state_v4 = FrameFinalState::kNoUpdateDesired;
  FrameFinalState final_state_raster_property =
      FrameFinalState::kNoUpdateDesired;
  FrameFinalState final_state_raster_scroll = FrameFinalState::kNoUpdateDesired;

  enum class SmoothThread {
    kSmoothNone,
    kSmoothRaster,
    kSmoothCompositor,
    kSmoothMain,
    kSmoothBoth
  };
  SmoothThread smooth_thread = SmoothThread::kSmoothNone;
  SmoothThread smooth_thread_raster_property = SmoothThread::kSmoothNone;

  enum class MainThreadResponse {
    kIncluded,
    kMissing,
  };
  MainThreadResponse main_thread_response = MainThreadResponse::kIncluded;

  enum class SmoothEffectDrivingThread {
    kMain = 0,
    kCompositor = 1,
    kRaster = 2,
    kUnknown = 3,
    kMaxValue = kUnknown,
  };
  SmoothEffectDrivingThread scroll_thread = SmoothEffectDrivingThread::kUnknown;

  bool checkerboarded_needs_raster = false;
  bool checkerboarded_needs_record = false;
  bool did_raster_inducing_scroll = false;

  // The time when the frame was terminated. If the frame had to be 'split'
  // (i.e. compositor-thread update and main-thread updates were presented in
  // separate frames,) then this contains the maximum time when the updates were
  // terminated. See GetTerminationTimeForThread to get the value for each.
  base::TimeTicks termination_time;

  // The frame number associated to the viz::BeginFrameArgs that started this
  // frame's production.
  uint64_t sequence_number = 0u;

  bool IsDroppedAffectingSmoothness() const;
  void MergeWith(const FrameInfo& info);

  bool Validate() const;

  // Returns whether any update from the compositor/main thread was dropped, and
  // whether the update was part of a smooth sequence.
  bool WasSmoothCompositorUpdateDropped() const;
  bool WasSmoothRasterPropertyUpdateDropped() const;
  bool WasSmoothRasterScrollUpdateDropped() const;
  bool WasSmoothMainUpdateDropped() const;
  bool WasSmoothMainUpdateDroppedV4() const;
  bool WasSmoothMainUpdateExpected() const;

  bool IsScrollPrioritizeFrameDropped() const;

  // If this `was_merged` these return the value for `thread`, otherwise returns
  // the default non-merged values.
  FrameFinalState GetFinalStateForThread(
      SmoothEffectDrivingThread thread) const;
  base::TimeTicks GetTerminationTimeForThread(
      SmoothEffectDrivingThread thread) const;

 private:
  bool was_merged = false;
  bool compositor_update_was_dropped = false;
  bool raster_property_was_dropped = false;
  bool raster_scroll_was_dropped = false;
  bool main_update_was_dropped = false;
  bool main_update_was_dropped_v4 = false;

  // A frame that `was_merged` could have differing final states, and differing
  // termination times. We track both so that each thread's jank can be
  // calculated.
  FrameFinalState compositor_final_state = FrameFinalState::kNoUpdateDesired;
  FrameFinalState main_final_state = FrameFinalState::kNoUpdateDesired;

  base::TimeTicks compositor_termination_time;
  base::TimeTicks main_termination_time;
};

}  // namespace cc

#endif  // CC_METRICS_FRAME_INFO_H_