Home | History | Annotate | Download | only in test
      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