зеркало из https://github.com/mozilla/gecko-dev.git
Bug 539356 - Avoid some causes of unnecessary painting. r=roc
This commit is contained in:
Родитель
3724c42399
Коммит
58294c1b55
|
@ -4642,7 +4642,18 @@ LayerActivityTracker::NotifyExpired(LayerActivity* aObject)
|
|||
nsIFrame* f = aObject->mFrame;
|
||||
aObject->mFrame = nullptr;
|
||||
f->Properties().Delete(LayerActivityProperty());
|
||||
|
||||
// if there are hints other than transform/opacity, invalidate, since we don't know what else to do.
|
||||
if (aObject->mChangeHint & ~(nsChangeHint_UpdateOpacityLayer|nsChangeHint_UpdateTransformLayer)) {
|
||||
f->InvalidateFrameSubtree();
|
||||
} else {
|
||||
if (aObject->mChangeHint & nsChangeHint_UpdateOpacityLayer) {
|
||||
f->InvalidateFrameSubtree(nsDisplayItem::TYPE_OPACITY);
|
||||
}
|
||||
if (aObject->mChangeHint & nsChangeHint_UpdateTransformLayer) {
|
||||
f->InvalidateFrameSubtree(nsDisplayItem::TYPE_TRANSFORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4752,12 +4763,40 @@ nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
|
|||
0.0f);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateFrameSubtree()
|
||||
static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = true)
|
||||
{
|
||||
InvalidateFrame();
|
||||
if (aHasDisplayItem) {
|
||||
aFrame->AddStateBits(NS_FRAME_NEEDS_PAINT);
|
||||
}
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(aFrame);
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
while (parent && !parent->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) {
|
||||
if (aHasDisplayItem) {
|
||||
parent->AddStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||
}
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(parent);
|
||||
parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
|
||||
}
|
||||
if (!aHasDisplayItem) {
|
||||
return;
|
||||
}
|
||||
if (!parent) {
|
||||
aFrame->SchedulePaint();
|
||||
}
|
||||
if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
|
||||
aFrame->Properties().Delete(nsIFrame::InvalidationRect());
|
||||
aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasAnyStateBits(NS_FRAME_ALL_DESCENDANTS_NEED_PAINT)) {
|
||||
void
|
||||
nsIFrame::InvalidateFrameSubtree(uint32_t aDisplayItemKey)
|
||||
{
|
||||
bool hasDisplayItem =
|
||||
!aDisplayItemKey || FrameLayerBuilder::HasRetainedDataFor(this, aDisplayItemKey);
|
||||
InvalidateFrameInternal(this, hasDisplayItem);
|
||||
|
||||
if (HasAnyStateBits(NS_FRAME_ALL_DESCENDANTS_NEED_PAINT) || !hasDisplayItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4796,41 +4835,30 @@ nsIFrame::ClearInvalidationStateBits()
|
|||
NS_FRAME_ALL_DESCENDANTS_NEED_PAINT);
|
||||
}
|
||||
|
||||
static void InvalidateFrameInternal(nsIFrame *aFrame)
|
||||
void
|
||||
nsIFrame::InvalidateFrame(uint32_t aDisplayItemKey)
|
||||
{
|
||||
aFrame->AddStateBits(NS_FRAME_NEEDS_PAINT);
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(aFrame);
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
while (parent && !parent->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) {
|
||||
parent->AddStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(parent);
|
||||
parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
|
||||
}
|
||||
if (!parent) {
|
||||
aFrame->SchedulePaint();
|
||||
}
|
||||
if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
|
||||
aFrame->Properties().Delete(nsIFrame::InvalidationRect());
|
||||
aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT);
|
||||
}
|
||||
bool hasDisplayItem =
|
||||
!aDisplayItemKey || FrameLayerBuilder::HasRetainedDataFor(this, aDisplayItemKey);
|
||||
InvalidateFrameInternal(this, hasDisplayItem);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateFrame()
|
||||
{
|
||||
InvalidateFrameInternal(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::InvalidateFrameWithRect(const nsRect& aRect)
|
||||
nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
|
||||
{
|
||||
bool hasDisplayItem =
|
||||
!aDisplayItemKey || FrameLayerBuilder::HasRetainedDataFor(this, aDisplayItemKey);
|
||||
bool alreadyInvalid = false;
|
||||
if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) {
|
||||
InvalidateFrameInternal(this);
|
||||
InvalidateFrameInternal(this, hasDisplayItem);
|
||||
} else {
|
||||
alreadyInvalid = true;
|
||||
}
|
||||
|
||||
if (!hasDisplayItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRect *rect = static_cast<nsRect*>(Properties().Get(InvalidationRect()));
|
||||
if (!rect) {
|
||||
if (alreadyInvalid) {
|
||||
|
@ -4894,7 +4922,14 @@ nsIFrame::InvalidateLayer(uint32_t aDisplayItemKey, const nsIntRect* aDamageRect
|
|||
}
|
||||
|
||||
if (!layer) {
|
||||
// Plugins can transition from not rendering anything to rendering,
|
||||
// and still only call this. So always invalidate, with specifying
|
||||
// the display item type just in case.
|
||||
if (aDisplayItemKey == nsDisplayItem::TYPE_PLUGIN) {
|
||||
InvalidateFrame();
|
||||
} else {
|
||||
InvalidateFrame(aDisplayItemKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -2183,8 +2183,12 @@ public:
|
|||
*
|
||||
* This includes all display items created by this frame, including
|
||||
* container types.
|
||||
*
|
||||
* @param aDisplayItemKey If specified, only issues an invalidate
|
||||
* if this frame painted a display item of that type during the
|
||||
* previous paint. SVG rendering observers are always notified.
|
||||
*/
|
||||
virtual void InvalidateFrame();
|
||||
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0);
|
||||
|
||||
/**
|
||||
* Same as InvalidateFrame(), but only mark a fixed rect as needing
|
||||
|
@ -2192,8 +2196,11 @@ public:
|
|||
*
|
||||
* @param aRect The rect to invalidate, relative to the TopLeft of the
|
||||
* frame's border box.
|
||||
* @param aDisplayItemKey If specified, only issues an invalidate
|
||||
* if this frame painted a display item of that type during the
|
||||
* previous paint. SVG rendering observers are always notified.
|
||||
*/
|
||||
virtual void InvalidateFrameWithRect(const nsRect& aRect);
|
||||
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0);
|
||||
|
||||
/**
|
||||
* Calls InvalidateFrame() on all frames descendant frames (including
|
||||
|
@ -2201,12 +2208,17 @@ public:
|
|||
*
|
||||
* This function doesn't walk through placeholder frames to invalidate
|
||||
* the out-of-flow frames.
|
||||
*
|
||||
* @param aDisplayItemKey If specified, only issues an invalidate
|
||||
* if this frame painted a display item of that type during the
|
||||
* previous paint. SVG rendering observers are always notified.
|
||||
*/
|
||||
void InvalidateFrameSubtree();
|
||||
void InvalidateFrameSubtree(uint32_t aDisplayItemKey = 0);
|
||||
|
||||
/**
|
||||
* Called when a frame is about to be removed and needs to be invalidated.
|
||||
* Normally does nothing since DLBI handles removed frames.
|
||||
*
|
||||
*/
|
||||
virtual void InvalidateFrameForRemoval() {}
|
||||
|
||||
|
|
|
@ -592,10 +592,14 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||
printf("Source rect (%d,%d,%d,%d)\n",
|
||||
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
#endif
|
||||
|
||||
if (aRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) {
|
||||
InvalidateFrame();
|
||||
InvalidateFrame(nsDisplayItem::TYPE_IMAGE);
|
||||
InvalidateFrame(nsDisplayItem::TYPE_ALT_FEEDBACK);
|
||||
} else {
|
||||
InvalidateFrameWithRect(SourceRectToDest(*aRect));
|
||||
nsRect invalid = SourceRectToDest(*aRect);
|
||||
InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_IMAGE);
|
||||
InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_ALT_FEEDBACK);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче