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

This commit is contained in:
Matt Woodrow 2012-08-29 17:48:15 +12:00
parent e79b288e75
commit e195484e72
5 changed files with 64 additions and 19 deletions

View File

@ -1239,6 +1239,11 @@ public:
* root pres shell.
*/
virtual void DidPaint() = 0;
/**
* Ensures that the refresh driver is running, and schedules a view
* manager flush on the next tick.
*/
virtual void ScheduleViewManagerFlush() = 0;
virtual void ClearMouseCaptureOnView(nsIView* aView) = 0;
virtual bool IsVisible() = 0;

View File

@ -4005,8 +4005,11 @@ nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame)
// NS_FRAME_IN_POPUP frame bit is set.
nsIFrame* f = aFrame;
for (;;) {
if (IsPopup(f))
if (!f->HasAnyStateBits(NS_FRAME_IN_POPUP)) {
f = f->PresContext()->FrameManager()->GetRootFrame();
} else if (IsPopup(f)) {
return f;
}
nsIFrame* parent = GetCrossDocParentFrame(f);
if (!parent)
return f;

View File

@ -175,6 +175,7 @@
#include "mozilla/css/ImageLoader.h"
#include "Layers.h"
#include "LayerTreeInvalidation.h"
#include "nsAsyncDOMEvent.h"
#define ANCHOR_SCROLL_FLAGS (SCROLL_OVERFLOW_HIDDEN | SCROLL_NO_PARENT_FRAMES)
@ -5235,17 +5236,43 @@ PresShell::Paint(nsIView* aViewToPaint,
return;
}
NS_WARNING("Must complete empty transaction when compositing!");
} else if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
layerManager->BeginTransaction();
if (layerManager->EndEmptyTransaction((aType == PaintType_NoComposite) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT)) {
frame->UpdatePaintCountForPaintedPresShells();
presContext->NotifyDidPaintForSubtree();
return;
}
} else {
layerManager->BeginTransaction();
}
if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
NotifySubDocInvalidationFunc computeInvalidFunc =
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
bool computeInvalidRect = computeInvalidFunc ||
(layerManager->GetBackendType() == LAYERS_BASIC);
nsAutoPtr<LayerProperties> props(computeInvalidRect ?
LayerProperties::CloneFrom(layerManager->GetRoot()) :
nullptr);
if (layerManager->EndEmptyTransaction((aType == PaintType_NoComposite) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT)) {
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;
}
}
frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
} else {
layerManager->BeginTransaction();

View File

@ -4808,18 +4808,21 @@ nsIFrame::IsInvalid()
}
void
nsIFrame::SchedulePaint()
nsIFrame::SchedulePaint(uint32_t aFlags)
{
nsPresContext *pres = PresContext()->GetRootPresContext();
if (HasAnyStateBits(NS_FRAME_IN_POPUP) || !pres) {
nsIFrame *displayRoot = nsLayoutUtils::GetDisplayRootFrame(this);
NS_ASSERTION(displayRoot, "Need a display root to schedule a paint!");
if (!displayRoot) {
return;
}
pres = displayRoot->PresContext();
nsIFrame *displayRoot = nsLayoutUtils::GetDisplayRootFrame(this);
nsPresContext *pres = displayRoot->PresContext()->GetRootPresContext();
// No need to schedule a paint for an external document since they aren't
// painted directly.
if (!pres || (pres->Document() && pres->Document()->GetDisplayDocument())) {
return;
}
pres->PresShell()->ScheduleViewManagerFlush();
if (!(aFlags & PAINT_COMPOSITE_ONLY)) {
displayRoot->AddStateBits(NS_FRAME_UPDATE_LAYER_TREE);
}
}
Layer*
@ -4843,7 +4846,7 @@ nsIFrame::InvalidateLayer(uint32_t aDisplayItemKey, const nsIntRect* aDamageRect
layer->SetInvalidRectToVisibleRegion();
}
SchedulePaint();
SchedulePaint(PAINT_COMPOSITE_ONLY);
return layer;
}

View File

@ -2216,8 +2216,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(uint32_t aFlags = 0);
/**
* Checks if the layer tree includes a dedicated layer for this