1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_APZCTreeManagerTester_h 8 #define mozilla_layers_APZCTreeManagerTester_h 9 10 /** 11 * Defines a test fixture used for testing multiple APZCs interacting in 12 * an APZCTreeManager. 13 */ 14 15 #include "APZTestCommon.h" 16 #include "gfxPlatform.h" 17 18 #include "mozilla/layers/APZSampler.h" 19 #include "mozilla/layers/APZUpdater.h" 20 21 class APZCTreeManagerTester : public APZCTesterBase { 22 protected: APZCTreeManagerTester()23 APZCTreeManagerTester() : mLayersOnly(false) {} 24 SetUp()25 virtual void SetUp() { 26 APZCTesterBase::SetUp(); 27 if (mLayersOnly) { 28 SCOPED_GFX_VAR_MAYBE_EMPLACE(mVarWebRender, UseWebRender, false); 29 SCOPED_GFX_VAR_MAYBE_EMPLACE(mVarSoftwareWebRender, UseSoftwareWebRender, 30 false); 31 } 32 33 APZThreadUtils::SetThreadAssertionsEnabled(false); 34 APZThreadUtils::SetControllerThread(NS_GetCurrentThread()); 35 36 manager = new TestAPZCTreeManager(mcc); 37 updater = new APZUpdater(manager, false); 38 sampler = new APZSampler(manager, false); 39 } 40 TearDown()41 virtual void TearDown() { 42 while (mcc->RunThroughDelayedTasks()) 43 ; 44 manager->ClearTree(); 45 manager->ClearContentController(); 46 mVarWebRender.reset(); 47 mVarSoftwareWebRender.reset(); 48 } 49 50 /** 51 * Sample animations once for all APZCs, 1 ms later than the last sample and 52 * return whether there is still any active animations or not. 53 */ SampleAnimationsOnce()54 bool SampleAnimationsOnce() { 55 const TimeDuration increment = TimeDuration::FromMilliseconds(1); 56 ParentLayerPoint pointOut; 57 AsyncTransform viewTransformOut; 58 mcc->AdvanceBy(increment); 59 60 bool activeAnimations = false; 61 62 for (const RefPtr<Layer>& layer : layers) { 63 if (TestAsyncPanZoomController* apzc = ApzcOf(layer)) { 64 activeAnimations |= 65 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut); 66 } 67 } 68 69 return activeAnimations; 70 } 71 72 // A convenience function for letting a test modify the frame metrics 73 // stored on a particular layer. The layer doesn't let us modify it in-place, 74 // so we take care of the copying in this function. 75 template <typename Callback> ModifyFrameMetrics(Layer * aLayer,Callback aCallback)76 void ModifyFrameMetrics(Layer* aLayer, Callback aCallback) { 77 ScrollMetadata metadata = aLayer->GetScrollMetadata(0); 78 aCallback(metadata, metadata.GetMetrics()); 79 aLayer->SetScrollMetadata(metadata); 80 } 81 82 // A convenience wrapper for manager->UpdateHitTestingTree(). 83 void UpdateHitTestingTree(uint32_t aPaintSequenceNumber = 0) { 84 manager->UpdateHitTestingTree(root, /* is first paint = */ false, 85 LayersId{0}, aPaintSequenceNumber); 86 } 87 88 nsTArray<RefPtr<Layer> > layers; 89 RefPtr<LayerManager> lm; 90 RefPtr<Layer> root; 91 92 RefPtr<TestAPZCTreeManager> manager; 93 RefPtr<APZSampler> sampler; 94 RefPtr<APZUpdater> updater; 95 96 SCOPED_GFX_VAR_MAYBE_TYPE(bool) mVarWebRender; 97 SCOPED_GFX_VAR_MAYBE_TYPE(bool) mVarSoftwareWebRender; 98 bool mLayersOnly; 99 100 protected: BuildScrollMetadata(ScrollableLayerGuid::ViewID aScrollId,const CSSRect & aScrollableRect,const ParentLayerRect & aCompositionBounds)101 static ScrollMetadata BuildScrollMetadata( 102 ScrollableLayerGuid::ViewID aScrollId, const CSSRect& aScrollableRect, 103 const ParentLayerRect& aCompositionBounds) { 104 ScrollMetadata metadata; 105 FrameMetrics& metrics = metadata.GetMetrics(); 106 metrics.SetScrollId(aScrollId); 107 // By convention in this test file, START_SCROLL_ID is the root, so mark it 108 // as such. 109 if (aScrollId == ScrollableLayerGuid::START_SCROLL_ID) { 110 metadata.SetIsLayersIdRoot(true); 111 } 112 metrics.SetCompositionBounds(aCompositionBounds); 113 metrics.SetScrollableRect(aScrollableRect); 114 metrics.SetLayoutScrollOffset(CSSPoint(0, 0)); 115 metadata.SetPageScrollAmount(LayoutDeviceIntSize(50, 100)); 116 metadata.SetLineScrollAmount(LayoutDeviceIntSize(5, 10)); 117 return metadata; 118 } 119 SetEventRegionsBasedOnBottommostMetrics(Layer * aLayer)120 static void SetEventRegionsBasedOnBottommostMetrics(Layer* aLayer) { 121 const FrameMetrics& metrics = aLayer->GetScrollMetadata(0).GetMetrics(); 122 CSSRect scrollableRect = metrics.GetScrollableRect(); 123 if (!scrollableRect.IsEqualEdges(CSSRect(-1, -1, -1, -1))) { 124 // The purpose of this is to roughly mimic what layout would do in the 125 // case of a scrollable frame with the event regions and clip. This lets 126 // us exercise the hit-testing code in APZCTreeManager 127 EventRegions er = aLayer->GetEventRegions(); 128 IntRect scrollRect = 129 RoundedToInt(scrollableRect * metrics.LayersPixelsPerCSSPixel()) 130 .ToUnknownRect(); 131 er.mHitRegion = nsIntRegion(IntRect( 132 RoundedToInt( 133 metrics.GetCompositionBounds().TopLeft().ToUnknownPoint()), 134 scrollRect.Size())); 135 aLayer->SetEventRegions(er); 136 } 137 } 138 139 static void SetScrollableFrameMetrics( 140 Layer* aLayer, ScrollableLayerGuid::ViewID aScrollId, 141 CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) { 142 ParentLayerIntRect compositionBounds = 143 RoundedToInt(aLayer->GetLocalTransformTyped().TransformBounds( 144 LayerRect(aLayer->GetVisibleRegion().GetBounds()))); 145 ScrollMetadata metadata = BuildScrollMetadata( 146 aScrollId, aScrollableRect, ParentLayerRect(compositionBounds)); 147 aLayer->SetScrollMetadata(metadata); 148 aLayer->SetClipRect(Some(compositionBounds)); 149 SetEventRegionsBasedOnBottommostMetrics(aLayer); 150 } 151 SetScrollHandoff(Layer * aChild,Layer * aParent)152 void SetScrollHandoff(Layer* aChild, Layer* aParent) { 153 ScrollMetadata metadata = aChild->GetScrollMetadata(0); 154 metadata.SetScrollParentId(aParent->GetFrameMetrics(0).GetScrollId()); 155 aChild->SetScrollMetadata(metadata); 156 } 157 ApzcOf(Layer * aLayer)158 static TestAsyncPanZoomController* ApzcOf(Layer* aLayer) { 159 EXPECT_EQ(1u, aLayer->GetScrollMetadataCount()); 160 return (TestAsyncPanZoomController*)aLayer->GetAsyncPanZoomController(0); 161 } 162 ApzcOf(Layer * aLayer,uint32_t aIndex)163 static TestAsyncPanZoomController* ApzcOf(Layer* aLayer, uint32_t aIndex) { 164 EXPECT_LT(aIndex, aLayer->GetScrollMetadataCount()); 165 return (TestAsyncPanZoomController*)aLayer->GetAsyncPanZoomController( 166 aIndex); 167 } 168 CreateSimpleScrollingLayer()169 void CreateSimpleScrollingLayer() { 170 const char* layerTreeSyntax = "t"; 171 nsIntRegion layerVisibleRegion[] = { 172 nsIntRegion(IntRect(0, 0, 200, 200)), 173 }; 174 root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, 175 layers); 176 SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, 177 CSSRect(0, 0, 500, 500)); 178 } 179 }; 180 181 #endif // mozilla_layers_APZCTreeManagerTester_h 182