Bug 805197 - Compute a region in LayerTreeInvalidation. r=roc
This commit is contained in:
@@ -14,7 +14,7 @@ namespace layers {
|
||||
struct LayerPropertiesBase;
|
||||
LayerPropertiesBase* CloneLayerTreePropertiesInternal(Layer* aRoot);
|
||||
|
||||
static nsIntRect
|
||||
static nsIntRect
|
||||
TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform)
|
||||
{
|
||||
if (aRect.IsEmpty()) {
|
||||
@@ -33,6 +33,32 @@ TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform)
|
||||
return intRect;
|
||||
}
|
||||
|
||||
static void
|
||||
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const gfx3DMatrix& aTransform)
|
||||
{
|
||||
nsIntRegionRectIterator iter(aSource);
|
||||
const nsIntRect *r;
|
||||
while ((r = iter.Next())) {
|
||||
aDest.Or(aDest, TransformRect(*r, aTransform));
|
||||
}
|
||||
aDest.SimplifyOutward(4);
|
||||
}
|
||||
|
||||
static void
|
||||
AddRegion(nsIntRegion& aDest, const nsIntRegion& aSource)
|
||||
{
|
||||
aDest.Or(aDest, aSource);
|
||||
aDest.SimplifyOutward(4);
|
||||
}
|
||||
|
||||
static nsIntRegion
|
||||
TransformRegion(const nsIntRegion& aRegion, const gfx3DMatrix& aTransform)
|
||||
{
|
||||
nsIntRegion result;
|
||||
AddTransformedRegion(result, aRegion, aTransform);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks over this layer, and all descendant layers.
|
||||
* If any of these are a ContainerLayer that reports invalidations to a PresShell,
|
||||
@@ -88,17 +114,17 @@ struct LayerPropertiesBase : public LayerProperties
|
||||
MOZ_COUNT_DTOR(LayerPropertiesBase);
|
||||
}
|
||||
|
||||
virtual nsIntRect ComputeDifferences(Layer* aRoot,
|
||||
NotifySubDocInvalidationFunc aCallback);
|
||||
virtual nsIntRegion ComputeDifferences(Layer* aRoot,
|
||||
NotifySubDocInvalidationFunc aCallback);
|
||||
|
||||
virtual void MoveBy(const nsIntPoint& aOffset);
|
||||
|
||||
nsIntRect ComputeChange(NotifySubDocInvalidationFunc aCallback)
|
||||
nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
bool transformChanged = !mTransform.FuzzyEqual(mLayer->GetTransform());
|
||||
Layer* otherMask = mLayer->GetMaskLayer();
|
||||
const nsIntRect* otherClip = mLayer->GetClipRect();
|
||||
nsIntRect result;
|
||||
nsIntRegion result;
|
||||
if ((mMaskLayer ? mMaskLayer->mLayer : nullptr) != otherMask ||
|
||||
(mUseClipRect != !!otherClip) ||
|
||||
mLayer->GetOpacity() != mOpacity ||
|
||||
@@ -106,7 +132,7 @@ struct LayerPropertiesBase : public LayerProperties
|
||||
{
|
||||
result = OldTransformedBounds();
|
||||
if (transformChanged) {
|
||||
result = result.Union(NewTransformedBounds());
|
||||
AddRegion(result, NewTransformedBounds());
|
||||
}
|
||||
|
||||
// If we don't have to generate invalidations separately for child
|
||||
@@ -120,21 +146,20 @@ struct LayerPropertiesBase : public LayerProperties
|
||||
|
||||
nsIntRegion visible;
|
||||
visible.Xor(mVisibleRegion, mLayer->GetVisibleRegion());
|
||||
result = result.Union(TransformRect(visible.GetBounds(), mTransform));
|
||||
AddTransformedRegion(result, visible, mTransform);
|
||||
|
||||
result = result.Union(ComputeChangeInternal(aCallback));
|
||||
result = result.Union(TransformRect(mLayer->GetInvalidRegion().GetBounds(), mTransform));
|
||||
AddRegion(result, ComputeChangeInternal(aCallback));
|
||||
AddTransformedRegion(result, mLayer->GetInvalidRegion().GetBounds(), mTransform);
|
||||
|
||||
if (mMaskLayer && otherMask) {
|
||||
nsIntRect maskDiff = mMaskLayer->ComputeChange(aCallback);
|
||||
result = result.Union(TransformRect(maskDiff, mTransform));
|
||||
AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback), mTransform);
|
||||
}
|
||||
|
||||
if (mUseClipRect && otherClip) {
|
||||
if (!mClipRect.IsEqualInterior(*otherClip)) {
|
||||
nsIntRegion tmp;
|
||||
tmp.Xor(mClipRect, *otherClip);
|
||||
result = result.Union(tmp.GetBounds());
|
||||
AddRegion(result, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +177,7 @@ struct LayerPropertiesBase : public LayerProperties
|
||||
return TransformRect(mVisibleRegion.GetBounds(), mTransform);
|
||||
}
|
||||
|
||||
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback) { return nsIntRect(); }
|
||||
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback) { return nsIntRect(); }
|
||||
|
||||
nsRefPtr<Layer> mLayer;
|
||||
nsAutoPtr<LayerPropertiesBase> mMaskLayer;
|
||||
@@ -173,7 +198,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
}
|
||||
}
|
||||
|
||||
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
ContainerLayer* container = mLayer->AsContainerLayer();
|
||||
nsIntRegion result;
|
||||
@@ -184,9 +209,9 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
// Child change. Invalidate the full areas.
|
||||
// TODO: We could be smarter here if non-overlapping children
|
||||
// swap order.
|
||||
result.Or(result, TransformRect(child->GetVisibleRegion().GetBounds(), child->GetTransform()));
|
||||
AddTransformedRegion(result, child->GetVisibleRegion(), child->GetTransform());
|
||||
if (i < mChildren.Length()) {
|
||||
result.Or(result, mChildren[i]->OldTransformedBounds());
|
||||
AddRegion(result, mChildren[i]->OldTransformedBounds());
|
||||
}
|
||||
if (aCallback) {
|
||||
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
||||
@@ -195,7 +220,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
}
|
||||
} else {
|
||||
// Same child, check for differences within the child
|
||||
result.Or(result, mChildren[i]->ComputeChange(aCallback));
|
||||
AddRegion(result, mChildren[i]->ComputeChange(aCallback));
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -203,7 +228,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
|
||||
// Process remaining removed children.
|
||||
while (i < mChildren.Length()) {
|
||||
result.Or(result, mChildren[i]->OldTransformedBounds());
|
||||
AddRegion(result, mChildren[i]->OldTransformedBounds());
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -211,7 +236,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
aCallback(container, result);
|
||||
}
|
||||
|
||||
return TransformRect(result.GetBounds(), mLayer->GetTransform());
|
||||
return TransformRegion(result, mLayer->GetTransform());
|
||||
}
|
||||
|
||||
nsAutoTArray<nsAutoPtr<LayerPropertiesBase>,1> mChildren;
|
||||
@@ -224,7 +249,7 @@ struct ColorLayerProperties : public LayerPropertiesBase
|
||||
, mColor(aLayer->GetColor())
|
||||
{ }
|
||||
|
||||
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
ColorLayer* color = static_cast<ColorLayer*>(mLayer.get());
|
||||
|
||||
@@ -232,7 +257,7 @@ struct ColorLayerProperties : public LayerPropertiesBase
|
||||
return NewTransformedBounds();
|
||||
}
|
||||
|
||||
return nsIntRect();
|
||||
return nsIntRegion();
|
||||
}
|
||||
|
||||
gfxRGBA mColor;
|
||||
@@ -250,7 +275,7 @@ struct ImageLayerProperties : public LayerPropertiesBase
|
||||
{
|
||||
}
|
||||
|
||||
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
|
||||
|
||||
@@ -318,7 +343,7 @@ LayerProperties::ClearInvalidations(Layer *aLayer)
|
||||
}
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
nsIntRegion
|
||||
LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
|
||||
|
||||
@@ -57,8 +57,8 @@ struct LayerProperties
|
||||
* are invalidated.
|
||||
* @return Painted area changed by the layer tree changes.
|
||||
*/
|
||||
virtual nsIntRect ComputeDifferences(Layer* aRoot,
|
||||
NotifySubDocInvalidationFunc aCallback) = 0;
|
||||
virtual nsIntRegion ComputeDifferences(Layer* aRoot,
|
||||
NotifySubDocInvalidationFunc aCallback) = 0;
|
||||
|
||||
|
||||
virtual void MoveBy(const nsIntPoint& aOffset) = 0;
|
||||
|
||||
@@ -2425,16 +2425,16 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||
|
||||
nsIntPoint offset = GetLastPaintOffset(aLayer) - GetTranslationForThebesLayer(aLayer);
|
||||
props->MoveBy(-offset);
|
||||
nsIntRect invalid = props->ComputeDifferences(layer, nullptr);
|
||||
nsIntRegion invalid = props->ComputeDifferences(layer, nullptr);
|
||||
if (aLayerState == LAYER_SVG_EFFECTS) {
|
||||
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem->GetUnderlyingFrame(), invalid);
|
||||
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem->GetUnderlyingFrame(), invalid.GetBounds());
|
||||
}
|
||||
if (!invalid.IsEmpty()) {
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->GetUnderlyingFrame(), aLayer);
|
||||
#endif
|
||||
if (hasClip) {
|
||||
invalid = invalid.Intersect(intClip);
|
||||
invalid.And(invalid, intClip);
|
||||
}
|
||||
|
||||
invalid.ScaleRoundOut(thebesData->mXScale, thebesData->mYScale);
|
||||
|
||||
@@ -1128,7 +1128,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
aBuilder->SetIsCompositingCheap(temp);
|
||||
layerBuilder->DidEndTransaction();
|
||||
|
||||
nsIntRect invalid;
|
||||
nsIntRegion invalid;
|
||||
if (props) {
|
||||
invalid = props->ComputeDifferences(root, computeInvalidFunc);
|
||||
} else if (widgetTransaction) {
|
||||
@@ -1138,12 +1138,13 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
if (view) {
|
||||
if (props) {
|
||||
if (!invalid.IsEmpty()) {
|
||||
nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
|
||||
presContext->DevPixelsToAppUnits(invalid.y),
|
||||
presContext->DevPixelsToAppUnits(invalid.width),
|
||||
presContext->DevPixelsToAppUnits(invalid.height));
|
||||
nsIntRect bounds = invalid.GetBounds();
|
||||
nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
|
||||
presContext->DevPixelsToAppUnits(bounds.y),
|
||||
presContext->DevPixelsToAppUnits(bounds.width),
|
||||
presContext->DevPixelsToAppUnits(bounds.height));
|
||||
view->GetViewManager()->InvalidateViewNoSuppression(view, rect);
|
||||
presContext->NotifyInvalidation(invalid, 0);
|
||||
presContext->NotifyInvalidation(bounds, 0);
|
||||
}
|
||||
} else {
|
||||
view->GetViewManager()->InvalidateView(view);
|
||||
|
||||
@@ -5310,7 +5310,7 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
|
||||
if (layerManager->EndEmptyTransaction((aFlags & PAINT_COMPOSITE) ?
|
||||
LayerManager::END_DEFAULT : LayerManager::END_NO_COMPOSITE)) {
|
||||
nsIntRect invalid;
|
||||
nsIntRegion invalid;
|
||||
if (props) {
|
||||
invalid = props->ComputeDifferences(layerManager->GetRoot(), computeInvalidFunc);
|
||||
} else {
|
||||
@@ -5318,12 +5318,13 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
}
|
||||
if (props) {
|
||||
if (!invalid.IsEmpty()) {
|
||||
nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
|
||||
presContext->DevPixelsToAppUnits(invalid.y),
|
||||
presContext->DevPixelsToAppUnits(invalid.width),
|
||||
presContext->DevPixelsToAppUnits(invalid.height));
|
||||
nsIntRect bounds = invalid.GetBounds();
|
||||
nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
|
||||
presContext->DevPixelsToAppUnits(bounds.y),
|
||||
presContext->DevPixelsToAppUnits(bounds.width),
|
||||
presContext->DevPixelsToAppUnits(bounds.height));
|
||||
aViewToPaint->GetViewManager()->InvalidateViewNoSuppression(aViewToPaint, rect);
|
||||
presContext->NotifyInvalidation(invalid, 0);
|
||||
presContext->NotifyInvalidation(bounds, 0);
|
||||
}
|
||||
} else {
|
||||
aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
|
||||
|
||||
Reference in New Issue
Block a user