• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 namespace Webkit {
16 class WebGraphicsContext3D;
17 }
18 
19 namespace cc {
20 class FakeLayerTreeHostClient;
21 class FakeOutputSurface;
22 class LayerImpl;
23 class LayerTreeHost;
24 class LayerTreeHostClient;
25 class LayerTreeHostImpl;
26 class TestContextProvider;
27 class TestWebGraphicsContext3D;
28 
29 // Used by test stubs to notify the test when something interesting happens.
30 class TestHooks : public AnimationDelegate {
31  public:
32   TestHooks();
33   virtual ~TestHooks();
34 
35   void ReadSettings(const LayerTreeSettings& settings);
36 
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const BeginFrameArgs & args)37   virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
38                                           const BeginFrameArgs& args) {}
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,bool did_handle)39   virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
40                                              bool did_handle) {}
BeginCommitOnThread(LayerTreeHostImpl * host_impl)41   virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)42   virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {}
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)43   virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)44   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)45   virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
46                                            bool success) {}
47   virtual DrawResult PrepareToDrawOnThread(
48       LayerTreeHostImpl* host_impl,
49       LayerTreeHostImpl::FrameData* frame_data,
50       DrawResult draw_result);
DrawLayersOnThread(LayerTreeHostImpl * host_impl)51   virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {}
SwapBuffersOnThread(LayerTreeHostImpl * host_impl,bool result)52   virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {}
SwapBuffersCompleteOnThread(LayerTreeHostImpl * host_impl)53   virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {}
UpdateVisibleTilesOnThread(LayerTreeHostImpl * host_impl)54   virtual void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) {}
AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)55   virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
56                              base::TimeTicks monotonic_time) {}
UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)57   virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
58                                     bool has_unfinished_animation) {}
WillAnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)59   virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
60                                  base::TimeTicks monotonic_time) {}
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float scale,float top_controls_delta)61   virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
62                                    float scale,
63                                    float top_controls_delta) {}
BeginMainFrame(const BeginFrameArgs & args)64   virtual void BeginMainFrame(const BeginFrameArgs& args) {}
WillBeginMainFrame()65   virtual void WillBeginMainFrame() {}
DidBeginMainFrame()66   virtual void DidBeginMainFrame() {}
Layout()67   virtual void Layout() {}
DidInitializeOutputSurface()68   virtual void DidInitializeOutputSurface() {}
DidFailToInitializeOutputSurface()69   virtual void DidFailToInitializeOutputSurface() {}
DidAddAnimation()70   virtual void DidAddAnimation() {}
WillCommit()71   virtual void WillCommit() {}
DidCommit()72   virtual void DidCommit() {}
DidCommitAndDrawFrame()73   virtual void DidCommitAndDrawFrame() {}
DidCompleteSwapBuffers()74   virtual void DidCompleteSwapBuffers() {}
DidDeferCommit()75   virtual void DidDeferCommit() {}
DidSetVisibleOnImplTree(LayerTreeHostImpl * host_impl,bool visible)76   virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
77                                        bool visible) {}
78   virtual base::TimeDelta LowFrequencyAnimationInterval() const;
79 
80   // Hooks for SchedulerClient.
ScheduledActionWillSendBeginMainFrame()81   virtual void ScheduledActionWillSendBeginMainFrame() {}
ScheduledActionSendBeginMainFrame()82   virtual void ScheduledActionSendBeginMainFrame() {}
ScheduledActionDrawAndSwapIfPossible()83   virtual void ScheduledActionDrawAndSwapIfPossible() {}
ScheduledActionAnimate()84   virtual void ScheduledActionAnimate() {}
ScheduledActionCommit()85   virtual void ScheduledActionCommit() {}
ScheduledActionBeginOutputSurfaceCreation()86   virtual void ScheduledActionBeginOutputSurfaceCreation() {}
87 
88   // Implementation of AnimationDelegate:
NotifyAnimationStarted(base::TimeTicks monotonic_time,Animation::TargetProperty target_property)89   virtual void NotifyAnimationStarted(base::TimeTicks monotonic_time,
90                                       Animation::TargetProperty target_property)
91       OVERRIDE {}
NotifyAnimationFinished(base::TimeTicks monotonic_time,Animation::TargetProperty target_property)92   virtual void NotifyAnimationFinished(
93       base::TimeTicks monotonic_time,
94       Animation::TargetProperty target_property) OVERRIDE {}
95 
96   virtual void RequestNewOutputSurface(bool fallback) = 0;
97 };
98 
99 class BeginTask;
100 class LayerTreeHostClientForTesting;
101 class TimeoutTask;
102 
103 // The LayerTreeTests runs with the main loop running. It instantiates a single
104 // LayerTreeHostForTesting and associated LayerTreeHostImplForTesting and
105 // LayerTreeHostClientForTesting.
106 //
107 // BeginTest() is called once the main message loop is running and the layer
108 // tree host is initialized.
109 //
110 // Key stages of the drawing loop, e.g. drawing or commiting, redirect to
111 // LayerTreeTest methods of similar names. To track the commit process, override
112 // these functions.
113 //
114 // The test continues until someone calls EndTest. EndTest can be called on any
115 // thread, but be aware that ending the test is an asynchronous process.
116 class LayerTreeTest : public testing::Test, public TestHooks {
117  public:
118   virtual ~LayerTreeTest();
119 
120   virtual void EndTest();
121   void EndTestAfterDelay(int delay_milliseconds);
122 
123   void PostAddAnimationToMainThread(Layer* layer_to_receive_animation);
124   void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation);
125   void PostAddLongAnimationToMainThread(Layer* layer_to_receive_animation);
126   void PostSetNeedsCommitToMainThread();
127   void PostSetNeedsUpdateLayersToMainThread();
128   void PostSetNeedsRedrawToMainThread();
129   void PostSetNeedsRedrawRectToMainThread(const gfx::Rect& damage_rect);
130   void PostSetVisibleToMainThread(bool visible);
131   void PostSetNextCommitForcesRedrawToMainThread();
132 
133   void DoBeginTest();
134   void Timeout();
135 
136  protected:
137   LayerTreeTest();
138 
InitializeSettings(LayerTreeSettings * settings)139   virtual void InitializeSettings(LayerTreeSettings* settings) {}
140 
141   void RealEndTest();
142 
143   virtual void DispatchAddAnimation(Layer* layer_to_receive_animation,
144                                     double animation_duration);
145   void DispatchSetNeedsCommit();
146   void DispatchSetNeedsUpdateLayers();
147   void DispatchSetNeedsRedraw();
148   void DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect);
149   void DispatchSetVisible(bool visible);
150   void DispatchSetNextCommitForcesRedraw();
151   void DispatchDidAddAnimation();
152 
153   virtual void AfterTest() = 0;
154   virtual void WillBeginTest();
155   virtual void BeginTest() = 0;
156   virtual void SetupTree();
157 
158   virtual void RunTest(bool threaded,
159                        bool delegating_renderer,
160                        bool impl_side_painting);
161   virtual void RunTestWithImplSidePainting();
162 
HasImplThread()163   bool HasImplThread() { return proxy() ? proxy()->HasImplThread() : false; }
ImplThreadTaskRunner()164   base::SingleThreadTaskRunner* ImplThreadTaskRunner() {
165     DCHECK(proxy());
166     return proxy()->ImplThreadTaskRunner() ? proxy()->ImplThreadTaskRunner()
167                                            : main_task_runner_.get();
168   }
MainThreadTaskRunner()169   base::SingleThreadTaskRunner* MainThreadTaskRunner() {
170     return main_task_runner_.get();
171   }
proxy()172   Proxy* proxy() const {
173     return layer_tree_host_ ? layer_tree_host_->proxy() : NULL;
174   }
175 
TestEnded()176   bool TestEnded() const { return ended_; }
177 
layer_tree_host()178   LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); }
delegating_renderer()179   bool delegating_renderer() const { return delegating_renderer_; }
output_surface()180   FakeOutputSurface* output_surface() { return output_surface_; }
181   int LastCommittedSourceFrameNumber(LayerTreeHostImpl* impl) const;
182 
183   void DestroyLayerTreeHost();
184 
185   // By default, output surface recreation is synchronous.
186   virtual void RequestNewOutputSurface(bool fallback) OVERRIDE;
187   // Override this for pixel tests, where you need a real output surface.
188   virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback);
189   // Override this for unit tests, which should not produce pixel output.
190   virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback);
191 
192   TestWebGraphicsContext3D* TestContext();
193 
194 
195  private:
196   LayerTreeSettings settings_;
197   scoped_ptr<LayerTreeHostClientForTesting> client_;
198   scoped_ptr<LayerTreeHost> layer_tree_host_;
199   FakeOutputSurface* output_surface_;
200 
201   bool beginning_;
202   bool end_when_begin_returns_;
203   bool timed_out_;
204   bool scheduled_;
205   bool started_;
206   bool ended_;
207   bool delegating_renderer_;
208 
209   int timeout_seconds_;
210 
211   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
212   scoped_ptr<base::Thread> impl_thread_;
213   base::CancelableClosure timeout_;
214   scoped_refptr<TestContextProvider> compositor_contexts_;
215   base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_;
216   base::WeakPtrFactory<LayerTreeTest> weak_factory_;
217 };
218 
219 }  // namespace cc
220 
221 #define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
222   TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer) {   \
223     RunTest(false, false, false);                               \
224   }                                                             \
225   class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
226 
227 #define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
228   TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DelegatingRenderer) {   \
229     RunTest(false, true, false);                                    \
230   }                                                                 \
231   class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
232 
233 #define SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME)            \
234   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
235   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
236 
237 #define MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)        \
238   TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \
239     RunTest(true, false, false);                                             \
240   }
241 
242 #define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)                 \
243   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)                \
244       TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) { \
245     RunTest(true, false, true);                                                \
246   }                                                                            \
247   class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
248 
249 #define MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
250   TEST_F(TEST_FIXTURE_NAME,                                               \
251          RunMultiThread_DelegatingRenderer_MainThreadPaint) {             \
252     RunTest(true, true, false);                                           \
253   }
254 
255 #define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)          \
256   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) TEST_F( \
257       TEST_FIXTURE_NAME, RunMultiThread_DelegatingRenderer_ImplSidePaint) { \
258     RunTest(true, true, true);                                              \
259   }                                                                         \
260   class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
261 
262 #define MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME)            \
263   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
264   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
265 
266 #define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME)            \
267   MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
268   MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
269 
270 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( \
271     TEST_FIXTURE_NAME)                                         \
272   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);     \
273   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
274 
275 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
276   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
277   MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)
278 
279 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( \
280     TEST_FIXTURE_NAME)                                             \
281   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME);     \
282   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
283 
284 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
285   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
286   MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
287 
288 #define SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME)            \
289   SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
290   SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
291 
292 #define SINGLE_AND_MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME)            \
293   SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
294   SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
295 
296 #endif  // CC_TEST_LAYER_TREE_TEST_H_
297