• 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 { class WebGraphicsContext3D; }
16 
17 namespace cc {
18 class FakeLayerTreeHostClient;
19 class FakeOutputSurface;
20 class LayerImpl;
21 class LayerTreeHost;
22 class LayerTreeHostClient;
23 class LayerTreeHostImpl;
24 class TestContextProvider;
25 
26 // Used by test stubs to notify the test when something interesting happens.
27 class TestHooks : public AnimationDelegate {
28  public:
29   TestHooks();
30   virtual ~TestHooks();
31 
32   void ReadSettings(const LayerTreeSettings& settings);
33 
WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const BeginFrameArgs & args)34   virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
35                                           const BeginFrameArgs& args) {}
DidBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const BeginFrameArgs & args)36   virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
37                                           const BeginFrameArgs& args) {}
BeginMainFrameAbortedOnThread(LayerTreeHostImpl * host_impl,bool did_handle)38   virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
39                                              bool did_handle) {}
BeginCommitOnThread(LayerTreeHostImpl * host_impl)40   virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
CommitCompleteOnThread(LayerTreeHostImpl * host_impl)41   virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {}
WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)42   virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)43   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
InitializedRendererOnThread(LayerTreeHostImpl * host_impl,bool success)44   virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
45                                            bool success) {}
46   virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
47                                      LayerTreeHostImpl::FrameData* frame_data,
48                                      bool result);
DrawLayersOnThread(LayerTreeHostImpl * host_impl)49   virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {}
SwapBuffersOnThread(LayerTreeHostImpl * host_impl,bool result)50   virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {}
SwapBuffersCompleteOnThread(LayerTreeHostImpl * host_impl)51   virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {}
UpdateVisibleTilesOnThread(LayerTreeHostImpl * host_impl)52   virtual void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) {}
AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)53   virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
54                              base::TimeTicks monotonic_time) {}
UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)55   virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
56                                     bool has_unfinished_animation) {}
WillAnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)57   virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
58                                  base::TimeTicks monotonic_time) {}
ApplyScrollAndScale(gfx::Vector2d scroll_delta,float scale)59   virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
60                                    float scale) {}
Animate(base::TimeTicks monotonic_time)61   virtual void Animate(base::TimeTicks monotonic_time) {}
WillBeginMainFrame()62   virtual void WillBeginMainFrame() {}
DidBeginMainFrame()63   virtual void DidBeginMainFrame() {}
Layout()64   virtual void Layout() {}
DidInitializeOutputSurface(bool succeeded)65   virtual void DidInitializeOutputSurface(bool succeeded) {}
DidFailToInitializeOutputSurface()66   virtual void DidFailToInitializeOutputSurface() {}
DidAddAnimation()67   virtual void DidAddAnimation() {}
WillCommit()68   virtual void WillCommit() {}
DidCommit()69   virtual void DidCommit() {}
DidCommitAndDrawFrame()70   virtual void DidCommitAndDrawFrame() {}
DidCompleteSwapBuffers()71   virtual void DidCompleteSwapBuffers() {}
ScheduleComposite()72   virtual void ScheduleComposite() {}
ScheduleAnimation()73   virtual void ScheduleAnimation() {}
DidDeferCommit()74   virtual void DidDeferCommit() {}
DidSetVisibleOnImplTree(LayerTreeHostImpl * host_impl,bool visible)75   virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
76                                        bool visible) {}
77   virtual base::TimeDelta LowFrequencyAnimationInterval() const;
78 
79   // Implementation of AnimationDelegate:
NotifyAnimationStarted(double wall_clock_time,base::TimeTicks monotonic_time,Animation::TargetProperty target_property)80   virtual void NotifyAnimationStarted(
81       double wall_clock_time,
82       base::TimeTicks monotonic_time,
83       Animation::TargetProperty target_property) OVERRIDE {}
NotifyAnimationFinished(double wall_clock_time,base::TimeTicks monotonic_time,Animation::TargetProperty target_property)84   virtual void NotifyAnimationFinished(
85       double wall_clock_time,
86       base::TimeTicks monotonic_time,
87       Animation::TargetProperty target_property) OVERRIDE {}
88 
89   virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) = 0;
90   virtual scoped_refptr<ContextProvider> OffscreenContextProvider() = 0;
91 };
92 
93 class BeginTask;
94 class LayerTreeHostClientForTesting;
95 class TimeoutTask;
96 
97 // The LayerTreeTests runs with the main loop running. It instantiates a single
98 // LayerTreeHostForTesting and associated LayerTreeHostImplForTesting and
99 // LayerTreeHostClientForTesting.
100 //
101 // BeginTest() is called once the main message loop is running and the layer
102 // tree host is initialized.
103 //
104 // Key stages of the drawing loop, e.g. drawing or commiting, redirect to
105 // LayerTreeTest methods of similar names. To track the commit process, override
106 // these functions.
107 //
108 // The test continues until someone calls EndTest. EndTest can be called on any
109 // thread, but be aware that ending the test is an asynchronous process.
110 class LayerTreeTest : public testing::Test, public TestHooks {
111  public:
112   virtual ~LayerTreeTest();
113 
114   virtual void AfterTest() = 0;
115   virtual void BeginTest() = 0;
116   virtual void SetupTree();
117 
118   virtual void EndTest();
119   void EndTestAfterDelay(int delay_milliseconds);
120 
121   void PostAddAnimationToMainThread(Layer* layer_to_receive_animation);
122   void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation);
123   void PostAddLongAnimationToMainThread(Layer* layer_to_receive_animation);
124   void PostSetNeedsCommitToMainThread();
125   void PostSetNeedsUpdateLayersToMainThread();
126   void PostReadbackToMainThread();
127   void PostAcquireLayerTextures();
128   void PostSetNeedsRedrawToMainThread();
129   void PostSetNeedsRedrawRectToMainThread(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   virtual void ScheduleComposite() OVERRIDE;
142 
143   void RealEndTest();
144 
145   virtual void DispatchAddAnimation(Layer* layer_to_receive_animation,
146                                     double animation_duration);
147   void DispatchSetNeedsCommit();
148   void DispatchSetNeedsUpdateLayers();
149   void DispatchReadback();
150   void DispatchAcquireLayerTextures();
151   void DispatchSetNeedsRedraw();
152   void DispatchSetNeedsRedrawRect(gfx::Rect damage_rect);
153   void DispatchSetVisible(bool visible);
154   void DispatchSetNextCommitForcesRedraw();
155   void DispatchComposite();
156   void DispatchDidAddAnimation();
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 
182   virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) OVERRIDE;
183   virtual scoped_refptr<ContextProvider> OffscreenContextProvider() OVERRIDE;
184 
185  private:
186   LayerTreeSettings settings_;
187   scoped_ptr<LayerTreeHostClientForTesting> client_;
188   scoped_ptr<LayerTreeHost> layer_tree_host_;
189   FakeOutputSurface* output_surface_;
190 
191   bool beginning_;
192   bool end_when_begin_returns_;
193   bool timed_out_;
194   bool scheduled_;
195   bool schedule_when_set_visible_true_;
196   bool started_;
197   bool ended_;
198   bool delegating_renderer_;
199 
200   int timeout_seconds_;
201 
202   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
203   scoped_ptr<base::Thread> impl_thread_;
204   base::CancelableClosure timeout_;
205   scoped_refptr<TestContextProvider> compositor_contexts_;
206   base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_;
207   base::WeakPtrFactory<LayerTreeTest> weak_factory_;
208 };
209 
210 }  // namespace cc
211 
212 #define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)   \
213   TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer) {     \
214     RunTest(false, false, false);                                 \
215   }                                                               \
216   class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
217 
218 #define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
219   TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DelegatingRenderer) {   \
220     RunTest(false, true, false);                                    \
221   }                                                                 \
222   class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
223 
224 #define SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME)                   \
225   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);        \
226   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
227 
228 #define MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)        \
229   TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \
230     RunTest(true, false, false);                                             \
231   }
232 
233 #define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)               \
234   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)              \
235   TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) {   \
236     RunTest(true, false, true);                                              \
237   }                                                                          \
238   class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
239 
240 #define MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)    \
241   TEST_F(TEST_FIXTURE_NAME,                                                  \
242          RunMultiThread_DelegatingRenderer_MainThreadPaint) {                \
243     RunTest(true, true, false);                                              \
244   }
245 
246 #define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
247   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)\
248   TEST_F(TEST_FIXTURE_NAME,                                        \
249          RunMultiThread_DelegatingRenderer_ImplSidePaint) {        \
250     RunTest(true, true, true);                                     \
251   }                                                                \
252   class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
253 
254 #define MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME)                   \
255   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME);        \
256   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
257 
258 #define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME)                   \
259   MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);        \
260   MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
261 
262 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( \
263   TEST_FIXTURE_NAME)                                           \
264   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);     \
265   MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
266 
267 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
268   SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
269   MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)
270 
271 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( \
272   TEST_FIXTURE_NAME)                                               \
273   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME);     \
274   MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
275 
276 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
277   SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME);                \
278   MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
279 
280 #define SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME)              \
281   SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME);   \
282   SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
283 
284 #define SINGLE_AND_MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \
285   SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME);    \
286   SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
287 
288 #endif  // CC_TEST_LAYER_TREE_TEST_H_
289