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 37 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 38 const BeginFrameArgs& args) {} 39 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, 40 bool did_handle) {} 41 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {} 42 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {} 43 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 44 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 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); 51 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {} 52 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {} 53 virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {} 54 virtual void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) {} 55 virtual void AnimateLayers(LayerTreeHostImpl* host_impl, 56 base::TimeTicks monotonic_time) {} 57 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, 58 bool has_unfinished_animation) {} 59 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, 60 base::TimeTicks monotonic_time) {} 61 virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, 62 float scale, 63 float top_controls_delta) {} 64 virtual void BeginMainFrame(const BeginFrameArgs& args) {} 65 virtual void WillBeginMainFrame() {} 66 virtual void DidBeginMainFrame() {} 67 virtual void Layout() {} 68 virtual void DidInitializeOutputSurface() {} 69 virtual void DidFailToInitializeOutputSurface() {} 70 virtual void DidAddAnimation() {} 71 virtual void WillCommit() {} 72 virtual void DidCommit() {} 73 virtual void DidCommitAndDrawFrame() {} 74 virtual void DidCompleteSwapBuffers() {} 75 virtual void DidDeferCommit() {} 76 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, 77 bool visible) {} 78 virtual base::TimeDelta LowFrequencyAnimationInterval() const; 79 80 // Hooks for SchedulerClient. 81 virtual void ScheduledActionWillSendBeginMainFrame() {} 82 virtual void ScheduledActionSendBeginMainFrame() {} 83 virtual void ScheduledActionDrawAndSwapIfPossible() {} 84 virtual void ScheduledActionAnimate() {} 85 virtual void ScheduledActionCommit() {} 86 virtual void ScheduledActionBeginOutputSurfaceCreation() {} 87 88 // Implementation of AnimationDelegate: 89 virtual void NotifyAnimationStarted(base::TimeTicks monotonic_time, 90 Animation::TargetProperty target_property) 91 OVERRIDE {} 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 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 163 bool HasImplThread() { return proxy() ? proxy()->HasImplThread() : false; } 164 base::SingleThreadTaskRunner* ImplThreadTaskRunner() { 165 DCHECK(proxy()); 166 return proxy()->ImplThreadTaskRunner() ? proxy()->ImplThreadTaskRunner() 167 : main_task_runner_.get(); 168 } 169 base::SingleThreadTaskRunner* MainThreadTaskRunner() { 170 return main_task_runner_.get(); 171 } 172 Proxy* proxy() const { 173 return layer_tree_host_ ? layer_tree_host_->proxy() : NULL; 174 } 175 176 bool TestEnded() const { return ended_; } 177 178 LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); } 179 bool delegating_renderer() const { return delegating_renderer_; } 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