Bug 841192. Part 4: Create DisplayListClipState. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 04 Mar 2013 22:56:00 +1300
changeset 127799 ec3f4cfe3866b48f0f7714a50ae5e621f588bfcd
parent 127798 fb7633e8733e0094329fa668b21738f6464e52cf
child 127800 d6f4ddf03ffb57f6618e3476f1c264d16e9f1b5f
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs841192
milestone23.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 841192. Part 4: Create DisplayListClipState. r=mattwoodrow
layout/base/DisplayItemClip.cpp
layout/base/DisplayItemClip.h
layout/base/DisplayListClipState.cpp
layout/base/DisplayListClipState.h
layout/base/Makefile.in
--- a/layout/base/DisplayItemClip.cpp
+++ b/layout/base/DisplayItemClip.cpp
@@ -37,16 +37,33 @@ DisplayItemClip::DisplayItemClip(const D
       static_cast<nsDisplayClipRoundedRect*>(item)->GetRadii(rr->mRadii);
     }
   }
 
   // FIXME: Optimize away excess rounded rectangles due to the new addition.
 }
 
 void
+DisplayItemClip::IntersectWith(const DisplayItemClip& aOther)
+{
+  if (!aOther.mHaveClipRect) {
+    return;
+  }
+  if (!mHaveClipRect) {
+    *this = aOther;
+    return;
+  }
+  if (!mClipRect.IntersectRect(mClipRect, aOther.mClipRect)) {
+    mRoundedClipRects.Clear();
+    return;
+  }
+  mRoundedClipRects.AppendElements(aOther.mRoundedClipRects);
+}
+
+void
 DisplayItemClip::ApplyTo(gfxContext* aContext,
                          nsPresContext* aPresContext,
                          uint32_t aBegin, uint32_t aEnd)
 {
   int32_t A2D = aPresContext->AppUnitsPerDevPixel();
   ApplyRectTo(aContext, A2D);
   ApplyRoundedRectsTo(aContext, A2D, aBegin, aEnd);
 }
--- a/layout/base/DisplayItemClip.h
+++ b/layout/base/DisplayItemClip.h
@@ -53,16 +53,18 @@ public:
   };
 
   // Constructs a DisplayItemClip that does no clipping at all.
   DisplayItemClip() : mHaveClipRect(false) {}
 
   // Construct as the intersection of aOther and aClipItem.
   DisplayItemClip(const DisplayItemClip& aOther, nsDisplayItem* aClipItem);
 
+  void IntersectWith(const DisplayItemClip& aOther);
+
   // Apply this |DisplayItemClip| to the given gfxContext.  Any saving of state
   // or clearing of other clips must be done by the caller.
   // See aBegin/aEnd note on ApplyRoundedRectsTo.
   void ApplyTo(gfxContext* aContext, nsPresContext* aPresContext,
                uint32_t aBegin = 0, uint32_t aEnd = UINT32_MAX);
 
   void ApplyRectTo(gfxContext* aContext, int32_t A2D) const;
   // Applies the rounded rects in this Clip to aContext
@@ -124,18 +126,18 @@ public:
     return mHaveClipRect == aOther.mHaveClipRect &&
            (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
            mRoundedClipRects == aOther.mRoundedClipRects;
   }
   bool operator!=(const DisplayItemClip& aOther) const {
     return !(*this == aOther);
   }
 
-  bool HasClip() { return mHaveClipRect; }
-  const nsRect& GetClipRect()
+  bool HasClip() const { return mHaveClipRect; }
+  const nsRect& GetClipRect() const
   {
     NS_ASSERTION(HasClip(), "No clip rect!");
     return mClipRect;
   }
 
   /**
    * Find the largest N such that the first N rounded rects in 'this' are
    * equal to the first N rounded rects in aOther, and N <= aMax.
new file mode 100644
--- /dev/null
+++ b/layout/base/DisplayListClipState.cpp
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#include "DisplayListClipState.h"
+
+#include "nsDisplayList.h"
+
+namespace mozilla {
+
+const DisplayItemClip*
+DisplayListClipState::GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder)
+{
+  if (mCurrentCombinedClip) {
+    return mCurrentCombinedClip;
+  }
+  if (!mClipContentDescendants && !mClipContainingBlockDescendants) {
+    return nullptr;
+  }
+  void* mem = aBuilder->Allocate(sizeof(DisplayItemClip));
+  if (mClipContentDescendants) {
+    mCurrentCombinedClip =
+      new (mem) DisplayItemClip(*mClipContentDescendants);
+    if (mClipContainingBlockDescendants) {
+      mCurrentCombinedClip->IntersectWith(*mClipContainingBlockDescendants);
+    }
+  } else {
+    mCurrentCombinedClip =
+      new (mem) DisplayItemClip(*mClipContainingBlockDescendants);
+  }
+  return mCurrentCombinedClip;
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/layout/base/DisplayListClipState.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 DISPLAYLISTCLIPSTATE_H_
+#define DISPLAYLISTCLIPSTATE_H_
+
+#include "DisplayItemClip.h"
+
+class nsIFrame;
+class nsDisplayListBuilder;
+
+namespace mozilla {
+
+/**
+ * All clip coordinates are in appunits relative to the reference frame
+ * for the display item we're building.
+ */
+class DisplayListClipState {
+public:
+  DisplayListClipState()
+    : mClipContentDescendants(nullptr)
+    , mClipContainingBlockDescendants(nullptr)
+    , mCurrentCombinedClip(nullptr)
+  {}
+
+  const DisplayItemClip* GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder);
+
+  const DisplayItemClip* GetClipForContainingBlockDescendants()
+  {
+    return mClipContainingBlockDescendants;
+  }
+
+  const DisplayItemClip* GetClipForContentDescendants()
+  {
+    return mClipContentDescendants;
+  }
+
+  void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
+  {
+    mClipContainingBlockDescendants = aClip;
+    mCurrentCombinedClip = nullptr;
+  }
+  void SetClipForContentDescendants(const DisplayItemClip* aClip)
+  {
+    mClipContentDescendants = aClip;
+    mCurrentCombinedClip = nullptr;
+  }
+
+private:
+  /**
+   * All content descendants (i.e. following placeholder frames to their
+   * out-of-flows if necessary) should be clipped by mClipContentDescendants.
+   * Null if no clipping applies.
+   */
+  const DisplayItemClip* mClipContentDescendants;
+  /**
+   * All containing-block descendants (i.e. frame descendants) should be
+   * clipped by mClipContainingBlockDescendants.
+   * Null if no clipping applies.
+   */
+  const DisplayItemClip* mClipContainingBlockDescendants;
+  /**
+   * The intersection of mClipContentDescendants and
+   * mClipContainingBlockDescendants.
+   * Allocated in the nsDisplayListBuilder arena. Null if none has been
+   * allocated or both mClipContentDescendants and mClipContainingBlockDescendants
+   * are null.
+   */
+  const DisplayItemClip* mCurrentCombinedClip;
+};
+
+}
+
+#endif /* DISPLAYLISTCLIPSTATE_H_ */
--- a/layout/base/Makefile.in
+++ b/layout/base/Makefile.in
@@ -16,16 +16,18 @@ ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 
 
 EXPORTS_NAMESPACES = mozilla
 
 EXPORTS		= \
+		DisplayItemClip.h \
+		DisplayListClipState.h \
 		FrameLayerBuilder.h \
 		FramePropertyTable.h \
 		nsArenaMemoryStats.h \
 		nsBidi.h \
 		nsBidiPresUtils.h \
 		nsCaret.h \
 		nsCSSFrameConstructor.h \
 		nsChangeHint.h \
@@ -54,16 +56,17 @@ EXPORTS		= \
 		$(NULL)
 
 EXPORTS_mozilla = \
   PaintTracker.h \
   $(NULL)
 
 CPPSRCS		= \
 		DisplayItemClip.cpp \
+		DisplayListClipState.cpp \
 		FrameLayerBuilder.cpp \
 		FramePropertyTable.cpp \
 		MaskLayerImageCache.cpp \
 		nsCSSColorUtils.cpp \
 		nsCSSFrameConstructor.cpp \
 		nsCSSRendering.cpp \
 		nsCSSRenderingBorders.cpp \
 		nsCaret.cpp \