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 34 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 35 const BeginFrameArgs& args) {} 36 virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 37 const BeginFrameArgs& args) {} 38 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, 39 bool did_handle) {} 40 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {} 41 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {} 42 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 43 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 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); 49 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {} 50 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {} 51 virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {} 52 virtual void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) {} 53 virtual void AnimateLayers(LayerTreeHostImpl* host_impl, 54 base::TimeTicks monotonic_time) {} 55 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, 56 bool has_unfinished_animation) {} 57 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, 58 base::TimeTicks monotonic_time) {} 59 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, 60 float scale) {} 61 virtual void Animate(base::TimeTicks monotonic_time) {} 62 virtual void WillBeginMainFrame() {} 63 virtual void DidBeginMainFrame() {} 64 virtual void Layout() {} 65 virtual void DidInitializeOutputSurface(bool succeeded) {} 66 virtual void DidFailToInitializeOutputSurface() {} 67 virtual void DidAddAnimation() {} 68 virtual void WillCommit() {} 69 virtual void DidCommit() {} 70 virtual void DidCommitAndDrawFrame() {} 71 virtual void DidCompleteSwapBuffers() {} 72 virtual void ScheduleComposite() {} 73 virtual void ScheduleAnimation() {} 74 virtual void DidDeferCommit() {} 75 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, 76 bool visible) {} 77 virtual base::TimeDelta LowFrequencyAnimationInterval() const; 78 79 // Implementation of AnimationDelegate: 80 virtual void NotifyAnimationStarted( 81 double wall_clock_time, 82 base::TimeTicks monotonic_time, 83 Animation::TargetProperty target_property) OVERRIDE {} 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 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 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 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