Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/layers/APZTestData.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 mozilla_layers_APZTestData_h
8
#define mozilla_layers_APZTestData_h
9
10
#include <map>
11
12
#include "gfxPrefs.h"
13
#include "FrameMetrics.h"
14
#include "nsDebug.h"             // for NS_WARNING
15
#include "nsTArray.h"
16
#include "mozilla/Assertions.h"  // for MOZ_ASSERT
17
#include "mozilla/DebugOnly.h"   // for DebugOnly
18
#include "mozilla/GfxMessageUtils.h" // for ParamTraits specializations
19
#include "mozilla/ToString.h"    // for ToString
20
#include "mozilla/gfx/CompositorHitTestInfo.h"
21
#include "ipc/IPCMessageUtils.h"
22
#include "js/TypeDecls.h"
23
24
namespace mozilla {
25
namespace layers {
26
27
typedef uint32_t SequenceNumber;
28
29
/**
30
 * This structure is used to store information logged by various gecko
31
 * components for later examination by test code.
32
 * It contains a bucket for every paint (initiated on the client side),
33
 * and every repaint request (initiated on the compositor side by
34
 * AsyncPanZoomController::RequestContentRepait), which are identified by
35
 * sequence numbers, and within that, a set of arbitrary string key/value
36
 * pairs for every scrollable frame, identified by a scroll id.
37
 * There are two instances of this data structure for every content thread:
38
 * one on the client side and one of the compositor side.
39
 * It also contains a list of hit-test results for MozMouseHittest events
40
 * dispatched during testing. This list is only populated on the compositor
41
 * instance of this class.
42
 */
43
// TODO(botond):
44
//  - Improve warnings/asserts.
45
//  - Add ability to associate a repaint request triggered during a layers update
46
//    with the sequence number of the paint that caused the layers update.
47
class APZTestData {
48
  typedef FrameMetrics::ViewID ViewID;
49
  friend struct IPC::ParamTraits<APZTestData>;
50
  friend struct APZTestDataToJSConverter;
51
public:
52
0
  void StartNewPaint(SequenceNumber aSequenceNumber) {
53
0
    // We should never get more than one paint with the same sequence number.
54
0
    MOZ_ASSERT(mPaints.find(aSequenceNumber) == mPaints.end());
55
0
    mPaints.insert(DataStore::value_type(aSequenceNumber, Bucket()));
56
0
  }
57
  void LogTestDataForPaint(SequenceNumber aSequenceNumber,
58
                           ViewID aScrollId,
59
                           const std::string& aKey,
60
0
                           const std::string& aValue) {
61
0
    LogTestDataImpl(mPaints, aSequenceNumber, aScrollId, aKey, aValue);
62
0
  }
63
64
0
  void StartNewRepaintRequest(SequenceNumber aSequenceNumber) {
65
0
    typedef std::pair<DataStore::iterator, bool> InsertResultT;
66
0
    DebugOnly<InsertResultT> insertResult = mRepaintRequests.insert(DataStore::value_type(aSequenceNumber, Bucket()));
67
0
    MOZ_ASSERT(((InsertResultT&)insertResult).second, "Already have a repaint request with this sequence number");
68
0
  }
69
  void LogTestDataForRepaintRequest(SequenceNumber aSequenceNumber,
70
                                    ViewID aScrollId,
71
                                    const std::string& aKey,
72
0
                                    const std::string& aValue) {
73
0
    LogTestDataImpl(mRepaintRequests, aSequenceNumber, aScrollId, aKey, aValue);
74
0
  }
75
  void RecordHitResult(const ScreenPoint& aPoint,
76
                       const mozilla::gfx::CompositorHitTestInfo& aResult,
77
                       const ViewID& aScrollId)
78
0
  {
79
0
    mHitResults.AppendElement(HitResult { aPoint, aResult, aScrollId });
80
0
  }
81
82
  // Convert this object to a JS representation.
83
  bool ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext) const;
84
85
  // Use dummy derived structures wrapping the tyepdefs to work around a type
86
  // name length limit in MSVC.
87
  typedef std::map<std::string, std::string> ScrollFrameDataBase;
88
  struct ScrollFrameData : ScrollFrameDataBase {};
89
  typedef std::map<ViewID, ScrollFrameData> BucketBase;
90
  struct Bucket : BucketBase {};
91
  typedef std::map<SequenceNumber, Bucket> DataStoreBase;
92
  struct DataStore : DataStoreBase {};
93
  struct HitResult {
94
    ScreenPoint point;
95
    mozilla::gfx::CompositorHitTestInfo result;
96
    ViewID scrollId;
97
  };
98
private:
99
  DataStore mPaints;
100
  DataStore mRepaintRequests;
101
  nsTArray<HitResult> mHitResults;
102
103
  void LogTestDataImpl(DataStore& aDataStore,
104
                       SequenceNumber aSequenceNumber,
105
                       ViewID aScrollId,
106
                       const std::string& aKey,
107
0
                       const std::string& aValue) {
108
0
    auto bucketIterator = aDataStore.find(aSequenceNumber);
109
0
    if (bucketIterator == aDataStore.end()) {
110
0
      MOZ_ASSERT(false, "LogTestDataImpl called with nonexistent sequence number");
111
0
      return;
112
0
    }
113
0
    Bucket& bucket = bucketIterator->second;
114
0
    ScrollFrameData& scrollFrameData = bucket[aScrollId];  // create if doesn't exist
115
0
    MOZ_ASSERT(scrollFrameData.find(aKey) == scrollFrameData.end()
116
0
            || scrollFrameData[aKey] == aValue);
117
0
    scrollFrameData.insert(ScrollFrameData::value_type(aKey, aValue));
118
0
  }
119
};
120
121
// A helper class for logging data for a paint.
122
class APZPaintLogHelper {
123
public:
124
  APZPaintLogHelper(APZTestData* aTestData, SequenceNumber aPaintSequenceNumber)
125
    : mTestData(aTestData),
126
0
      mPaintSequenceNumber(aPaintSequenceNumber) {
127
0
    MOZ_ASSERT(!aTestData || gfxPrefs::APZTestLoggingEnabled(), "don't call me");
128
0
  }
129
130
  template <typename Value>
131
  void LogTestData(FrameMetrics::ViewID aScrollId,
132
                   const std::string& aKey,
133
0
                   const Value& aValue) const {
134
0
    if (mTestData) {  // avoid stringifying if mTestData == nullptr
135
0
      LogTestData(aScrollId, aKey, ToString(aValue));
136
0
    }
137
0
  }
Unexecuted instantiation: void mozilla::layers::APZPaintLogHelper::LogTestData<bool>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool const&) const
Unexecuted instantiation: void mozilla::layers::APZPaintLogHelper::LogTestData<unsigned long>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&) const
Unexecuted instantiation: void mozilla::layers::APZPaintLogHelper::LogTestData<mozilla::gfx::PointTyped<mozilla::ParentLayerPixel, float> >(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, mozilla::gfx::PointTyped<mozilla::ParentLayerPixel, float> const&) const
138
139
  void LogTestData(FrameMetrics::ViewID aScrollId,
140
                   const std::string& aKey,
141
0
                   const std::string& aValue) const {
142
0
    if (mTestData) {
143
0
      mTestData->LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
144
0
    }
145
0
  }
