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 FakeContextProvider; 19 class FakeLayerTreeHostClient; 20 class LayerImpl; 21 class LayerTreeHost; 22 class LayerTreeHostClient; 23 class LayerTreeHostImpl; 24 class FakeOutputSurface; 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 BeginCommitOnThread(LayerTreeHostImpl* host_impl) {} 35 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {} 36 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 37 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {} 38 virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, 39 bool success) {} 40 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 41 LayerTreeHostImpl::FrameData* frame_data, 42 bool result); 43 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {} 44 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {} 45 virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {} 46 virtual void AnimateLayers(LayerTreeHostImpl* host_impl, 47 base::TimeTicks monotonic_time) {} 48 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, 49 bool has_unfinished_animation) {} 50 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, 51 base::TimeTicks monotonic_time) {} 52 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, 53 float scale) {} 54 virtual void Animate(base::TimeTicks monotonic_time) {} 55 virtual void WillBeginFrame() {} 56 virtual void DidBeginFrame() {} 57 virtual void Layout() {} 58 virtual void DidInitializeOutputSurface(bool succeeded) {} 59 virtual void DidFailToInitializeOutputSurface() {} 60 virtual void DidAddAnimation() {} 61 virtual void WillCommit() {} 62 virtual void DidCommit() {} 63 virtual void DidCommitAndDrawFrame() {} 64 virtual void DidCompleteSwapBuffers() {} 65 virtual void ScheduleComposite() {} 66 virtual void DidDeferCommit() {} 67 virtual bool CanActivatePendingTree(LayerTreeHostImpl* host_impl); 68 virtual bool CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* host_impl); 69 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, 70 bool visible) {} 71 72 // Implementation of AnimationDelegate: 73 virtual void NotifyAnimationStarted(double time) OVERRIDE {} 74 virtual void NotifyAnimationFinished(double time) OVERRIDE {} 75 76 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) = 0; 77 virtual scoped_refptr<cc::ContextProvider> 78 OffscreenContextProviderForMainThread() = 0; 79 virtual scoped_refptr<cc::ContextProvider> 80 OffscreenContextProviderForCompositorThread() = 0; 81 }; 82 83 class BeginTask; 84 class LayerTreeHostClientForTesting; 85 class TimeoutTask; 86 87 // The LayerTreeTests runs with the main loop running. It instantiates a single 88 // LayerTreeHostForTesting and associated LayerTreeHostImplForTesting and 89 // LayerTreeHostClientForTesting. 90 // 91 // BeginTest() is called once the main message loop is running and the layer 92 // tree host is initialized. 93 // 94 // Key stages of the drawing loop, e.g. drawing or commiting, redirect to 95 // LayerTreeTest methods of similar names. To track the commit process, override 96 // these functions. 97 // 98 // The test continues until someone calls EndTest. EndTest can be called on any 99 // thread, but be aware that ending the test is an asynchronous process. 100 class LayerTreeTest : public testing::Test, public TestHooks { 101 public: 102 virtual ~LayerTreeTest(); 103 104 virtual void AfterTest() = 0; 105 virtual void BeginTest() = 0; 106 virtual void SetupTree(); 107 108 virtual void EndTest(); 109 void EndTestAfterDelay(int delay_milliseconds); 110 111 void PostAddAnimationToMainThread(Layer* layer_to_receive_animation); 112 void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation); 113 void PostSetNeedsCommitToMainThread(); 114 void PostAcquireLayerTextures(); 115 void PostSetNeedsRedrawToMainThread(); 116 void PostSetNeedsRedrawRectToMainThread(gfx::Rect damage_rect); 117 void PostSetVisibleToMainThread(bool visible); 118 119 void DoBeginTest(); 120 void Timeout(); 121 122 protected: 123 LayerTreeTest(); 124 125 virtual void InitializeSettings(LayerTreeSettings* settings) {} 126 127 virtual void ScheduleComposite() OVERRIDE; 128 129 void RealEndTest(); 130 131 virtual void DispatchAddInstantAnimation(Layer* layer_to_receive_animation); 132 virtual void DispatchAddAnimation(Layer* layer_to_receive_animation); 133 void DispatchSetNeedsCommit(); 134 void DispatchAcquireLayerTextures(); 135 void DispatchSetNeedsRedraw(); 136 void DispatchSetNeedsRedrawRect(gfx::Rect damage_rect); 137 void DispatchSetVisible(bool visible); 138 void DispatchComposite(); 139 void DispatchDidAddAnimation(); 140 141 virtual void RunTest(bool threaded, 142 bool delegating_renderer, 143 bool impl_side_painting); 144 145 bool HasImplThread() { return proxy() ? proxy()->HasImplThread() : false; } 146 base::SingleThreadTaskRunner* ImplThreadTaskRunner() { 147 return proxy() ? proxy()->ImplThreadTaskRunner() : NULL; 148 } 149 Proxy* proxy() const { 150 return layer_tree_host_ ? layer_tree_host_->proxy() : NULL; 151 } 152 153 bool TestEnded() const { return ended_; } 154 155 LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); } 156 bool delegating_renderer() const { return delegating_renderer_; } 157 FakeOutputSurface* output_surface() { return output_surface_; } 158 159 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) OVERRIDE; 160 virtual scoped_refptr<cc::ContextProvider> 161 OffscreenContextProviderForMainThread() OVERRIDE; 162 virtual scoped_refptr<cc::ContextProvider> 163 OffscreenContextProviderForCompositorThread() OVERRIDE; 164 165 private: 166 LayerTreeSettings settings_; 167 scoped_ptr<LayerTreeHostClientForTesting> client_; 168 scoped_ptr<LayerTreeHost> layer_tree_host_; 169 FakeOutputSurface* output_surface_; 170 171 bool beginning_; 172 bool end_when_begin_returns_; 173 bool timed_out_; 174 bool scheduled_; 175 bool schedule_when_set_visible_true_; 176 bool started_; 177 bool ended_; 178 bool delegating_renderer_; 179 180 int timeout_seconds_; 181 182 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 183 scoped_ptr<base::Thread> impl_thread_; 184 base::CancelableClosure timeout_; 185 base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_; 186 base::WeakPtrFactory<LayerTreeTest> weak_factory_; 187 scoped_refptr<FakeContextProvider> main_thread_contexts_; 188 scoped_refptr<FakeContextProvider> compositor_thread_contexts_; 189 }; 190 191 } // namespace cc 192 193 #define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 194 TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer) { \ 195 RunTest(false, false, false); \ 196 } \ 197 class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {} 198 199 #define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 200 TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DelegatingRenderer) { \ 201 RunTest(false, true, false); \ 202 } \ 203 class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {} 204 205 #define SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME) \ 206 SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \ 207 SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) 208 209 #define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 210 TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \ 211 RunTest(true, false, false); \ 212 } \ 213 TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) { \ 214 RunTest(true, false, true); \ 215 } \ 216 class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {} 217 218 #define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 219 TEST_F(TEST_FIXTURE_NAME, \ 220 RunMultiThread_DelegatingRenderer_MainThreadPaint) { \ 221 RunTest(true, true, false); \ 222 } \ 223 TEST_F(TEST_FIXTURE_NAME, \ 224 RunMultiThread_DelegatingRenderer_ImplSidePaint) { \ 225 RunTest(true, true, true); \ 226 } \ 227 class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {} 228 229 #define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \ 230 MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \ 231 MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) 232 233 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 234 SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \ 235 MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) 236 237 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \ 238 SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME); \ 239 MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) 240 241 #define SINGLE_AND_MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \ 242 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \ 243 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) 244 245 #endif // CC_TEST_LAYER_TREE_TEST_H_ 246