Bug 505896. Try to avoid invalidating plugins unnecessarily on Windows. r=jmathies

--HG--
extra : rebase_source : dfd12f047b693a61126e4d1c961a75a84fd6e9a2
This commit is contained in:
Robert O'Callahan 2009-07-27 09:19:15 +12:00
parent c95fd3cf9a
commit 75b988c589
4 changed files with 56 additions and 8 deletions

View File

@ -4457,7 +4457,8 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
nsresult
nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects)
{
StoreWindowClipRegion(aRects);
if (!StoreWindowClipRegion(aRects))
return NS_OK;
if (!mDrawingarea)
return NS_OK;

View File

@ -2299,11 +2299,22 @@ NS_IMETHODIMP nsWindow::Update()
*
**************************************************************/
static PRBool
ClipRegionContainedInRect(const nsTArray<nsIntRect>& aClipRects,
const nsIntRect& aRect)
{
for (PRUint32 i = 0; i < aClipRects.Length(); ++i) {
if (!aRect.Contains(aClipRects[i]))
return PR_FALSE;
}
return PR_TRUE;
}
void
nsWindow::Scroll(const nsIntPoint& aDelta, const nsIntRect& aSource,
const nsTArray<Configuration>& aConfigurations)
{
// We can use SW_SCROLLCHILDREN if all the windows that intersect the
// We use SW_SCROLLCHILDREN if all the windows that intersect the
// affected area are moving by the scroll amount.
// First, build the set of widgets that are to be moved by the scroll
// amount.
@ -2338,7 +2349,25 @@ nsWindow::Scroll(const nsIntPoint& aDelta, const nsIntRect& aSource,
}
}
nsIntRect destRect = aSource + aDelta;
if (flags & SW_SCROLLCHILDREN) {
for (PRUint32 i = 0; i < aConfigurations.Length(); ++i) {
const Configuration& configuration = aConfigurations[i];
nsWindow* w = static_cast<nsWindow*>(configuration.mChild);
// Widgets that will be scrolled by SW_SCROLLCHILDREN but which
// will be partly visible outside the scroll area after scrolling
// must be invalidated, because SW_SCROLLCHILDREN doesn't
// update parts of widgets outside the area it scrolled, even
// if it moved them.
if (w->mBounds.Intersects(affectedRect) &&
!ClipRegionContainedInRect(configuration.mClipRegion,
affectedRect - (w->mBounds.TopLeft() + aDelta))) {
w->Invalidate(PR_FALSE);
}
}
}
// Note that when SW_SCROLLCHILDREN is used, WM_MOVE messages are sent
// which will update the mBounds of the children.
RECT clip = { affectedRect.x, affectedRect.y, affectedRect.XMost(), affectedRect.YMost() };
::ScrollWindowEx(mWnd, aDelta.x, aDelta.y, &clip, &clip, NULL, NULL, flags);
@ -5540,9 +5569,15 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
// We put the region back just below, anyway.
::SetWindowRgn(w->mWnd, NULL, TRUE);
#endif
w->Resize(configuration.mBounds.x, configuration.mBounds.y,
configuration.mBounds.width, configuration.mBounds.height,
PR_TRUE);
nsIntRect bounds;
w->GetBounds(bounds);
if (bounds.Size() != configuration.mBounds.Size()) {
w->Resize(configuration.mBounds.x, configuration.mBounds.y,
configuration.mBounds.width, configuration.mBounds.height,
PR_TRUE);
} else if (bounds.TopLeft() != configuration.mBounds.TopLeft()) {
w->Move(configuration.mBounds.x, configuration.mBounds.y);
}
nsresult rv = w->SetWindowClipRegion(configuration.mClipRegion, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -5575,6 +5610,11 @@ nsresult
nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
PRBool aIntersectWithExisting)
{
if (!aIntersectWithExisting) {
if (!StoreWindowClipRegion(aRects))
return NS_OK;
}
HRGN dest = CreateHRGNFromArray(aRects);
if (!dest)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -561,14 +561,19 @@ nsTransparencyMode nsBaseWidget::GetTransparencyMode() {
return eTransparencyOpaque;
}
void
PRBool
nsBaseWidget::StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects)
{
if (mClipRects && mClipRectCount == aRects.Length() &&
memcmp(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount) == 0)
return PR_FALSE;
mClipRectCount = aRects.Length();
mClipRects = new nsIntRect[mClipRectCount];
if (mClipRects) {
memcpy(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount);
}
return PR_TRUE;
}
void

View File

@ -171,7 +171,9 @@ protected:
const nsAString& aUnmodifiedCharacters)
{ return NS_ERROR_UNEXPECTED; }
void StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
// Stores the clip rectangles in aRects into mClipRects. Returns true
// if the new rectangles are different from the old rectangles.
PRBool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
protected:
void* mClientData;