Bug 1529892 - Extend APZTestData with free-form additional data not grouped by paint or scroll frame. r=kats,Ehsan
authorBotond Ballo <botond@mozilla.com>
Fri, 26 Apr 2019 05:10:44 +0000
changeset 530237 dfe53274deb8405d428ec93212b5c61208cff071
parent 530236 2e7759e843acce4d577a8fe74e10670c098c5d54
child 530238 eef11daea095e66f46d9f37382b1fd57f1abf85b
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, Ehsan
bugs1529892
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
dom/webidl/APZTestData.webidl
gfx/layers/apz/testutil/APZTestData.cpp
gfx/layers/apz/testutil/APZTestData.h
gfx/layers/client/ClientLayerManager.h
gfx/layers/wr/WebRenderLayerManager.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/dom/webidl/APZTestData.webidl
+++ b/dom/webidl/APZTestData.webidl
@@ -50,21 +50,27 @@ namespace APZHitResultFlags {
 
 dictionary APZHitResult {
   float screenX;
   float screenY;
   unsigned short hitResult; // combination of the APZHitResultFlags.* flags
   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<APZBucket> paints;
   sequence<APZBucket> repaintRequests;
   sequence<APZHitResult> hitResults;
+  sequence<AdditionalDataEntry> additionalData;
 };
 
 // A frame uniformity measurement for every scrollable layer
 dictionary FrameUniformity {
   unsigned long layerAddress;
   float frameUniformity;
 };
 
--- a/gfx/layers/apz/testutil/APZTestData.cpp
+++ b/gfx/layers/apz/testutil/APZTestData.cpp
@@ -36,16 +36,18 @@ struct APZTestDataToJSConverter {
 
   static void ConvertAPZTestData(const APZTestData& aFrom,
                                  dom::APZTestData& aOutTo) {
     ConvertMap(aFrom.mPaints, aOutTo.mPaints.Construct(), ConvertBucket);
     ConvertMap(aFrom.mRepaintRequests, aOutTo.mRepaintRequests.Construct(),
                ConvertBucket);
     ConvertList(aFrom.mHitResults, aOutTo.mHitResults.Construct(),
                 ConvertHitResult);
+    ConvertMap(aFrom.mAdditionalData, aOutTo.mAdditionalData.Construct(),
+               ConvertAdditionalDataEntry);
   }
 
   static void ConvertBucket(const SequenceNumber& aKey,
                             const APZTestData::Bucket& aValue,
                             dom::APZBucket& aOutKeyValuePair) {
     aOutKeyValuePair.mSequenceNumber.Construct() = aKey;
     ConvertMap(aValue, aOutKeyValuePair.mScrollFrames.Construct(),
                ConvertScrollFrameData);
@@ -59,16 +61,23 @@ struct APZTestDataToJSConverter {
   }
 
   static void ConvertEntry(const std::string& aKey, const std::string& aValue,
                            dom::ScrollFrameDataEntry& aOutKeyValuePair) {
     ConvertString(aKey, aOutKeyValuePair.mKey.Construct());
     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());
   }
 
   static void ConvertHitResult(const APZTestData::HitResult& aResult,
                                dom::APZHitResult& aOutHitResult) {
     aOutHitResult.mScreenX.Construct() = aResult.point.x;
     aOutHitResult.mScreenY.Construct() = aResult.point.y;
--- a/gfx/layers/apz/testutil/APZTestData.h
+++ b/gfx/layers/apz/testutil/APZTestData.h
@@ -38,18 +38,18 @@ typedef uint32_t SequenceNumber;
  * one on the client side and one of the compositor side.
  * It also contains a list of hit-test results for MozMouseHittest events
  * dispatched during testing. This list is only populated on the compositor
  * instance of this class.
  */
 // 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<APZTestData>;
   friend struct APZTestDataToJSConverter;
 
  public:
   void StartNewPaint(SequenceNumber aSequenceNumber) {
     // We should never get more than one paint with the same sequence number.
@@ -73,21 +73,25 @@ class APZTestData {
                                     const std::string& aValue) {
     LogTestDataImpl(mRepaintRequests, aSequenceNumber, aScrollId, aKey, aValue);
   }
   void RecordHitResult(const ScreenPoint& aPoint,
                        const mozilla::gfx::CompositorHitTestInfo& aResult,
                        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<std::string, std::string> ScrollFrameDataBase;
   struct ScrollFrameData : ScrollFrameDataBase {};
   typedef std::map<ViewID, ScrollFrameData> BucketBase;
   struct Bucket : BucketBase {};
   typedef std::map<SequenceNumber, Bucket> DataStoreBase;
   struct DataStore : DataStoreBase {};
   struct HitResult {
@@ -95,16 +99,18 @@ class APZTestData {
     mozilla::gfx::CompositorHitTestInfo result;
     ViewID scrollId;
   };
 
  private:
   DataStore mPaints;
   DataStore mRepaintRequests;
   nsTArray<HitResult> mHitResults;
+  // Additional free-form data that's not grouped paint or scroll frame.
+  std::map<std::string, std::string> mAdditionalData;
 
   void LogTestDataImpl(DataStore& aDataStore, SequenceNumber aSequenceNumber,
                        ViewID aScrollId, const std::string& aKey,
                        const std::string& aValue) {
     auto bucketIterator = aDataStore.find(aSequenceNumber);
     if (bucketIterator == aDataStore.end()) {
       MOZ_ASSERT(false,
                  "LogTestDataImpl called with nonexistent sequence number");
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -219,16 +219,21 @@ class ClientLayerManager final : public 
   void LogTestDataForRepaintRequest(SequenceNumber aSequenceNumber,
                                     ScrollableLayerGuid::ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue) {
     MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
     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.
   const APZTestData& GetAPZTestData() const { return mApzTestData; }
 
   // Get a copy of the compositor-side APZ test data for our layers ID.
   void GetCompositorSideAPZTestData(APZTestData* aData) const;
 
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -153,16 +153,22 @@ class WebRenderLayerManager final : publ
   // See equivalent function in ClientLayerManager
   void LogTestDataForCurrentPaint(ScrollableLayerGuid::ViewID aScrollId,
                                   const std::string& aKey,
                                   const std::string& aValue) {
     MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
     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; }
 
   WebRenderCommandBuilder& CommandBuilder() { return mWebRenderCommandBuilder; }
   WebRenderUserDataRefTable* GetWebRenderUserDataTable() {
     return mWebRenderCommandBuilder.GetWebRenderUserDataTable();
   }
   WebRenderScrollData& GetScrollData(wr::RenderRoot aRenderRoot) {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8586,16 +8586,30 @@ void nsLayoutUtils::DoLogTestDataForPain
   if (ClientLayerManager* mgr = aManager->AsClientLayerManager()) {
     mgr->LogTestDataForCurrentPaint(aScrollId, aKey, aValue);
   } else if (WebRenderLayerManager* wrlm =
                  aManager->AsWebRenderLayerManager()) {
     wrlm->LogTestDataForCurrentPaint(aScrollId, aKey, aValue);
   }
 }
 
+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();
 }
 
 ////////////////////////////////////////
 // SurfaceFromElementResult
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2724,16 +2724,31 @@ class nsLayoutUtils {
    * Returns true if we need to disable async scrolling for this particular
    * element. Note that this does a partial disabling - the displayport still
    * exists but uses a very small margin, and the compositor doesn't apply the
    * async transform. However, the content may still be layerized.
    */
   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
    *                   with this layer manager.
    * @param aScrollId Identifies the scroll frame to which the data pertains.
    * @param aKey The key under which to log the data.
    * @param aValue The value of the data to be logged.
    */
   static void LogTestDataForPaint(mozilla::layers::LayerManager* aManager,