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_TEST_LAYER_TREE_TEST_H_
6#define CC_TEST_LAYER_TREE_TEST_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/threading/thread.h"
10#include "cc/animation/animation_delegate.h"
11#include "cc/trees/layer_tree_host.h"
12#include "cc/trees/layer_tree_host_impl.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace Webkit { class WebGraphicsContext3D; }
16
17namespace cc {
18class FakeContextProvider;
19class FakeLayerTreeHostClient;
20class LayerImpl;
21class LayerTreeHost;
22class LayerTreeHostClient;
23class LayerTreeHostImpl;
24class FakeOutputSurface;
25
26// Used by test stubs to notify the test when something interesting happens.
27class TestHooks : public AnimationDelegate {
28 public:
29  TestHooks();
30  virtual ~TestHooks();
31
32  void ReadSettings(const LayerTreeSettings& settings);
33
34  virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
35  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {}
36  virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
37  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
38  virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
39                                           bool success) {}
40  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
41                                     LayerTreeHostImpl::FrameData* frame_data,
42                                     bool result);
43  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {}
44  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {}
45  virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {}
46  virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
47                             base::TimeTicks monotonic_time) {}
48  virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
49                                    bool has_unfinished_animation) {}
50  virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
51                                 base::TimeTicks monotonic_time) {}
52  virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
53                                   float scale) {}
54  virtual void Animate(base::TimeTicks monotonic_time) {}
55  virtual void WillBeginFrame() {}
56  virtual void DidBeginFrame() {}
57  virtual void Layout() {}
58  virtual void DidInitializeOutputSurface(bool succeeded) {}
59  virtual void DidFailToInitializeOutputSurface() {}
60  virtual void DidAddAnimation() {}
61  virtual void WillCommit() {}
62  virtual void DidCommit() {}
63  virtual void DidCommitAndDrawFrame() {}
64  virtual void DidCompleteSwapBuffers() {}
65  virtual void ScheduleComposite() {}
66  virtual void DidDeferCommit() {}
67  virtual bool CanActivatePendingTree(LayerTreeHostImpl* host_impl);
68  virtual bool CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* host_impl);
69  virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
70                                       bool visible) {}
71
72  // Implementation of AnimationDelegate:
73  virtual void NotifyAnimationStarted(double time) OVERRIDE {}
74  virtual void NotifyAnimationFinished(double time) OVERRIDE {}
75
76  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) = 0;
77  virtual scoped_refptr<cc::ContextProvider>
78  OffscreenContextProviderForMainThread() = 0;
79  virtual scoped_refptr<cc::ContextProvider>
80      OffscreenContextProviderForCompositorThread() = 0;
81};
82
83class BeginTask;
84class LayerTreeHostClientForTesting;
85class TimeoutTask;
86
87// The LayerTreeTests runs with the main loop running. It instantiates a single
88// LayerTreeHostForTesting and associated LayerTreeHostImplForTesting and
89// LayerTreeHostClientForTesting.
90//
91// BeginTest() is called once the main message loop is running and the layer
92// tree host is initialized.
93//
94// Key stages of the drawing loop, e.g. drawing or commiting, redirect to
95// LayerTreeTest methods of similar names. To track the commit process, override
96// these functions.
97//
98// The test continues until someone calls EndTest. EndTest can be called on any
99// thread, but be aware that ending the test is an asynchronous process.
100class LayerTreeTest : public testing::Test, public TestHooks {
101 public:
102  virtual ~LayerTreeTest();
103
104  virtual void AfterTest() = 0;
105  virtual void BeginTest() = 0;
106  virtual void SetupTree();
107
108  virtual void EndTest();
109  void EndTestAfterDelay(int delay_milliseconds);
110
111  void PostAddAnimationToMainThread(Layer* layer_to_receive_animation);
112  void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation);
113  void PostSetNeedsCommitToMainThread();
114  void PostAcquireLayerTextures();
115  void PostSetNeedsRedrawToMainThread();
116  void PostSetNeedsRedrawRectToMainThread(gfx::Rect damage_rect);
117  void PostSetVisibleToMainThread(bool visible);
118
119  void DoBeginTest();
120  void Timeout();
121
122 protected:
123  LayerTreeTest();
124
125  virtual void InitializeSettings(LayerTreeSettings* settings) {}
126
127  virtual void ScheduleComposite() OVERRIDE;
128
129  void RealEndTest();
130
131  virtual void DispatchAddInstantAnimation(Layer* layer_to_receive_animation);
132  virtual void DispatchAddAnimation(Layer* layer_to_receive_animation);
133  void DispatchSetNeedsCommit();
134  void DispatchAcquireLayerTextures();
135  void DispatchSetNeedsRedraw();
136  void DispatchSetNeedsRedrawRect(gfx::Rect damage_rect);
137  void DispatchSetVisible(bool visible);
138  void DispatchComposite();
139  void DispatchDidAddAnimation();
140
141  virtual void RunTest(bool threaded,
142                       bool delegating_renderer,
143                       bool impl_side_painting);
144
145  bool HasImplThread() { return proxy() ? proxy()->HasImplThread() : false; }
146  base::SingleThreadTaskRunner* ImplThreadTaskRunner() {
147    return proxy() ? proxy()->ImplThreadTaskRunner() : NULL;
148  }
149  Proxy* proxy() const {
150    return layer_tree_host_ ? layer_tree_host_->proxy() : NULL;
151  }
152
153  bool TestEnded() const { return ended_; }
154
155  LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); }
156  bool delegating_renderer() const { return delegating_renderer_; }
157  FakeOutputSurface* output_surface() { return output_surface_; }
158
159  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) OVERRIDE;
160  virtual scoped_refptr<cc::ContextProvider>
161  OffscreenContextProviderForMainThread() OVERRIDE;
162  virtual scoped_refptr<cc::ContextProvider>
163      OffscreenContextProviderForCompositorThread() OVERRIDE;
164
165 private:
166  LayerTreeSettings settings_;
167  scoped_ptr<LayerTreeHostClientForTesting> client_;
168  scoped_ptr<LayerTreeHost> layer_tree_host_;
169  FakeOutputSurface* output_surface_;
170
171  bool beginning_;
172  bool end_when_begin_returns_;
173  bool timed_out_;
174  bool scheduled_;
175  bool schedule_when_set_visible_true_;
176  bool started_;
177  bool ended_;
178  bool delegating_renderer_;
179
180  int timeout_seconds_;
181
182  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
183  scoped_ptr<base::Thread> impl_thread_;
184  base::CancelableClosure timeout_;
185  base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_;
186  base::WeakPtrFactory<LayerTreeTest> weak_factory_;
187  scoped_refptr<FakeContextProvider> main_thread_contexts_;
188  scoped_refptr<FakeContextProvider> compositor_thread_contexts_;
189};
190
191}  // namespace cc
192
193#define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)   \
194  TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer) {     \
195    RunTest(false, false, false);                                 \
196  }                                                               \
197  class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
198
199#define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
200  TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DelegatingRenderer) {   \
201    RunTest(false, true, false);                                    \
202  }                                                                 \
203  class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
204
205#define SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME)                   \
206  SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);        \
207  SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
208
209#define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)               \
210  TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \
211    RunTest(true, false, false);                                             \
212  }                                                                          \
213  TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) {   \
214    RunTest(true, false, true);                                              \
215  }                                                                          \
216  class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
217
218#define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
219  TEST_F(TEST_FIXTURE_NAME,                                        \
220         RunMultiThread_DelegatingRenderer_MainThreadPaint) {      \
221    RunTest(true, true, false);                                    \
222  }                                                                \
223  TEST_F(TEST_FIXTURE_NAME,                                        \
224         RunMultiThread_DelegatingRenderer_ImplSidePaint) {        \
225    RunTest(true, true, true);                                     \
226  }                                                                \
227  class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
228
229#define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME)                   \
230  MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);        \
231  MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
232
233#define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
234  SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
235  MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)
236
237#define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
238  SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
239  MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
240
241#define SINGLE_AND_MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \
242  SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);    \
243  SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
244
245#endif  // CC_TEST_LAYER_TREE_TEST_H_
246