mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1022612. Part 4: Track current dirty rect in nsDisplayListBuilder. r=mattwoodrow
We need this to set the initial visible rect during display list construction. Eventually we'll also be able to get rid of the dirty rect parameter to nsIFrame::BuildDisplayList. --HG-- extra : rebase_source : 1ba0444270986dd799a27e4373ca16525f3ced6c
This commit is contained in:
parent
5965c3d7f7
commit
59f4b64c9f
@ -497,7 +497,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mFinalTransparentRegion(nullptr),
|
||||
mCurrentFrame(aReferenceFrame),
|
||||
mCurrentReferenceFrame(aReferenceFrame),
|
||||
mCurrentOffsetToReferenceFrame(0, 0),
|
||||
mDirtyRect(-1,-1,-1,-1),
|
||||
mGlassDisplayItem(nullptr),
|
||||
mMode(aMode),
|
||||
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
|
||||
@ -890,11 +890,11 @@ void
|
||||
nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
|
||||
const nsRect& aDirtyRect) {
|
||||
PresShellState* state = mPresShellStates.AppendElement();
|
||||
if (!state)
|
||||
return;
|
||||
state->mPresShell = aReferenceFrame->PresContext()->PresShell();
|
||||
state->mCaretFrame = nullptr;
|
||||
state->mFirstFrameMarkedForDisplay = mFramesMarkedForDisplay.Length();
|
||||
state->mPrevDirtyRect = mDirtyRect;
|
||||
mDirtyRect = aDirtyRect;
|
||||
|
||||
state->mPresShell->UpdateCanvasBackground();
|
||||
|
||||
@ -938,12 +938,10 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
|
||||
void
|
||||
nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame,
|
||||
const nsRect& aDirtyRect) {
|
||||
if (CurrentPresShellState()->mPresShell != aReferenceFrame->PresContext()->PresShell()) {
|
||||
// Must have not allocated a state for this presshell, presumably due
|
||||
// to OOM.
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(CurrentPresShellState()->mPresShell ==
|
||||
aReferenceFrame->PresContext()->PresShell(),
|
||||
"Presshell mismatch");
|
||||
mDirtyRect = CurrentPresShellState()->mPrevDirtyRect;
|
||||
ResetMarkedFramesForDisplayList();
|
||||
mPresShellStates.SetLength(mPresShellStates.Length() - 1);
|
||||
}
|
||||
|
@ -313,6 +313,14 @@ public:
|
||||
void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
|
||||
bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
|
||||
|
||||
/**
|
||||
* Get dirty rect relative to current frame (the frame that we're calling
|
||||
* BuildDisplayList on right now).
|
||||
*/
|
||||
const nsRect& GetDirtyRect() { return mDirtyRect; }
|
||||
const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
|
||||
const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
|
||||
|
||||
/**
|
||||
* Returns true if merging and flattening of display lists should be
|
||||
* performed while computing visibility.
|
||||
@ -528,20 +536,22 @@ public:
|
||||
/**
|
||||
* A helper class to temporarily set the value of
|
||||
* mIsAtRootOfPseudoStackingContext, and temporarily
|
||||
* update mCachedOffsetFrame/mCachedOffset from a frame to its child.
|
||||
* Also saves and restores mClipState.
|
||||
* set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
|
||||
* aDirtyRect is relative to aForChild.
|
||||
*/
|
||||
class AutoBuildingDisplayList;
|
||||
friend class AutoBuildingDisplayList;
|
||||
class AutoBuildingDisplayList {
|
||||
public:
|
||||
AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aForChild, bool aIsRoot)
|
||||
nsIFrame* aForChild,
|
||||
const nsRect& aDirtyRect, bool aIsRoot)
|
||||
: mBuilder(aBuilder),
|
||||
mPrevFrame(aBuilder->mCurrentFrame),
|
||||
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
|
||||
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
|
||||
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
|
||||
mPrevDirtyRect(aBuilder->mDirtyRect),
|
||||
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
|
||||
mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
|
||||
{
|
||||
@ -556,13 +566,18 @@ public:
|
||||
&aBuilder->mCurrentOffsetToReferenceFrame);
|
||||
}
|
||||
aBuilder->mCurrentFrame = aForChild;
|
||||
aBuilder->mDirtyRect = aDirtyRect;
|
||||
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
|
||||
}
|
||||
void SetDirtyRect(const nsRect& aRect) {
|
||||
mBuilder->mDirtyRect = aRect;
|
||||
}
|
||||
~AutoBuildingDisplayList() {
|
||||
mBuilder->mCurrentFrame = mPrevFrame;
|
||||
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
|
||||
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
|
||||
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
|
||||
mBuilder->mDirtyRect = mPrevDirtyRect;
|
||||
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
|
||||
mBuilder->mAncestorHasTouchEventHandler = mPrevAncestorHasTouchEventHandler;
|
||||
}
|
||||
@ -572,6 +587,7 @@ public:
|
||||
const nsIFrame* mPrevReferenceFrame;
|
||||
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
|
||||
nsPoint mPrevOffset;
|
||||
nsRect mPrevDirtyRect;
|
||||
bool mPrevIsAtRootOfPseudoStackingContext;
|
||||
bool mPrevAncestorHasTouchEventHandler;
|
||||
};
|
||||
@ -736,6 +752,7 @@ private:
|
||||
struct PresShellState {
|
||||
nsIPresShell* mPresShell;
|
||||
nsIFrame* mCaretFrame;
|
||||
nsRect mPrevDirtyRect;
|
||||
uint32_t mFirstFrameMarkedForDisplay;
|
||||
bool mIsBackgroundOnly;
|
||||
};
|
||||
@ -763,6 +780,8 @@ private:
|
||||
const nsIFrame* mCurrentReferenceFrame;
|
||||
// The offset from mCurrentFrame to mCurrentReferenceFrame.
|
||||
nsPoint mCurrentOffsetToReferenceFrame;
|
||||
// Relative to mCurrentFrame.
|
||||
nsRect mDirtyRect;
|
||||
nsRegion mExcludedGlassRegion;
|
||||
// The display item for the Windows window glass background, if any
|
||||
nsDisplayItem* mGlassDisplayItem;
|
||||
|
@ -1907,6 +1907,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
AutoSaveRestoreBlendMode autoRestoreBlendMode(*aBuilder);
|
||||
aBuilder->SetContainsBlendModes(BlendModeSet());
|
||||
|
||||
nsPoint offsetToReferenceFrame = aBuilder->ToReferenceFrame(this);
|
||||
|
||||
if (isTransformed) {
|
||||
const nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
||||
if (aBuilder->IsForPainting() &&
|
||||
@ -1917,11 +1919,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
return;
|
||||
}
|
||||
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(this);
|
||||
dirtyRect += offset;
|
||||
|
||||
dirtyRect += offsetToReferenceFrame;
|
||||
nsRect untransformedDirtyRect;
|
||||
if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this, offset, &untransformedDirtyRect)) {
|
||||
if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this,
|
||||
offsetToReferenceFrame, &untransformedDirtyRect)) {
|
||||
dirtyRect = untransformedDirtyRect;
|
||||
} else {
|
||||
NS_WARNING("Unable to untransform dirty rect!");
|
||||
@ -1940,6 +1941,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
nsLayoutUtils::SCROLLABLE_SAME_DOC |
|
||||
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
|
||||
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList
|
||||
buildingDisplayList(aBuilder, this, dirtyRect, true);
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
|
||||
if (isTransformed || useOpacity || useBlendMode || usingSVGEffects || useStickyPosition) {
|
||||
@ -1952,8 +1955,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
nsDisplayListCollection set;
|
||||
{
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList rootSetter(aBuilder, this, true);
|
||||
{
|
||||
DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
|
||||
nsDisplayListBuilder::AutoInTransformSetter
|
||||
inTransformSetter(aBuilder, inTransform);
|
||||
@ -1994,7 +1996,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
set.PositionedDescendants()->DeleteAll();
|
||||
set.Outlines()->DeleteAll();
|
||||
}
|
||||
|
||||
|
||||
// This z-order sort also sorts secondarily by content order. We need to do
|
||||
// this so that boxes produced by the same element are placed together
|
||||
// in the sort. Consider a position:relative inline element that breaks
|
||||
@ -2002,7 +2004,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
// children should be z-ordered after all the boxes for the position:relative
|
||||
// element itself.
|
||||
set.PositionedDescendants()->SortByZOrder(aBuilder, GetContent());
|
||||
|
||||
|
||||
nsDisplayList resultList;
|
||||
// Now follow the rules of http://www.w3.org/TR/CSS21/zindex.html
|
||||
// 1,2: backgrounds and borders
|
||||
@ -2072,8 +2074,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
new (aBuilder) nsDisplayStickyPosition(aBuilder, this, &resultList));
|
||||
}
|
||||
|
||||
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
|
||||
* everything in an nsDisplayTransform. If there's nothing in the list, don't add
|
||||
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
|
||||
* everything in an nsDisplayTransform. If there's nothing in the list, don't add
|
||||
* anything.
|
||||
*
|
||||
* For the preserve-3d case we want to individually wrap every child in the list with
|
||||
@ -2086,6 +2088,9 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
if (isTransformed && !resultList.IsEmpty()) {
|
||||
// Restore clip state now so nsDisplayTransform is clipped properly.
|
||||
clipState.Restore();
|
||||
// Revert to the dirtyrect coming in from the parent, without our transform
|
||||
// taken into account.
|
||||
buildingDisplayList.SetDirtyRect(aDirtyRect + offsetToReferenceFrame);
|
||||
|
||||
if (Preserves3DChildren()) {
|
||||
WrapPreserve3DList(this, aBuilder, &resultList);
|
||||
@ -2293,7 +2298,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
buildingInFixedPos(aBuilder, isInFixedPos);
|
||||
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList
|
||||
buildingForChild(aBuilder, child, pseudoStackingContext);
|
||||
buildingForChild(aBuilder, child, dirty, pseudoStackingContext);
|
||||
DisplayListClipState::AutoClipMultiple clipState(aBuilder);
|
||||
CheckForTouchEventHandler(aBuilder, child);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user