Bug 1477693 - Part 1: Move TransformClipNode and TransformWithNode functions to TransformClipNode.h r=mattwoodrow
authorMiko Mynttinen <mikokm@gmail.com>
Wed, 25 Jul 2018 21:58:22 +0200
changeset 484456 26a74b8d85a615021c909bc3b02de25cf3eb73ac
parent 484455 db33ad0133586e3c7956078f2b832c8d89693d3d
child 484457 da8f43847ea7f9398ecd88a4917b6c1900b6f886
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1477693
milestone63.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 1477693 - Part 1: Move TransformClipNode and TransformWithNode functions to TransformClipNode.h r=mattwoodrow MozReview-Commit-ID: 13uSenWdNXJ
layout/painting/FrameLayerBuilder.cpp
layout/painting/FrameLayerBuilder.h
layout/painting/MatrixStack.h
layout/painting/TransformClipNode.h
layout/painting/moz.build
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -568,107 +568,16 @@ public:
 FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
 {
   RemoveFrameFromLayerManager(aFrame, aFrame->DisplayItemData());
   aFrame->DisplayItemData().Clear();
   aFrame->DeleteProperty(WebRenderUserDataProperty::Key());
 }
 
 /**
- * Transforms and clips |aRegion| using |aNode| up to the root transform node.
- * |aRegion| is expected be in integer pixels.
- */
-static nsIntRegion
-TransformWithNode(const TransformClipNode* aNode,
-                  const nsIntRegion& aRegion, const int32_t aA2D)
-{
-  MOZ_ASSERT(aNode);
-  if (aRegion.IsEmpty()) {
-    return aRegion;
-  }
-
-  nsIntRegion result = aRegion;
-
-  while (aNode) {
-    const Matrix4x4Flagged& transform = aNode->Transform();
-    result = result.Transform(transform.GetMatrix());
-
-    if (aNode->Clip()) {
-      const nsRect& clip = *aNode->Clip();
-      const gfx::IntRect clipRect = clip.ToNearestPixels(aA2D);
-      result.AndWith(clipRect);
-    }
-
-    aNode = aNode->Parent();
-  }
-
-  return result;
-}
-
-static void
-TransformRect(const TransformClipNode* aNode,
-              gfx::Rect& aRect, const int32_t aA2D)
-{
-  while (aNode) {
-    const Matrix4x4Flagged& transform = aNode->Transform();
-    gfx::Rect maxBounds = gfx::Rect::MaxIntRect();
-
-    if (aNode->Clip()) {
-      const nsRect& clip = *aNode->Clip();
-      maxBounds = IntRectToRect(clip.ToNearestPixels(aA2D));
-    }
-
-    aRect = transform.TransformAndClipBounds(aRect, maxBounds);
-    aNode = aNode->Parent();
-  }
-}
-
-/**
- * Transforms and clips |aRect| using |aNode| up to the root transform node.
- * |aRect| is expected to be in app units.
- */
-static nsRect
-TransformWithNode(const TransformClipNode* aNode,
-                  const nsRect& aRect, const int32_t aA2D)
-{
-  MOZ_ASSERT(aNode);
-  if (aRect.IsEmpty()) {
-    return aRect;
-  }
-
-  gfx::Rect result(NSAppUnitsToFloatPixels(aRect.x, aA2D),
-                   NSAppUnitsToFloatPixels(aRect.y, aA2D),
-                   NSAppUnitsToFloatPixels(aRect.width, aA2D),
-                   NSAppUnitsToFloatPixels(aRect.height, aA2D));
-  TransformRect(aNode, result, aA2D);
-  return nsRect(NSFloatPixelsToAppUnits(result.x, aA2D),
-                NSFloatPixelsToAppUnits(result.y, aA2D),
-                NSFloatPixelsToAppUnits(result.width, aA2D),
-                NSFloatPixelsToAppUnits(result.height, aA2D));
-}
-
-/**
- * Transforms and clips |aRect| using |aNode| up to the root transform node.
- * |aRect| is expected to be in integer pixels.
- */
-static gfx::IntRect
-TransformWithNode(const TransformClipNode* aNode,
-                  const gfx::IntRect& aRect, const int32_t aA2D)
-{
-  MOZ_ASSERT(aNode);
-  if (aRect.IsEmpty()) {
-    return aRect;
-  }
-
-  gfx::Rect result(IntRectToRect(aRect));
-  TransformRect(aNode, result, aA2D);
-  return RoundedToInt(result);
-}
-
-/**
  * We keep a stack of these to represent the PaintedLayers that are
  * currently available to have display items added to.
  * We use a stack here because as much as possible we want to
  * assign display items to existing PaintedLayers, and to the lowest
  * PaintedLayer in z-order. This reduces the number of layers and
  * makes it more likely a display item will be rendered to an opaque
  * layer, giving us the best chance of getting subpixel AA.
  */
