зеркало из https://github.com/mozilla/gecko-dev.git
Bug 770001. When comparing clips, adjust for any change in the ThebesLayer coordinate system. When clips are different, try to accumulate differences intelligently, taking into account that changes in clips outside the bounds of the clipped display item don't matter. r=mattwoodrow
--HG-- extra : rebase_source : d958c629307045f2592ffe658cd1a2e608713cbd
This commit is contained in:
Родитель
d2ee12f6f9
Коммит
b1e87e032b
|
@ -1991,7 +1991,8 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer,
|
|||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>(t->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
InvalidatePostTransformRegion(t,
|
||||
oldGeometry->ComputeInvalidationRegion().ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
|
||||
oldGeometry->ComputeInvalidationRegion().
|
||||
ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
|
||||
mLayerBuilder->GetLastPaintOffset(t));
|
||||
}
|
||||
if (aNewLayer) {
|
||||
|
@ -2000,7 +2001,8 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer,
|
|||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>(newThebesLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
InvalidatePostTransformRegion(newThebesLayer,
|
||||
geometry->ComputeInvalidationRegion().ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
|
||||
geometry->ComputeInvalidationRegion().
|
||||
ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
|
||||
GetTranslationForThebesLayer(newThebesLayer));
|
||||
}
|
||||
}
|
||||
|
@ -2028,27 +2030,27 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer,
|
|||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Display item type %s(%p) added to layer %p!\n", aItem->Name(), f, aNewLayer);
|
||||
#endif
|
||||
} else if (aItem->IsInvalid() || *oldClip != aClip) {
|
||||
// Either layout marked item as needing repainting, or the clip on it changed, invalidate
|
||||
// the entire old and new areas.
|
||||
// TODO: We could be smarter about handling clip changes here instead of repainting everything.
|
||||
} else if (aItem->IsInvalid()) {
|
||||
// Layout marked item as needing repainting. Invalidate the entire old
|
||||
// and new areas.
|
||||
combined.Or(geometry->ComputeInvalidationRegion(), oldGeometry->ComputeInvalidationRegion());
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", aItem->Name(), f, aNewLayer);
|
||||
#endif
|
||||
} else {
|
||||
// No obvious differences, so let the display item check for geometry changes and decide what needs to be
|
||||
// repainted.
|
||||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>(newThebesLayer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
nsIntPoint paintOffset = GetTranslationForThebesLayer(newThebesLayer);
|
||||
nsPoint offset((paintOffset.x + data->mActiveScrolledRootPosition.x) * mAppUnitsPerDevPixel / data->mXScale,
|
||||
(paintOffset.y + data->mActiveScrolledRootPosition.y) * mAppUnitsPerDevPixel / data->mYScale);
|
||||
nsPoint prevOffset((oldGeometry->mPaintOffset.x + oldGeometry->mActiveScrolledRootPosition.x) * oldGeometry->mAppUnitsPerDevPixel / data->mXScale,
|
||||
(oldGeometry->mPaintOffset.y + oldGeometry->mActiveScrolledRootPosition.y) * oldGeometry->mAppUnitsPerDevPixel / data->mYScale);
|
||||
nsPoint shift = offset - prevOffset;
|
||||
// Let the display item check for geometry changes and decide what needs to be
|
||||
// repainted.
|
||||
oldGeometry->MoveBy(shift);
|
||||
aItem->ComputeInvalidationRegion(mBuilder, oldGeometry, &combined);
|
||||
oldClip->AddOffsetAndComputeDifference(shift, oldGeometry->ComputeInvalidationRegion(),
|
||||
aClip, geometry->ComputeInvalidationRegion(),
|
||||
&combined);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
if (!combined.IsEmpty()) {
|
||||
printf("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), f, aNewLayer);
|
||||
|
@ -3158,6 +3160,43 @@ FrameLayerBuilder::Clip::RemoveRoundedCorners()
|
|||
mRoundedClipRects.Clear();
|
||||
}
|
||||
|
||||
static void
|
||||
AccumulateRectDifference(const nsRect& aR1, const nsRect& aR2, nsRegion* aOut)
|
||||
{
|
||||
if (aR1.IsEqualInterior(aR2))
|
||||
return;
|
||||
nsRegion r;
|
||||
r.Xor(aR1, aR2);
|
||||
aOut->Or(*aOut, r);
|
||||
}
|
||||
|
||||
void
|
||||
FrameLayerBuilder::Clip::AddOffsetAndComputeDifference(const nsPoint& aOffset,
|
||||
const nsRect& aBounds,
|
||||
const Clip& aOther,
|
||||
const nsRect& aOtherBounds,
|
||||
nsRegion* aDifference)
|
||||
{
|
||||
if (mHaveClipRect != aOther.mHaveClipRect ||
|
||||
mRoundedClipRects.Length() != aOther.mRoundedClipRects.Length()) {
|
||||
aDifference->Or(*aDifference, aBounds);
|
||||
aDifference->Or(*aDifference, aOtherBounds);
|
||||
return;
|
||||
}
|
||||
if (mHaveClipRect) {
|
||||
AccumulateRectDifference((mClipRect + aOffset).Intersect(aBounds),
|
||||
aOther.mClipRect.Intersect(aOtherBounds),
|
||||
aDifference);
|
||||
}
|
||||
for (PRUint32 i = 0; i < mRoundedClipRects.Length(); ++i) {
|
||||
if (mRoundedClipRects[i] + aOffset != aOther.mRoundedClipRects[i]) {
|
||||
// The corners make it tricky so we'll just add both rects here.
|
||||
aDifference->Or(*aDifference, mRoundedClipRects[i].mRect.Intersect(aBounds));
|
||||
aDifference->Or(*aDifference, aOther.mRoundedClipRects[i].mRect.Intersect(aOtherBounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfxRect
|
||||
CalculateBounds(nsTArray<FrameLayerBuilder::Clip::RoundedRect> aRects, PRInt32 A2D)
|
||||
{
|
||||
|
|
|
@ -398,6 +398,11 @@ public:
|
|||
// Indices into mRadii are the NS_CORNER_* constants in nsStyleConsts.h
|
||||
nscoord mRadii[8];
|
||||
|
||||
RoundedRect operator+(const nsPoint& aOffset) const {
|
||||
RoundedRect r = *this;
|
||||
r.mRect += aOffset;
|
||||
return r;
|
||||
}
|
||||
bool operator==(const RoundedRect& aOther) const {
|
||||
if (!mRect.IsEqualInterior(aOther.mRect)) {
|
||||
return false;
|
||||
|
@ -460,6 +465,12 @@ public:
|
|||
// Gets rid of any rounded corners in this clip.
|
||||
void RemoveRoundedCorners();
|
||||
|
||||
// Adds the difference between Intersect(*this + aPoint, aBounds) and
|
||||
// Intersect(aOther, aOtherBounds) to aDifference.
|
||||
void AddOffsetAndComputeDifference(const nsPoint& aPoint, const nsRect& aBounds,
|
||||
const Clip& aOther, const nsRect& aOtherBounds,
|
||||
nsRegion* aDifference);
|
||||
|
||||
bool operator==(const Clip& aOther) const {
|
||||
return mHaveClipRect == aOther.mHaveClipRect &&
|
||||
(!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
* Compute the area required to be invalidated if this
|
||||
* display item is removed.
|
||||
*/
|
||||
nsRegion ComputeInvalidationRegion() { return mBounds; }
|
||||
const nsRect& ComputeInvalidationRegion() { return mBounds; }
|
||||
|
||||
/**
|
||||
* Shifts all retained areas of the nsDisplayItemGeometry by the given offset.
|
||||
|
|
Загрузка…
Ссылка в новой задаче