summaryrefslogtreecommitdiffstats
path: root/cc/trees/remote_channel_impl.h
blob: acd44aa43bba6c587eaa368f409df13206c2078f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TREES_REMOTE_CHANNEL_IMPL_H_
#define CC_TREES_REMOTE_CHANNEL_IMPL_H_

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/base/completion_event.h"
#include "cc/proto/compositor_message_to_impl.pb.h"
#include "cc/trees/channel_impl.h"
#include "cc/trees/proxy.h"
#include "cc/trees/proxy_impl.h"
#include "cc/trees/remote_proto_channel.h"

namespace cc {
class LayerTreeHost;

namespace proto {
class CompositorMessage;
class CompositorMessageToImpl;
class CompositorMessageToMain;
}

// The Proxy and ChannelImpl implementation for the remote compositor.
// The object life cycle and communication across threads is as follows:
//
// The RemoteChannelImpl is created by the remote client LayerTreeHost, which
// initializes the impl side of the compositor.
//
//           Main Thread              |               Impl Thread
//                                    |
//         Proxy::Start               |
//               |                    |
//               |              RemoteChannelImpl
// ---------------------------------------------------------------------------
// RemoteChannelImpl::Start()---PostTask---> RemoteChannelImpl::
//                                                    InitializeImplOnImpl
//                                                          |
//                                                   ProxyImpl::Create
//                                                          |
//                                                          .
//                                                          .
//                                          ProxyImpl::ScheduledActionBegin
//                                                     OutputSurfaceCreation
//                                                          |
//                                         ChannelImpl::RequestNewOutputSurface
//                                                          |
// RemoteChannelImpl::                                      |
//      RequestNewOutputSurface()<----PostTask--------------
//              .
//              .
//              |
// RemoteChannelImpl::
//          ~RemoteChannelImpl() ---PostTask---> RemoteChannelImpl::
//                                                      ShutdownImplOnImpl
// ----------------------------------------------------------------------------
//
// The class is created and destroyed on the main thread but can be safely
// called from the main or impl thread. It is safe to call RemoteChannelImpl on
// the impl thread since:
// 1) The only impl threaded callers of RemoteChannelImpl is the
// RemoteChannelImpl itself and ProxyImpl which is created and owned by the
// RemoteChannelImpl.
// 2) The RemoteChannelImpl blocks the main thread in its dtor to wait for the
// impl-thread teardown to complete, which ensures that any tasks queued to call
// it on the impl thread are run before it is destroyed on the main thread.
//
// The RemoteChannelImpl receives and processes messages from the remote server
// compositor on the main thread. The requests from ProxyImpl are received on
// the impl thread which may be directed to the LayerTreeHost on the client
// (for instance output surface requests) or sent to the LayerTreeHost on the
// server. The messages to the server are created on the impl thread and sent
// using the RemoteProtoChannel on the main thread.
class CC_EXPORT RemoteChannelImpl : public ChannelImpl,
                                    public RemoteProtoChannel::ProtoReceiver,
                                    public Proxy {
 public:
  static scoped_ptr<RemoteChannelImpl> Create(
      LayerTreeHost* layer_tree_host,
      RemoteProtoChannel* remote_proto_channel,
      TaskRunnerProvider* task_runner_provider);

  ~RemoteChannelImpl() override;

 protected:
  RemoteChannelImpl(LayerTreeHost* layer_tree_host,
                    RemoteProtoChannel* remote_proto_channel,
                    TaskRunnerProvider* task_runner_provider);

  // virtual for testing.
  virtual scoped_ptr<ProxyImpl> CreateProxyImpl(
      ChannelImpl* channel_impl,
      LayerTreeHost* layer_tree_host,
      TaskRunnerProvider* task_runner_provider,
      scoped_ptr<BeginFrameSource> external_begin_frame_source);

 private:
  struct MainThreadOnly {
    LayerTreeHost* layer_tree_host;
    RemoteProtoChannel* remote_proto_channel;

    bool started;

    // This is set to true if we lost the output surface and can not push any
    // commits to the impl thread.
    bool waiting_for_output_surface_initialization;

    // The queue of messages received from the server. The messages are added to
    // this queue if we are waiting for a new output surface to be initialized.
    std::queue<proto::CompositorMessageToImpl> pending_messages;

    RendererCapabilities renderer_capabilities;

    base::WeakPtrFactory<RemoteChannelImpl> remote_channel_weak_factory;

    MainThreadOnly(RemoteChannelImpl*,
                   LayerTreeHost* layer_tree_host,
                   RemoteProtoChannel* remote_proto_channel);
    ~MainThreadOnly();
  };

  struct CompositorThreadOnly {
    scoped_ptr<ProxyImpl> proxy_impl;
    scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory;
    base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr;

    CompositorThreadOnly(
        base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr);
    ~CompositorThreadOnly();
  };

  // called on main thread.
  // RemoteProtoChannel::ProtoReceiver implementation.
  void OnProtoReceived(scoped_ptr<proto::CompositorMessage> proto) override;

  // Proxy implementation
  void FinishAllRendering() override;
  bool IsStarted() const override;
  bool CommitToActiveTree() const override;
  void SetOutputSurface(OutputSurface* output_surface) override;
  void ReleaseOutputSurface() override;
  void SetVisible(bool visible) override;
  const RendererCapabilities& GetRendererCapabilities() const override;
  void SetNeedsAnimate() override;
  void SetNeedsUpdateLayers() override;
  void SetNeedsCommit() override;
  void SetNeedsRedraw(const gfx::Rect& damage_rect) override;
  void SetNextCommitWaitsForActivation() override;
  void NotifyInputThrottledUntilCommit() override;
  void SetDeferCommits(bool defer_commits) override;
  void MainThreadHasStoppedFlinging() override;
  bool CommitRequested() const override;
  bool BeginMainFrameRequested() const override;
  void Start(scoped_ptr<BeginFrameSource> external_begin_frame_source) override;
  void Stop() override;
  bool SupportsImplScrolling() const override;
  void SetChildrenNeedBeginFrames(bool children_need_begin_frames) override;
  void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) override;
  void UpdateTopControlsState(TopControlsState constraints,
                              TopControlsState current,
                              bool animate) override;
  void SetOutputIsSecure(bool output_is_secure) override;
  bool MainFrameWillHappenForTesting() override;

  // Called on impl thread.
  // ChannelImpl implementation
  void DidCompleteSwapBuffers() override;
  void SetRendererCapabilitiesMainCopy(
      const RendererCapabilities& capabilities) override;
  void BeginMainFrameNotExpectedSoon() override;
  void DidCommitAndDrawFrame() override;
  void SetAnimationEvents(scoped_ptr<AnimationEvents> queue) override;
  void DidLoseOutputSurface() override;
  void RequestNewOutputSurface() override;
  void DidInitializeOutputSurface(
      bool success,
      const RendererCapabilities& capabilities) override;
  void DidCompletePageScaleAnimation() override;
  void PostFrameTimingEventsOnMain(
      scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
      scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
      override;
  void BeginMainFrame(
      scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) override;

  void SendMessageProto(scoped_ptr<proto::CompositorMessage> proto);

  // called on main thread.
  void HandleProto(const proto::CompositorMessageToImpl& proto);
  void DidLoseOutputSurfaceOnMain();
  void RequestNewOutputSurfaceOnMain();
  void DidInitializeOutputSurfaceOnMain(
      bool success,
      const RendererCapabilities& capabilities);
  void SendMessageProtoOnMain(scoped_ptr<proto::CompositorMessage> proto);
  void PostSetNeedsRedrawToImpl(const gfx::Rect& damaged_rect);

  void InitializeImplOnImpl(CompletionEvent* completion,
                            LayerTreeHost* layer_tree_host);
  void ShutdownImplOnImpl(CompletionEvent* completion);

  MainThreadOnly& main();
  const MainThreadOnly& main() const;
  CompositorThreadOnly& impl();
  const CompositorThreadOnly& impl() const;

  base::SingleThreadTaskRunner* MainThreadTaskRunner() const;
  base::SingleThreadTaskRunner* ImplThreadTaskRunner() const;

  TaskRunnerProvider* task_runner_provider_;

  // use accessors instead of these variables directly
  MainThreadOnly main_thread_vars_unsafe_;
  CompositorThreadOnly compositor_thread_vars_unsafe_;

  base::WeakPtr<ProxyImpl> proxy_impl_weak_ptr_;

  DISALLOW_COPY_AND_ASSIGN(RemoteChannelImpl);
};

}  // namespace cc

#endif  // CC_TREES_REMOTE_CHANNEL_IMPL_H_