Bug 539356 - Part 11 - Reimplement empty transactions. r=roc

This commit is contained in:
Matt Woodrow 2012-06-30 15:06:12 +12:00
parent 4b10a2b53c
commit 67eaa8edd4
6 changed files with 69 additions and 16 deletions

View File

@ -1229,7 +1229,16 @@ public:
* root pres shell.
*/
virtual void DidPaint() = 0;
virtual void ScheduleViewManagerFlush() = 0;
/**
* Ensures that the refresh driver is running, and schedules a view
* manager flush on the next tick.
*
* @param aFlags nsIFrame::PAINT_COMPOSITE_ONLY : No changes have
* been made that require a layer tree update, so only schedule a
* layer tree composite.
*/
virtual void ScheduleViewManagerFlush(PRUint32 aFlags = 0) = 0;
virtual void ClearMouseCaptureOnView(nsIView* aView) = 0;
virtual bool IsVisible() = 0;
virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;

View File

@ -170,6 +170,7 @@
#include "sampler.h"
#include "Layers.h"
#include "LayerTreeInvalidation.h"
#include "nsAsyncDOMEvent.h"
#ifdef NS_FUNCTION_TIMER
@ -3374,11 +3375,14 @@ PresShell::GetRectVisibility(nsIFrame* aFrame,
}
void
PresShell::ScheduleViewManagerFlush()
PresShell::ScheduleViewManagerFlush(PRUint32 aFlags)
{
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->RefreshDriver()->ScheduleViewManagerFlush();
if (!(aFlags & nsIFrame::PAINT_COMPOSITE_ONLY)) {
mPaintRequired = true;
}
}
if (mDocument) {
mDocument->SetNeedLayoutFlush();
@ -5238,7 +5242,7 @@ PresShell::Paint(nsIView* aViewToPaint,
// need to be updated. Do not try to do an empty transaction on
// a non-retained layer manager (like the BasicLayerManager that
// draws the window title bar on Mac), because a) it won't work
// and b) below we don't want to clear NS_FRAME_UPDATE_LAYER_TREE,
// and b) below we don't want to clear mPaintRequired,
// that will cause us to forget to update the real layer manager!
if (aType == PaintType_Composite) {
if (layerManager->HasShadowManager()) {
@ -5253,7 +5257,40 @@ PresShell::Paint(nsIView* aViewToPaint,
layerManager->BeginTransaction();
}
frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
if (!mPaintRequired) {
NotifySubDocInvalidationFunc computeInvalidFunc =
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
bool computeInvalidRect = computeInvalidFunc ||
(layerManager->GetBackendType() == LayerManager::LAYERS_BASIC);
nsAutoPtr<LayerProperties> props(computeInvalidRect ?
LayerProperties::CloneFrom(layerManager->GetRoot()) :
nsnull);
if (layerManager->EndEmptyTransaction()) {
nsIntRect invalid;
if (props) {
invalid = props->ComputeDifferences(layerManager->GetRoot(), computeInvalidFunc);
}
if (!invalid.IsEmpty()) {
if (props) {
nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
presContext->DevPixelsToAppUnits(invalid.y),
presContext->DevPixelsToAppUnits(invalid.width),
presContext->DevPixelsToAppUnits(invalid.height));
aViewToPaint->GetViewManager()->InvalidateViewNoSuppression(aViewToPaint, rect);
presContext->NotifyInvalidation(invalid, 0);
} else {
aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
}
}
frame->UpdatePaintCountForPaintedPresShells();
presContext->NotifyDidPaintForSubtree();
return;
}
}
mPaintRequired = false;
} else {
layerManager->BeginTransaction();
}

View File

@ -199,7 +199,7 @@ public:
virtual bool ShouldIgnoreInvalidation();
virtual void WillPaint(bool aWillSendDidPaint);
virtual void DidPaint();
virtual void ScheduleViewManagerFlush();
virtual void ScheduleViewManagerFlush(PRUint32 aFlags = 0);
virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange);
virtual void ClearMouseCaptureOnView(nsIView* aView);
virtual bool IsVisible();
@ -768,6 +768,12 @@ protected:
bool mNoDelayedMouseEvents : 1;
bool mNoDelayedKeyEvents : 1;
// False if calls to Paint with the retaining manager can be handled
// with an empty transaction, True if we require painting and a layer
// tree update.
bool mPaintRequired : 1;
// We've been disconnected from the document. We will refuse to paint the
// document until either our timer fires or all frames are constructed.
bool mIsDocumentGone : 1;

View File

@ -4651,7 +4651,7 @@ nsIFrame::IsInvalid()
}
void
nsIFrame::SchedulePaint()
nsIFrame::SchedulePaint(PRUint32 aFlags)
{
nsPresContext *pres = PresContext()->GetRootPresContext();
if (HasAnyStateBits(NS_FRAME_IN_POPUP) || !pres) {
@ -4662,7 +4662,7 @@ nsIFrame::SchedulePaint()
}
pres = displayRoot->PresContext();
}
pres->PresShell()->ScheduleViewManagerFlush();
pres->PresShell()->ScheduleViewManagerFlush(aFlags);
}
Layer*
@ -4686,7 +4686,7 @@ nsIFrame::InvalidateLayer(PRUint32 aDisplayItemKey, const nsIntRect* aDamageRect
layer->SetInvalidRectToVisibleRegion();
}
SchedulePaint();
SchedulePaint(PAINT_COMPOSITE_ONLY);
return layer;
}

View File

@ -242,12 +242,6 @@ typedef PRUint64 nsFrameState;
// Frame's overflow area was clipped by the 'clip' property.
#define NS_FRAME_HAS_CLIP NS_FRAME_STATE_BIT(35)
// Frame is a display root and the retained layer tree needs to be updated
// at the next paint via display list construction.
// Only meaningful for display roots, so we don't really need a global state
// bit; we could free up this bit with a little extra complexity.
#define NS_FRAME_UPDATE_LAYER_TREE NS_FRAME_STATE_BIT(36)
// Frame can accept absolutely positioned children.
#define NS_FRAME_HAS_ABSPOS_CHILDREN NS_FRAME_STATE_BIT(37)
@ -2159,8 +2153,15 @@ public:
* The view manager flush will update the layer tree, repaint any
* invalid areas in the layer tree and schedule a layer tree
* composite operation to display the layer tree.
*
* @param aFlags PAINT_COMPOSITE_ONLY : No changes have been made
* that require a layer tree update, so only schedule a layer
* tree composite.
*/
void SchedulePaint();
enum {
PAINT_COMPOSITE_ONLY
};
void SchedulePaint(PRUint32 aFlags = 0);
/**
* Checks if the layer tree includes a dedicated layer for this

View File

@ -433,7 +433,7 @@ nsViewManager::PostPendingUpdate()
nsViewManager* rootVM = RootViewManager();
rootVM->mHasPendingWidgetGeometryChanges = true;
if (rootVM->mPresShell) {
rootVM->mPresShell->ScheduleViewManagerFlush();
rootVM->mPresShell->ScheduleViewManagerFlush(nsIFrame::PAINT_COMPOSITE_ONLY);
}
}