Bug 442291. Avoid the bitblit scrolling path completely if the area to be repainted is more than half the area to scroll. The goal is to avoid the synchronous repaint required by bitblitting (synchronicity is required to minimize the delay between blitting and repainting --- the intermediate display is very ugly). Also, make scroll-induced full-view repainting DEFERRED, so that it's less urgent and more apt to coalesce, so we drop frames more easily when painting can't keep up during scrolling. r+sr=bz

This commit is contained in:
Robert O'Callahan 2008-09-06 20:42:47 +12:00
parent 1bc2d8883a
commit b934dd7421
3 changed files with 10 additions and 4 deletions

View File

@ -546,7 +546,7 @@ void nsScrollPortView::Scroll(nsView *aScrolledView, nsPoint aTwipsDelta, nsPoin
// If we don't have a scroll widget then we must just update.
// We should call this after fixing up the widget positions to be
// consistent with the view hierarchy.
mViewManager->UpdateView(this, 0);
mViewManager->UpdateView(this, NS_VMREFRESH_DEFERRED);
} else if (!canBitBlit) {
// We can't blit for some reason.
// Just update the view and adjust widgets
@ -557,7 +557,7 @@ void nsScrollPortView::Scroll(nsView *aScrolledView, nsPoint aTwipsDelta, nsPoin
GetPosition() - topLeft, aP2A, PR_FALSE);
// We should call this after fixing up the widget positions to be
// consistent with the view hierarchy.
mViewManager->UpdateView(this, 0);
mViewManager->UpdateView(this, NS_VMREFRESH_DEFERRED);
} else { // if we can blit and have a scrollwidget then scroll.
nsRect* toScrollPtr = nsnull;

View File

@ -1685,6 +1685,11 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
return NS_OK;
}
static double GetArea(const nsRect& aRect)
{
return double(aRect.width)*double(aRect.height);
}
PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView, nsPoint aDelta,
nsRegion* aUpdateRegion)
{
@ -1711,7 +1716,7 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView, nsPoint aDelta,
#if defined(MOZ_WIDGET_GTK2) || defined(XP_OS2)
return aUpdateRegion->IsEmpty();
#else
return PR_TRUE;
return GetArea(aUpdateRegion->GetBounds()) < GetArea(parentBounds)/2;
#endif
}

View File

@ -395,7 +395,8 @@ public: // NOT in nsIViewManager, so private to the view module
nsresult WillBitBlit(nsView* aView, nsPoint aScrollAmount);
/**
* Called to inform the view manager that a view has scrolled.
* Called to inform the view manager that a view has scrolled via a
* bitblit.
* The view manager will invalidate any widgets which may need
* to be rerendered.
* @param aView view to paint. should be the nsScrollPortView that