зеркало из https://github.com/mozilla/gecko-dev.git
Bug 593243: Clip invalidations to the displayport when one is set. r=tn
This commit is contained in:
Родитель
38a95f5928
Коммит
7155968a31
|
@ -6062,21 +6062,11 @@ void PresShell::SetRenderingState(const RenderingState& aState)
|
|||
mXResolution = aState.mXResolution;
|
||||
mYResolution = aState.mYResolution;
|
||||
|
||||
// FIXME (Bug 593243 should fix this.)
|
||||
//
|
||||
// Invalidated content does not pay any attention to the displayport, so
|
||||
// invalidating the subdocument's root frame could end up not repainting
|
||||
// visible content.
|
||||
//
|
||||
// For instance, imagine the iframe is located at y=1000. Even though the
|
||||
// displayport may intersect the iframe's viewport, the visual overflow
|
||||
// rect of the root content could be (0, 0, 800, 500). Since the dirty region
|
||||
// does not intersect the visible overflow rect, the display list for the
|
||||
// iframe will not even be generated.
|
||||
//
|
||||
// Here, we find the very top presShell and use its root frame for
|
||||
// invalidation instead.
|
||||
//
|
||||
nsIView* rootView;
|
||||
if (NS_SUCCEEDED(mViewManager->GetRootView(rootView)) && rootView) {
|
||||
rootView->SetInvalidationDimensions(&mDisplayPort);
|
||||
}
|
||||
|
||||
nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
||||
if (rootPresContext) {
|
||||
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
|
||||
|
|
|
@ -195,7 +195,15 @@ nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
||||
// This is the damage rect that we're going to pass up to our parent.
|
||||
nsRect parentDamage;
|
||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
||||
nsIPresShell* presShell = PresContext()->PresShell();
|
||||
// If we're using a displayport, we might be displaying an area
|
||||
// different than our scroll port and the damage needs to be
|
||||
// clipped to that instead.
|
||||
if (mInner.mIsRoot && presShell->UsingDisplayPort()) {
|
||||
parentDamage.IntersectRect(damage, presShell->GetDisplayPort());
|
||||
} else {
|
||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
||||
}
|
||||
|
||||
if (IsScrollingActive()) {
|
||||
// This is the damage rect that we're going to pass up and
|
||||
|
@ -1104,7 +1112,15 @@ nsXULScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
||||
// This is the damage rect that we're going to pass up to our parent.
|
||||
nsRect parentDamage;
|
||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
||||
nsIPresShell* presShell = PresContext()->PresShell();
|
||||
// If we're using a displayport, we might be displaying an area
|
||||
// different than our scroll port and the damage needs to be
|
||||
// clipped to that instead.
|
||||
if (mInner.mIsRoot && presShell->UsingDisplayPort()) {
|
||||
parentDamage.IntersectRect(damage, presShell->GetDisplayPort());
|
||||
} else {
|
||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
||||
}
|
||||
|
||||
if (IsScrollingActive()) {
|
||||
// This is the damage rect that we're going to pass up and
|
||||
|
|
|
@ -173,6 +173,17 @@ public:
|
|||
*/
|
||||
nsRect GetBounds() const { return mDimBounds; }
|
||||
|
||||
/**
|
||||
* Set the dimensions at which invalidations are clipped, which can
|
||||
* be different than |GetDimensions()|. |aRect| is relative to
|
||||
* |this|. It can be null, in which case invalidations return to
|
||||
* being clipped to the view dimensions.
|
||||
*
|
||||
* The caller is responsible for invalidating the area that may lie
|
||||
* outside the view dimensions but inside |aRect| after this call.
|
||||
*/
|
||||
void SetInvalidationDimensions(const nsRect* aRect);
|
||||
|
||||
/**
|
||||
* Get the offset between the coordinate systems of |this| and aOther.
|
||||
* Adding the return value to a point in the coordinate system of |this|
|
||||
|
|
|
@ -209,6 +209,7 @@ nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
|
|||
mViewManager = aViewManager;
|
||||
mDirtyRegion = nsnull;
|
||||
mDeletionObserver = nsnull;
|
||||
mHaveInvalidationDimensions = PR_FALSE;
|
||||
mWidgetIsTopLevel = PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -350,6 +351,11 @@ void nsView::SetPosition(nscoord aX, nscoord aY)
|
|||
ResetWidgetBounds(PR_TRUE, PR_TRUE, PR_FALSE);
|
||||
}
|
||||
|
||||
void nsIView::SetInvalidationDimensions(const nsRect* aRect)
|
||||
{
|
||||
return Impl()->SetInvalidationDimensions(aRect);
|
||||
}
|
||||
|
||||
void nsView::SetPositionIgnoringChildWidgets(nscoord aX, nscoord aY)
|
||||
{
|
||||
mDimBounds.x += aX - mPosX;
|
||||
|
@ -495,6 +501,13 @@ void nsView::SetDimensions(const nsRect& aRect, PRBool aPaint, PRBool aResizeWid
|
|||
}
|
||||
}
|
||||
|
||||
void nsView::SetInvalidationDimensions(const nsRect* aRect)
|
||||
{
|
||||
if ((mHaveInvalidationDimensions = !!aRect)) {
|
||||
mInvalidationDimensions = *aRect;
|
||||
}
|
||||
}
|
||||
|
||||
void nsView::NotifyEffectiveVisibilityChanged(PRBool aEffectivelyVisible)
|
||||
{
|
||||
if (!aEffectivelyVisible)
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
*/
|
||||
virtual void SetDimensions(const nsRect &aRect, PRBool aPaint = PR_TRUE,
|
||||
PRBool aResizeWidget = PR_TRUE);
|
||||
void SetInvalidationDimensions(const nsRect* aRect);
|
||||
void GetDimensions(nsRect &aRect) const { aRect = mDimBounds; aRect.x -= mPosX; aRect.y -= mPosY; }
|
||||
void GetDimensions(nsSize &aSize) const { aSize.width = mDimBounds.width; aSize.height = mDimBounds.height; }
|
||||
|
||||
|
@ -148,6 +149,11 @@ public:
|
|||
nsRect GetDimensions() const { nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r; }
|
||||
// Same as GetBounds but converts to parent appunits if they are different.
|
||||
nsRect GetBoundsInParentUnits() const;
|
||||
|
||||
nsRect GetInvalidationDimensions() const {
|
||||
return mHaveInvalidationDimensions ? mInvalidationDimensions : GetDimensions();
|
||||
}
|
||||
|
||||
// These are defined exactly the same in nsIView, but for now they have to be redeclared
|
||||
// here because of stupid C++ method hiding rules
|
||||
|
||||
|
@ -202,6 +208,13 @@ protected:
|
|||
void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize);
|
||||
|
||||
nsRegion* mDirtyRegion;
|
||||
// invalidations are clipped to mInvalidationDimensions, not
|
||||
// GetDimensions(), when mHaveInvalidationDimensions is true. This
|
||||
// is used to support persistent "displayport" rendering; see
|
||||
// nsPresShell.cpp. The coordinates of mInvalidationDimensions are
|
||||
// relative to |this|.
|
||||
nsRect mInvalidationDimensions;
|
||||
PRPackedBool mHaveInvalidationDimensions;
|
||||
|
||||
private:
|
||||
void InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility);
|
||||
|
|
|
@ -571,7 +571,7 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, nsIWidget* aWidget,
|
|||
|
||||
// If the bounds don't overlap at all, there's nothing to do
|
||||
nsRegion intersection;
|
||||
intersection.And(aWidgetView->GetDimensions(), aDamagedRegion);
|
||||
intersection.And(aWidgetView->GetInvalidationDimensions(), aDamagedRegion);
|
||||
if (intersection.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1623,7 +1623,7 @@ nsIntRect nsViewManager::ViewToWidget(nsView *aView, const nsRect &aRect) const
|
|||
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
|
||||
|
||||
// intersect aRect with bounds of aView, to prevent generating any illegal rectangles.
|
||||
nsRect bounds = aView->GetDimensions();
|
||||
nsRect bounds = aView->GetInvalidationDimensions();
|
||||
nsRect rect;
|
||||
rect.IntersectRect(aRect, bounds);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче