Bug 724189. Don't invalidate entire frame when the frame has shadows or effects and the post-transform overflow area changes. r=mats

This commit is contained in:
Robert O'Callahan 2012-02-05 21:14:00 -08:00
Родитель 72407e61a6
Коммит 986c3c419f
1 изменённых файлов: 23 добавлений и 21 удалений

Просмотреть файл

@ -6729,6 +6729,9 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
RemoveStateBits(NS_FRAME_HAS_CLIP);
}
bool preTransformVisualOverflowChanged =
!GetVisualOverflowRectRelativeToSelf().IsEqualInterior(aOverflowAreas.VisualOverflow());
/* If we're transformed, transform the overflow rect by the current transformation. */
bool hasTransform = IsTransformed();
if (hasTransform) {
@ -6751,8 +6754,6 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty());
}
bool visualOverflowChanged =
!GetVisualOverflowRect().IsEqualInterior(aOverflowAreas.VisualOverflow());
bool anyOverflowChanged;
if (aOverflowAreas != nsOverflowAreas(bounds, bounds)) {
anyOverflowChanged = SetOverflowAreas(aOverflowAreas);
@ -6760,7 +6761,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
anyOverflowChanged = ClearOverflowRects();
}
if (visualOverflowChanged) {
if (preTransformVisualOverflowChanged) {
if (hasOutlineOrEffects) {
// When there's an outline or box-shadow or SVG effects,
// changes to those styles might require repainting of the old and new
@ -6782,26 +6783,27 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
// changed (in particular, if it grows), we have to repaint the
// new area here.
Invalidate(aOverflowAreas.VisualOverflow());
} else if (hasTransform) {
// When there's a transform, changes to that style might require
// repainting of the old and new overflow areas in the widget.
// Repainting of the frame itself will not be required if there's
// a retained layer, so we can call InvalidateLayer here
// which will avoid repainting ThebesLayers if possible.
// nsCSSFrameConstructor::DoApplyRenderingChangeToTree repaints
// the old overflow area in the widget in response to
// nsChangeHint_UpdateTransformLayer. But since the new overflow
// area is not known at that time, we have to handle it here.
// If the overflow area hasn't changed, then it doesn't matter that
// we didn't reach here since repainting the old overflow area was enough.
// If there is no transform now, then the container layer for
// the transform will go away and the frame contents will change
// ThebesLayers, forcing it to be invalidated, so it doesn't matter
// that we didn't reach here.
InvalidateLayer(aOverflowAreas.VisualOverflow(),
nsDisplayItem::TYPE_TRANSFORM);
}
}
if (anyOverflowChanged && hasTransform) {
// When there's a transform, changes to that style might require
// repainting of the old and new overflow areas in the widget.
// Repainting of the frame itself will not be required if there's
// a retained layer, so we can call InvalidateLayer here
// which will avoid repainting ThebesLayers if possible.
// nsCSSFrameConstructor::DoApplyRenderingChangeToTree repaints
// the old overflow area in the widget in response to
// nsChangeHint_UpdateTransformLayer. But since the new overflow
// area is not known at that time, we have to handle it here.
// If the overflow area hasn't changed, then it doesn't matter that
// we didn't reach here since repainting the old overflow area was enough.
// If there is no transform now, then the container layer for
// the transform will go away and the frame contents will change
// ThebesLayers, forcing it to be invalidated, so it doesn't matter
// that we didn't reach here.
InvalidateLayer(aOverflowAreas.VisualOverflow(),
nsDisplayItem::TYPE_TRANSFORM);
}
return anyOverflowChanged;
}