summaryrefslogtreecommitdiffstats
path: root/cc/trees/threaded_channel.h
blob: ab20e525cf0ad40c0f934dffb9ed1c24d7cb6a4e (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
// Copyright 2015 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_THREADED_CHANNEL_H_
#define CC_TREES_THREADED_CHANNEL_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/trees/channel_impl.h"
#include "cc/trees/channel_main.h"
#include "cc/trees/proxy_common.h"
#include "cc/trees/proxy_impl.h"
#include "cc/trees/proxy_main.h"

namespace base {
class SingleThreadTaskRunner;
}

namespace cc {
class ChannelImpl;
class ChannelMain;
class LayerTreeHost;
class ProxyImpl;
class ProxyMain;

// An implementation of ChannelMain and ChannelImpl that sends commands between
// ProxyMain and ProxyImpl across thread boundaries.
//
// LayerTreeHost creates ThreadedChannel and passes the ownership to ProxyMain.
// The object life cycle and communication across threads is as follows:
//
//
//           Main Thread              |               Impl Thread
//   LayerTreeHost->InitializeProxy   |
//               |                    |
//        ProxyMain->Start()          |
//               |              ThreadedChannel
// ---------------------------------------------------------------------------
//  ChannelMain::SynchronouslyInitializeImpl ---PostTask---> ThreadedChannel::
//                                                    InitializeImplOnImpl
//                                                          |
//                                                   ProxyImpl::Create
//                                                          |
//                                                   ProxyImpl->Initialize()
//                                                          .
//                                                          .
//                                          ProxyImpl::ScheduledActionBegin
//                                                     OutputSurfaceCreation
//                                                          |
//                                         ChannelImpl::RequestNewOutputSurface
// ----------------------------------------------------------------------------
//                                                          |
// ProxyMain->RequestNewOutputSurface()<----PostTask--------
//              .
//              .
// ProxyMain->Stop()
//              |
// ---------------------------------------------------------------------------
// ChannelMain::SynchronouslyCloseImpl ---PostTask---> ThreadedChannel::
//                                                      CloseImplOnImpl
// ----------------------------------------------------------------------------
//
// ThreadedChannel is created and destroyed on the main thread but can be
// called from main or impl thread. It is safe for the Threadedchannel to be
// called on the impl thread because:
// 1) The only impl-threaded callers of ThreadedChannel are the ThreadedChannel
// itself and ProxyImpl which is created and owned by the ThreadedChannel.
// 2) ThreadedChannel blocks the main thread in
// ThreadedChannel::SynchronouslyCloseImpl to wait for the impl-thread teardown
// to complete, so there is no risk of any queued tasks calling it on the impl
// thread after it has been deleted on the main thread.

class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl {
 public:
  static scoped_ptr<ThreadedChannel> Create(
      ProxyMain* proxy_main,
      TaskRunnerProvider* task_runner_provider);

  ~ThreadedChannel() override;

  // ChannelMain Implementation
  void SetThrottleFrameProductionOnImpl(bool throttle) override;
  void UpdateTopControlsStateOnImpl(TopControlsState constraints,
                                    TopControlsState current,
                                    bool animate) override;
  void InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) override;
  void MainThreadHasStoppedFlingingOnImpl() override;
  void SetInputThrottledUntilCommitOnImpl(bool is_throttled) override;
  void SetDeferCommitsOnImpl(bool defer_commits) override;
  void SetNeedsCommitOnImpl() override;
  void BeginMainFrameAbortedOnImpl(
      CommitEarlyOutReason reason,
      base::TimeTicks main_thread_start_time) override;
  void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) override;
  void SetVisibleOnImpl(bool visible) override;

  // Blocking calls to ProxyImpl
  void FinishAllRenderingOnImpl(CompletionEvent* completion) override;
  void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override;
  void MainFrameWillHappenOnImplForTesting(
      CompletionEvent* completion,
      bool* main_frame_will_happen) override;
  void StartCommitOnImpl(CompletionEvent* completion,
                         LayerTreeHost* layer_tree_host,
                         base::TimeTicks main_thread_start_time,
                         bool hold_commit_for_activation) override;
  void SynchronouslyInitializeImpl(
      LayerTreeHost* layer_tree_host,
      scoped_ptr<BeginFrameSource> external_begin_frame_source) override;
  void SynchronouslyCloseImpl() override;

  // ChannelImpl Implementation
  void DidCompleteSwapBuffers() override;
  void SetRendererCapabilitiesMainCopy(
      const RendererCapabilities& capabilities) override;
  void BeginMainFrameNotExpectedSoon() override;
  void DidCommitAndDrawFrame() override;
  void SetAnimationEvents(scoped_ptr<AnimationEvents> events) 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;

 protected:
  ThreadedChannel(ProxyMain* proxy_main,
                  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:
  // The members of this struct should be accessed on the main thread only.
  struct MainThreadOnly {
    explicit MainThreadOnly(ProxyMain* proxy_main);
    ~MainThreadOnly();

    base::WeakPtrFactory<ProxyMain> proxy_main_weak_factory;
    bool initialized;
  };

  // The members of this struct should be accessed on the impl thread only.
  struct CompositorThreadOnly {
    explicit CompositorThreadOnly(base::WeakPtr<ProxyMain> proxy_main_weak_ptr);
    ~CompositorThreadOnly();

    scoped_ptr<ProxyImpl> proxy_impl;

    // We use a scoped_ptr for the weak ptr factory here since the factory is
    // created after ProxyImpl is created in InitializeImplOnImpl. Since the
    // weak ptrs are needed only by the ThreadedChannel to safely post tasks on
    // ProxyImpl to be run on the impl thread, we avoid creating it in ProxyImpl
    // and ensure that it is destroyed before ProxyImpl during the impl-thread
    // tear down in CloseImplOnImpl.
    scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory;

    // Used on the impl thread to queue calls to ProxyMain to be run on the main
    // thread. Since the weak pointer is invalidated after the impl-thread tear
    // down in SynchronouslyCloseImpl, this ensures that any tasks posted to
    // ProxyMain from the impl thread are abandoned after the impl side has been
    // destroyed.
    base::WeakPtr<ProxyMain> proxy_main_weak_ptr;
  };

  // Called on impl thread.
  void InitializeImplOnImpl(
      CompletionEvent* completion,
      LayerTreeHost* layer_tree_host,
      scoped_ptr<BeginFrameSource> external_begin_frame_source);
  void CloseImplOnImpl(CompletionEvent* completion);

  bool IsInitialized() const;

  base::SingleThreadTaskRunner* MainThreadTaskRunner() const;
  base::SingleThreadTaskRunner* ImplThreadTaskRunner() const;
  bool IsMainThread() const;
  bool IsImplThread() const;

  TaskRunnerProvider* task_runner_provider_;

  MainThreadOnly& main();
  const MainThreadOnly& main() const;

  CompositorThreadOnly& impl();
  const CompositorThreadOnly& impl() const;

  // Use accessors instead of this variable directly.
  MainThreadOnly main_thread_only_vars_unsafe_;

  // Use accessors instead of this variable directly.
  CompositorThreadOnly compositor_thread_vars_unsafe_;

  // Used on the main thread to safely queue calls to ProxyImpl to be run on the
  // impl thread.
  base::WeakPtr<ProxyImpl> proxy_impl_weak_ptr_;

  DISALLOW_COPY_AND_ASSIGN(ThreadedChannel);
};

}  // namespace cc

#endif  // CC_TREES_THREADED_CHANNEL_H_