blob: 0dded01b359f5ddeafd2973bf21d709439ce0655 [file] [log] [blame]
// Copyright 2020 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_SEQUENCE_TRACKER_COLLECTION_H_
#define CC_METRICS_FRAME_SEQUENCE_TRACKER_COLLECTION_H_
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "cc/cc_export.h"
#include "cc/metrics/frame_info.h"
#include "cc/metrics/frame_sequence_metrics.h"
#include "cc/metrics/frame_sorter.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
namespace viz {
struct BeginFrameArgs;
} // namespace viz
namespace cc {
class FrameSequenceTracker;
// Map of kCustom tracker results keyed by a sequence id.
using CustomTrackerResults =
base::flat_map<int, FrameSequenceMetrics::CustomReportData>;
typedef uint16_t ActiveFrameSequenceTrackers;
// Used for notifying attached FrameSequenceTracker's of begin-frames and
// submitted frames.
class CC_EXPORT FrameSequenceTrackerCollection : public FrameSorterObserver {
public:
explicit FrameSequenceTrackerCollection(bool is_single_threaded);
~FrameSequenceTrackerCollection() override;
FrameSequenceTrackerCollection(const FrameSequenceTrackerCollection&) =
delete;
FrameSequenceTrackerCollection& operator=(
const FrameSequenceTrackerCollection&) = delete;
// Creates a new tracker for the specified sequence-type if one doesn't
// already exist. Returns the associated FrameSequenceTracker instance.
FrameSequenceTracker* StartSequence(FrameSequenceTrackerType type);
FrameSequenceTracker* StartScrollSequence(
FrameSequenceTrackerType type,
FrameInfo::SmoothEffectDrivingThread scrolling_thread);
// Schedules |tracker| for destruction. This is preferred instead of outright
// desrtruction of the tracker, since this ensures that the actual tracker
// instance is destroyed *after* the presentation-feedbacks have been received
// for all submitted frames.
void StopSequence(FrameSequenceTrackerType type);
// Creates a kCustom tracker for the given sequence id. It is an error and
// DCHECKs if there is already a tracker associated with the sequence id.
void StartCustomSequence(int sequence_id);
// Schedules the kCustom tracker representing |sequence_id| for destruction.
// It is a no-op if there is no tracker associated with the sequence id.
// Similar to StopSequence above, the tracker instance is destroyed *after*
// the presentation feedbacks have been received for all submitted frames.
void StopCustomSequence(int sequence_id);
// Removes all trackers. This also immediately destroys all trackers that had
// been scheduled for destruction, even if there are pending
// presentation-feedbacks. This is typically used if the client no longer
// expects to receive presentation-feedbacks for the previously submitted
// frames (e.g. when the gpu process dies).
void ClearAll();
// Notifies all trackers of various events.
void NotifyBeginImplFrame(const viz::BeginFrameArgs& args);
void NotifyPauseFrameProduction();
void NotifyFrameEnd(const viz::BeginFrameArgs& args,
const viz::BeginFrameArgs& main_args);
// Return the type of each active frame tracker, encoded into a 16 bit
// integer with the bit at each position corresponding to the enum value of
// each type.
ActiveFrameSequenceTrackers FrameSequenceTrackerActiveTypes() const;
FrameSequenceTracker* GetRemovalTrackerForTesting(
FrameSequenceTrackerType type);
using NotifyCustomerTrackerResutlsCallback =
base::RepeatingCallback<void(const CustomTrackerResults&)>;
void set_custom_tracker_results_added_callback(
NotifyCustomerTrackerResutlsCallback callback) {
custom_tracker_results_added_callback_ = std::move(callback);
}
void AddSortedFrame(const viz::BeginFrameArgs& args,
const FrameInfo& frame_info) override;
// Registers the shared memory location for PDF4 UKMs.
void SetUkmDroppedFramesDestination(
UkmDroppedFramesDataShared* dropped_frames_data);
ActiveTrackers GetActiveTrackers() const;
FrameInfo::SmoothThread GetSmoothThreadAtTime(
base::TimeTicks timestamp) const;
FrameInfo::SmoothEffectDrivingThread GetScrollThreadAtTime(
base::TimeTicks timestamp) const;
FrameInfo::SmoothEffectDrivingThread GetScrollingThread() const;
FrameInfo::SmoothThread GetSmoothThread() const;
void UpdateSmoothThreadHistory(
FrameInfo::SmoothEffectDrivingThread thread_type,
int modifier);
private:
friend class CompositorFrameReportingControllerTest;
friend class FrameSequenceTrackerTest;
FrameSequenceTracker* StartSequenceInternal(
FrameSequenceTrackerType type,
FrameInfo::SmoothEffectDrivingThread scrolling_thread);
void SetScrollingThread(FrameInfo::SmoothEffectDrivingThread thread);
void RecreateTrackers(const viz::BeginFrameArgs& args);
// Destroy the trackers that are ready to be terminated.
void DestroyTrackers();
// Ask all trackers to report their metrics if there is any, must be the first
// thing in the destructor.
void CleanUp();
// Adds collected metrics data for |custom_sequence_id| to be picked up via
// TakeCustomTrackerResults() below.
void AddCustomTrackerResult(
int custom_sequence_id,
const FrameSequenceMetrics::CustomReportData& data);
const bool is_single_threaded_;
// The callsite can use the type to manipulate the tracker.
base::flat_map<
std::pair<FrameSequenceTrackerType, FrameInfo::SmoothEffectDrivingThread>,
std::unique_ptr<FrameSequenceTracker>>
frame_trackers_;
// Custom trackers are keyed by a custom sequence id.
base::flat_map<int, std::unique_ptr<FrameSequenceTracker>>
custom_frame_trackers_;
// Called when throughput metrics are available for custom trackers added by
// |AddCustomTrackerResult()|.
NotifyCustomerTrackerResutlsCallback custom_tracker_results_added_callback_;
std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_;
ActiveTrackers active_trackers_;
FrameInfo::SmoothEffectDrivingThread scrolling_thread_ =
FrameInfo::SmoothEffectDrivingThread::kUnknown;
base::flat_map<
std::pair<FrameSequenceTrackerType, FrameInfo::SmoothEffectDrivingThread>,
std::unique_ptr<FrameSequenceMetrics>>
accumulated_metrics_;
// Tracks how many smoothness effects are driven by each thread.
size_t main_thread_driving_smoothness_ = 0;
size_t compositor_thread_driving_smoothness_ = 0;
size_t raster_thread_driving_smoothness_ = 0;
// Sorted history of smooththread. Element i indicating the smooththread
// from timestamp of element i-1 until timestamp of element i.
std::map<base::TimeTicks, FrameInfo::SmoothThread> smooth_thread_history_;
// Sorted history of scrollthread. Element i indicating the smooththread
// from timestamp of element i-1 until timestamp of element i.
std::map<base::TimeTicks, FrameInfo::SmoothEffectDrivingThread>
scroll_thread_history_;
// Pointer to shared memory map for PDF4 UKMs
raw_ptr<UkmDroppedFramesDataShared> ukm_dropped_frames_data_ = nullptr;
};
} // namespace cc
#endif // CC_METRICS_FRAME_SEQUENCE_TRACKER_COLLECTION_H_