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