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 "PLDHashTable.h"
12 struct DisplayItemKey
{
13 bool operator==(const DisplayItemKey
& aOther
) const {
14 return mFrame
== aOther
.mFrame
&& mPerFrameKey
== aOther
.mPerFrameKey
;
18 uint32_t mPerFrameKey
;
21 class DisplayItemHashEntry
: public PLDHashEntryHdr
{
23 typedef DisplayItemKey KeyType
;
24 typedef const DisplayItemKey
* KeyTypePointer
;
26 explicit DisplayItemHashEntry(KeyTypePointer aKey
) : mKey(*aKey
) {}
27 DisplayItemHashEntry(DisplayItemHashEntry
&&) = default;
29 ~DisplayItemHashEntry() = default;
31 KeyType
GetKey() const { return mKey
; }
32 bool KeyEquals(KeyTypePointer aKey
) const { return mKey
== *aKey
; }
34 static KeyTypePointer
KeyToPointer(KeyType
& aKey
) { return &aKey
; }
35 static PLDHashNumber
HashKey(KeyTypePointer aKey
) {
40 return mozilla::HashGeneric(aKey
->mFrame
, aKey
->mPerFrameKey
);
42 enum { ALLOW_MEMMOVE
= true };
48 bool SpanContains(mozilla::Span
<const T
>& aSpan
, T aItem
) {
49 for (const T
& i
: aSpan
) {
57 class OldListUnits
{};
58 class MergedListUnits
{};
60 template <typename Units
>
63 explicit Index(size_t aVal
) : val(aVal
) {
64 MOZ_RELEASE_ASSERT(aVal
< std::numeric_limits
<uint32_t>::max(),
65 "List index overflowed");
68 bool operator==(const Index
<Units
>& aOther
) const {
69 return val
== aOther
.val
;
74 typedef Index
<OldListUnits
> OldListIndex
;
75 typedef Index
<MergedListUnits
> MergedListIndex
;
78 class DirectedAcyclicGraph
{
80 DirectedAcyclicGraph() = default;
81 DirectedAcyclicGraph(DirectedAcyclicGraph
&& aOther
)
82 : mNodesInfo(std::move(aOther
.mNodesInfo
)),
83 mDirectPredecessorList(std::move(aOther
.mDirectPredecessorList
)) {}
85 DirectedAcyclicGraph
& operator=(DirectedAcyclicGraph
&& aOther
) {
86 mNodesInfo
= std::move(aOther
.mNodesInfo
);
87 mDirectPredecessorList
= std::move(aOther
.mDirectPredecessorList
);
92 mozilla::Span
<const Index
<T
>> aDirectPredecessors
,
93 const mozilla::Maybe
<Index
<T
>>& aExtraPredecessor
= mozilla::Nothing()) {
94 size_t index
= mNodesInfo
.Length();
95 mNodesInfo
.AppendElement(NodeInfo(mDirectPredecessorList
.Length(),
96 aDirectPredecessors
.Length()));
97 if (aExtraPredecessor
&&
98 !SpanContains(aDirectPredecessors
, aExtraPredecessor
.value())) {
99 mNodesInfo
.LastElement().mDirectPredecessorCount
++;
100 mDirectPredecessorList
.SetCapacity(mDirectPredecessorList
.Length() +
101 aDirectPredecessors
.Length() + 1);
102 mDirectPredecessorList
.AppendElements(aDirectPredecessors
);
103 mDirectPredecessorList
.AppendElement(aExtraPredecessor
.value());
105 mDirectPredecessorList
.AppendElements(aDirectPredecessors
);
107 return Index
<T
>(index
);
110 size_t Length() { return mNodesInfo
.Length(); }
112 mozilla::Span
<Index
<T
>> GetDirectPredecessors(Index
<T
> aNodeIndex
) {
113 NodeInfo
& node
= mNodesInfo
[aNodeIndex
.val
];
114 return mozilla::MakeSpan(mDirectPredecessorList
)
115 .Subspan(node
.mIndexInDirectPredecessorList
,
116 node
.mDirectPredecessorCount
);
119 template <typename OtherUnits
>
120 void EnsureCapacityFor(const DirectedAcyclicGraph
<OtherUnits
>& aOther
) {
121 mNodesInfo
.SetCapacity(aOther
.mNodesInfo
.Length());
122 mDirectPredecessorList
.SetCapacity(aOther
.mDirectPredecessorList
.Length());
127 mDirectPredecessorList
.Clear();
131 NodeInfo(size_t aIndexInDirectPredecessorList
,
132 size_t aDirectPredecessorCount
)
133 : mIndexInDirectPredecessorList(aIndexInDirectPredecessorList
),
134 mDirectPredecessorCount(aDirectPredecessorCount
) {}
135 size_t mIndexInDirectPredecessorList
;
136 size_t mDirectPredecessorCount
;
139 nsTArray
<NodeInfo
> mNodesInfo
;
140 nsTArray
<Index
<T
>> mDirectPredecessorList
;
143 struct RetainedDisplayListBuilder
;
147 explicit OldItemInfo(nsDisplayItem
* aItem
);
149 void AddedToMergedList(MergedListIndex aIndex
) {
150 MOZ_ASSERT(!IsUsed());
156 void AddedMatchToMergedList(RetainedDisplayListBuilder
* aBuilder
,
157 MergedListIndex aIndex
);
158 void Discard(RetainedDisplayListBuilder
* aBuilder
,
159 nsTArray
<MergedListIndex
>&& aDirectPredecessors
);
160 bool IsUsed() { return mUsed
; }
163 MOZ_ASSERT(IsUsed());
169 nsDisplayItem
* mItem
;
170 nsTArray
<MergedListIndex
> mDirectPredecessors
;
171 MergedListIndex mIndex
;
177 bool AnyContentAncestorModified(nsIFrame
* aFrame
,
178 nsIFrame
* aStopAtFrame
= nullptr);
180 #endif // RETAINEDDISPLAYLISTHELPERS_H_