Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_layers_APZTestData_h
7 : #define mozilla_layers_APZTestData_h
8 :
9 : #include <map>
10 :
11 : #include "gfxPrefs.h"
12 : #include "FrameMetrics.h"
13 : #include "nsDebug.h" // for NS_WARNING
14 : #include "mozilla/Assertions.h" // for MOZ_ASSERT
15 : #include "mozilla/DebugOnly.h" // for DebugOnly
16 : #include "mozilla/ToString.h" // for ToString
17 : #include "ipc/IPCMessageUtils.h"
18 : #include "js/TypeDecls.h"
19 :
20 : namespace mozilla {
21 : namespace layers {
22 :
23 : typedef uint32_t SequenceNumber;
24 :
25 : /**
26 : * This structure is used to store information logged by various gecko
27 : * components for later examination by test code.
28 : * It consists of a bucket for every paint (initiated on the client side),
29 : * and every repaint request (initiated on the compositor side by
30 : * AsyncPanZoomController::RequestContentRepait), which are identified by
31 : * sequence numbers, and within that, a set of arbitrary string key/value
32 : * pairs for every scrollable frame, identified by a scroll id.
33 : * There are two instances of this data structure for every content thread:
34 : * one on the client side and one of the compositor side.
35 : */
36 : // TODO(botond):
37 : // - Improve warnings/asserts.
38 : // - Add ability to associate a repaint request triggered during a layers update
39 : // with the sequence number of the paint that caused the layers update.
40 4 : class APZTestData {
41 : typedef FrameMetrics::ViewID ViewID;
42 : friend struct IPC::ParamTraits<APZTestData>;
43 : friend struct APZTestDataToJSConverter;
44 : public:
45 0 : void StartNewPaint(SequenceNumber aSequenceNumber) {
46 : // We should never get more than one paint with the same sequence number.
47 0 : MOZ_ASSERT(mPaints.find(aSequenceNumber) == mPaints.end());
48 0 : mPaints.insert(DataStore::value_type(aSequenceNumber, Bucket()));
49 0 : }
50 0 : void LogTestDataForPaint(SequenceNumber aSequenceNumber,
51 : ViewID aScrollId,
52 : const std::string& aKey,
53 : const std::string& aValue) {
54 0 : LogTestDataImpl(mPaints, aSequenceNumber, aScrollId, aKey, aValue);
55 0 : }
56 :
57 0 : void StartNewRepaintRequest(SequenceNumber aSequenceNumber) {
58 : typedef std::pair<DataStore::iterator, bool> InsertResultT;
59 0 : DebugOnly<InsertResultT> insertResult = mRepaintRequests.insert(DataStore::value_type(aSequenceNumber, Bucket()));
60 0 : MOZ_ASSERT(((InsertResultT&)insertResult).second, "Already have a repaint request with this sequence number");
61 0 : }
62 : void LogTestDataForRepaintRequest(SequenceNumber aSequenceNumber,
63 : ViewID aScrollId,
64 : const std::string& aKey,
65 : const std::string& aValue) {
66 : LogTestDataImpl(mRepaintRequests, aSequenceNumber, aScrollId, aKey, aValue);
67 : }
68 :
69 : // Convert this object to a JS representation.
70 : bool ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext) const;
71 :
72 : // Use dummy derived structures wrapping the tyepdefs to work around a type
73 : // name length limit in MSVC.
74 : typedef std::map<std::string, std::string> ScrollFrameDataBase;
75 0 : struct ScrollFrameData : ScrollFrameDataBase {};
76 : typedef std::map<ViewID, ScrollFrameData> BucketBase;
77 0 : struct Bucket : BucketBase {};
78 : typedef std::map<SequenceNumber, Bucket> DataStoreBase;
79 8 : struct DataStore : DataStoreBase {};
80 : private:
81 : DataStore mPaints;
82 : DataStore mRepaintRequests;
83 :
84 0 : void LogTestDataImpl(DataStore& aDataStore,
85 : SequenceNumber aSequenceNumber,
86 : ViewID aScrollId,
87 : const std::string& aKey,
88 : const std::string& aValue) {
89 0 : MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
90 0 : auto bucketIterator = aDataStore.find(aSequenceNumber);
91 0 : if (bucketIterator == aDataStore.end()) {
92 0 : MOZ_ASSERT(false, "LogTestDataImpl called with nonexistent sequence number");
93 : return;
94 : }
95 0 : Bucket& bucket = bucketIterator->second;
96 0 : ScrollFrameData& scrollFrameData = bucket[aScrollId]; // create if doesn't exist
97 0 : MOZ_ASSERT(scrollFrameData.find(aKey) == scrollFrameData.end()
98 : || scrollFrameData[aKey] == aValue);
99 0 : scrollFrameData.insert(ScrollFrameData::value_type(aKey, aValue));
100 0 : }
101 : };
102 :
103 : // A helper class for logging data for a paint.
104 : class APZPaintLogHelper {
105 : public:
106 28 : APZPaintLogHelper(APZTestData* aTestData, SequenceNumber aPaintSequenceNumber)
107 28 : : mTestData(aTestData),
108 28 : mPaintSequenceNumber(aPaintSequenceNumber)
109 28 : {}
110 :
111 : template <typename Value>
112 54 : void LogTestData(FrameMetrics::ViewID aScrollId,
113 : const std::string& aKey,
114 : const Value& aValue) const {
115 54 : if (mTestData) { // avoid stringifying if mTestData == nullptr
116 0 : LogTestData(aScrollId, aKey, ToString(aValue));
117 : }
118 54 : }
119 :
120 0 : void LogTestData(FrameMetrics::ViewID aScrollId,
121 : const std::string& aKey,
122 : const std::string& aValue) const {
123 0 : if (mTestData) {
124 0 : mTestData->LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
125 : }
126 0 : }
127 : private:
128 : APZTestData* mTestData;
129 : SequenceNumber mPaintSequenceNumber;
130 : };
131 :
132 : } // namespace layers
133 : } // namespace mozilla
134 :
135 : namespace IPC {
136 :
137 : template <>
138 : struct ParamTraits<mozilla::layers::APZTestData>
139 : {
140 : typedef mozilla::layers::APZTestData paramType;
141 :
142 0 : static void Write(Message* aMsg, const paramType& aParam)
143 : {
144 0 : WriteParam(aMsg, aParam.mPaints);
145 0 : WriteParam(aMsg, aParam.mRepaintRequests);
146 0 : }
147 :
148 0 : static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
149 : {
150 0 : return (ReadParam(aMsg, aIter, &aResult->mPaints) &&
151 0 : ReadParam(aMsg, aIter, &aResult->mRepaintRequests));
152 : }
153 : };
154 :
155 : template <>
156 : struct ParamTraits<mozilla::layers::APZTestData::ScrollFrameData>
157 : : ParamTraits<mozilla::layers::APZTestData::ScrollFrameDataBase> {};
158 :
159 : template <>
160 : struct ParamTraits<mozilla::layers::APZTestData::Bucket>
161 : : ParamTraits<mozilla::layers::APZTestData::BucketBase> {};
162 :
163 : template <>
164 : struct ParamTraits<mozilla::layers::APZTestData::DataStore>
165 : : ParamTraits<mozilla::layers::APZTestData::DataStoreBase> {};
166 :
167 : } // namespace IPC
168 :
169 :
170 : #endif /* mozilla_layers_APZTestData_h */
|