Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/painting/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
  {
16
    return mFrame == aOther.mFrame && mPerFrameKey == aOther.mPerFrameKey;
17
  }
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
  {
32
  }
33
  DisplayItemHashEntry(DisplayItemHashEntry&&) = default;
34
35
  ~DisplayItemHashEntry() = default;
36
37
  KeyType GetKey() const { return mKey; }
38
  bool KeyEquals(KeyTypePointer aKey) const { return mKey == *aKey; }
39
40
  static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
41
  static PLDHashNumber HashKey(KeyTypePointer aKey)
42
  {
43
    if (!aKey)
44
      return 0;
45
46
    return mozilla::HashGeneric(aKey->mFrame, aKey->mPerFrameKey);
47
  }
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
0
{
60
0
  for (const T& i : aSpan) {
61
0
    if (i == aItem) {
62
0
      return true;
63
0
    }
64
0
  }
65
0
  return false;
66
0
}
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
0
  {
81
0
  }
Unexecuted instantiation: Index<OldListUnits>::Index()
Unexecuted instantiation: Index<MergedListUnits>::Index()
82
  explicit Index(size_t aVal)
83
    : val(aVal)
84
0
  {
85
0
  }
Unexecuted instantiation: Index<MergedListUnits>::Index(unsigned long)
Unexecuted instantiation: Index<OldListUnits>::Index(unsigned long)
86
87
  bool operator==(const Index<Units>& aOther) const
88
0
  {
89
0
    return val == aOther.val;
90
0
  }
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
0
  DirectedAcyclicGraph() = default;
102
  DirectedAcyclicGraph(DirectedAcyclicGraph&& aOther)
103
    : mNodesInfo(std::move(aOther.mNodesInfo))
104
    , mDirectPredecessorList(std::move(aOther.mDirectPredecessorList))
105
0
  {
106
0
  }
107
108
  DirectedAcyclicGraph& operator=(DirectedAcyclicGraph&& aOther)
109
0
  {
110
0
    mNodesInfo = std::move(aOther.mNodesInfo);
111
0
    mDirectPredecessorList = std::move(aOther.mDirectPredecessorList);
112
0
    return *this;
113
0
  }
114
115
  Index<T> AddNode(
116
    mozilla::Span<const Index<T>> aDirectPredecessors,
117
    const mozilla::Maybe<Index<T>>& aExtraPredecessor = mozilla::Nothing())
118
0
  {
119
0
    size_t index = mNodesInfo.Length();
120
0
    mNodesInfo.AppendElement(
121
0
      NodeInfo(mDirectPredecessorList.Length(), aDirectPredecessors.Length()));
122
0
    if (aExtraPredecessor &&
123
0
        !SpanContains(aDirectPredecessors, aExtraPredecessor.value())) {
124
0
      mNodesInfo.LastElement().mDirectPredecessorCount++;
125
0
      mDirectPredecessorList.SetCapacity(mDirectPredecessorList.Length() +
126
0
                                         aDirectPredecessors.Length() + 1);
127
0
      mDirectPredecessorList.AppendElements(aDirectPredecessors);
128
0
      mDirectPredecessorList.AppendElement(aExtraPredecessor.value());
129
0
    } else {
130
0
      mDirectPredecessorList.AppendElements(aDirectPredecessors);
131
0
    }
132
0
    return Index<T>(index);
133
0
  }
134
135
0
  size_t Length() { return mNodesInfo.Length(); }
Unexecuted instantiation: DirectedAcyclicGraph<OldListUnits>::Length()
Unexecuted instantiation: DirectedAcyclicGraph<MergedListUnits>::Length()
136
137
  mozilla::Span<Index<T>> GetDirectPredecessors(Index<T> aNodeIndex)
138
0
  {
139
0
    NodeInfo& node = mNodesInfo[aNodeIndex.val];
140
0
    return mozilla::MakeSpan(mDirectPredecessorList)
141
0
      .Subspan(node.mIndexInDirectPredecessorList,
142
0
               node.mDirectPredecessorCount);
143
0
  }
144
145
  template<typename OtherUnits>
146
  void EnsureCapacityFor(const DirectedAcyclicGraph<OtherUnits>& aOther)
147
0
  {
148
0
    mNodesInfo.SetCapacity(aOther.mNodesInfo.Length());
149
0
    mDirectPredecessorList.SetCapacity(aOther.mDirectPredecessorList.Length());
150
0
  }
151
152
  void Clear()
153
0
  {
154
0
    mNodesInfo.Clear();
155
0
    mDirectPredecessorList.Clear();
156
0
  }
157
158
  struct NodeInfo
159
  {
160
    NodeInfo(size_t aIndexInDirectPredecessorList,
161
             size_t aDirectPredecessorCount)
162
      : mIndexInDirectPredecessorList(aIndexInDirectPredecessorList)
163
      , mDirectPredecessorCount(aDirectPredecessorCount)
164
0
    {
165
0
    }
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
0
  {
184
0
  }
185
186
  void AddedToMergedList(MergedListIndex aIndex)
187
0
  {
188
0
    MOZ_ASSERT(!IsUsed());
189
0
    mUsed = true;
190
0
    mIndex = aIndex;
191
0
    mItem = nullptr;
192
0
  }
193
194
  void AddedMatchToMergedList(RetainedDisplayListBuilder* aBuilder,
195
                              MergedListIndex aIndex);
196
  void Discard(RetainedDisplayListBuilder* aBuilder,
197
               nsTArray<MergedListIndex>&& aDirectPredecessors);
198
0
  bool IsUsed() { return mUsed; }
199
200
  bool IsDiscarded()
201
0
  {
202
0
    MOZ_ASSERT(IsUsed());
203
0
    return mDiscarded;
204
0
  }
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_