From d33987f1232431a89a898238b0ea6f209f082efb Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Fri, 26 Apr 2019 05:10:44 +0000 Subject: [PATCH] Bug 1529892 - Extend APZTestData with free-form additional data not grouped by paint or scroll frame. r=kats,Ehsan Differential Revision: https://phabricator.services.mozilla.com/D28773 --HG-- extra : moz-landing-system : lando --- dom/webidl/APZTestData.webidl | 6 ++++++ gfx/layers/apz/testutil/APZTestData.cpp | 9 +++++++++ gfx/layers/apz/testutil/APZTestData.h | 12 +++++++++--- gfx/layers/client/ClientLayerManager.h | 5 +++++ gfx/layers/wr/WebRenderLayerManager.h | 6 ++++++ layout/base/nsLayoutUtils.cpp | 14 ++++++++++++++ layout/base/nsLayoutUtils.h | 15 +++++++++++++++ 7 files changed, 64 insertions(+), 3 deletions(-) diff --git a/dom/webidl/APZTestData.webidl b/dom/webidl/APZTestData.webidl index 29a371a6252b..cf02ff215409 100644 --- a/dom/webidl/APZTestData.webidl +++ b/dom/webidl/APZTestData.webidl @@ -55,11 +55,17 @@ dictionary APZHitResult { unsigned long long scrollId; }; +dictionary AdditionalDataEntry { + DOMString key; + DOMString value; +}; + // All the paints and repaint requests. This is the top-level data structure. dictionary APZTestData { sequence paints; sequence repaintRequests; sequence hitResults; + sequence additionalData; }; // A frame uniformity measurement for every scrollable layer diff --git a/gfx/layers/apz/testutil/APZTestData.cpp b/gfx/layers/apz/testutil/APZTestData.cpp index ddb377ef4559..365adf935d18 100644 --- a/gfx/layers/apz/testutil/APZTestData.cpp +++ b/gfx/layers/apz/testutil/APZTestData.cpp @@ -41,6 +41,8 @@ struct APZTestDataToJSConverter { ConvertBucket); ConvertList(aFrom.mHitResults, aOutTo.mHitResults.Construct(), ConvertHitResult); + ConvertMap(aFrom.mAdditionalData, aOutTo.mAdditionalData.Construct(), + ConvertAdditionalDataEntry); } static void ConvertBucket(const SequenceNumber& aKey, @@ -64,6 +66,13 @@ struct APZTestDataToJSConverter { ConvertString(aValue, aOutKeyValuePair.mValue.Construct()); } + static void ConvertAdditionalDataEntry( + const std::string& aKey, const std::string& aValue, + dom::AdditionalDataEntry& aOutKeyValuePair) { + ConvertString(aKey, aOutKeyValuePair.mKey.Construct()); + ConvertString(aValue, aOutKeyValuePair.mValue.Construct()); + } + static void ConvertString(const std::string& aFrom, nsString& aOutTo) { aOutTo = NS_ConvertUTF8toUTF16(aFrom.c_str(), aFrom.size()); } diff --git a/gfx/layers/apz/testutil/APZTestData.h b/gfx/layers/apz/testutil/APZTestData.h index e7ecf7cb7865..2fe1edc3e98b 100644 --- a/gfx/layers/apz/testutil/APZTestData.h +++ b/gfx/layers/apz/testutil/APZTestData.h @@ -43,8 +43,8 @@ typedef uint32_t SequenceNumber; // TODO(botond): // - Improve warnings/asserts. // - Add ability to associate a repaint request triggered during a layers -// update -// with the sequence number of the paint that caused the layers update. +// update with the sequence number of the paint that caused the layers +// update. class APZTestData { typedef ScrollableLayerGuid::ViewID ViewID; friend struct IPC::ParamTraits; @@ -78,11 +78,15 @@ class APZTestData { const ViewID& aScrollId) { mHitResults.AppendElement(HitResult{aPoint, aResult, aScrollId}); } + void RecordAdditionalData(const std::string& aKey, + const std::string& aValue) { + mAdditionalData[aKey] = aValue; + } // Convert this object to a JS representation. bool ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext) const; - // Use dummy derived structures wrapping the tyepdefs to work around a type + // Use dummy derived structures wrapping the typedefs to work around a type // name length limit in MSVC. typedef std::map ScrollFrameDataBase; struct ScrollFrameData : ScrollFrameDataBase {}; @@ -100,6 +104,8 @@ class APZTestData { DataStore mPaints; DataStore mRepaintRequests; nsTArray mHitResults; + // Additional free-form data that's not grouped paint or scroll frame. + std::map mAdditionalData; void LogTestDataImpl(DataStore& aDataStore, SequenceNumber aSequenceNumber, ViewID aScrollId, const std::string& aKey, diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 4e8080af3f23..891a55156b95 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -224,6 +224,11 @@ class ClientLayerManager final : public LayerManager, mApzTestData.LogTestDataForRepaintRequest(aSequenceNumber, aScrollId, aKey, aValue); } + void LogAdditionalTestData(const std::string& aKey, + const std::string& aValue) { + MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me"); + mApzTestData.RecordAdditionalData(aKey, aValue); + } // Get the content-side APZ test data for reading. For writing, use the // LogTestData...() functions. diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index cae88990c59e..3f42acc58cde 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -158,6 +158,12 @@ class WebRenderLayerManager final : public LayerManager { mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue); } + void LogAdditionalTestData(const std::string& aKey, + const std::string& aValue) { + MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me"); + mApzTestData.RecordAdditionalData(aKey, aValue); + } + // See equivalent function in ClientLayerManager const APZTestData& GetAPZTestData() const { return mApzTestData; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 0505b4a298a0..c529f3b71b47 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8591,6 +8591,20 @@ void nsLayoutUtils::DoLogTestDataForPaint(LayerManager* aManager, } } +void nsLayoutUtils::LogAdditionalTestData(nsDisplayListBuilder* aBuilder, + const std::string& aKey, + const std::string& aValue) { + LayerManager* manager = aBuilder->GetWidgetLayerManager(nullptr); + if (!manager) { + return; + } + if (ClientLayerManager* clm = manager->AsClientLayerManager()) { + clm->LogAdditionalTestData(aKey, aValue); + } else if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) { + wrlm->LogAdditionalTestData(aKey, aValue); + } +} + /* static */ bool nsLayoutUtils::IsAPZTestLoggingEnabled() { return gfxPrefs::APZTestLoggingEnabled(); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 5d91a7e668a6..502727b96dec 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2728,6 +2728,21 @@ class nsLayoutUtils { */ static bool ShouldDisableApzForElement(nsIContent* aContent); + /** + * Log a key/value pair as "additional data" (not associated with a paint) + * for APZ testing. + * While the data is not associated with a paint, the APZTestData object + * is still owned by {Client,WebRender}LayerManager, so we need to be passed + * something from which we can derive the layer manager. + * This function takes a display list builder as the object to derive the + * layer manager from, to facilitate logging test data during display list + * building, but other overloads that take other objects could be added if + * desired. + */ + static void LogAdditionalTestData(nsDisplayListBuilder* aBuilder, + const std::string& aKey, + const std::string& aValue); + /** * Log a key/value pair for APZ testing during a paint. * @param aManager The data will be written to the APZTestData associated