@@ -2272,17 +2181,17 @@ InvalidatePostTransformRegion(PaintedLay
   // Convert the region from the coordinates of the container layer
   // (relative to the snapped top-left of the display list reference frame)
   // to the PaintedLayer's own coordinates
   nsIntRegion rgn = aRegion;
 
   if (aTransform) {
     PaintedDisplayItemLayerUserData* data =
       GetPaintedDisplayItemLayerUserData(aLayer);
-    rgn = TransformWithNode(aTransform, rgn, data->mAppUnitsPerDevPixel);
+    rgn = aTransform->TransformRegion(rgn, data->mAppUnitsPerDevPixel);
   }
 
   rgn.MoveBy(-aTranslation);
   aLayer->InvalidateRegion(rgn);
 #ifdef MOZ_DUMP_PAINTING
   if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     nsAutoCString str;
     AppendToString(str, rgn);
@@ -2360,22 +2269,24 @@ FrameLayerBuilder::RemoveFrameFromLayerM
 #endif
 
   for (DisplayItemData* data : aArray) {
     PaintedLayer* t = data->mLayer ? data->mLayer->AsPaintedLayer() : nullptr;
     if (t) {
       PaintedDisplayItemLayerUserData* paintedData =
           static_cast<PaintedDisplayItemLayerUserData*>(t->GetUserData(&gPaintedDisplayItemLayerUserData));
       if (paintedData && data->mGeometry) {
+        const int32_t appUnitsPerDevPixel = paintedData->mAppUnitsPerDevPixel;
         nsRegion old = data->mGeometry->ComputeInvalidationRegion();
-        nsIntRegion rgn = old.ScaleToOutsidePixels(paintedData->mXScale, paintedData->mYScale, paintedData->mAppUnitsPerDevPixel);
+        nsIntRegion rgn = old.ScaleToOutsidePixels(paintedData->mXScale,
+                                                   paintedData->mYScale,
+                                                   appUnitsPerDevPixel);
 
         if (data->mTransform) {
-          rgn = TransformWithNode(data->mTransform, rgn,
-                                  paintedData->mAppUnitsPerDevPixel);
+          rgn = data->mTransform->TransformRegion(rgn, appUnitsPerDevPixel);
         }
 
         rgn.MoveBy(-GetTranslationForPaintedLayer(t));
 
         paintedData->mRegionToInvalidate.Or(paintedData->mRegionToInvalidate, rgn);
         paintedData->mRegionToInvalidate.SimplifyOutward(8);
       }
     }
@@ -4118,17 +4029,17 @@ PaintedLayerData::AccumulateHitTestInfo(
                                         TransformClipNode* aTransform)
 {
   FLB_LOG_PAINTED_LAYER_DECISION(this,
     "Accumulating hit test info %p against pld=%p\n", aItem, this);
 
   const mozilla::DisplayItemClip& clip = aItem->GetClip();
   nsRect area = clip.ApplyNonRoundedIntersection(aItem->Area());
   if (aTransform) {
-    area = TransformWithNode(aTransform, area, aState->mAppUnitsPerDevPixel);
+    area = aTransform->TransformRect(area, aState->mAppUnitsPerDevPixel);
   }
   const mozilla::gfx::CompositorHitTestInfo hitTestInfo = aItem->HitTestInfo();
 
   bool hasRoundedCorners = clip.GetRoundedRectCount() > 0;
 
   // use the NS_FRAME_SIMPLE_EVENT_REGIONS to avoid calling the slightly
   // expensive HasNonZeroCorner function if we know from a previous run that
   // the frame has zero corners.
@@ -4747,20 +4658,20 @@ ContainerState::ProcessDisplayItems(nsDi
     }
 
 
     if (transformNode) {
       // If we are within transform, transform itemContent and itemDrawRect.
       MOZ_ASSERT(transformNode);
 
       itemContent =
-        TransformWithNode(transformNode, itemContent, mAppUnitsPerDevPixel);
+        transformNode->TransformRect(itemContent,mAppUnitsPerDevPixel);
 
       itemDrawRect =
-        TransformWithNode(transformNode, itemDrawRect, mAppUnitsPerDevPixel);
+        transformNode->TransformRect(itemDrawRect, mAppUnitsPerDevPixel);
     }
 
 #ifdef DEBUG
     nsRect bounds = itemContent;
 
     if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO || inEffect) {
       bounds.SetEmpty();
     }
@@ -4780,18 +4691,18 @@ ContainerState::ProcessDisplayItems(nsDi
     nsIntRect itemVisibleRect = itemDrawRect;
 
     // We intersect the building rect with the clipped item bounds to get a
     // tighter visible rect.
     if (!prerenderedTransform) {
       nsRect itemBuildingRect = item->GetBuildingRect();
 
       if (transformNode) {
-        itemBuildingRect = TransformWithNode(transformNode, itemBuildingRect,
-                                             mAppUnitsPerDevPixel);
+        itemBuildingRect =
+          transformNode->TransformRect(itemBuildingRect, mAppUnitsPerDevPixel);
       }
 
       itemVisibleRect = itemVisibleRect.Intersect(
         ScaleToOutsidePixels(itemBuildingRect, false));
     }
 
     if (maxLayers != -1 && layerCount >= maxLayers) {
       forceInactive = true;
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -15,17 +15,17 @@
 #include "nsIFrame.h"
 #include "DisplayItemClip.h"
 #include "mozilla/gfx/MatrixFwd.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "LayerState.h"
 #include "Layers.h"
 #include "LayerUserData.h"
 #include "nsDisplayItemTypes.h"
-#include "MatrixStack.h"
+#include "TransformClipNode.h"
 
 class nsDisplayListBuilder;
 class nsDisplayList;
 class nsDisplayItem;
 class gfxContext;
 class nsDisplayItemGeometry;
 class nsDisplayMask;
 
--- a/layout/painting/MatrixStack.h
+++ b/layout/painting/MatrixStack.h
@@ -2,21 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_PAINTING_MATRIXSTACK_H
 #define MOZILLA_PAINTING_MATRIXSTACK_H
 
-#include "nsISupports.h"
 #include "nsTArray.h"
 #include "mozilla/gfx/MatrixFwd.h"
-#include "mozilla/Maybe.h"
-#include "DisplayItemClip.h"
 
 namespace mozilla {
 
 /**
  * MatrixStack stores a stack of matrices and keeps track of the accumulated
  * transform matrix.
  */
 template<typename T>
@@ -65,67 +62,11 @@ public:
 
 private:
   T mCurrentMatrix;
   AutoTArray<T, 2> mMatrices;
 };
 
 typedef MatrixStack<gfx::Matrix4x4Flagged> MatrixStack4x4;
 
-
-/**
- * TransformClipNode stores a transformation matrix and a post-transform
- * clip rect.
- * They can be used to transform and clip a display item inside a flattened
- * nsDisplayTransform to the coordinate space of that nsDisplayTransform.
- */
-class TransformClipNode {
-  NS_INLINE_DECL_REFCOUNTING(TransformClipNode);
-public:
-  TransformClipNode(const RefPtr<TransformClipNode>& aParent,
-                    const gfx::Matrix4x4Flagged& aTransform,
-                    const Maybe<nsRect>& aClip)
-  : mParent(aParent)
-  , mTransform(aTransform)
-  , mClip(aClip)
-  {
-    MOZ_COUNT_CTOR(TransformClipNode);
-  }
-
-  /*
-   * Returns the parent node, or nullptr if this is the root node.
-   */
-  const RefPtr<TransformClipNode>& Parent() const
-  {
-    return mParent;
-  }
-
-  /*
-   * Returns the post-transform clip, if there is one.
-   */
-  const Maybe<nsRect>& Clip() const
-  {
-    return mClip;
-  }
-
-  /*
-   * Returns the matrix that transforms the item bounds to the coordinate space
-   * of the flattened nsDisplayTransform.
-   */
-  const gfx::Matrix4x4Flagged& Transform() const
-  {
-    return mTransform;
-  }
-
-private:
-  ~TransformClipNode()
-  {
-    MOZ_COUNT_DTOR(TransformClipNode);
-  }
-
-  const RefPtr<TransformClipNode> mParent;
-  const gfx::Matrix4x4Flagged mTransform;
-  const Maybe<nsRect> mClip;
-};
-
 } // namespace mozilla
 
-#endif /* MOZILLA_PAINTING_MATRIXSTACK_H */
\ No newline at end of file
+#endif /* MOZILLA_PAINTING_MATRIXSTACK_H */
new file mode 100644
--- /dev/null
+++ b/layout/painting/TransformClipNode.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_PAINTING_TRANSFORMCLIPNODE_H
+#define MOZILLA_PAINTING_TRANSFORMCLIPNODE_H
+
+#include "mozilla/gfx/MatrixFwd.h"
+#include "mozilla/gfx/Rect.h"
+#include "mozilla/Maybe.h"
+#include "nsISupports.h"
+#include "nsRegionFwd.h"
+
+namespace mozilla {
+
+/**
+ * TransformClipNode stores a transformation matrix and a post-transform
+ * clip rect.
+ * They can be used to transform and clip a display item inside a flattened
+ * nsDisplayTransform to the coordinate space of that nsDisplayTransform.
+ */
+class TransformClipNode {
+  NS_INLINE_DECL_REFCOUNTING(TransformClipNode);
+public:
+  TransformClipNode(const RefPtr<TransformClipNode>& aParent,
+                    const gfx::Matrix4x4Flagged& aTransform,
+                    const Maybe<nsRect>& aClip)
+  : mParent(aParent)
+  , mTransform(aTransform)
+  , mClip(aClip)
+  {
+    MOZ_COUNT_CTOR(TransformClipNode);
+  }
+
+  /**
+   * Returns the parent node, or nullptr if this is the root node.
+   */
+  const RefPtr<TransformClipNode>& Parent() const
+  {
+    return mParent;
+  }
+
+  /**
+   * Transforms and clips |aRect| up to the root transform node.
+   * |aRect| is expected to be in app units.
+   */
+  nsRect TransformRect(const nsRect& aRect, const int32_t aA2D)
+  {
+    if (aRect.IsEmpty()) {
+      return aRect;
+    }
+
+    gfx::Rect result(NSAppUnitsToFloatPixels(aRect.x, aA2D),
+                     NSAppUnitsToFloatPixels(aRect.y, aA2D),
+                     NSAppUnitsToFloatPixels(aRect.width, aA2D),
+                     NSAppUnitsToFloatPixels(aRect.height, aA2D));
+    TransformRect(result, aA2D);
+    return nsRect(NSFloatPixelsToAppUnits(result.x, aA2D),
+                  NSFloatPixelsToAppUnits(result.y, aA2D),
+                  NSFloatPixelsToAppUnits(result.width, aA2D),
+                  NSFloatPixelsToAppUnits(result.height, aA2D));
+  }
+
+  /**
+   * Transforms and clips |aRect| up to the root transform node.
+   * |aRect| is expected to be in integer pixels.
+   */
+  gfx::IntRect TransformRect(const gfx::IntRect& aRect, const int32_t aA2D)
+  {
+    if (aRect.IsEmpty()) {
+      return aRect;
+    }
+
+    gfx::Rect result(IntRectToRect(aRect));
+    TransformRect(result, aA2D);
+    return RoundedToInt(result);
+  }
+
+  /**
+   * Transforms and clips |aRegion| up to the root transform node.
+   * |aRegion| is expected be in integer pixels.
+   */
+  nsIntRegion TransformRegion(const nsIntRegion& aRegion, const int32_t aA2D)
+  {
+    if (aRegion.IsEmpty()) {
+      return aRegion;
+    }
+
+    nsIntRegion result = aRegion;
+
+    const TransformClipNode* node = this;
+    while (node) {
+      const gfx::Matrix4x4Flagged& transform = node->Transform();
+      result = result.Transform(transform.GetMatrix());
+
+      if (node->Clip()) {
+        const nsRect& clip = *node->Clip();
+        const gfx::IntRect clipRect = clip.ToNearestPixels(aA2D);
+        result.AndWith(clipRect);
+      }
+
+      node = node->Parent();
+    }
+
+    return result;
+  }
+
+protected:
+  /**
+   * Returns the post-transform clip, if there is one.
+   */
+  const Maybe<nsRect>& Clip() const
+  {
+    return mClip;
+  }
+
+  /**
+   * Returns the matrix that transforms the item bounds to the coordinate space
+   * of the flattened nsDisplayTransform.
+   */
+  const gfx::Matrix4x4Flagged& Transform() const
+  {
+    return mTransform;
+  }
+
+  void TransformRect(gfx::Rect& aRect, const int32_t aA2D)
+  {
+    const TransformClipNode* node = this;
+    while (node) {
+      const gfx::Matrix4x4Flagged& transform = node->Transform();
+      gfx::Rect maxBounds = gfx::Rect::MaxIntRect();
+
+      if (node->Clip()) {
+        const nsRect& clip = *node->Clip();
+        maxBounds = IntRectToRect(clip.ToNearestPixels(aA2D));
+      }
+
+      aRect = transform.TransformAndClipBounds(aRect, maxBounds);
+      node = node->Parent();
+    }
+  }
+
+private:
+  ~TransformClipNode()
+  {
+    MOZ_COUNT_DTOR(TransformClipNode);
+  }
+
+  const RefPtr<TransformClipNode> mParent;
+  const gfx::Matrix4x4Flagged mTransform;
+  const Maybe<nsRect> mClip;
+};
+
+} // namespace mozilla
+
+#endif /* MOZILLA_PAINTING_TRANSFORMCLIPNODE_H */
--- a/layout/painting/moz.build
+++ b/layout/painting/moz.build
@@ -19,16 +19,17 @@ EXPORTS += [
     'nsCSSRenderingGradients.h',
     'nsDisplayItemTypes.h',
     'nsDisplayItemTypesList.h',
     'nsDisplayList.h',
     'nsDisplayListInvalidation.h',
     'nsImageRenderer.h',
     'RetainedDisplayListBuilder.h',
     'RetainedDisplayListHelpers.h',
+    'TransformClipNode.h',
 ]
 
 EXPORTS.mozilla += [
     'PaintTracker.h',
 ]
 
 UNIFIED_SOURCES += [
     'ActiveLayerTracker.cpp',