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/. */
7 #ifndef RETAINEDDISPLAYLISTHELPERS_H_
8 #define RETAINEDDISPLAYLISTHELPERS_H_
10 #include "mozilla/Span.h"
11 #include "PLDHashTable.h"
17 struct DisplayItemKey
{
18 bool operator==(const DisplayItemKey
& aOther
) const {
19 return mFrame
== aOther
.mFrame
&& mPerFrameKey
== aOther
.mPerFrameKey
;
23 uint32_t mPerFrameKey
;
26 class DisplayItemHashEntry
: public PLDHashEntryHdr
{
28 typedef DisplayItemKey KeyType
;
29 typedef const DisplayItemKey
* KeyTypePointer
;
31 explicit DisplayItemHashEntry(KeyTypePointer aKey
) : mKey(*aKey
) {}
32 DisplayItemHashEntry(DisplayItemHashEntry
&&) = default;
34 ~DisplayItemHashEntry() = default;
36 KeyType
GetKey() const { return mKey
; }
37 bool KeyEquals(KeyTypePointer aKey
) const { return mKey
== *aKey
; }
39 static KeyTypePointer
KeyToPointer(KeyType
& aKey
) { return &aKey
; }
40 static PLDHashNumber
HashKey(KeyTypePointer aKey
) {
45 return mozilla::HashGeneric(aKey
->mFrame
, aKey
->mPerFrameKey
);
47 enum { ALLOW_MEMMOVE
= true };
53 bool SpanContains(mozilla::Span
<const T
>& aSpan
, T aItem
) {
54 for (const T
& i
: aSpan
) {
62 class OldListUnits
{};
63 class MergedListUnits
{};
65 template <typename Units
>
68 explicit Index(size_t aVal
) : val(aVal
) {
69 MOZ_RELEASE_ASSERT(aVal
< std::numeric_limits
<uint32_t>::max(),
70 "List index overflowed");
73 bool operator==(const Index
<Units
>& aOther
) const {
74 return val
== aOther
.val
;
79 typedef Index
<OldListUnits
> OldListIndex
;
80 typedef Index
<MergedListUnits
> MergedListIndex
;
83 class DirectedAcyclicGraph
{
85 DirectedAcyclicGraph() = default;
86 DirectedAcyclicGraph(DirectedAcyclicGraph
&& aOther
)
87 : mNodesInfo(std::move(aOther
.mNodesInfo
)),
88 mDirectPredecessorList(std::move(aOther
.mDirectPredecessorList
)) {}
90 DirectedAcyclicGraph
& operator=(DirectedAcyclicGraph
&& aOther
) {
91 mNodesInfo
= std::move(aOther
.mNodesInfo
);
92 mDirectPredecessorList
= std::move(aOther
.mDirectPredecessorList
);
97 mozilla::Span
<const Index
<T
>> aDirectPredecessors
,
98 const mozilla::Maybe
<Index
<T
>>& aExtraPredecessor
= mozilla::Nothing()) {
99 size_t index
= mNodesInfo
.Length();
100 mNodesInfo
.AppendElement(NodeInfo(mDirectPredecessorList
.Length(),
101 aDirectPredecessors
.Length()));
102 if (aExtraPredecessor
&&
103 !SpanContains(aDirectPredecessors
, aExtraPredecessor
.value())) {
104 mNodesInfo
.LastElement().mDirectPredecessorCount
++;
105 mDirectPredecessorList
.SetCapacity(mDirectPredecessorList
.Length() +
106 aDirectPredecessors
.Length() + 1);
107 mDirectPredecessorList
.AppendElements(aDirectPredecessors
);
108 mDirectPredecessorList
.AppendElement(aExtraPredecessor
.value());
110 mDirectPredecessorList
.AppendElements(aDirectPredecessors
);
112 return Index
<T
>(index
);
115 size_t Length() { return mNodesInfo
.Length(); }
117 mozilla::Span
<Index
<T
>> GetDirectPredecessors(Index
<T
> aNodeIndex
) {
118 NodeInfo
& node
= mNodesInfo
[aNodeIndex
.val
];
119 const auto span
= mozilla::Span
{mDirectPredecessorList
};
120 return span
.Subspan(node
.mIndexInDirectPredecessorList
,
121 node
.mDirectPredecessorCount
);
124 template <typename OtherUnits
>
125 void EnsureCapacityFor(const DirectedAcyclicGraph
<OtherUnits
>& aOther
) {
126 mNodesInfo
.SetCapacity(aOther
.mNodesInfo
.Length());
127 mDirectPredecessorList
.SetCapacity(aOther
.mDirectPredecessorList
.Length());
132 mDirectPredecessorList
.Clear();
136 NodeInfo(size_t aIndexInDirectPredecessorList
,
137 size_t aDirectPredecessorCount
)
138 : mIndexInDirectPredecessorList(aIndexInDirectPredecessorList
),
139 mDirectPredecessorCount(aDirectPredecessorCount
) {}
140 size_t mIndexInDirectPredecessorList
;
141 size_t mDirectPredecessorCount
;
144 nsTArray
<NodeInfo
> mNodesInfo
;
145 nsTArray
<Index
<T
>> mDirectPredecessorList
;
148 class RetainedDisplayListBuilder
;
152 explicit OldItemInfo(nsDisplayItem
* aItem
);
154 void AddedToMergedList(MergedListIndex aIndex
) {
155 MOZ_ASSERT(!IsUsed());
161 void AddedMatchToMergedList(RetainedDisplayListBuilder
* aBuilder
,
162 MergedListIndex aIndex
);
163 void Discard(RetainedDisplayListBuilder
* aBuilder
,
164 nsTArray
<MergedListIndex
>&& aDirectPredecessors
);
165 bool IsUsed() { return mUsed
; }
168 MOZ_ASSERT(IsUsed());
174 nsDisplayItem
* mItem
;
175 nsTArray
<MergedListIndex
> mDirectPredecessors
;
176 MergedListIndex mIndex
;
182 bool AnyContentAncestorModified(nsIFrame
* aFrame
,
183 nsIFrame
* aStopAtFrame
= nullptr);
185 } // namespace mozilla
187 #endif // RETAINEDDISPLAYLISTHELPERS_H_