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