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.
5 #ifndef CC_TEST_LAYER_TREE_TEST_H_
6 #define CC_TEST_LAYER_TREE_TEST_H_
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"
16 class WebGraphicsContext3D;
20 class FakeLayerTreeHostClient;
21 class FakeOutputSurface;
24 class LayerTreeHostClient;
25 class LayerTreeHostImpl;
26 class TestContextProvider;
27 class TestWebGraphicsContext3D;
29 // Used by test stubs to notify the test when something interesting happens.
30 class TestHooks : public AnimationDelegate {
33 ~TestHooks() override;
35 void ReadSettings(const LayerTreeSettings& settings);
37 virtual void CreateResourceAndRasterWorkerPool(
38 LayerTreeHostImpl* host_impl,
39 scoped_ptr<RasterWorkerPool>* raster_worker_pool,
40 scoped_ptr<ResourcePool>* resource_pool,
41 scoped_ptr<ResourcePool>* staging_resource_pool);
42 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
43 const BeginFrameArgs& args) {}
44 virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
46 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
47 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {}
48 virtual void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
49 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) {}
50 virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
52 virtual DrawResult PrepareToDrawOnThread(
53 LayerTreeHostImpl* host_impl,
54 LayerTreeHostImpl::FrameData* frame_data,
55 DrawResult draw_result);
56 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {}
57 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) {}
58 virtual void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) {}
59 virtual void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) {}
60 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
61 base::TimeTicks monotonic_time) {}
62 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
63 bool has_unfinished_animation) {}
64 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
65 base::TimeTicks monotonic_time) {}
66 virtual void ApplyViewportDeltas(const gfx::Vector2d& inner_delta,
67 const gfx::Vector2d& outer_delta,
69 float top_controls_delta) {}
70 virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
72 float top_controls_delta) {}
73 virtual void BeginMainFrame(const BeginFrameArgs& args) {}
74 virtual void WillBeginMainFrame() {}
75 virtual void DidBeginMainFrame() {}
76 virtual void Layout() {}
77 virtual void DidInitializeOutputSurface() {}
78 virtual void DidFailToInitializeOutputSurface() {}
79 virtual void DidAddAnimation() {}
80 virtual void WillCommit() {}
81 virtual void DidCommit() {}
82 virtual void DidCommitAndDrawFrame() {}
83 virtual void DidCompleteSwapBuffers() {}
84 virtual void DidDeferCommit() {}
85 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
87 virtual base::TimeDelta LowFrequencyAnimationInterval() const;
88 virtual void ScheduleComposite() {}
90 // Hooks for SchedulerClient.
91 virtual void ScheduledActionWillSendBeginMainFrame() {}
92 virtual void ScheduledActionSendBeginMainFrame() {}
93 virtual void ScheduledActionDrawAndSwapIfPossible() {}
94 virtual void ScheduledActionAnimate() {}
95 virtual void ScheduledActionCommit() {}
96 virtual void ScheduledActionBeginOutputSurfaceCreation() {}
98 // Implementation of AnimationDelegate:
99 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
100 Animation::TargetProperty target_property,
101 int group) override {}
102 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
103 Animation::TargetProperty target_property,
104 int group) override {}
106 virtual void RequestNewOutputSurface(bool fallback) = 0;
110 class LayerTreeHostClientForTesting;
113 // The LayerTreeTests runs with the main loop running. It instantiates a single
114 // LayerTreeHostForTesting and associated LayerTreeHostImplForTesting and
115 // LayerTreeHostClientForTesting.
117 // BeginTest() is called once the main message loop is running and the layer
118 // tree host is initialized.
120 // Key stages of the drawing loop, e.g. drawing or commiting, redirect to
121 // LayerTreeTest methods of similar names. To track the commit process, override
124 // The test continues until someone calls EndTest. EndTest can be called on any
125 // thread, but be aware that ending the test is an asynchronous process.
126 class LayerTreeTest : public testing::Test, public TestHooks {
128 virtual ~LayerTreeTest();
130 virtual void EndTest();
131 void EndTestAfterDelay(int delay_milliseconds);
133 void PostAddAnimationToMainThread(Layer* layer_to_receive_animation);
134 void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation);
135 void PostAddLongAnimationToMainThread(Layer* layer_to_receive_animation);
136 void PostSetNeedsCommitToMainThread();
137 void PostSetNeedsUpdateLayersToMainThread();
138 void PostSetNeedsRedrawToMainThread();
139 void PostSetNeedsRedrawRectToMainThread(const gfx::Rect& damage_rect);
140 void PostSetVisibleToMainThread(bool visible);
141 void PostSetNextCommitForcesRedrawToMainThread();
142 void PostCompositeImmediatelyToMainThread();
150 virtual void InitializeSettings(LayerTreeSettings* settings) {}
154 virtual void DispatchAddAnimation(Layer* layer_to_receive_animation,
155 double animation_duration);
156 void DispatchSetNeedsCommit();
157 void DispatchSetNeedsUpdateLayers();
158 void DispatchSetNeedsRedraw();
159 void DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect);
160 void DispatchSetVisible(bool visible);
161 void DispatchSetNextCommitForcesRedraw();
162 void DispatchDidAddAnimation();
163 void DispatchCompositeImmediately();
165 virtual void AfterTest() = 0;
166 virtual void WillBeginTest();
167 virtual void BeginTest() = 0;
168 virtual void SetupTree();
170 virtual void RunTest(bool threaded,
171 bool delegating_renderer,
172 bool impl_side_painting);
173 virtual void RunTestWithImplSidePainting();
175 bool HasImplThread() { return proxy() ? proxy()->HasImplThread() : false; }
176 base::SingleThreadTaskRunner* ImplThreadTaskRunner() {
178 return proxy()->ImplThreadTaskRunner() ? proxy()->ImplThreadTaskRunner()
179 : main_task_runner_.get();
181 base::SingleThreadTaskRunner* MainThreadTaskRunner() {
182 return main_task_runner_.get();
184 Proxy* proxy() const {
185 return layer_tree_host_ ? layer_tree_host_->proxy() : NULL;
188 bool TestEnded() const { return ended_; }
190 LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); }
191 bool delegating_renderer() const { return delegating_renderer_; }
192 FakeOutputSurface* output_surface() { return output_surface_; }
193 int LastCommittedSourceFrameNumber(LayerTreeHostImpl* impl) const;
195 void DestroyLayerTreeHost();
197 // By default, output surface recreation is synchronous.
198 void RequestNewOutputSurface(bool fallback) override;
199 // Override this for pixel tests, where you need a real output surface.
200 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback);
201 // Override this for unit tests, which should not produce pixel output.
202 virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback);
204 TestWebGraphicsContext3D* TestContext();
208 LayerTreeSettings settings_;
209 scoped_ptr<LayerTreeHostClientForTesting> client_;
210 scoped_ptr<LayerTreeHost> layer_tree_host_;
211 FakeOutputSurface* output_surface_;
214 bool end_when_begin_returns_;
219 bool delegating_renderer_;
221 int timeout_seconds_;
223 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
224 scoped_ptr<base::Thread> impl_thread_;
225 base::CancelableClosure timeout_;
226 scoped_refptr<TestContextProvider> compositor_contexts_;
227 base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_;
228 base::WeakPtrFactory<LayerTreeTest> weak_factory_;
233 #define SINGLE_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
234 TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer_MainThreadPaint) { \
235 RunTest(false, false, false); \
237 class SingleThreadDirectNoImplNeedsSemicolon##TEST_FIXTURE_NAME {}
239 #define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
240 SINGLE_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
241 TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer_ImplSidePaint) { \
242 RunTest(false, false, true); \
244 class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
246 #define SINGLE_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
247 TEST_F(TEST_FIXTURE_NAME, \
248 RunSingleThread_DelegatingRenderer_MainThreadPaint) { \
249 RunTest(false, true, false); \
251 class SingleThreadDelegatingNoImplNeedsSemicolon##TEST_FIXTURE_NAME {}
253 #define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
254 SINGLE_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
255 TEST_F(TEST_FIXTURE_NAME, \
256 RunSingleThread_DelegatingRenderer_ImplSidePaint) { \
257 RunTest(false, true, true); \
259 class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
261 #define SINGLE_THREAD_TEST_F(TEST_FIXTURE_NAME) \
262 SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
263 SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
265 #define SINGLE_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
266 SINGLE_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
267 SINGLE_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
269 #define MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
270 TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \
271 RunTest(true, false, false); \
273 class MultiThreadDirectNoImplNeedsSemicolon##TEST_FIXTURE_NAME {}
275 #define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
276 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
277 TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) { \
278 RunTest(true, false, true); \
280 class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
282 #define MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
283 TEST_F(TEST_FIXTURE_NAME, \
284 RunMultiThread_DelegatingRenderer_MainThreadPaint) { \
285 RunTest(true, true, false); \
287 class MultiThreadDelegatingNoImplNeedsSemicolon##TEST_FIXTURE_NAME {}
289 #define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
290 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
291 TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DelegatingRenderer_ImplSidePaint) { \
292 RunTest(true, true, true); \
294 class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
296 #define MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
297 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
298 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
300 #define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \
301 MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
302 MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
304 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( \
306 SINGLE_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
307 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
309 #define SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
310 SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
311 MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME)
313 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( \
315 SINGLE_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
316 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
318 #define SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
319 SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
320 MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
322 #define SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME) \
323 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
324 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(TEST_FIXTURE_NAME)
326 #define SINGLE_AND_MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \
327 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
328 SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
330 // Some tests want to control when notify ready for activation occurs,
331 // but this is not supported in the single-threaded case.
332 #define SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(TEST_FIXTURE_NAME) \
333 SINGLE_THREAD_NOIMPL_TEST_F(TEST_FIXTURE_NAME); \
334 MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME)
336 #endif // CC_TEST_LAYER_TREE_TEST_H_