зеркало из 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;
|
nsIFrame* f = aObject->mFrame;
|
||||||
aObject->mFrame = nullptr;
|
aObject->mFrame = nullptr;
|
||||||
f->Properties().Delete(LayerActivityProperty());
|
f->Properties().Delete(LayerActivityProperty());
|
||||||
f->InvalidateFrameSubtree();
|
|
||||||
|
// 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
|
void
|
||||||
|
@ -4752,12 +4763,40 @@ nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
|
||||||
0.0f);
|
0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = true)
|
||||||
nsIFrame::InvalidateFrameSubtree()
|
|
||||||
{
|
{
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4796,41 +4835,30 @@ nsIFrame::ClearInvalidationStateBits()
|
||||||
NS_FRAME_ALL_DESCENDANTS_NEED_PAINT);
|
NS_FRAME_ALL_DESCENDANTS_NEED_PAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InvalidateFrameInternal(nsIFrame *aFrame)
|
void
|
||||||
|
nsIFrame::InvalidateFrame(uint32_t aDisplayItemKey)
|
||||||
{
|
{
|
||||||
aFrame->AddStateBits(NS_FRAME_NEEDS_PAINT);
|
bool hasDisplayItem =
|
||||||
nsSVGEffects::InvalidateDirectRenderingObservers(aFrame);
|
!aDisplayItemKey || FrameLayerBuilder::HasRetainedDataFor(this, aDisplayItemKey);
|
||||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
InvalidateFrameInternal(this, hasDisplayItem);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIFrame::InvalidateFrame()
|
nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
|
||||||
{
|
|
||||||
InvalidateFrameInternal(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateFrameWithRect(const nsRect& aRect)
|
|
||||||
{
|
{
|
||||||
|
bool hasDisplayItem =
|
||||||
|
!aDisplayItemKey || FrameLayerBuilder::HasRetainedDataFor(this, aDisplayItemKey);
|
||||||
bool alreadyInvalid = false;
|
bool alreadyInvalid = false;
|
||||||
if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) {
|
if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) {
|
||||||
InvalidateFrameInternal(this);
|
InvalidateFrameInternal(this, hasDisplayItem);
|
||||||
} else {
|
} else {
|
||||||
alreadyInvalid = true;
|
alreadyInvalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasDisplayItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsRect *rect = static_cast<nsRect*>(Properties().Get(InvalidationRect()));
|
nsRect *rect = static_cast<nsRect*>(Properties().Get(InvalidationRect()));
|
||||||
if (!rect) {
|
if (!rect) {
|
||||||
if (alreadyInvalid) {
|
if (alreadyInvalid) {
|
||||||
|
@ -4894,7 +4922,14 @@ nsIFrame::InvalidateLayer(uint32_t aDisplayItemKey, const nsIntRect* aDamageRect
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
InvalidateFrame();
|
// 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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2183,8 +2183,12 @@ public:
|
||||||
*
|
*
|
||||||
* This includes all display items created by this frame, including
|
* This includes all display items created by this frame, including
|
||||||
* container types.
|
* 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
|
* 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
|
* @param aRect The rect to invalidate, relative to the TopLeft of the
|
||||||
* frame's border box.
|
* 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
|
* Calls InvalidateFrame() on all frames descendant frames (including
|
||||||
|
@ -2201,12 +2208,17 @@ public:
|
||||||
*
|
*
|
||||||
* This function doesn't walk through placeholder frames to invalidate
|
* This function doesn't walk through placeholder frames to invalidate
|
||||||
* the out-of-flow frames.
|
* 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.
|
* Called when a frame is about to be removed and needs to be invalidated.
|
||||||
* Normally does nothing since DLBI handles removed frames.
|
* Normally does nothing since DLBI handles removed frames.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
virtual void InvalidateFrameForRemoval() {}
|
virtual void InvalidateFrameForRemoval() {}
|
||||||
|
|
||||||
|
|
|
@ -592,10 +592,14 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||||
printf("Source rect (%d,%d,%d,%d)\n",
|
printf("Source rect (%d,%d,%d,%d)\n",
|
||||||
aRect->x, aRect->y, aRect->width, aRect->height);
|
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (aRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) {
|
if (aRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect())) {
|
||||||
InvalidateFrame();
|
InvalidateFrame(nsDisplayItem::TYPE_IMAGE);
|
||||||
|
InvalidateFrame(nsDisplayItem::TYPE_ALT_FEEDBACK);
|
||||||
} else {
|
} else {
|
||||||
InvalidateFrameWithRect(SourceRectToDest(*aRect));
|
nsRect invalid = SourceRectToDest(*aRect);
|
||||||
|
InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_IMAGE);
|
||||||
|
InvalidateFrameWithRect(invalid, nsDisplayItem::TYPE_ALT_FEEDBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче