tor-browser

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

RetainedDisplayListHelpers.h (5446B)


      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 RETAINEDDISPLAYLISTHELPERS_H_
      8 #define RETAINEDDISPLAYLISTHELPERS_H_
      9 
     10 #include "PLDHashTable.h"
     11 #include "mozilla/Span.h"
     12 
     13 class nsIFrame;
     14 
     15 namespace mozilla {
     16 
     17 struct DisplayItemKey {
     18  bool operator==(const DisplayItemKey&) const = default;
     19 
     20  nsIFrame* mFrame;
     21  uint32_t mPerFrameKey;
     22 };
     23 
     24 class DisplayItemHashEntry : public PLDHashEntryHdr {
     25 public:
     26  typedef DisplayItemKey KeyType;
     27  typedef const DisplayItemKey* KeyTypePointer;
     28 
     29  explicit DisplayItemHashEntry(KeyTypePointer aKey) : mKey(*aKey) {}
     30  DisplayItemHashEntry(DisplayItemHashEntry&&) = default;
     31 
     32  ~DisplayItemHashEntry() = default;
     33 
     34  KeyType GetKey() const { return mKey; }
     35  bool KeyEquals(KeyTypePointer aKey) const { return mKey == *aKey; }
     36 
     37  static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
     38  static PLDHashNumber HashKey(KeyTypePointer aKey) {
     39    if (!aKey) {
     40      return 0;
     41    }
     42 
     43    return mozilla::HashGeneric(aKey->mFrame, aKey->mPerFrameKey);
     44  }
     45  enum { ALLOW_MEMMOVE = true };
     46 
     47  DisplayItemKey mKey;
     48 };
     49 
     50 template <typename T>
     51 bool SpanContains(mozilla::Span<const T>& aSpan, T aItem) {
     52  for (const T& i : aSpan) {
     53    if (i == aItem) {
     54      return true;
     55    }
     56  }
     57  return false;
     58 }
     59 
     60 class OldListUnits {};
     61 class MergedListUnits {};
     62 
     63 template <typename Units>
     64 struct Index {
     65  Index() = default;
     66  explicit Index(size_t aVal) : val(aVal) {
     67    MOZ_RELEASE_ASSERT(aVal < std::numeric_limits<uint32_t>::max(),
     68                       "List index overflowed");
     69  }
     70 
     71  bool operator==(const Index<Units>&) const = default;
     72 
     73  uint32_t val = 0;
     74 };
     75 typedef Index<OldListUnits> OldListIndex;
     76 typedef Index<MergedListUnits> MergedListIndex;
     77 
     78 template <typename T>
     79 class DirectedAcyclicGraph {
     80 public:
     81  DirectedAcyclicGraph() = default;
     82  DirectedAcyclicGraph(DirectedAcyclicGraph&& aOther)
     83      : mNodesInfo(std::move(aOther.mNodesInfo)),
     84        mDirectPredecessorList(std::move(aOther.mDirectPredecessorList)) {}
     85 
     86  DirectedAcyclicGraph& operator=(DirectedAcyclicGraph&& aOther) {
     87    mNodesInfo = std::move(aOther.mNodesInfo);
     88    mDirectPredecessorList = std::move(aOther.mDirectPredecessorList);
     89    return *this;
     90  }
     91 
     92  Index<T> AddNode(
     93      mozilla::Span<const Index<T>> aDirectPredecessors,
     94      const mozilla::Maybe<Index<T>>& aExtraPredecessor = mozilla::Nothing()) {
     95    size_t index = mNodesInfo.Length();
     96    mNodesInfo.AppendElement(NodeInfo(mDirectPredecessorList.Length(),
     97                                      aDirectPredecessors.Length()));
     98    if (aExtraPredecessor &&
     99        !SpanContains(aDirectPredecessors, aExtraPredecessor.value())) {
    100      mNodesInfo.LastElement().mDirectPredecessorCount++;
    101      mDirectPredecessorList.SetCapacity(mDirectPredecessorList.Length() +
    102                                         aDirectPredecessors.Length() + 1);
    103      mDirectPredecessorList.AppendElements(aDirectPredecessors);
    104      mDirectPredecessorList.AppendElement(aExtraPredecessor.value());
    105    } else {
    106      mDirectPredecessorList.AppendElements(aDirectPredecessors);
    107    }
    108    return Index<T>(index);
    109  }
    110 
    111  size_t Length() { return mNodesInfo.Length(); }
    112 
    113  mozilla::Span<Index<T>> GetDirectPredecessors(Index<T> aNodeIndex) {
    114    NodeInfo& node = mNodesInfo[aNodeIndex.val];
    115    const auto span = mozilla::Span{mDirectPredecessorList};
    116    return span.Subspan(node.mIndexInDirectPredecessorList,
    117                        node.mDirectPredecessorCount);
    118  }
    119 
    120  template <typename OtherUnits>
    121  void EnsureCapacityFor(const DirectedAcyclicGraph<OtherUnits>& aOther) {
    122    mNodesInfo.SetCapacity(aOther.mNodesInfo.Length());
    123    mDirectPredecessorList.SetCapacity(aOther.mDirectPredecessorList.Length());
    124  }
    125 
    126  void Clear() {
    127    mNodesInfo.Clear();
    128    mDirectPredecessorList.Clear();
    129  }
    130 
    131  struct NodeInfo {
    132    NodeInfo(size_t aIndexInDirectPredecessorList,
    133             size_t aDirectPredecessorCount)
    134        : mIndexInDirectPredecessorList(aIndexInDirectPredecessorList),
    135          mDirectPredecessorCount(aDirectPredecessorCount) {}
    136    size_t mIndexInDirectPredecessorList;
    137    size_t mDirectPredecessorCount;
    138  };
    139 
    140  nsTArray<NodeInfo> mNodesInfo;
    141  nsTArray<Index<T>> mDirectPredecessorList;
    142 };
    143 
    144 class RetainedDisplayListBuilder;
    145 class nsDisplayItem;
    146 
    147 struct OldItemInfo {
    148  explicit OldItemInfo(nsDisplayItem* aItem);
    149 
    150  void AddedToMergedList(MergedListIndex aIndex) {
    151    MOZ_ASSERT(!IsUsed());
    152    mUsed = true;
    153    mIndex = aIndex;
    154    mItem = nullptr;
    155  }
    156 
    157  void AddedMatchToMergedList(RetainedDisplayListBuilder* aBuilder,
    158                              MergedListIndex aIndex);
    159  void Discard(RetainedDisplayListBuilder* aBuilder,
    160               nsTArray<MergedListIndex>&& aDirectPredecessors);
    161  bool IsUsed() { return mUsed; }
    162 
    163  bool IsDiscarded() {
    164    MOZ_ASSERT(IsUsed());
    165    return mDiscarded;
    166  }
    167 
    168  bool IsChanged();
    169 
    170  nsDisplayItem* mItem;
    171  nsTArray<MergedListIndex> mDirectPredecessors;
    172  MergedListIndex mIndex;
    173  bool mUsed;
    174  bool mDiscarded;
    175  bool mOwnsItem;
    176 };
    177 
    178 bool AnyContentAncestorModified(nsIFrame* aFrame,
    179                                nsIFrame* aStopAtFrame = nullptr);
    180 
    181 }  // namespace mozilla
    182 
    183 #endif  // RETAINEDDISPLAYLISTHELPERS_H_