146
private:
147
  APZTestData* mTestData;
148
  SequenceNumber mPaintSequenceNumber;
149
};
150
151
} // namespace layers
152
} // namespace mozilla
153
154
namespace IPC {
155
156
template <>
157
struct ParamTraits<mozilla::layers::APZTestData>
158
{
159
  typedef mozilla::layers::APZTestData paramType;
160
161
  static void Write(Message* aMsg, const paramType& aParam)
162
0
  {
163
0
    WriteParam(aMsg, aParam.mPaints);
164
0
    WriteParam(aMsg, aParam.mRepaintRequests);
165
0
    WriteParam(aMsg, aParam.mHitResults);
166
0
  }
167
168
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
169
0
  {
170
0
    return (ReadParam(aMsg, aIter, &aResult->mPaints) &&
171
0
            ReadParam(aMsg, aIter, &aResult->mRepaintRequests) &&
172
0
            ReadParam(aMsg, aIter, &aResult->mHitResults));
173
0
  }
174
};
175
176
template <>
177
struct ParamTraits<mozilla::layers::APZTestData::ScrollFrameData>
178
  : ParamTraits<mozilla::layers::APZTestData::ScrollFrameDataBase> {};
179
180
template <>
181
struct ParamTraits<mozilla::layers::APZTestData::Bucket>
182
  : ParamTraits<mozilla::layers::APZTestData::BucketBase> {};
183
184
template <>
185
struct ParamTraits<mozilla::layers::APZTestData::DataStore>
186
  : ParamTraits<mozilla::layers::APZTestData::DataStoreBase> {};
187
188
template <>
189
struct ParamTraits<mozilla::layers::APZTestData::HitResult>
190
{
191
  typedef mozilla::layers::APZTestData::HitResult paramType;
192
193
  static void Write(Message* aMsg, const paramType& aParam)
194
0
  {
195
0
    WriteParam(aMsg, aParam.point);
196
0
    WriteParam(aMsg, aParam.result);
197
0
    WriteParam(aMsg, aParam.scrollId);
198
0
  }
199
200
  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
201
0
  {
202
0
    return (ReadParam(aMsg, aIter, &aResult->point) &&
203
0
            ReadParam(aMsg, aIter, &aResult->result) &&
204
0
            ReadParam(aMsg, aIter, &aResult->scrollId));
205
0
  }
206
};
207
208
} // namespace IPC
209
210
211
#endif /* mozilla_layers_APZTestData_h */