From 00e692667f7a575fff3928aa7fa2e1ff58d863e0 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Fri, 21 Oct 2011 14:21:40 +1300 Subject: [PATCH] Bug 695275 - Add nsIDOMWindowUtils::CheckAndClearPaintedState to test painting. r=roc --- dom/base/nsDOMWindowUtils.cpp | 17 +++++++++++++++++ dom/interfaces/base/nsIDOMWindowUtils.idl | 9 ++++++++- layout/base/FrameLayerBuilder.cpp | 4 ++++ layout/generic/nsFrame.cpp | 19 +++++++++++++++++++ layout/generic/nsIFrame.h | 7 +++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 2d95dd6c660a..65e0b8113a3e 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1941,3 +1941,20 @@ nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult) return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult) +{ + if (!aElement) { + return NS_ERROR_INVALID_ARG; + } + + nsresult rv; + nsCOMPtr content = do_QueryInterface(aElement, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsIFrame* frame = content->GetPrimaryFrame(); + + *aResult = frame->CheckAndClearPaintedState(); + return NS_OK; +} + diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 23e2e0d452db..9e55574e8152 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -68,7 +68,7 @@ interface nsIDOMWindow; interface nsIDOMFile; interface nsIFile; -[scriptable, uuid(bc6c156a-c41f-43dd-ace3-e3bca9894ed1)] +[scriptable, uuid(910484d7-219c-4c72-b999-7a7e9c954646)] interface nsIDOMWindowUtils : nsISupports { /** @@ -919,4 +919,11 @@ interface nsIDOMWindowUtils : nsISupports { * 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); + }; diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 30470c706dc6..57c529d35844 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2106,6 +2106,10 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer, 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); } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 69e6bec05520..2a7be0aefe52 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -282,6 +282,25 @@ nsIFrame::MarkAsAbsoluteContainingBlock() { 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, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index b0124063f2cd..f454083fd200 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -290,6 +290,9 @@ typedef PRUint64 nsFrameState; // 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 @@ -2753,6 +2756,10 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::EmbeddingLevelProperty())) // 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;