[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / frame_sorter.h
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CC_METRICS_FRAME_SORTER_H_
6 #define CC_METRICS_FRAME_SORTER_H_
7
8 #include <stddef.h>
9
10 #include <map>
11
12 #include "base/callback.h"
13 #include "base/containers/circular_deque.h"
14 #include "cc/cc_export.h"
15 #include "components/viz/common/frame_sinks/begin_frame_args.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17
18 namespace cc {
19
20 struct FrameInfo;
21
22 // This class is used to process the frames in order of initiation.
23 // So regardless of which order frames are terminated, the  callback function
24 // will frames sorter will br called on the frames in the order of initiation
25 // (e.g. frame_time of that frame).
26 class CC_EXPORT FrameSorter {
27  public:
28   class FrameState {
29    public:
30     void OnBegin();
31     void OnAck(bool frame_is_dropped);
32     void OnReset();
33     bool IsComplete() const;  // Checks if all acks are received.
34     bool is_dropped() const { return is_dropped_; }
35     bool should_ignore() const { return should_ignore_; }
36
37    private:
38     uint16_t on_begin_counter = 0;  // Counts the number of AddNewFrame calls.
39     uint16_t ack_counter = 0;       // Counts the number of acks received.
40     bool is_dropped_ = false;       // Flags if any of the acks were dropped.
41     bool should_ignore_ = false;    // Flags if there was a reset prior to acks.
42   };
43
44   using InOrderBeginFramesCallback =
45       base::RepeatingCallback<void(const viz::BeginFrameArgs&,
46                                    const FrameInfo&)>;
47   explicit FrameSorter(InOrderBeginFramesCallback callback);
48   ~FrameSorter();
49
50   FrameSorter(const FrameSorter&) = delete;
51   FrameSorter& operator=(const FrameSorter&) = delete;
52
53   // The frames must be added in the correct order.
54   void AddNewFrame(const viz::BeginFrameArgs& args);
55
56   // The results can be added in any order. However, the frame must have been
57   // added by an earlier call to |AddNewFrame()|.
58   void AddFrameResult(const viz::BeginFrameArgs& args,
59                       const FrameInfo& frame_info);
60
61   // Check if a frame has been previously reported as dropped.
62   bool IsAlreadyReportedDropped(const viz::BeginFrameId& id) const;
63
64   void Reset();
65
66  private:
67   void FlushFrames();
68
69   const uint64_t kPendingFramesMaxSize = 300u;
70
71   // The callback to run for each flushed frame.
72   const InOrderBeginFramesCallback flush_callback_;
73
74   // Frames which are started.
75   base::circular_deque<viz::BeginFrameArgs> pending_frames_;
76
77   // State of each frame in terms of ack expectation.
78   std::map<viz::BeginFrameId, FrameState> frame_states_;
79   std::map<viz::BeginFrameId, FrameInfo> frame_infos_;
80
81   absl::optional<uint64_t> current_source_id_;
82 };
83
84 }  // namespace cc
85
86 #endif  // CC_METRICS_FRAME_SORTER_H_