tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

APZCTreeManagerTester.h (8704B)


      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 "APZTestAccess.h"
     16 #include "APZTestCommon.h"
     17 #include "gfxPlatform.h"
     18 #include "MockHitTester.h"
     19 #include "apz/src/WRHitTester.h"
     20 
     21 #include "mozilla/layers/APZSampler.h"
     22 #include "mozilla/layers/APZUpdater.h"
     23 #include "mozilla/layers/WebRenderScrollDataWrapper.h"
     24 
     25 class APZCTreeManagerTester : public APZCTesterBase {
     26 protected:
     27  APZCTreeManagerTester() : mHitTester(MakeUnique<WRHitTester>()) {}
     28 
     29  virtual void SetUp() {
     30    APZCTesterBase::SetUp();
     31 
     32    APZThreadUtils::SetThreadAssertionsEnabled(false);
     33    APZThreadUtils::SetControllerThread(NS_GetCurrentThread());
     34 
     35    manager = new TestAPZCTreeManager(mcc, std::move(mHitTester));
     36    updater = new APZUpdater(manager, false);
     37    sampler = new APZSampler(manager, false);
     38  }
     39 
     40  virtual void TearDown() {
     41    while (mcc->RunThroughDelayedTasks());
     42    manager->ClearTree();
     43    manager->ClearContentController();
     44 
     45    APZCTesterBase::TearDown();
     46  }
     47 
     48  /**
     49   * Sample animations once for all APZCs, 1 ms later than the last sample and
     50   * return whether there is still any active animations or not.
     51   */
     52  bool SampleAnimationsOnce() {
     53    const TimeDuration increment = TimeDuration::FromMilliseconds(1);
     54    ParentLayerPoint pointOut;
     55    AsyncTransform viewTransformOut;
     56    mcc->AdvanceBy(increment);
     57 
     58    bool activeAnimations = false;
     59 
     60    for (size_t i = 0; i < layers.GetLayerCount(); ++i) {
     61      if (TestAsyncPanZoomController* apzc = ApzcOf(layers[i])) {
     62        activeAnimations |=
     63            apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
     64      }
     65    }
     66 
     67    return activeAnimations;
     68  }
     69 
     70  // A convenience function for letting a test modify the frame metrics
     71  // stored on a particular layer.
     72  template <typename Callback>
     73  void ModifyFrameMetrics(WebRenderLayerScrollData* aLayer,
     74                          Callback aCallback) {
     75    MOZ_ASSERT(aLayer->GetScrollMetadataCount() == 1);
     76    ScrollMetadata& metadataRef =
     77        APZTestAccess::GetScrollMetadataMut(*aLayer, layers, 0);
     78    aCallback(metadataRef, metadataRef.GetMetrics());
     79  }
     80 
     81  // A convenience wrapper for manager->UpdateHitTestingTree().
     82  void UpdateHitTestingTree(uint32_t aPaintSequenceNumber = 0) {
     83    manager->UpdateHitTestingTree(WebRenderScrollDataWrapper{*updater, &layers},
     84                                  LayersId{0}, aPaintSequenceNumber);
     85  }
     86 
     87  void CreateScrollData(const char* aTreeShape,
     88                        const LayerIntRect* aVisibleRects = nullptr,
     89                        const gfx::Matrix4x4* aTransforms = nullptr) {
     90    layers = TestWRScrollData::Create(aTreeShape, *updater, aVisibleRects,
     91                                      aTransforms);
     92    root = layers[0];
     93  }
     94 
     95  void CreateMockHitTester() {
     96    mHitTester = MakeUnique<MockHitTester>();
     97    // Save a pointer in a separate variable, because SetUp() will
     98    // move the value out of mHitTester.
     99    mMockHitTester = static_cast<MockHitTester*>(mHitTester.get());
    100  }
    101  void QueueMockHitResult(ScrollableLayerGuid::ViewID aScrollId,
    102                          gfx::CompositorHitTestInfo aHitInfo =
    103                              gfx::CompositorHitTestFlags::eVisibleToHitTest) {
    104    QueueMockHitResult(ScrollableLayerGuid(LayersId{0}, 0, aScrollId),
    105                       aHitInfo);
    106  }
    107 
    108  // This overload allows customizing the LayersId as well.
    109  void QueueMockHitResult(ScrollableLayerGuid aGuid,
    110                          gfx::CompositorHitTestInfo aHitInfo =
    111                              gfx::CompositorHitTestFlags::eVisibleToHitTest) {
    112    MOZ_ASSERT(mMockHitTester);
    113    mMockHitTester->QueueHitResult(aGuid, aHitInfo);
    114  }
    115 
    116  RefPtr<TestAPZCTreeManager> manager;
    117  RefPtr<APZSampler> sampler;
    118  RefPtr<APZUpdater> updater;
    119  TestWRScrollData layers;
    120  WebRenderLayerScrollData* root = nullptr;
    121 
    122  UniquePtr<IAPZHitTester> mHitTester;
    123  MockHitTester* mMockHitTester = nullptr;
    124 
    125 protected:
    126  static ScrollMetadata BuildScrollMetadata(
    127      ScrollableLayerGuid::ViewID aScrollId, const CSSRect& aScrollableRect,
    128      const ParentLayerRect& aCompositionBounds) {
    129    ScrollMetadata metadata;
    130    FrameMetrics& metrics = metadata.GetMetrics();
    131    metrics.SetScrollId(aScrollId);
    132    // By convention in this test file, START_SCROLL_ID is the root, so mark it
    133    // as such.
    134    if (aScrollId == ScrollableLayerGuid::START_SCROLL_ID) {
    135      metadata.SetIsLayersIdRoot(true);
    136    }
    137    metrics.SetCompositionBounds(aCompositionBounds);
    138    metrics.SetScrollableRect(aScrollableRect);
    139    metrics.SetLayoutScrollOffset(CSSPoint(0, 0));
    140    metadata.SetPageScrollAmount(LayoutDeviceIntSize(50, 100));
    141    metadata.SetLineScrollAmount(LayoutDeviceIntSize(5, 10));
    142    return metadata;
    143  }
    144 
    145  void SetScrollMetadata(WebRenderLayerScrollData* aLayer,
    146                         const ScrollMetadata& aMetadata) {
    147    MOZ_ASSERT(aLayer->GetScrollMetadataCount() <= 1,
    148               "This function does not support multiple ScrollMetadata on a "
    149               "single layer");
    150    if (aLayer->GetScrollMetadataCount() == 0) {
    151      // Add new metrics
    152      aLayer->AppendScrollMetadata(layers, aMetadata);
    153    } else {
    154      // Overwrite existing metrics
    155      ModifyFrameMetrics(
    156          aLayer, [&](ScrollMetadata& aSm, FrameMetrics&) { aSm = aMetadata; });
    157    }
    158  }
    159 
    160  void SetScrollMetadata(WebRenderLayerScrollData* aLayer,
    161                         const nsTArray<ScrollMetadata>& aMetadata) {
    162    // The reason for this restriction is that WebRenderLayerScrollData does not
    163    // have an API to *remove* previous metadata.
    164    MOZ_ASSERT(aLayer->GetScrollMetadataCount() == 0,
    165               "This function can only be used on layers which do not yet have "
    166               "scroll metadata");
    167    for (const ScrollMetadata& metadata : aMetadata) {
    168      aLayer->AppendScrollMetadata(layers, metadata);
    169    }
    170  }
    171 
    172  void SetScrollableFrameMetrics(WebRenderLayerScrollData* aLayer,
    173                                 ScrollableLayerGuid::ViewID aScrollId,
    174                                 CSSRect aScrollableRect = CSSRect(-1, -1, -1,
    175                                                                   -1)) {
    176    auto localTransform = aLayer->GetTransformTyped() * AsyncTransformMatrix();
    177    ParentLayerIntRect compositionBounds = RoundedToInt(
    178        localTransform.TransformBounds(LayerRect(aLayer->GetVisibleRect())));
    179    ScrollMetadata metadata = BuildScrollMetadata(
    180        aScrollId, aScrollableRect, ParentLayerRect(compositionBounds));
    181    SetScrollMetadata(aLayer, metadata);
    182  }
    183 
    184  bool HasScrollableFrameMetrics(const WebRenderLayerScrollData* aLayer) const {
    185    for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
    186      if (aLayer->GetScrollMetadata(layers, i).GetMetrics().IsScrollable()) {
    187        return true;
    188      }
    189    }
    190    return false;
    191  }
    192 
    193  void SetScrollHandoff(WebRenderLayerScrollData* aChild,
    194                        WebRenderLayerScrollData* aParent) {
    195    ModifyFrameMetrics(aChild, [&](ScrollMetadata& aSm, FrameMetrics&) {
    196      aSm.SetScrollParentId(
    197          aParent->GetScrollMetadata(layers, 0).GetMetrics().GetScrollId());
    198    });
    199  }
    200 
    201  TestAsyncPanZoomController* ApzcOf(WebRenderLayerScrollData* aLayer) {
    202    EXPECT_EQ(1u, aLayer->GetScrollMetadataCount());
    203    return ApzcOf(aLayer, 0);
    204  }
    205 
    206  TestAsyncPanZoomController* ApzcOf(WebRenderLayerScrollData* aLayer,
    207                                     uint32_t aIndex) {
    208    EXPECT_LT(aIndex, aLayer->GetScrollMetadataCount());
    209    // Unlike Layer, WebRenderLayerScrollData does not store the associated
    210    // APZCs, so look it up using the tree manager instead.
    211    RefPtr<AsyncPanZoomController> apzc = manager->GetTargetAPZC(
    212        LayersId{0},
    213        aLayer->GetScrollMetadata(layers, aIndex).GetMetrics().GetScrollId());
    214    return (TestAsyncPanZoomController*)apzc.get();
    215  }
    216 
    217  void CreateSimpleScrollingLayer() {
    218    const char* treeShape = "x";
    219    LayerIntRect layerVisibleRect[] = {
    220        LayerIntRect(0, 0, 200, 200),
    221    };
    222    CreateScrollData(treeShape, layerVisibleRect);
    223    SetScrollableFrameMetrics(layers[0], ScrollableLayerGuid::START_SCROLL_ID,
    224                              CSSRect(0, 0, 500, 500));
    225  }
    226 };
    227 
    228 #endif  // mozilla_layers_APZCTreeManagerTester_h