mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 564993. Part 3: Split nsDisplayList::Paint into PaintForFrame and PaintRoot. Set the visible rect on the root layer from PaintRoot, let the visible rects of other layers be set when they're placed in their containers. r=mats
This commit is contained in:
parent
d1e569cf6b
commit
5b63e43695
@ -316,6 +316,8 @@ nsDisplayList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
NS_ASSERTION((aVisibleRegionBeforeMove != nsnull) == aBuilder->HasMovingFrames(),
|
||||
"Should have aVisibleRegionBeforeMove when there are moving frames");
|
||||
|
||||
mVisibleRect = aVisibleRegion->GetBounds();
|
||||
|
||||
nsAutoTArray<nsDisplayItem*, 512> elements;
|
||||
FlattenTo(&elements);
|
||||
|
||||
@ -706,8 +708,6 @@ already_AddRefed<Layer>
|
||||
nsDisplayList::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
nsTArray<LayerItems>* aLayers) const {
|
||||
BuildLayers(aBuilder, aManager, aLayers);
|
||||
|
||||
// If there's only one layer, then in principle we can try to flatten
|
||||
// things by returning that layer here. But that adds complexity to
|
||||
// retained layer management so we don't do it. Layer backends can
|
||||
@ -717,29 +717,34 @@ nsDisplayList::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
if (!container)
|
||||
return nsnull;
|
||||
|
||||
BuildLayers(aBuilder, aManager, aLayers);
|
||||
|
||||
Layer* lastChild = nsnull;
|
||||
nsIntRect visibleRect;
|
||||
for (PRUint32 i = 0; i < aLayers->Length(); ++i) {
|
||||
LayerItems* layerItems = &aLayers->ElementAt(i);
|
||||
visibleRect.UnionRect(visibleRect, layerItems->mVisibleRect);
|
||||
Layer* child = layerItems->mLayer;
|
||||
Layer* child = aLayers->ElementAt(i).mLayer;
|
||||
container->InsertAfter(child, lastChild);
|
||||
lastChild = child;
|
||||
}
|
||||
container->SetVisibleRegion(nsIntRegion(visibleRect));
|
||||
container->SetIsOpaqueContent(mIsOpaque);
|
||||
nsRefPtr<Layer> layer = container.forget();
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
void nsDisplayList::PaintRoot(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const {
|
||||
PaintForFrame(aBuilder, aCtx, aBuilder->ReferenceFrame(), aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* We paint by executing a layer manager transaction, constructing a
|
||||
* single layer representing the display list, and then making it the
|
||||
* root of the layer manager, drawing into the ThebesLayers.
|
||||
*/
|
||||
void nsDisplayList::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const {
|
||||
void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx,
|
||||
nsIFrame* aForFrame,
|
||||
PRUint32 aFlags) const {
|
||||
NS_ASSERTION(mDidComputeVisibility,
|
||||
"Must call ComputeVisibility before calling Paint");
|
||||
|
||||
@ -774,6 +779,10 @@ void nsDisplayList::Paint(nsDisplayListBuilder* aBuilder,
|
||||
if (!root)
|
||||
return;
|
||||
|
||||
nsIntRect visible =
|
||||
mVisibleRect.ToNearestPixels(aForFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
root->SetVisibleRegion(nsIntRegion(visible));
|
||||
|
||||
layerManager->SetRoot(root);
|
||||
layerManager->EndConstruction();
|
||||
PaintThebesLayers(aBuilder, layers);
|
||||
@ -1533,7 +1542,7 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
if (!layer)
|
||||
return nsnull;
|
||||
|
||||
layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity*layer->GetOpacity());
|
||||
layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
@ -1853,7 +1862,8 @@ void nsDisplayTransform::Paint(nsDisplayListBuilder *aBuilder,
|
||||
|
||||
/* Now, send the paint call down.
|
||||
*/
|
||||
mStoredList.GetList()->Paint(aBuilder, aCtx, nsDisplayList::PAINT_DEFAULT);
|
||||
mStoredList.GetList()->
|
||||
PaintForFrame(aBuilder, aCtx, mFrame, nsDisplayList::PAINT_DEFAULT);
|
||||
|
||||
/* The AutoSaveRestore object will clean things up. */
|
||||
}
|
||||
|
@ -861,13 +861,22 @@ public:
|
||||
* not be null.
|
||||
*
|
||||
* ComputeVisibility must be called before Paint.
|
||||
*
|
||||
* This must only be called on the root display list of the display list
|
||||
* tree.
|
||||
*/
|
||||
enum {
|
||||
PAINT_DEFAULT = 0,
|
||||
PAINT_USE_WIDGET_LAYERS = 0x01
|
||||
};
|
||||
void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const;
|
||||
void PaintRoot(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const;
|
||||
/**
|
||||
* Like PaintRoot, but used for internal display sublists.
|
||||
* aForFrame is the frame that the list is associated with.
|
||||
*/
|
||||
void PaintForFrame(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
nsIFrame* aForFrame, PRUint32 aFlags) const;
|
||||
/**
|
||||
* Get the bounds. Takes the union of the bounds of all children.
|
||||
*/
|
||||
@ -944,6 +953,7 @@ public:
|
||||
* we construct layers belonging to aManager. The layers used to
|
||||
* construct the layer tree (along with the display items associated
|
||||
* with each layer) are returned in aLayers.
|
||||
* The caller is responsible for setting the visible region on the layer.
|
||||
*/
|
||||
already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
@ -968,6 +978,8 @@ private:
|
||||
nsDisplayItemLink mSentinel;
|
||||
nsDisplayItemLink* mTop;
|
||||
|
||||
// This is set by ComputeVisibility
|
||||
nsRect mVisibleRect;
|
||||
// This is set to true by ComputeVisibility if the final visible region
|
||||
// is empty (i.e. everything that was visible is covered by some
|
||||
// opaque content in this list).
|
||||
|
@ -1259,7 +1259,7 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
||||
|
||||
widget->UpdatePossiblyTransparentRegion(dirtyWindowRegion, visibleWindowRegion);
|
||||
}
|
||||
list.Paint(&builder, aRenderingContext, flags);
|
||||
list.PaintRoot(&builder, aRenderingContext, flags);
|
||||
// Flush the list so we don't trigger the IsEmpty-on-destruction assertion
|
||||
list.DeleteAll();
|
||||
return NS_OK;
|
||||
|
@ -5146,7 +5146,7 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
|
||||
if (aFlags & RENDER_USE_WIDGET_LAYERS) {
|
||||
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
|
||||
}
|
||||
list.Paint(&builder, rc, flags);
|
||||
list.PaintRoot(&builder, rc, flags);
|
||||
// Flush the list so we don't trigger the IsEmpty-on-destruction assertion
|
||||
list.DeleteAll();
|
||||
|
||||
@ -5439,7 +5439,7 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
|
||||
aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y);
|
||||
nsRegion visible(aArea);
|
||||
rangeInfo->mList.ComputeVisibility(&rangeInfo->mBuilder, &visible, nsnull);
|
||||
rangeInfo->mList.Paint(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
|
||||
rangeInfo->mList.PaintRoot(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
|
||||
aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y);
|
||||
}
|
||||
|
||||
|
@ -202,20 +202,23 @@ class RegularFramePaintCallback : public nsSVGFilterPaintCallback
|
||||
public:
|
||||
RegularFramePaintCallback(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aInnerList,
|
||||
nsIFrame* aFrame,
|
||||
const nsPoint& aOffset)
|
||||
: mBuilder(aBuilder), mInnerList(aInnerList), mOffset(aOffset) {}
|
||||
: mBuilder(aBuilder), mInnerList(aInnerList), mFrame(aFrame),
|
||||
mOffset(aOffset) {}
|
||||
|
||||
virtual void Paint(nsSVGRenderState *aContext, nsIFrame *aTarget,
|
||||
const nsIntRect* aDirtyRect)
|
||||
{
|
||||
nsIRenderingContext* ctx = aContext->GetRenderingContext(aTarget);
|
||||
nsIRenderingContext::AutoPushTranslation push(ctx, -mOffset.x, -mOffset.y);
|
||||
mInnerList->Paint(mBuilder, ctx, nsDisplayList::PAINT_DEFAULT);
|
||||
mInnerList->PaintForFrame(mBuilder, ctx, mFrame, nsDisplayList::PAINT_DEFAULT);
|
||||
}
|
||||
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
nsDisplayList* mInnerList;
|
||||
nsIFrame* mFrame;
|
||||
nsPoint mOffset;
|
||||
};
|
||||
|
||||
@ -298,12 +301,14 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsIRenderingContext* aCtx,
|
||||
|
||||
/* Paint the child */
|
||||
if (filterFrame) {
|
||||
RegularFramePaintCallback paint(aBuilder, aInnerList, userSpaceRect.TopLeft());
|
||||
RegularFramePaintCallback paint(aBuilder, aInnerList, aEffectsFrame,
|
||||
userSpaceRect.TopLeft());
|
||||
nsIntRect r = (aDirtyRect - userSpaceRect.TopLeft()).ToOutsidePixels(appUnitsPerDevPixel);
|
||||
filterFrame->FilterPaint(&svgContext, aEffectsFrame, &paint, &r);
|
||||
} else {
|
||||
gfx->SetMatrix(savedCTM);
|
||||
aInnerList->Paint(aBuilder, aCtx, nsDisplayList::PAINT_DEFAULT);
|
||||
aInnerList->PaintForFrame(aBuilder, aCtx, aEffectsFrame,
|
||||
nsDisplayList::PAINT_DEFAULT);
|
||||
aCtx->Translate(userSpaceRect.x, userSpaceRect.y);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user