mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 539356 - Part 19 - Only repaint retained layers after the previous repainted has been drawn to the window. r=roc
This commit is contained in:
parent
dbca7f19d8
commit
895528986f
@ -415,7 +415,8 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
|
||||
printf("Starting ProcessPendingUpdates\n");
|
||||
#endif
|
||||
mViewManagerFlushIsPending = false;
|
||||
mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
|
||||
bool skippedFlush = mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
|
||||
mViewManagerFlushIsPending |= skippedFlush;
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Ending ProcessPendingUpdates\n");
|
||||
#endif
|
||||
|
@ -296,8 +296,11 @@ public:
|
||||
/**
|
||||
* Flush the accumulated dirty region to the widget and update widget
|
||||
* geometry.
|
||||
*
|
||||
* @param True if a paint was skipped due to throttling and this
|
||||
* should be called again after a delay.
|
||||
*/
|
||||
virtual void ProcessPendingUpdates()=0;
|
||||
virtual bool ProcessPendingUpdates()=0;
|
||||
|
||||
/**
|
||||
* Just update widget geometry without flushing the dirty region
|
||||
|
@ -176,6 +176,8 @@ nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
|
||||
mDirtyRegion = nsnull;
|
||||
mDeletionObserver = nsnull;
|
||||
mWidgetIsTopLevel = false;
|
||||
mPendingRefresh = false;
|
||||
mSkippedPaints = 0;
|
||||
}
|
||||
|
||||
void nsView::DropMouseGrabbing()
|
||||
|
@ -162,6 +162,13 @@ public:
|
||||
nsPoint GetOffsetTo(const nsView* aOther, const PRInt32 aAPD) const;
|
||||
nsIWidget* GetNearestWidget(nsPoint* aOffset, const PRInt32 aAPD) const;
|
||||
|
||||
void SetPendingRefresh(bool aPending) { mPendingRefresh = aPending; }
|
||||
bool PendingRefresh() { return mPendingRefresh; }
|
||||
|
||||
void SkippedPaint() { mSkippedPaints++; }
|
||||
void ClearSkippedPaints() { mSkippedPaints = 0; }
|
||||
PRUint32 SkippedPaints() { return mSkippedPaints; }
|
||||
|
||||
protected:
|
||||
// Do the actual work of ResetWidgetBounds, unconditionally. Don't
|
||||
// call this method if we have no widget.
|
||||
@ -169,6 +176,15 @@ protected:
|
||||
|
||||
nsRegion* mDirtyRegion;
|
||||
|
||||
// True if the view has invalidate scheduled with the widget
|
||||
// and is waiting for nsViewManager::Refresh to be called.
|
||||
bool mPendingRefresh;
|
||||
|
||||
// True if a paint event was skipped while mPendingRefresh was
|
||||
// true, and a new one should be scheduled once we get
|
||||
// nsViewManager::Refresh called.
|
||||
PRUint32 mSkippedPaints;
|
||||
|
||||
private:
|
||||
void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
|
||||
};
|
||||
|
@ -303,6 +303,11 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion,
|
||||
bool aWillSendDidPaint)
|
||||
{
|
||||
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
|
||||
aView->SetPendingRefresh(false);
|
||||
if (aView->SkippedPaints()) {
|
||||
RootViewManager()->GetPresShell()->ScheduleViewManagerFlush(true);
|
||||
aView->ClearSkippedPaints();
|
||||
}
|
||||
|
||||
// damageRegion is the damaged area, in twips, relative to the view origin
|
||||
nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
|
||||
@ -354,14 +359,14 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion,
|
||||
}
|
||||
}
|
||||
|
||||
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
bool nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
bool aFlushDirtyRegion)
|
||||
{
|
||||
NS_ASSERTION(IsRootVM(), "Updates will be missed");
|
||||
|
||||
// Protect against a null-view.
|
||||
if (!aView) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aView->HasWidget()) {
|
||||
@ -369,9 +374,10 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
}
|
||||
|
||||
// process pending updates in child view.
|
||||
bool skipped = false;
|
||||
for (nsView* childView = aView->GetFirstChild(); childView;
|
||||
childView = childView->GetNextSibling()) {
|
||||
ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
|
||||
skipped |= ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
|
||||
}
|
||||
|
||||
// Push out updates after we've processed the children; ensures that
|
||||
@ -379,18 +385,28 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
if (aFlushDirtyRegion) {
|
||||
nsIWidget *widget = aView->GetWidget();
|
||||
if (widget && widget->NeedsPaint()) {
|
||||
widget->SetNeedsPaint(false);
|
||||
if (aView->PendingRefresh() && aView->SkippedPaints() < 5) {
|
||||
aView->SkippedPaint();
|
||||
skipped = true;
|
||||
} else {
|
||||
aView->ClearSkippedPaints();
|
||||
aView->SetPendingRefresh(false);
|
||||
widget->SetNeedsPaint(false);
|
||||
SetPainting(true);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
|
||||
printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
|
||||
#endif
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, false);
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, false);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("---- PAINT END ----\n");
|
||||
printf("---- PAINT END ----\n");
|
||||
#endif
|
||||
SetPainting(false);
|
||||
}
|
||||
}
|
||||
FlushDirtyRegionToWidget(aView);
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
|
||||
void nsViewManager::FlushDirtyRegionToWidget(nsView* aView)
|
||||
@ -433,7 +449,7 @@ nsViewManager::PostPendingUpdate()
|
||||
{
|
||||
nsViewManager* rootVM = RootViewManager();
|
||||
rootVM->mHasPendingWidgetGeometryChanges = true;
|
||||
if (rootVM->mPresShell) {
|
||||
if (rootVM->mPresShell && !rootVM->IsPainting()) {
|
||||
rootVM->mPresShell->ScheduleViewManagerFlush(nsIFrame::PAINT_COMPOSITE_ONLY);
|
||||
}
|
||||
}
|
||||
@ -516,6 +532,7 @@ nsViewManager::InvalidateWidgetArea(nsView *aWidgetView,
|
||||
leftOver.Sub(aDamagedRegion, children);
|
||||
|
||||
if (!leftOver.IsEmpty()) {
|
||||
aWidgetView->SetPendingRefresh(true);
|
||||
const nsRect* r;
|
||||
for (nsRegionRectIterator iter(leftOver); (r = iter.Next());) {
|
||||
nsIntRect bounds = ViewToWidget(aWidgetView, *r);
|
||||
@ -1302,16 +1319,15 @@ nsViewManager::IsPainting(bool& aIsPainting)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
nsViewManager::ProcessPendingUpdates()
|
||||
{
|
||||
if (!IsRootVM()) {
|
||||
RootViewManager()->ProcessPendingUpdates();
|
||||
return;
|
||||
return RootViewManager()->ProcessPendingUpdates();
|
||||
}
|
||||
|
||||
mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
|
||||
ProcessPendingUpdatesForView(mRootView, true);
|
||||
return ProcessPendingUpdatesForView(mRootView, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
/* Update the cached RootViewManager pointer on this view manager. */
|
||||
void InvalidateHierarchy();
|
||||
|
||||
virtual void ProcessPendingUpdates();
|
||||
virtual bool ProcessPendingUpdates();
|
||||
virtual void UpdateWidgetGeometry();
|
||||
|
||||
protected:
|
||||
@ -114,7 +114,10 @@ protected:
|
||||
private:
|
||||
|
||||
void FlushPendingInvalidates();
|
||||
void ProcessPendingUpdatesForView(nsView *aView,
|
||||
/* Returns true if we skipped painting a view and we should try
|
||||
* again later.
|
||||
*/
|
||||
bool ProcessPendingUpdatesForView(nsView *aView,
|
||||
bool aFlushDirtyRegion = true);
|
||||
void FlushDirtyRegionToWidget(nsView* aView);
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user