Bug 1282312 - Part 1: Invalidate direct rendering observers for a frame when we schedule a paint due to changes. r=mstange

This commit is contained in:
Matt Woodrow 2016-07-29 17:58:21 +12:00
parent fe3cfdc416
commit e45bc78bff

View File

@ -5467,6 +5467,51 @@ nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
0.0f);
}
static void InvalidateRenderingObservers(nsIFrame* aFrame)
{
nsSVGEffects::InvalidateDirectRenderingObservers(aFrame);
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame);
nsIFrame* parent = aFrame;
while (parent != displayRoot &&
(parent = nsLayoutUtils::GetCrossDocParentFrame(parent)) &&
!parent->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) {
nsSVGEffects::InvalidateDirectRenderingObservers(parent);
}
}
void
SchedulePaintInternal(nsIFrame* aFrame, nsIFrame::PaintType aType = nsIFrame::PAINT_DEFAULT)
{
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame);
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()->IsResourceDoc())) {
return;
}
if (!pres->GetContainerWeak()) {
NS_WARNING("Shouldn't call SchedulePaint in a detached pres context");
return;
}
pres->PresShell()->ScheduleViewManagerFlush(aType == nsIFrame::PAINT_DELAYED_COMPRESS ?
nsIPresShell::PAINT_DELAYED_COMPRESS :
nsIPresShell::PAINT_DEFAULT);
if (aType == nsIFrame::PAINT_DELAYED_COMPRESS) {
return;
}
if (aType == nsIFrame::PAINT_DEFAULT) {
displayRoot->AddStateBits(NS_FRAME_UPDATE_LAYER_TREE);
}
nsIPresShell* shell = aFrame->PresContext()->PresShell();
if (shell) {
shell->AddInvalidateHiddenPresShellObserver(pres->RefreshDriver());
}
}
static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = true)
{
if (aHasDisplayItem) {
@ -5501,7 +5546,7 @@ static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = tru
return;
}
if (needsSchedulePaint) {
aFrame->SchedulePaint();
SchedulePaintInternal(aFrame);
}
if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
aFrame->Properties().Delete(nsIFrame::InvalidationRect());
@ -5698,34 +5743,8 @@ nsIFrame::IsInvalid(nsRect& aRect)
void
nsIFrame::SchedulePaint(PaintType aType)
{
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()->IsResourceDoc())) {
return;
}
if (!pres->GetContainerWeak()) {
NS_WARNING("Shouldn't call SchedulePaint in a detached pres context");
return;
}
pres->PresShell()->ScheduleViewManagerFlush(aType == PAINT_DELAYED_COMPRESS ?
nsIPresShell::PAINT_DELAYED_COMPRESS :
nsIPresShell::PAINT_DEFAULT);
if (aType == PAINT_DELAYED_COMPRESS) {
return;
}
if (aType == PAINT_DEFAULT) {
displayRoot->AddStateBits(NS_FRAME_UPDATE_LAYER_TREE);
}
nsIPresShell* shell = PresContext()->PresShell();
if (shell) {
shell->AddInvalidateHiddenPresShellObserver(pres->RefreshDriver());
}
InvalidateRenderingObservers(this);
SchedulePaintInternal(this, aType);
}
Layer*
@ -5738,6 +5757,8 @@ nsIFrame::InvalidateLayer(uint32_t aDisplayItemKey,
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(this, aDisplayItemKey);
InvalidateRenderingObservers(this);
// If the layer is being updated asynchronously, and it's being forwarded
// to a compositor, then we don't need to invalidate.
if ((aFlags & UPDATE_IS_ASYNC) && layer &&
@ -5783,7 +5804,7 @@ nsIFrame::InvalidateLayer(uint32_t aDisplayItemKey,
layer->SetInvalidRectToVisibleRegion();
}
SchedulePaint(PAINT_COMPOSITE_ONLY);
SchedulePaintInternal(this, PAINT_COMPOSITE_ONLY);
return layer;
}