зеркало из https://github.com/mozilla/gecko-dev.git
Bug 564991. Part 13: Optimize invalidation to avoid repainting ThebesLayer contents sometimes. r=mats,sr=dbaron
This commit is contained in:
Родитель
4b1b78c893
Коммит
2e3d02e038
|
@ -46,6 +46,7 @@
|
|||
#include "jsapi.h"
|
||||
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "BasicLayers.h"
|
||||
|
||||
|
@ -502,10 +503,10 @@ nsHTMLCanvasElement::InvalidateFrame(const gfxRect* damageRect)
|
|||
// account for border/padding
|
||||
invalRect.MoveBy(contentArea.TopLeft() - frame->GetPosition());
|
||||
|
||||
frame->Invalidate(invalRect);
|
||||
frame->InvalidateLayer(invalRect, nsDisplayItem::TYPE_CANVAS);
|
||||
} else {
|
||||
nsRect r(frame->GetContentRect() - frame->GetPosition());
|
||||
frame->Invalidate(r);
|
||||
frame->InvalidateLayer(r, nsDisplayItem::TYPE_CANVAS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "gfxImageSurface.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include "gfxQuartzImageSurface.h"
|
||||
|
@ -149,8 +150,9 @@ void nsMediaDecoder::Invalidate()
|
|||
}
|
||||
|
||||
if (frame) {
|
||||
nsRect r(nsPoint(0,0), frame->GetSize());
|
||||
frame->Invalidate(r);
|
||||
nsRect contentRect = frame->GetContentRect() - frame->GetPosition();
|
||||
// Only the layer needs to be updated here
|
||||
frame->InvalidateLayer(contentRect, nsDisplayItem::TYPE_VIDEO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1004,6 +1004,27 @@ FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
FrameLayerBuilder::HasDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
|
||||
{
|
||||
void* propValue = aFrame->Properties().Get(DisplayItemDataProperty());
|
||||
if (!propValue)
|
||||
return PR_FALSE;
|
||||
|
||||
nsTArray<DisplayItemData>* array =
|
||||
(reinterpret_cast<nsTArray<DisplayItemData>*>(&propValue));
|
||||
for (PRUint32 i = 0; i < array->Length(); ++i) {
|
||||
if (array->ElementAt(i).mDisplayItemKey == aDisplayItemKey) {
|
||||
void* layerUserData = array->ElementAt(i).mLayer->GetUserData();
|
||||
if (layerUserData != &gColorLayerUserData &&
|
||||
layerUserData != &gThebesDisplayItemLayerUserData)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
||||
gfxContext* aContext,
|
||||
|
|
|
@ -170,7 +170,13 @@ public:
|
|||
* the next paint.
|
||||
*/
|
||||
static void InvalidateAllLayers(LayerManager* aManager);
|
||||
|
||||
|
||||
/**
|
||||
* Call this to determine if a frame has a dedicated (non-Thebes) layer
|
||||
* for the given display item key.
|
||||
*/
|
||||
static PRBool HasDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
||||
|
||||
/**
|
||||
* This callback must be provided to EndTransaction. The callback data
|
||||
* must be the nsDisplayListBuilder containing this FrameLayerBuilder.
|
||||
|
|
|
@ -7670,6 +7670,10 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame,
|
|||
aFrame->InvalidateOverflowRect();
|
||||
}
|
||||
}
|
||||
if (aChange & nsChangeHint_UpdateOpacityLayer) {
|
||||
aFrame->InvalidateLayer(aFrame->GetOverflowRectRelativeToSelf(),
|
||||
nsDisplayItem::TYPE_OPACITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7952,7 +7956,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
StyleChangeReflow(frame, hint);
|
||||
didReflow = PR_TRUE;
|
||||
}
|
||||
if (hint & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView)) {
|
||||
if (hint & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView |
|
||||
nsChangeHint_UpdateOpacityLayer)) {
|
||||
ApplyRenderingChangeToTree(presContext, frame, hint);
|
||||
didInvalidate = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -82,9 +82,15 @@ enum nsChangeHint {
|
|||
*/
|
||||
nsChangeHint_UpdateEffects = 0x80,
|
||||
|
||||
/**
|
||||
* Visual change only, but the change can be handled entirely by
|
||||
* updating the layer(s) for the frame.
|
||||
*/
|
||||
nsChangeHint_UpdateOpacityLayer = 0x100,
|
||||
|
||||
// change requires frame change (e.g., display:).
|
||||
// This subsumes all the above.
|
||||
nsChangeHint_ReconstructFrame = 0x100
|
||||
nsChangeHint_ReconstructFrame = 0x200
|
||||
};
|
||||
|
||||
// Redefine these operators to return nothing. This will catch any use
|
||||
|
|
|
@ -3679,6 +3679,19 @@ nsIFrame::IsLeaf() const
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey)
|
||||
{
|
||||
NS_ASSERTION(aDisplayItemKey > 0, "Need a key");
|
||||
|
||||
if (!FrameLayerBuilder::HasDedicatedLayer(this, aDisplayItemKey)) {
|
||||
Invalidate(aDamageRect);
|
||||
return;
|
||||
}
|
||||
|
||||
InvalidateWithFlags(aDamageRect, INVALIDATE_NO_THEBES_LAYERS);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags)
|
||||
{
|
||||
|
|
|
@ -1835,6 +1835,15 @@ public:
|
|||
void Invalidate(const nsRect& aDamageRect)
|
||||
{ return InvalidateWithFlags(aDamageRect, 0); }
|
||||
|
||||
/**
|
||||
* As Invalidate above, except that this should be called when the
|
||||
* rendering that has changed is performed using layers so we can avoid
|
||||
* updating the contents of ThebesLayers.
|
||||
* @param aDisplayItemKey must not be zero; indicates the kind of display
|
||||
* item that is being invalidated.
|
||||
*/
|
||||
void InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey);
|
||||
|
||||
/**
|
||||
* Helper function that can be overridden by frame classes. The rectangle
|
||||
* (plus aOffsetX/aOffsetY) is relative to this frame.
|
||||
|
|
|
@ -412,9 +412,6 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
|
|||
// our position in the rule node tree is also the same.
|
||||
PRBool compare = mRuleNode != aOther->mRuleNode;
|
||||
|
||||
nsChangeHint maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
|
||||
nsChangeHint_UpdateCursor);
|
||||
|
||||
#define DO_STRUCT_DIFFERENCE(struct_) \
|
||||
PR_BEGIN_MACRO \
|
||||
NS_ASSERTION(NS_IsHintSubset(nsStyle##struct_::MaxDifference(), maxHint), \
|
||||
|
@ -438,7 +435,12 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
|
|||
// causing the maximal difference, a FRAMECHANGE.
|
||||
// FRAMECHANGE Structs: Display, XUL, Content, UserInterface,
|
||||
// Visibility, Outline, TableBorder, Table, Text, UIReset, Quotes
|
||||
nsChangeHint maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
|
||||
nsChangeHint_UpdateOpacityLayer);
|
||||
DO_STRUCT_DIFFERENCE(Display);
|
||||
|
||||
maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
|
||||
nsChangeHint_UpdateCursor);
|
||||
DO_STRUCT_DIFFERENCE(XUL);
|
||||
DO_STRUCT_DIFFERENCE(Column);
|
||||
DO_STRUCT_DIFFERENCE(Content);
|
||||
|
|
|
@ -1890,8 +1890,9 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
|
|||
|| mAppearance != aOther.mAppearance)
|
||||
NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame));
|
||||
|
||||
if (mOpacity != aOther.mOpacity)
|
||||
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
|
||||
if (mOpacity != aOther.mOpacity) {
|
||||
NS_UpdateHint(hint, nsChangeHint_UpdateOpacityLayer);
|
||||
}
|
||||
|
||||
/* If we've added or removed the transform property, we need to reconstruct the frame to add
|
||||
* or remove the view object, and also to handle abs-pos and fixed-pos containers.
|
||||
|
@ -1936,7 +1937,8 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
|
|||
nsChangeHint nsStyleDisplay::MaxDifference()
|
||||
{
|
||||
// All the parts of FRAMECHANGE are present above in CalcDifference.
|
||||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
|
||||
nsChangeHint_UpdateOpacityLayer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче