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