mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Bug 786817; Check multiple masks properly and invalidate after removing a mask layer. r=roc
This commit is contained in:
parent
bf62bdbc2a
commit
219d6ac104
@ -497,11 +497,19 @@ public:
|
||||
mXScale(1.f), mYScale(1.f),
|
||||
mActiveScrolledRootPosition(0, 0) {}
|
||||
|
||||
/**
|
||||
* Record the number of clips in the Thebes layer's mask layer.
|
||||
* Should not be reset when the layer is recycled since it is used to track
|
||||
* changes in the use of mask layers.
|
||||
*/
|
||||
uint32_t mMaskClipCount;
|
||||
|
||||
/**
|
||||
* A color that should be painted over the bounds of the layer's visible
|
||||
* region before any other content is painted.
|
||||
*/
|
||||
nscolor mForcedBackgroundColor;
|
||||
|
||||
/**
|
||||
* The resolution scale used.
|
||||
*/
|
||||
@ -1675,6 +1683,10 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
||||
layer = thebesLayerData->mLayer;
|
||||
}
|
||||
|
||||
// check to see if the new item has rounded rect clips in common with
|
||||
// other items in the layer
|
||||
thebesLayerData->UpdateCommonClipCount(aClip);
|
||||
|
||||
thebesLayerData->Accumulate(this, aItem, aVisibleRect, aDrawRect, aClip);
|
||||
|
||||
return thebesLayerData;
|
||||
@ -3202,7 +3214,7 @@ FrameLayerBuilder::Clip::RemoveRoundedCorners()
|
||||
}
|
||||
|
||||
gfxRect
|
||||
CalculateBounds(nsTArray<FrameLayerBuilder::Clip::RoundedRect> aRects, int32_t A2D)
|
||||
CalculateBounds(const nsTArray<FrameLayerBuilder::Clip::RoundedRect>& aRects, int32_t A2D)
|
||||
{
|
||||
nsRect bounds = aRects[0].mRect;
|
||||
for (uint32_t i = 1; i < aRects.Length(); ++i) {
|
||||
@ -3211,16 +3223,36 @@ CalculateBounds(nsTArray<FrameLayerBuilder::Clip::RoundedRect> aRects, int32_t A
|
||||
|
||||
return nsLayoutUtils::RectToGfxRect(bounds, A2D);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SetClipCount(ThebesDisplayItemLayerUserData* aThebesData,
|
||||
uint32_t aClipCount)
|
||||
{
|
||||
if (aThebesData) {
|
||||
aThebesData->mMaskClipCount = aClipCount;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
|
||||
uint32_t aRoundedRectClipCount)
|
||||
{
|
||||
// if the number of clips we are going to mask has decreased, then aLayer might have
|
||||
// cached graphics which assume the existence of a soon-to-be non-existent mask layer
|
||||
// in that case, invalidate the whole layer.
|
||||
ThebesDisplayItemLayerUserData* thebesData = GetThebesDisplayItemLayerUserData(aLayer);
|
||||
if (thebesData &&
|
||||
aRoundedRectClipCount < thebesData->mMaskClipCount) {
|
||||
ThebesLayer* thebes = aLayer->AsThebesLayer();
|
||||
thebes->InvalidateRegion(thebes->GetValidRegion().GetBounds());
|
||||
}
|
||||
|
||||
// don't build an unnecessary mask
|
||||
nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
|
||||
if (aClip.mRoundedClipRects.IsEmpty() ||
|
||||
aRoundedRectClipCount <= 0 ||
|
||||
aRoundedRectClipCount == 0 ||
|
||||
layerBounds.IsEmpty()) {
|
||||
SetClipCount(thebesData, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3238,6 +3270,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
|
||||
if (*userData == newData) {
|
||||
aLayer->SetMaskLayer(maskLayer);
|
||||
SetClipCount(thebesData, aRoundedRectClipCount);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3292,6 +3325,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
// fail if we can't get the right surface
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
NS_WARNING("Could not create surface for mask layer.");
|
||||
SetClipCount(thebesData, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3327,6 +3361,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
userData->mImageKey = key;
|
||||
|
||||
aLayer->SetMaskLayer(maskLayer);
|
||||
SetClipCount(thebesData, aRoundedRectClipCount);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user