зеркало из 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;
|
mXResolution = aState.mXResolution;
|
||||||
mYResolution = aState.mYResolution;
|
mYResolution = aState.mYResolution;
|
||||||
|
|
||||||
// FIXME (Bug 593243 should fix this.)
|
nsIView* rootView;
|
||||||
//
|
if (NS_SUCCEEDED(mViewManager->GetRootView(rootView)) && rootView) {
|
||||||
// Invalidated content does not pay any attention to the displayport, so
|
rootView->SetInvalidationDimensions(&mDisplayPort);
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
||||||
if (rootPresContext) {
|
if (rootPresContext) {
|
||||||
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
|
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
|
||||||
|
|
|
@ -195,7 +195,15 @@ nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
||||||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
||||||
// This is the damage rect that we're going to pass up to our parent.
|
// This is the damage rect that we're going to pass up to our parent.
|
||||||
nsRect parentDamage;
|
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()) {
|
if (IsScrollingActive()) {
|
||||||
// This is the damage rect that we're going to pass up and
|
// 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);
|
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
||||||
// This is the damage rect that we're going to pass up to our parent.
|
// This is the damage rect that we're going to pass up to our parent.
|
||||||
nsRect parentDamage;
|
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()) {
|
if (IsScrollingActive()) {
|
||||||
// This is the damage rect that we're going to pass up and
|
// This is the damage rect that we're going to pass up and
|
||||||
|
|
|
@ -173,6 +173,17 @@ public:
|
||||||
*/
|
*/
|
||||||
nsRect GetBounds() const { return mDimBounds; }
|
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.
|
* Get the offset between the coordinate systems of |this| and aOther.
|
||||||
* Adding the return value to a point in the coordinate system of |this|
|
* 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;
|
mViewManager = aViewManager;
|
||||||
mDirtyRegion = nsnull;
|
mDirtyRegion = nsnull;
|
||||||
mDeletionObserver = nsnull;
|
mDeletionObserver = nsnull;
|
||||||
|
mHaveInvalidationDimensions = PR_FALSE;
|
||||||
mWidgetIsTopLevel = PR_FALSE;
|
mWidgetIsTopLevel = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +351,11 @@ void nsView::SetPosition(nscoord aX, nscoord aY)
|
||||||
ResetWidgetBounds(PR_TRUE, PR_TRUE, PR_FALSE);
|
ResetWidgetBounds(PR_TRUE, PR_TRUE, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsIView::SetInvalidationDimensions(const nsRect* aRect)
|
||||||
|
{
|
||||||
|
return Impl()->SetInvalidationDimensions(aRect);
|
||||||
|
}
|
||||||
|
|
||||||
void nsView::SetPositionIgnoringChildWidgets(nscoord aX, nscoord aY)
|
void nsView::SetPositionIgnoringChildWidgets(nscoord aX, nscoord aY)
|
||||||
{
|
{
|
||||||
mDimBounds.x += aX - mPosX;
|
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)
|
void nsView::NotifyEffectiveVisibilityChanged(PRBool aEffectivelyVisible)
|
||||||
{
|
{
|
||||||
if (!aEffectivelyVisible)
|
if (!aEffectivelyVisible)
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void SetDimensions(const nsRect &aRect, PRBool aPaint = PR_TRUE,
|
virtual void SetDimensions(const nsRect &aRect, PRBool aPaint = PR_TRUE,
|
||||||
PRBool aResizeWidget = 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(nsRect &aRect) const { aRect = mDimBounds; aRect.x -= mPosX; aRect.y -= mPosY; }
|
||||||
void GetDimensions(nsSize &aSize) const { aSize.width = mDimBounds.width; aSize.height = mDimBounds.height; }
|
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; }
|
nsRect GetDimensions() const { nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r; }
|
||||||
// Same as GetBounds but converts to parent appunits if they are different.
|
// Same as GetBounds but converts to parent appunits if they are different.
|
||||||
nsRect GetBoundsInParentUnits() const;
|
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
|
// These are defined exactly the same in nsIView, but for now they have to be redeclared
|
||||||
// here because of stupid C++ method hiding rules
|
// here because of stupid C++ method hiding rules
|
||||||
|
|
||||||
|
@ -202,6 +208,13 @@ protected:
|
||||||
void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize);
|
void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize);
|
||||||
|
|
||||||
nsRegion* mDirtyRegion;
|
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:
|
private:
|
||||||
void InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility);
|
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
|
// If the bounds don't overlap at all, there's nothing to do
|
||||||
nsRegion intersection;
|
nsRegion intersection;
|
||||||
intersection.And(aWidgetView->GetDimensions(), aDamagedRegion);
|
intersection.And(aWidgetView->GetInvalidationDimensions(), aDamagedRegion);
|
||||||
if (intersection.IsEmpty()) {
|
if (intersection.IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1623,7 @@ nsIntRect nsViewManager::ViewToWidget(nsView *aView, const nsRect &aRect) const
|
||||||
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
|
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
|
||||||
|
|
||||||
// intersect aRect with bounds of aView, to prevent generating any illegal rectangles.
|
// intersect aRect with bounds of aView, to prevent generating any illegal rectangles.
|
||||||
nsRect bounds = aView->GetDimensions();
|
nsRect bounds = aView->GetInvalidationDimensions();
|
||||||
nsRect rect;
|
nsRect rect;
|
||||||
rect.IntersectRect(aRect, bounds);
|
rect.IntersectRect(aRect, bounds);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче