Bug 695275 - Add CheckAndClearPaintedState to test painting. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 26 Oct 2011 16:23:26 +1300
changeset 79229 68d6ef3d84a3bf31b836695810d0585c85db1bf6
parent 79228 cc6b39f2b51218531a5670af867d401475f3aa32
child 79230 8b89d7037306c52884e4d9b7b068dac16dc01a44
push id21380
push userbmo@edmorley.co.uk
push dateWed, 26 Oct 2011 23:31:27 +0000
treeherderautoland@16a8d2ab5240 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs695275
milestone10.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 695275 - Add CheckAndClearPaintedState to test painting. r=roc
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/FrameLayerBuilder.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1936,8 +1936,30 @@ nsDOMWindowUtils::GetMayHaveTouchEventLi
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsPIDOMWindow* innerWindow = mWindow->GetCurrentInnerWindow();
   *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
+{
+  if (!aElement) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsresult rv;
+  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIFrame* frame = content->GetPrimaryFrame();
+
+  if (!frame) {
+    *aResult = false;
+    return NS_OK;
+  }
+
+  *aResult = frame->CheckAndClearPaintedState();
+  return NS_OK;
+}
+
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -63,17 +63,17 @@ interface nsIDOMElement;
 interface nsIDOMHTMLCanvasElement;
 interface nsIDOMEvent;
 interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMFile;
 interface nsIFile;
 
-[scriptable, uuid(bc6c156a-c41f-43dd-ace3-e3bca9894ed1)]
+[scriptable, uuid(910484d7-219c-4c72-b999-7a7e9c954646)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -914,9 +914,16 @@ interface nsIDOMWindowUtils : nsISupport
    * the bounds of the window. Always returns true in non-DEBUG builds.
    */
   boolean leafLayersPartitionWindow();
 
   /**
    * true if the (current inner) window may have event listeners for touch events.
    */
   readonly attribute boolean mayHaveTouchEventListeners;
+ 
+  /**
+   * Check if any ThebesLayer painting has been done for this element,
+   * clears the painted flags if they have.
+   */
+  boolean checkAndClearPaintedState(in nsIDOMElement aElement);
+
 };
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2101,16 +2101,20 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
         aContext->Save();
         currentClip.ApplyTo(aContext, presContext);
       }
     }
 
     if (cdi->mInactiveLayer) {
       PaintInactiveLayer(builder, cdi->mItem, aContext);
     } else {
+      nsIFrame* frame = cdi->mItem->GetUnderlyingFrame();
+      if (frame) {
+        frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
+      }
       cdi->mItem->Paint(builder, rc);
     }
 
     if (builder->LayerBuilder()->CheckDOMModified())
       break;
   }
 
   if (setClipRect) {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -277,16 +277,35 @@ nsIFrame::GetAbsoluteContainingBlock() c
 }
 
 void
 nsIFrame::MarkAsAbsoluteContainingBlock() {
   AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
   Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
 }
 
+bool
+nsIFrame::CheckAndClearPaintedState()
+{
+  bool result = (GetStateBits() & NS_FRAME_PAINTED_THEBES);
+  RemoveStateBits(NS_FRAME_PAINTED_THEBES);
+  
+  nsIFrame::ChildListIterator lists(this);
+  for (; !lists.IsDone(); lists.Next()) {
+    nsFrameList::Enumerator childFrames(lists.CurrentList());
+    for (; !childFrames.AtEnd(); childFrames.Next()) {
+      nsIFrame* child = childFrames.get();
+      if (child->CheckAndClearPaintedState()) {
+        result = true;
+      }
+    }
+  }
+  return result;
+}
+
 static bool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
                                     const nsIFrame* aFrame,
                                     const nsStyleDisplay* aDisp, 
                                     nsRect* aRect);
 
 static bool ApplyAbsPosClipping(nsDisplayListBuilder* aBuilder,
                                   const nsStyleDisplay* aDisp, 
                                   const nsIFrame* aFrame,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -285,16 +285,19 @@ typedef PRUint64 nsFrameState;
 // at the next paint via display list construction.
 // Only meaningful for display roots, so we don't really need a global state
 // bit; we could free up this bit with a little extra complexity.
 #define NS_FRAME_UPDATE_LAYER_TREE                  NS_FRAME_STATE_BIT(36)
 
 // Frame can accept absolutely positioned children.
 #define NS_FRAME_HAS_ABSPOS_CHILDREN                NS_FRAME_STATE_BIT(37)
 
+// A display item for this frame has been painted as part of a ThebesLayer.
+#define NS_FRAME_PAINTED_THEBES                     NS_FRAME_STATE_BIT(38)
+
 // The lower 20 bits and upper 32 bits of the frame state are reserved
 // by this API.
 #define NS_FRAME_RESERVED                           ~NS_FRAME_IMPL_RESERVED
 
 // Box layout bits
 #define NS_STATE_IS_HORIZONTAL                      NS_FRAME_STATE_BIT(22)
 #define NS_STATE_IS_DIRECTION_NORMAL                NS_FRAME_STATE_BIT(31)
 
@@ -2748,16 +2751,20 @@ NS_PTR_TO_INT32(frame->Properties().Get(
    */
   bool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
   bool HasAbsolutelyPositionedChildren() const;
   nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
   virtual void MarkAsAbsoluteContainingBlock();
   // Child frame types override this function to select their own child list name
   virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kAbsoluteList; }
 
+  // Checks if we (or any of our descendents) have NS_FRAME_PAINTED_THEBES set, and
+  // clears this bit if so.
+  bool CheckAndClearPaintedState();
+
 protected:
   // Members
   nsRect           mRect;
   nsIContent*      mContent;
   nsStyleContext*  mStyleContext;
   nsIFrame*        mParent;
 private:
   nsIFrame*        mNextSibling;  // doubly-linked list of frames