1 // Copyright 2013 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_TREES_SWAP_PROMISE_H_
6 #define CC_TREES_SWAP_PROMISE_H_
7 
8 #include <stdint.h>
9 
10 #include "cc/cc_export.h"
11 #include "components/viz/common/quads/compositor_frame_metadata.h"
12 
13 namespace cc {
14 
15 // When a change to the compositor's state/invalidation/whatever happens, a
16 // Swap Promise can be inserted into LayerTreeHost/LayerTreeImpl, to track
17 // whether the compositor's reply to the new state/invaliadtion/whatever is
18 // completed in the compositor, i.e. the compositor knows it has been sent
19 // to its output or not.
20 //
21 // If the commit results in a successful activation of the pending layer tree,
22 // SwapPromise::DidActivate() will be called.
23 //
24 // If the new compositor state is goint to be sent to the output,
25 // SwapPromise::WillSwap() will be called before the swap and
26 // SwapPromise::DidSwap() will be called once the swap is over.
27 //
28 // If the scheduler fails to activate the pending tree, or the compositor
29 // fails to send its new state to the output, SwapPromise::DidNotSwap() will
30 // be called. Note that it is possible to activate, and subsequently not swap.
31 //
32 // Promises complete afer either DidSwap() or DidNotSwap() is called, thus
33 // there are three possible call sequences:
34 //   DidNotSwap()
35 //   DidActivate() ; WillSwap(); DidSwap()
36 //   DidActivate() ; DidNotSwap()
37 //
38 // Clients that wish to use SwapPromise should have a subclass that defines
39 // the behavior of DidActivate(), WillSwap(), DidSwap() and DidNotSwap(). Notice
40 // that the promise can be broken at either main or impl thread, e.g. commit
41 // fails on main thread, new frame data has no actual damage so
42 // LayerTreeHostImpl::SwapBuffers() bails out early on impl thread, so don't
43 // assume that DidNotSwap() method is called at a particular thread. It is
44 // better to let the subclass carry thread-safe member data and operate on that
45 // member data in DidNotSwap().
46 class CC_EXPORT SwapPromise {
47  public:
48   enum DidNotSwapReason {
49     SWAP_FAILS,
50     COMMIT_FAILS,
51     COMMIT_NO_UPDATE,
52     ACTIVATION_FAILS,
53   };
54 
55   enum class DidNotSwapAction {
56     BREAK_PROMISE,
57     KEEP_ACTIVE,
58   };
59 
SwapPromise()60   SwapPromise() {}
~SwapPromise()61   virtual ~SwapPromise() {}
62 
63   virtual void DidActivate() = 0;
64   virtual void WillSwap(viz::CompositorFrameMetadata* metadata) = 0;
65   virtual void DidSwap() = 0;
66   // Return |KEEP_ACTIVE| if this promise should remain active (should not be
67   // broken by the owner).
68   virtual DidNotSwapAction DidNotSwap(DidNotSwapReason reason) = 0;
69   // This is called when the main thread starts a (blocking) commit
OnCommit()70   virtual void OnCommit() {}
71 
72   // A non-zero trace id identifies a trace flow object that is embedded in the
73   // swap promise. This can be used for registering additional flow steps to
74   // visualize the object's path through the system.
75   virtual int64_t TraceId() const = 0;
76 };
77 
78 }  // namespace cc
79 
80 #endif  // CC_TREES_SWAP_PROMISE_H_
81