1// Copyright 2011 The Chromium Authors. All rights reserved.
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_SCHEDULER_FRAME_RATE_CONTROLLER_H_
6#define CC_SCHEDULER_FRAME_RATE_CONTROLLER_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/memory/weak_ptr.h"
11#include "base/time/time.h"
12#include "cc/base/cc_export.h"
13#include "cc/output/begin_frame_args.h"
14
15namespace base { class SingleThreadTaskRunner; }
16
17namespace cc {
18
19class TimeSource;
20class FrameRateController;
21
22class CC_EXPORT FrameRateControllerClient {
23 protected:
24  virtual ~FrameRateControllerClient() {}
25
26 public:
27  // Throttled is true when we have a maximum number of frames pending.
28  virtual void FrameRateControllerTick(bool throttled,
29                                       const BeginFrameArgs& args) = 0;
30};
31
32class FrameRateControllerTimeSourceAdapter;
33
34// The FrameRateController is used in cases where we self-tick (i.e. BeginFrame
35// is not sent by a parent compositor.
36class CC_EXPORT FrameRateController {
37 public:
38  explicit FrameRateController(scoped_refptr<TimeSource> timer);
39  // Alternate form of FrameRateController with unthrottled frame-rate.
40  explicit FrameRateController(base::SingleThreadTaskRunner* task_runner);
41  virtual ~FrameRateController();
42
43  void SetClient(FrameRateControllerClient* client) { client_ = client; }
44
45  // Returns a valid BeginFrame on activation to potentially be used
46  // retroactively.
47  BeginFrameArgs SetActive(bool active);
48
49  bool IsActive() { return active_; }
50
51  // Use the following methods to adjust target frame rate.
52  //
53  // Multiple frames can be in-progress, but for every DidSwapBuffers, a
54  // DidFinishFrame should be posted.
55  //
56  // If the rendering pipeline crashes, call DidAbortAllPendingFrames.
57  void DidSwapBuffers();
58  void DidSwapBuffersComplete();
59  void DidAbortAllPendingFrames();
60  void SetMaxSwapsPending(int max_swaps_pending);  // 0 for unlimited.
61  int MaxSwapsPending() const { return max_swaps_pending_; }
62  int NumSwapsPendingForTesting() const { return num_frames_pending_; }
63
64  void SetTimebaseAndInterval(base::TimeTicks timebase,
65                              base::TimeDelta interval);
66  void SetDeadlineAdjustment(base::TimeDelta delta);
67
68 protected:
69  friend class FrameRateControllerTimeSourceAdapter;
70  void OnTimerTick();
71
72  void PostManualTick();
73  void ManualTick();
74
75    // This returns null for unthrottled frame-rate.
76  base::TimeTicks NextTickTime();
77  // This returns now for unthrottled frame-rate.
78  base::TimeTicks LastTickTime();
79
80  FrameRateControllerClient* client_;
81  int num_frames_pending_;
82  int max_swaps_pending_;
83  base::TimeDelta interval_;
84  base::TimeDelta deadline_adjustment_;
85  scoped_refptr<TimeSource> time_source_;
86  scoped_ptr<FrameRateControllerTimeSourceAdapter> time_source_client_adapter_;
87  bool active_;
88
89  // Members for unthrottled frame-rate.
90  bool is_time_source_throttling_;
91  bool manual_tick_pending_;
92  base::SingleThreadTaskRunner* task_runner_;
93  base::WeakPtrFactory<FrameRateController> weak_factory_;
94
95 private:
96  DISALLOW_COPY_AND_ASSIGN(FrameRateController);
97};
98
99}  // namespace cc
100
101#endif  // CC_SCHEDULER_FRAME_RATE_CONTROLLER_H_
102