Bug 1022612. Part 27: Make FrameLayerBuilder responsible for setting all layer visible regions. r=mattwoodrow

Calling Layer::SetVisibleRegion multiple times in a transaction can result in
unnecessary IPC traffic.

This patch removes Intersect(childGfxBounds). This is only needed to
restrict the visible region to something sane for 3D transforms, and this will
be fixed up in a later patch.

--HG--
extra : rebase_source : dc1eaa8079f61648c24ac9502e837ac9f2630730
This commit is contained in:
Robert O'Callahan 2014-06-18 15:12:55 +12:00
parent 2aec49a3b7
commit 30dd0c42a3
9 changed files with 17 additions and 29 deletions

View File

@ -1614,30 +1614,27 @@ AppUnitsPerDevPixel(nsDisplayItem* aItem)
* parent's coordinate system
*/
static void
SetVisibleRegionForLayer(Layer* aLayer, const nsIntRegion& aLayerVisibleRegion,
const nsIntRect& aRestrictToRect)
SetVisibleRegionForLayer(Layer* aLayer, const nsIntRect* aLayerVisibleRect,
const nsIntRect& aOuterVisibleRect)
{
gfx3DMatrix transform;
To3DMatrix(aLayer->GetTransform(), transform);
// if 'transform' is not invertible, then nothing will be displayed
// for the layer, so it doesn't really matter what we do here
gfxRect itemVisible(aRestrictToRect.x, aRestrictToRect.y,
aRestrictToRect.width, aRestrictToRect.height);
nsIntRect childBounds = aLayerVisibleRegion.GetBounds();
gfxRect childGfxBounds(childBounds.x, childBounds.y,
childBounds.width, childBounds.height);
gfxRect layerVisible = transform.Inverse().ProjectRectBounds(itemVisible);
layerVisible = layerVisible.Intersect(childGfxBounds);
gfxRect outerVisible(aOuterVisibleRect.x, aOuterVisibleRect.y,
aOuterVisibleRect.width, aOuterVisibleRect.height);
gfxRect layerVisible = transform.Inverse().ProjectRectBounds(outerVisible);
layerVisible.RoundOut();
nsIntRect visibleRect;
if (!gfxUtils::GfxRectToIntRect(layerVisible, &visibleRect)) {
aLayer->SetVisibleRegion(nsIntRegion());
} else {
nsIntRegion rgn;
rgn.And(aLayerVisibleRegion, visibleRect);
aLayer->SetVisibleRegion(rgn);
if (aLayerVisibleRect) {
visibleRect.IntersectRect(visibleRect, *aLayerVisibleRect);
}
aLayer->SetVisibleRegion(nsIntRegion(visibleRect));
}
}
@ -2655,7 +2652,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
}
itemVisibleRect.MoveBy(mParameters.mOffset);
if (item->SetVisibleRegionOnLayer()) {
SetVisibleRegionForLayer(ownLayer, ownLayer->GetVisibleRegion(), itemVisibleRect);
SetVisibleRegionForLayer(ownLayer, nullptr, itemVisibleRect);
}
// rounded rectangle clipping using mask layers
@ -3517,7 +3514,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
pixBounds.MoveBy(nsIntPoint(scaleParameters.mOffset.x, scaleParameters.mOffset.y));
if (aParameters.mAncestorClipRect && !(aFlags & CONTAINER_NOT_CLIPPED_BY_ANCESTORS)) {
SetVisibleRegionForLayer(containerLayer, nsIntRegion(pixBounds),
SetVisibleRegionForLayer(containerLayer, &pixBounds,
*aParameters.mAncestorClipRect);
} else {
containerLayer->SetVisibleRegion(pixBounds);

View File

@ -2029,7 +2029,6 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& a
transform.Scale(mDestRect.width/imageSize.width,
mDestRect.height/imageSize.height);
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageSize.width, imageSize.height));
}
void

View File

@ -2619,6 +2619,12 @@ public:
return &mList;
}
virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return &mList; }
/**
* All our subclasses BuildLayers call
* FrameLayerBuilder::BuildContainerLayerFor, which
* sets the visible region of the layer correctly.
*/
virtual bool SetVisibleRegionOnLayer() { return false; }
virtual int32_t ZIndex() const MOZ_OVERRIDE
{
@ -2887,8 +2893,6 @@ public:
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return !(mFlags & GENERATE_SCROLLABLE_LAYER); }
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
@ -3024,8 +3028,6 @@ public:
virtual nsIFrame* GetScrollFrame() { return mScrollFrame; }
virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; }
virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; }
#ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
#endif
@ -3397,8 +3399,6 @@ public:
bool aLogAnimations = false);
bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; }
#ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
#endif

View File

@ -271,7 +271,6 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
transform.Scale(r.Width()/canvasSize.width, r.Height()/canvasSize.height);
layer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
layer->SetVisibleRegion(nsIntRect(0, 0, canvasSize.width, canvasSize.height));
return layer.forget();
}

View File

@ -1425,7 +1425,6 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer, const nsIntPoint& aOffset)
transform.Scale(destRect.Width()/imageWidth,
destRect.Height()/imageHeight);
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
}
void

View File

@ -1612,7 +1612,6 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
transform.Translate(p.x, p.y);
layer->SetBaseTransform(Matrix4x4::From2D(transform));
layer->SetVisibleRegion(ThebesIntRect(IntRect(IntPoint(0, 0), size)));
return layer.forget();
}

View File

@ -219,7 +219,6 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
transform.Translate(p.x, p.y);
transform.Scale(r.Width()/frameSize.width, r.Height()/frameSize.height);
layer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
layer->SetVisibleRegion(nsIntRect(0, 0, frameSize.width, frameSize.height));
nsRefPtr<Layer> result = layer.forget();
return result.forget();
}

View File

@ -873,7 +873,6 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
}
static_cast<RefLayer*>(layer.get())->SetReferentId(id);
nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
layer->SetVisibleRegion(aVisibleRect - offset);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
@ -926,7 +925,6 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
mBackgroundColor,
aManager, aFrame);
}
mContainer->SetVisibleRegion(aVisibleRect);
return nsRefPtr<Layer>(mContainer).forget();
}

View File

@ -406,8 +406,6 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
transform.Scale(destRect.Width()/imageWidth,
destRect.Height()/imageHeight);
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
}
already_AddRefed<ImageContainer>