Backed out 46 changesets (bug 1022612) for B2G mochitest permafails on a CLOSED TREE.

Backed out changeset 34b3014a3112 (bug 1022612)
Backed out changeset 6ae9316fd909 (bug 1022612)
Backed out changeset b8f3749c95eb (bug 1022612)
Backed out changeset caab10bf6ca3 (bug 1022612)
Backed out changeset 0c57c620c898 (bug 1022612)
Backed out changeset fac64141a00a (bug 1022612)
Backed out changeset bf0df1c9d68b (bug 1022612)
Backed out changeset b42054800020 (bug 1022612)
Backed out changeset 667793b21194 (bug 1022612)
Backed out changeset f14ada64fe1b (bug 1022612)
Backed out changeset 75b837686bdf (bug 1022612)
Backed out changeset 66de53183a22 (bug 1022612)
Backed out changeset 0ff86ced4d46 (bug 1022612)
Backed out changeset 18eecc5b1ef7 (bug 1022612)
Backed out changeset 2763c4878de5 (bug 1022612)
Backed out changeset b72413ecc385 (bug 1022612)
Backed out changeset b23f1081afb8 (bug 1022612)
Backed out changeset f7e2c6a72043 (bug 1022612)
Backed out changeset 959917c9027d (bug 1022612)
Backed out changeset 0268a46f4880 (bug 1022612)
Backed out changeset 3388856a80ad (bug 1022612)
Backed out changeset e4b17cf0f806 (bug 1022612)
Backed out changeset 2f4e9da0e4b6 (bug 1022612)
Backed out changeset 489f6a7c0c03 (bug 1022612)
Backed out changeset 8369d9ad7ad3 (bug 1022612)
Backed out changeset 0758d2a06002 (bug 1022612)
Backed out changeset f2ae9cb22edb (bug 1022612)
Backed out changeset 9c48c6ee5dc2 (bug 1022612)
Backed out changeset fe7134400f08 (bug 1022612)
Backed out changeset cc2c5397ca8b (bug 1022612)
Backed out changeset a3d1a3e8b39d (bug 1022612)
Backed out changeset 8974b74b0eb0 (bug 1022612)
Backed out changeset 75f7dbb5a2a6 (bug 1022612)
Backed out changeset 2aa04a071e60 (bug 1022612)
Backed out changeset f2ab1bcd4c39 (bug 1022612)
Backed out changeset da9152b6ea29 (bug 1022612)
Backed out changeset 58abf5b0e148 (bug 1022612)
Backed out changeset 797058a09ad2 (bug 1022612)
Backed out changeset ea3e99a92ff0 (bug 1022612)
Backed out changeset adc4a4a7aa73 (bug 1022612)
Backed out changeset 7b18dedd1505 (bug 1022612)
Backed out changeset 055dd1921e8e (bug 1022612)
Backed out changeset 42fa2c97e989 (bug 1022612)
Backed out changeset cd594236388f (bug 1022612)
Backed out changeset 9eadc5fee43d (bug 1022612)
Backed out changeset 5cc8d30ff7c9 (bug 1022612)
This commit is contained in:
Ryan VanderMeulen 2014-07-17 11:24:47 -04:00
parent 093f4c3fbe
commit f6dd40d9e0
32 changed files with 852 additions and 1089 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,6 @@ class ThebesLayer;
class FrameLayerBuilder;
class LayerManagerData;
class ThebesLayerData;
class ContainerState;
enum LayerState {
LAYER_NONE,
@ -58,44 +57,34 @@ public:
bool mIsInfinite;
};
struct NewLayerEntry;
struct ContainerLayerParameters {
ContainerLayerParameters()
: mXScale(1)
, mYScale(1)
, mLayerContentsVisibleRect(nullptr)
, mInTransformedSubtree(false)
, mInActiveTransformedSubtree(false)
, mDisableSubpixelAntialiasingInDescendants(false)
ContainerLayerParameters() :
mXScale(1), mYScale(1), mAncestorClipRect(nullptr),
mInTransformedSubtree(false), mInActiveTransformedSubtree(false),
mDisableSubpixelAntialiasingInDescendants(false)
{}
ContainerLayerParameters(float aXScale, float aYScale)
: mXScale(aXScale)
, mYScale(aYScale)
, mLayerContentsVisibleRect(nullptr)
, mInTransformedSubtree(false)
, mInActiveTransformedSubtree(false)
, mDisableSubpixelAntialiasingInDescendants(false)
ContainerLayerParameters(float aXScale, float aYScale) :
mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr),
mInTransformedSubtree(false), mInActiveTransformedSubtree(false),
mDisableSubpixelAntialiasingInDescendants(false)
{}
ContainerLayerParameters(float aXScale, float aYScale,
const nsIntPoint& aOffset,
const ContainerLayerParameters& aParent)
: mXScale(aXScale)
, mYScale(aYScale)
, mLayerContentsVisibleRect(nullptr)
, mOffset(aOffset)
, mInTransformedSubtree(aParent.mInTransformedSubtree)
, mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree)
, mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants)
const ContainerLayerParameters& aParent) :
mXScale(aXScale), mYScale(aYScale), mAncestorClipRect(nullptr),
mOffset(aOffset),
mInTransformedSubtree(aParent.mInTransformedSubtree),
mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree),
mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants)
{}
float mXScale, mYScale;
/**
* If non-null, the rectangle in which BuildContainerLayerFor stores the
* visible rect of the layer, in the coordinate system of the created layer.
* An ancestor clip rect that can be applied to restrict the visibility
* of this container. Null if none available.
*/
nsIntRect* mLayerContentsVisibleRect;
const nsIntRect* mAncestorClipRect;
/**
* An offset to apply to all child layers created.
* An offset to append to the transform set on all child layers created.
*/
nsIntPoint mOffset;
@ -218,16 +207,13 @@ public:
* is set based on what's in the layer.
* The container layer is transformed by aTransform (if non-null), and
* the result is transformed by the scale factors in aContainerParameters.
* aChildren is modified due to display item merging and flattening.
* The visible region of the returned layer is set only if aContainerItem
* is null.
*/
already_AddRefed<ContainerLayer>
BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
nsIFrame* aContainerFrame,
nsDisplayItem* aContainerItem,
nsDisplayList* aChildren,
const nsDisplayList& aChildren,
const ContainerLayerParameters& aContainerParameters,
const gfx3DMatrix* aTransform,
uint32_t aFlags = 0);
@ -313,8 +299,7 @@ public:
void AddThebesDisplayItem(ThebesLayerData* aLayer,
nsDisplayItem* aItem,
const DisplayItemClip& aClip,
const nsIntRect& aItemVisibleRect,
const ContainerState& aContainerState,
nsIFrame* aContainerLayerFrame,
LayerState aLayerState,
const nsPoint& aTopLeft,
nsAutoPtr<nsDisplayItemGeometry> aGeometry);
@ -611,11 +596,6 @@ public:
return mContainingThebesLayer;
}
bool IsBuildingRetainedLayers()
{
return !mContainingThebesLayer && mRetainingManager;
}
/**
* Attempt to build the most compressed layer tree possible, even if it means
* throwing away existing retained buffers.

View File

@ -491,9 +491,10 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mIgnoreScrollFrame(nullptr),
mLayerEventRegions(nullptr),
mCurrentTableItem(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mDirtyRect(-1,-1,-1,-1),
mFinalTransparentRegion(nullptr),
mCachedOffsetFrame(aReferenceFrame),
mCachedReferenceFrame(aReferenceFrame),
mCachedOffset(0, 0),
mGlassDisplayItem(nullptr),
mMode(aMode),
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
@ -510,6 +511,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mAllowMergingAndFlattening(true),
mWillComputePluginGeometry(false),
mInTransform(false),
mInFixedPos(false),
mSyncDecodeImages(false),
mIsPaintingToWindow(false),
mIsCompositingCheap(false),
@ -615,6 +617,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
nsIFrame* aScrollFrame,
const nsIFrame* aReferenceFrame,
ContainerLayer* aRoot,
const nsRect& aVisibleRect,
const nsRect& aViewport,
bool aForceNullScrollId,
bool aIsRoot,
@ -623,6 +626,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
LayoutDeviceToLayerScale resolution(aContainerParameters.mXScale, aContainerParameters.mYScale);
nsIntRect visible = aVisibleRect.ScaleToNearestPixels(
resolution.scale, resolution.scale, auPerDevPixel);
aRoot->SetVisibleRegion(visible);
nsIPresShell* presShell = presContext->GetPresShell();
FrameMetrics metrics;
metrics.mViewport = CSSRect::FromAppUnits(aViewport);
@ -880,11 +887,11 @@ void
nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
const nsRect& aDirtyRect) {
PresShellState* state = mPresShellStates.AppendElement();
if (!state)
return;
state->mPresShell = aReferenceFrame->PresContext()->PresShell();
state->mCaretFrame = nullptr;
state->mFirstFrameMarkedForDisplay = mFramesMarkedForDisplay.Length();
state->mPrevDirtyRect = mDirtyRect;
mDirtyRect = aDirtyRect;
state->mPresShell->UpdateCanvasBackground();
@ -928,10 +935,12 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
void
nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame,
const nsRect& aDirtyRect) {
NS_ASSERTION(CurrentPresShellState()->mPresShell ==
aReferenceFrame->PresContext()->PresShell(),
"Presshell mismatch");
mDirtyRect = CurrentPresShellState()->mPrevDirtyRect;
if (CurrentPresShellState()->mPresShell != aReferenceFrame->PresContext()->PresShell()) {
// Must have not allocated a state for this presshell, presumably due
// to OOM.
return;
}
ResetMarkedFramesForDisplayList();
mPresShellStates.SetLength(mPresShellStates.Length() - 1);
}
@ -1016,11 +1025,16 @@ void nsDisplayListSet::MoveTo(const nsDisplayListSet& aDestination) const
aDestination.Outlines()->AppendToTop(Outlines());
}
static void
MoveListTo(nsDisplayList* aList, nsTArray<nsDisplayItem*>* aElements) {
void
nsDisplayList::FlattenTo(nsTArray<nsDisplayItem*>* aElements) {
nsDisplayItem* item;
while ((item = aList->RemoveBottom()) != nullptr) {
aElements->AppendElement(item);
while ((item = RemoveBottom()) != nullptr) {
if (item->GetType() == nsDisplayItem::TYPE_WRAP_LIST) {
item->GetSameCoordinateSystemChildren()->FlattenTo(aElements);
item->~nsDisplayItem();
} else {
aElements->AppendElement(item);
}
}
}
@ -1033,15 +1047,6 @@ nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const {
return bounds;
}
nsRect
nsDisplayList::GetVisibleRect() const {
nsRect result;
for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) {
result.UnionRect(result, i->GetVisibleRect());
}
return result;
}
bool
nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -1052,7 +1057,8 @@ nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion,
r.GetBounds(), aDisplayPortFrame);
r.GetBounds(), r.GetBounds(),
aDisplayPortFrame);
}
static nsRegion
@ -1087,10 +1093,36 @@ TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
return opaqueClipped;
}
/* Checks if aPotentialScrollItem is a scroll layer item and aPotentialScrollbarItem
* is an overlay scrollbar item for the same scroll frame.
*/
static bool
IsScrollLayerItemAndOverlayScrollbarForScrollFrame(
nsDisplayItem* aPotentialScrollItem, nsDisplayItem* aPotentialScrollbarItem)
{
if (aPotentialScrollItem->GetType() == nsDisplayItem::TYPE_SCROLL_LAYER &&
aPotentialScrollbarItem &&
aPotentialScrollbarItem->GetType() == nsDisplayItem::TYPE_OWN_LAYER &&
LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
nsDisplayScrollLayer* scrollItem =
static_cast<nsDisplayScrollLayer*>(aPotentialScrollItem);
nsDisplayOwnLayer* layerItem =
static_cast<nsDisplayOwnLayer*>(aPotentialScrollbarItem);
if ((layerItem->GetFlags() &
(nsDisplayOwnLayer::VERTICAL_SCROLLBAR |
nsDisplayOwnLayer::HORIZONTAL_SCROLLBAR)) &&
layerItem->Frame()->GetParent() == scrollItem->GetScrollFrame()) {
return true;
}
}
return false;
}
bool
nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds,
const nsRect& aAllowVisibleRegionExpansion,
nsIFrame* aDisplayPortFrame) {
#ifdef DEBUG
nsRegion r;
@ -1099,38 +1131,113 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
"bad aListVisibleBounds");
#endif
mVisibleRect = aListVisibleBounds;
bool anyVisible = false;
nsAutoTArray<nsDisplayItem*, 512> elements;
MoveListTo(this, &elements);
FlattenTo(&elements);
bool forceTransparentSurface = false;
for (int32_t i = elements.Length() - 1; i >= 0; --i) {
nsDisplayItem* item = elements[i];
nsDisplayItem* belowItem = i < 1 ? nullptr : elements[i - 1];
nsDisplayList* list = item->GetSameCoordinateSystemChildren();
if (aBuilder->AllowMergingAndFlattening()) {
if (belowItem && item->TryMerge(aBuilder, belowItem)) {
belowItem->~nsDisplayItem();
elements.ReplaceElementsAt(i - 1, 1, item);
continue;
}
// If an overlay scrollbar item is between a scroll layer item and the
// other scroll layer items that we need to merge with just move the
// scrollbar item up, that way it will be on top of the scrolled content
// and we can try to merge all the scroll layer items.
if (IsScrollLayerItemAndOverlayScrollbarForScrollFrame(item, belowItem)) {
elements[i] = belowItem;
elements[i-1] = item;
i++;
continue;
}
if (list && item->ShouldFlattenAway(aBuilder)) {
// The elements on the list >= i no longer serve any use.
elements.SetLength(i);
list->FlattenTo(&elements);
i = elements.Length();
item->~nsDisplayItem();
continue;
}
}
nsRect bounds = item->GetClippedBounds(aBuilder);
nsRegion itemVisible;
itemVisible.And(*aVisibleRegion, bounds);
item->mVisibleRect = itemVisible.GetBounds();
if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
if (item->ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion.Intersect(bounds))) {
anyVisible = true;
// If we're in a displayport, we need to make sure that fixed position
// items do not subtract from the visible region, as async scrolling
// may expose these occluded areas.
// If the item is fixed pos in the same document as the displayport
// then don't let it occlude this list. The only other case possible
// is that the fixed pos content is in a child document, in which it
// would scroll with the rest of the content.
bool occlude = true;
nsIPresShell* presShell = nullptr;
if (aDisplayPortFrame && item->IsInFixedPos()) {
if (item->Frame()->PresContext() == aDisplayPortFrame->PresContext()) {
occlude = false;
presShell = aDisplayPortFrame->PresContext()->PresShell();
}
}
nsRegion opaque = TreatAsOpaque(item, aBuilder);
// Subtract opaque item from the visible region
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
if (occlude) {
// Subtract opaque item from the visible region
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
} else if (presShell &&
presShell->IsScrollPositionClampingScrollPortSizeSet() &&
!opaque.IsEmpty()) {
// We make an exception if the fixed position item would fully occlude
// the scroll position clamping scroll-port. In that case, it's very
// unlikely that it will become visible via async scrolling, so we let
// it occlude.
nsRect scrollClampingScrollPort(nsPoint(0, 0),
presShell->GetScrollPositionClampingScrollPortSize());
if (opaque.Contains(scrollClampingScrollPort)) {
aVisibleRegion->SetEmpty();
}
}
if (aBuilder->NeedToForceTransparentSurfaceForItem(item) ||
(list && list->NeedsTransparentSurface())) {
forceTransparentSurface = true;
}
}
AppendToBottom(item);
}
mIsOpaque = !aVisibleRegion->Intersects(aListVisibleBounds);
mIsOpaque = !aVisibleRegion->Intersects(mVisibleRect);
mForceTransparentSurface = forceTransparentSurface;
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
mDidComputeVisibility = true;
#endif
return anyVisible;
}
void nsDisplayList::PaintRoot(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,
uint32_t aFlags) {
uint32_t aFlags) const {
PROFILER_LABEL("nsDisplayList", "PaintRoot",
js::ProfileEntry::Category::GRAPHICS);
PaintForFrame(aBuilder, aCtx, aBuilder->RootReferenceFrame(), aFlags);
}
@ -1142,7 +1249,10 @@ void nsDisplayList::PaintRoot(nsDisplayListBuilder* aBuilder,
void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,
nsIFrame* aForFrame,
uint32_t aFlags) {
uint32_t aFlags) const {
NS_ASSERTION(mDidComputeVisibility,
"Must call ComputeVisibility before calling Paint");
nsRefPtr<LayerManager> layerManager;
bool widgetTransaction = false;
bool allowRetaining = false;
@ -1211,7 +1321,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
ContainerLayerParameters containerParameters
(presShell->GetXResolution(), presShell->GetYResolution());
nsRefPtr<ContainerLayer> root = layerBuilder->
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nullptr, this,
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nullptr, *this,
containerParameters, nullptr);
nsIDocument* document = nullptr;
@ -1250,7 +1360,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
RecordFrameMetrics(aForFrame, rootScrollFrame,
aBuilder->FindReferenceFrameFor(aForFrame),
root, viewport,
root, mVisibleRect, viewport,
!isRoot, isRoot, containerParameters);
if (usingDisplayport &&
!(root->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
@ -1614,7 +1724,8 @@ nsDisplayItem::ZIndex() const
bool
nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
return !mVisibleRect.IsEmpty() &&
!IsInvisibleInRect(aVisibleRegion->GetBounds());
@ -1632,10 +1743,8 @@ nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
// When we recompute visibility within layers we don't need to
// expand the visible region for content behind plugins (the plugin
// is not in the layer).
if (!ComputeVisibility(aBuilder, aVisibleRegion)) {
mVisibleRect = nsRect();
if (!ComputeVisibility(aBuilder, aVisibleRegion, nsRect()))
return false;
}
nsRegion opaque = TreatAsOpaque(this, aBuilder);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
@ -2030,6 +2139,7 @@ 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
@ -2045,9 +2155,11 @@ nsDisplayBackgroundImage::HitTest(nsDisplayListBuilder* aBuilder,
bool
nsDisplayBackgroundImage::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion)) {
return false;
}
@ -2144,6 +2256,23 @@ nsDisplayBackgroundImage::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aCo
return false;
}
bool
nsDisplayBackgroundImage::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
if (!mBackgroundStyle)
return false;
if (!mBackgroundStyle->HasFixedBackground())
return false;
// If aFrame is mFrame or an ancestor in this document, and aFrame is
// not the viewport frame, then moving aFrame will move mFrame
// relative to the viewport, so our fixed-pos background will change.
return aFrame->GetParent() &&
(aFrame == mFrame ||
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame));
}
nsRect
nsDisplayBackgroundImage::GetPositioningArea()
{
@ -2792,8 +2921,10 @@ nsDisplayBoxShadowOuter::IsInvisibleInRect(const nsRect& aRect)
bool
nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion)) {
return false;
}
@ -2852,8 +2983,10 @@ nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder,
bool
nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion)) {
return false;
}
@ -2867,8 +3000,6 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
: nsDisplayItem(aBuilder, aFrame)
, mOverrideZIndex(0)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
mList.AppendToTop(aList);
UpdateBounds(aBuilder);
@ -2884,28 +3015,28 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame =
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
} else {
// If we're a transformed frame, then we need to find out if we're inside
// the nsDisplayTransform or outside of it. Frames inside the transform
// need mReferenceFrame == mFrame, outside needs the next ancestor
// reference frame.
// If we're inside the transform, then the nsDisplayItem constructor
// will have done the right thing.
// If we're outside the transform, then we should have only one child
// (since nsDisplayTransform wraps all actual content), and that child
// will have the correct reference frame set (since nsDisplayTransform
// handles this explictly).
//
// Preserve-3d can cause us to have multiple nsDisplayTransform
// children.
nsDisplayItem *i = mList.GetBottom();
if (i && (!i->GetAbove() || i->GetType() == TYPE_TRANSFORM) &&
i->Frame() == mFrame) {
mReferenceFrame = i->ReferenceFrame();
mToReferenceFrame = i->ToReferenceFrame();
}
return;
}
// If we're a transformed frame, then we need to find out if we're inside
// the nsDisplayTransform or outside of it. Frames inside the transform
// need mReferenceFrame == mFrame, outside needs the next ancestor
// reference frame.
// If we're inside the transform, then the nsDisplayItem constructor
// will have done the right thing.
// If we're outside the transform, then we should have only one child
// (since nsDisplayTransform wraps all actual content), and that child
// will have the correct reference frame set (since nsDisplayTransform
// handles this explictly).
//
// Preserve-3d can cause us to have multiple nsDisplayTransform
// children.
nsDisplayItem *i = mList.GetBottom();
if (i && (!i->GetAbove() || i->GetType() == TYPE_TRANSFORM) &&
i->Frame() == mFrame) {
mReferenceFrame = i->ReferenceFrame();
mToReferenceFrame = i->ToReferenceFrame();
}
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
@ -2913,8 +3044,6 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
: nsDisplayItem(aBuilder, aFrame)
, mOverrideZIndex(0)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
mList.AppendToTop(aItem);
UpdateBounds(aBuilder);
@ -2926,20 +3055,29 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame =
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
} else {
// See the previous nsDisplayWrapList constructor
if (aItem->Frame() == aFrame) {
mReferenceFrame = aItem->ReferenceFrame();
mToReferenceFrame = aItem->ToReferenceFrame();
}
return;
}
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
// See the previous nsDisplayWrapList constructor
if (aItem->Frame() == aFrame) {
mReferenceFrame = aItem->ReferenceFrame();
mToReferenceFrame = aItem->ToReferenceFrame();
}
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem,
const nsIFrame* aReferenceFrame,
const nsPoint& aToReferenceFrame)
: nsDisplayItem(aBuilder, aFrame, aReferenceFrame, aToReferenceFrame)
, mOverrideZIndex(0)
{
mList.AppendToTop(aItem);
mBounds = mList.GetBounds(aBuilder);
}
nsDisplayWrapList::~nsDisplayWrapList() {
mList.DeleteAll();
MOZ_COUNT_DTOR(nsDisplayWrapList);
}
void
@ -2956,7 +3094,8 @@ nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
bool
nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
// Convert the passed in visible region to our appunits.
nsRegion visibleRegion;
// mVisibleRect has been clipped to GetClippedBounds
@ -2965,7 +3104,8 @@ nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
bool retval =
mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
mVisibleRect);
mVisibleRect,
aAllowVisibleRegionExpansion);
nsRegion removed;
// removed = originalVisibleRegion - visibleRegion
@ -2994,6 +3134,13 @@ bool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColo
return false;
}
bool nsDisplayWrapList::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) {
NS_WARNING("nsDisplayWrapList::IsVaryingRelativeToMovingFrame called unexpectedly");
// We could try to do something but let's conservatively just return true.
return true;
}
void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) {
NS_ERROR("nsDisplayWrapList should have been flattened away for painting");
@ -3154,7 +3301,7 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
return nullptr;
}
nsRefPtr<Layer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nullptr);
if (!container)
return nullptr;
@ -3238,7 +3385,8 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
bool
nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
// Our children are translucent so we should not allow them to subtract
// area from aVisibleRegion. We do need to find out what is visible under
// our children in the temporary compositing buffer, because if our children
@ -3247,8 +3395,10 @@ nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRect bounds = GetClippedBounds(aBuilder);
nsRegion visibleUnderChildren;
visibleUnderChildren.And(*aVisibleRegion, bounds);
nsRect allowExpansion = bounds.Intersect(aAllowVisibleRegionExpansion);
return
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren);
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren,
allowExpansion);
}
bool nsDisplayOpacity::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
@ -3314,7 +3464,7 @@ nsDisplayMixBlendMode::BuildLayer(nsDisplayListBuilder* aBuilder,
newContainerParameters.mDisableSubpixelAntialiasingInDescendants = true;
nsRefPtr<Layer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
newContainerParameters, nullptr);
if (!container) {
return nullptr;
@ -3326,7 +3476,8 @@ nsDisplayMixBlendMode::BuildLayer(nsDisplayListBuilder* aBuilder,
}
bool nsDisplayMixBlendMode::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
// Our children are need their backdrop so we should not allow them to subtract
// area from aVisibleRegion. We do need to find out what is visible under
// our children in the temporary compositing buffer, because if our children
@ -3335,7 +3486,10 @@ bool nsDisplayMixBlendMode::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRect bounds = GetClippedBounds(aBuilder);
nsRegion visibleUnderChildren;
visibleUnderChildren.And(*aVisibleRegion, bounds);
return nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren);
nsRect allowExpansion = bounds.Intersect(aAllowVisibleRegionExpansion);
return
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren,
allowExpansion);
}
bool nsDisplayMixBlendMode::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
@ -3387,7 +3541,7 @@ nsDisplayBlendContainer::BuildLayer(nsDisplayListBuilder* aBuilder,
newContainerParameters.mDisableSubpixelAntialiasingInDescendants = true;
nsRefPtr<Layer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
newContainerParameters, nullptr);
if (!container) {
return nullptr;
@ -3432,7 +3586,7 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
nsRefPtr<ContainerLayer> layer = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nullptr);
if (mFlags & VERTICAL_SCROLLBAR) {
layer->SetScrollbarData(mScrollTarget, Layer::ScrollDirection::VERTICAL);
@ -3485,7 +3639,7 @@ nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder,
container->SetScrollHandoffParentId(mScrollParentId);
RecordFrameMetrics(mFrame, rootScrollFrame, ReferenceFrame(),
container, viewport,
container, mList.GetVisibleRect(), viewport,
false, isRootContentDocument, aContainerParameters);
}
@ -3508,14 +3662,16 @@ nsDisplaySubDocument::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
bool
nsDisplaySubDocument::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
nsRect displayport;
bool usingDisplayPort =
nsLayoutUtils::ViewportHasDisplayPort(mFrame->PresContext(), &displayport);
if (!(mFlags & GENERATE_SCROLLABLE_LAYER) || !usingDisplayPort) {
return nsDisplayWrapList::ComputeVisibility(aBuilder, aVisibleRegion);
return nsDisplayWrapList::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
nsRegion childVisibleRegion;
@ -3526,8 +3682,9 @@ nsDisplaySubDocument::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRect boundedRect =
childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder));
nsRect allowExpansion = boundedRect.Intersect(aAllowVisibleRegionExpansion);
bool visible = mList.ComputeVisibilityForSublist(
aBuilder, &childVisibleRegion, boundedRect,
aBuilder, &childVisibleRegion, boundedRect, allowExpansion,
usingDisplayPort ? mFrame : nullptr);
// We don't allow this computation to influence aVisibleRegion, on the
// assumption that the layer can be asynchronously scrolled so we'll
@ -3685,7 +3842,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
, mScrollFrame(aScrollFrame)
, mScrolledFrame(aScrolledFrame)
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
, mDisplayPortContentsOpaque(false)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
@ -3704,7 +3860,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
, mScrollFrame(aScrollFrame)
, mScrolledFrame(aScrolledFrame)
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
, mDisplayPortContentsOpaque(false)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
@ -3722,7 +3877,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
, mScrollFrame(aScrollFrame)
, mScrolledFrame(aScrolledFrame)
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
, mDisplayPortContentsOpaque(false)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
@ -3750,28 +3904,12 @@ nsDisplayScrollLayer::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
return nsDisplayWrapList::GetBounds(aBuilder, aSnap);
}
nsRect
nsDisplayScrollLayer::GetScrolledContentRectToDraw(nsDisplayListBuilder* aBuilder,
nsRect* aDisplayPort)
{
if (aDisplayPort) {
// The visible region for the children may be much bigger than the hole we
// are viewing the children from, so that the compositor process has enough
// content to asynchronously pan while content is being refreshed.
// XXX mScrollFrame seems wrong here; we should add the offset of the
// scrollport
return *aDisplayPort + mScrollFrame->GetOffsetToCrossDoc(ReferenceFrame());
}
bool snap;
return GetBounds(aBuilder, &snap);
}
already_AddRefed<Layer>
nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
nsRefPtr<ContainerLayer> layer = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nullptr);
nsRect viewport = mScrollFrame->GetRect() -
@ -3780,28 +3918,12 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
layer->SetScrollHandoffParentId(mScrollParentId);
RecordFrameMetrics(mScrolledFrame, mScrollFrame, ReferenceFrame(), layer,
viewport, false, false, aContainerParameters);
if (mList.IsOpaque()) {
nsRect displayport;
bool usingDisplayport =
nsLayoutUtils::GetDisplayPort(mScrolledFrame->GetContent(), &displayport);
mDisplayPortContentsOpaque = mList.GetBounds(aBuilder).Contains(
GetScrolledContentRectToDraw(aBuilder, usingDisplayport ? &displayport : nullptr));
} else {
mDisplayPortContentsOpaque = false;
}
mList.GetVisibleRect(), viewport,
false, false, aContainerParameters);
return layer.forget();
}
bool
nsDisplayScrollLayer::IsConstructingScrollLayerForScrolledFrame(const nsIFrame* aScrolledFrame)
{
FrameProperties props = aScrolledFrame->Properties();
return reinterpret_cast<intptr_t>(props.Get(nsIFrame::ScrollLayerCount())) != 0;
}
bool
nsDisplayScrollLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
{
@ -3814,18 +3936,28 @@ nsDisplayScrollLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBui
bool
nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
nsRect displayport;
bool usingDisplayPort =
nsLayoutUtils::GetDisplayPort(mScrolledFrame->GetContent(), &displayport);
nsRect scrolledContentRect = GetScrolledContentRectToDraw(aBuilder,
usingDisplayPort ? &displayport : nullptr);
nsRegion childVisibleRegion;
if (usingDisplayPort) {
// The visible region for the children may be much bigger than the hole we
// are viewing the children from, so that the compositor process has enough
// content to asynchronously pan while content is being refreshed.
childVisibleRegion = displayport + mScrollFrame->GetOffsetToCrossDoc(ReferenceFrame());
} else {
bool snap;
childVisibleRegion = GetBounds(aBuilder, &snap);
}
nsRect boundedRect = scrolledContentRect.Intersect(mList.GetBounds(aBuilder));
nsRegion childVisibleRegion = scrolledContentRect;
nsRect boundedRect =
childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder));
nsRect allowExpansion = boundedRect.Intersect(aAllowVisibleRegionExpansion);
bool visible = mList.ComputeVisibilityForSublist(
aBuilder, &childVisibleRegion, boundedRect,
aBuilder, &childVisibleRegion, boundedRect, allowExpansion,
usingDisplayPort ? mScrollFrame : nullptr);
// We don't allow this computation to influence aVisibleRegion, on the
// assumption that the layer can be asynchronously scrolled so we'll
@ -4003,6 +4135,8 @@ nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
{
FrameProperties props = mScrolledFrame->Properties();
props.Remove(nsIFrame::ScrollLayerCount());
MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer);
}
@ -4083,7 +4217,8 @@ void nsDisplayZoom::Paint(nsDisplayListBuilder* aBuilder,
}
bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion)
nsRegion *aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
// Convert the passed in visible region to our appunits.
nsRegion visibleRegion;
@ -4094,6 +4229,8 @@ bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRect transformedVisibleRect =
mVisibleRect.ConvertAppUnitsRoundOut(mParentAPD, mAPD);
nsRect allowExpansion =
aAllowVisibleRegionExpansion.ConvertAppUnitsRoundIn(mParentAPD, mAPD);
bool retval;
// If we are to generate a scrollable layer we call
// nsDisplaySubDocument::ComputeVisibility to make the necessary adjustments
@ -4103,10 +4240,12 @@ bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
if (!(mFlags & GENERATE_SCROLLABLE_LAYER) || !usingDisplayPort) {
retval =
mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
transformedVisibleRect);
transformedVisibleRect,
allowExpansion);
} else {
retval =
nsDisplaySubDocument::ComputeVisibility(aBuilder, &visibleRegion);
nsDisplaySubDocument::ComputeVisibility(aBuilder, &visibleRegion,
allowExpansion);
}
nsRegion removed;
@ -4193,15 +4332,12 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
#endif
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
ComputeTransformFunction aTransformGetter,
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, ComputeTransformFunction aTransformGetter,
uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aList)
, mTransformGetter(aTransformGetter)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
@ -4210,44 +4346,33 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
}
void
nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
{
mReferenceFrame =
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(mFrame));
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex)
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aList)
, mTransformGetter(nullptr)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
SetReferenceFrameToAncestor(aBuilder);
mReferenceFrame =
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayItem *aItem,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex)
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayItem *aItem, uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aItem)
, mTransformGetter(nullptr)
, mChildrenVisibleRect(aChildrenVisibleRect)
, mIndex(aIndex)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
SetReferenceFrameToAncestor(aBuilder);
mReferenceFrame =
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
}
@ -4682,11 +4807,10 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
return nullptr;
}
bool prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame, false);
uint32_t flags = prerender ?
uint32_t flags = ShouldPrerenderTransformedContent(aBuilder, mFrame, false) ?
FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0;
nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(),
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetChildren(),
aContainerParameters, &newTransformMatrix, flags);
if (!container) {
@ -4704,7 +4828,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
this, mFrame,
eCSSProperty_transform);
if (prerender) {
if (ShouldPrerenderTransformedContent(aBuilder, mFrame, false)) {
container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(),
/*the value is irrelevant*/nullptr);
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM);
@ -4750,7 +4874,8 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
}
bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion)
nsRegion *aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
/* As we do this, we need to be sure to
* untransform the visible rect, since we want everything that's painting to
@ -4936,7 +5061,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
if (matrix.Is2D(&matrix2d) &&
matrix2d.PreservesAxisAlignedRectangles() &&
mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap).Contains(untransformedVisible)) {
result = mVisibleRect.Intersect(GetBounds(aBuilder, &tmpSnap));
result = mVisibleRect;
}
return result;
}
@ -4996,7 +5121,7 @@ nsDisplayTransform::TryMerge(nsDisplayListBuilder *aBuilder,
/* Now, move everything over to this frame and signal that
* we merged things!
*/
mStoredList.MergeFromTrackingMergedFrames(&static_cast<nsDisplayTransform*>(aItem)->mStoredList);
mStoredList.MergeFrom(&static_cast<nsDisplayTransform*>(aItem)->mStoredList);
return true;
}
@ -5209,14 +5334,15 @@ nsDisplaySVGEffects::BuildLayer(nsDisplayListBuilder* aBuilder,
}
nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
newContainerParameters, nullptr);
return container.forget();
}
bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
nsPoint offset = ToReferenceFrame();
nsRect dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mFrame,
@ -5227,7 +5353,7 @@ bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
// not allow them to subtract area from aVisibleRegion.
nsRegion childrenVisible(dirtyRect);
nsRect r = dirtyRect.Intersect(mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r, nsRect());
return true;
}

View File

@ -201,27 +201,23 @@ public:
* @return the root of given frame's (sub)tree, whose origin
* establishes the coordinate system for the child display items.
*/
const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
nsPoint* aOffset = nullptr)
const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame)
{
if (aFrame == mCurrentFrame) {
if (aOffset) {
*aOffset = mCurrentOffsetToReferenceFrame;
}
return mCurrentReferenceFrame;
if (aFrame == mCachedOffsetFrame) {
return mCachedReferenceFrame;
}
for (const nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f))
{
if (f == mReferenceFrame || f->IsTransformed()) {
if (aOffset) {
*aOffset = aFrame->GetOffsetToCrossDoc(f);
}
mCachedOffsetFrame = aFrame;
mCachedReferenceFrame = f;
mCachedOffset = aFrame->GetOffsetToCrossDoc(f);
return f;
}
}
if (aOffset) {
*aOffset = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
}
mCachedOffsetFrame = aFrame;
mCachedReferenceFrame = mReferenceFrame;
mCachedOffset = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
return mReferenceFrame;
}
@ -238,12 +234,14 @@ public:
* @return a point pt such that adding pt to a coordinate relative to aFrame
* makes it relative to ReferenceFrame(), i.e., returns
* aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
* the appunits of aFrame.
* the appunits of aFrame. It may be optimized to be faster than
* aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't).
*/
const nsPoint ToReferenceFrame(const nsIFrame* aFrame) {
nsPoint result;
FindReferenceFrameFor(aFrame, &result);
return result;
const nsPoint& ToReferenceFrame(const nsIFrame* aFrame) {
if (aFrame != mCachedOffsetFrame) {
FindReferenceFrameFor(aFrame);
}
return mCachedOffset;
}
/**
* When building the display list, the scrollframe aFrame will be "ignored"
@ -313,14 +311,6 @@ public:
void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
/**
* Get dirty rect relative to current frame (the frame that we're calling
* BuildDisplayList on right now).
*/
const nsRect& GetDirtyRect() { return mDirtyRect; }
const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
/**
* Returns true if merging and flattening of display lists should be
* performed while computing visibility.
@ -406,6 +396,12 @@ public:
*/
void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
/**
* Returns true if we're currently building display items that are in
* true fixed position subtree.
*/
bool IsInFixedPos() const { return mInFixedPos; }
/**
* @return true if images have been set to decode synchronously.
*/
@ -454,6 +450,19 @@ public:
*/
void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect);
/**
* Get the area of the final transparent region.
*/
const nsRegion* GetFinalTransparentRegion() { return mFinalTransparentRegion; }
/**
* Record the area of the final transparent region after all visibility
* calculations were performed.
*/
void SetFinalTransparentRegion(const nsRegion& aFinalTransparentRegion)
{
mFinalTransparentRegion = &aFinalTransparentRegion;
}
const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; }
/**
@ -517,58 +526,59 @@ public:
/**
* A helper class to temporarily set the value of
* mIsAtRootOfPseudoStackingContext, and temporarily
* set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
* aDirtyRect is relative to aForChild.
* update mCachedOffsetFrame/mCachedOffset from a frame to its child.
* Also saves and restores mClipState.
*/
class AutoBuildingDisplayList;
friend class AutoBuildingDisplayList;
class AutoBuildingDisplayList {
public:
AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
nsIFrame* aForChild,
const nsRect& aDirtyRect, bool aIsRoot)
AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, bool aIsRoot)
: mBuilder(aBuilder),
mPrevFrame(aBuilder->mCurrentFrame),
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevCachedOffset(aBuilder->mCachedOffset),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
{
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
}
AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
nsIFrame* aForChild, bool aIsRoot)
: mBuilder(aBuilder),
mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
mPrevCachedOffset(aBuilder->mCachedOffset),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
{
if (aForChild->IsTransformed()) {
aBuilder->mCurrentOffsetToReferenceFrame = nsPoint();
aBuilder->mCurrentReferenceFrame = aForChild;
} else if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
aBuilder->mCurrentOffsetToReferenceFrame += aForChild->GetPosition();
aBuilder->mCachedOffset = nsPoint();
aBuilder->mCachedReferenceFrame = aForChild;
} else if (mPrevCachedOffsetFrame == aForChild->GetParent()) {
aBuilder->mCachedOffset += aForChild->GetPosition();
} else {
aBuilder->mCurrentReferenceFrame =
aBuilder->FindReferenceFrameFor(aForChild,
&aBuilder->mCurrentOffsetToReferenceFrame);
aBuilder->mCachedOffset = aBuilder->ToReferenceFrame(aForChild);
}
aBuilder->mCurrentFrame = aForChild;
aBuilder->mDirtyRect = aDirtyRect;
aBuilder->mCachedOffsetFrame = aForChild;
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
}
void SetDirtyRect(const nsRect& aRect) {
mBuilder->mDirtyRect = aRect;
}
~AutoBuildingDisplayList() {
mBuilder->mCurrentFrame = mPrevFrame;
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
mBuilder->mCachedOffsetFrame = mPrevCachedOffsetFrame;
mBuilder->mCachedReferenceFrame = mPrevCachedReferenceFrame;
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCachedOffset = mPrevCachedOffset;
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
mBuilder->mAncestorHasTouchEventHandler = mPrevAncestorHasTouchEventHandler;
}
private:
nsDisplayListBuilder* mBuilder;
const nsIFrame* mPrevFrame;
const nsIFrame* mPrevReferenceFrame;
const nsIFrame* mPrevCachedOffsetFrame;
const nsIFrame* mPrevCachedReferenceFrame;
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
nsPoint mPrevOffset;
nsRect mPrevDirtyRect;
nsPoint mPrevCachedOffset;
bool mPrevIsAtRootOfPseudoStackingContext;
bool mPrevAncestorHasTouchEventHandler;
};
@ -592,6 +602,25 @@ public:
bool mOldValue;
};
/**
* A helper class to temporarily set the value of mInFixedPos.
*/
class AutoInFixedPosSetter;
friend class AutoInFixedPosSetter;
class AutoInFixedPosSetter {
public:
AutoInFixedPosSetter(nsDisplayListBuilder* aBuilder, bool aInFixedPos)
: mBuilder(aBuilder), mOldValue(aBuilder->mInFixedPos) {
aBuilder->mInFixedPos = aInFixedPos;
}
~AutoInFixedPosSetter() {
mBuilder->mInFixedPos = mOldValue;
}
private:
nsDisplayListBuilder* mBuilder;
bool mOldValue;
};
/**
* A helper class to temporarily set the value of mCurrentScrollParentId.
*/
@ -667,15 +696,11 @@ public:
* -moz-win-exclude-glass style. Used in setting glass margins on
* Windows.
*/
void AddWindowOpaqueRegion(const nsRegion& bounds) {
mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
void AddExcludedGlassRegion(nsRect &bounds) {
mExcludedGlassRegion.Or(mExcludedGlassRegion, bounds);
}
/**
* Returns the window opaque region built so far. This may be incomplete
* since the opaque region is built during layer construction.
*/
const nsRegion& GetWindowOpaqueRegion() {
return mWindowOpaqueRegion;
const nsRegion& GetExcludedGlassRegion() {
return mExcludedGlassRegion;
}
void SetGlassDisplayItem(nsDisplayItem* aItem) {
if (mGlassDisplayItem) {
@ -718,7 +743,6 @@ private:
struct PresShellState {
nsIPresShell* mPresShell;
nsIFrame* mCaretFrame;
nsRect mPrevDirtyRect;
uint32_t mFirstFrameMarkedForDisplay;
bool mIsBackgroundOnly;
};
@ -738,16 +762,13 @@ private:
nsAutoTArray<ThemeGeometry,2> mThemeGeometries;
nsDisplayTableItem* mCurrentTableItem;
DisplayListClipState mClipState;
// mCurrentFrame is the frame that we're currently calling (or about to call)
// BuildDisplayList on.
const nsIFrame* mCurrentFrame;
// The reference frame for mCurrentFrame.
const nsIFrame* mCurrentReferenceFrame;
// The offset from mCurrentFrame to mCurrentReferenceFrame.
nsPoint mCurrentOffsetToReferenceFrame;
// Relative to mCurrentFrame.
nsRect mDirtyRect;
nsRegion mWindowOpaqueRegion;
const nsRegion* mFinalTransparentRegion;
// When mCachedOffsetFrame is non-null, mCachedOffset is the offset from
// mCachedOffsetFrame to mReferenceFrame.
const nsIFrame* mCachedOffsetFrame;
const nsIFrame* mCachedReferenceFrame;
nsPoint mCachedOffset;
nsRegion mExcludedGlassRegion;
// The display item for the Windows window glass background, if any
nsDisplayItem* mGlassDisplayItem;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
@ -769,6 +790,7 @@ private:
// True when we're building a display list that's directly or indirectly
// under an nsDisplayTransform
bool mInTransform;
bool mInFixedPos;
bool mSyncDecodeImages;
bool mIsPaintingToWindow;
bool mIsCompositingCheap;
@ -826,14 +848,26 @@ public:
nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: mFrame(aFrame)
, mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
, mInFixedPos(aBuilder->IsInFixedPos())
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame);
mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
}
nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsIFrame* aReferenceFrame,
const nsPoint& aToReferenceFrame)
: mFrame(aFrame)
, mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
, mReferenceFrame(aReferenceFrame)
, mToReferenceFrame(aToReferenceFrame)
, mInFixedPos(aBuilder->IsInFixedPos())
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
!aBuilder->IsForPainting(), "dirty rect not set");
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
/**
* This constructor is only used in rare cases when we need to construct
@ -843,13 +877,14 @@ public:
: mFrame(aFrame)
, mClip(nullptr)
, mReferenceFrame(nullptr)
, mInFixedPos(false)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
}
virtual ~nsDisplayItem() {}
void* operator new(size_t aSize,
nsDisplayListBuilder* aBuilder) CPP_THROW_NEW {
return aBuilder->Allocate(aSize);
@ -1059,7 +1094,7 @@ public:
* @param aSnap set to true if the edges of the rectangles of the opaque
* region would be snapped to device pixels when drawing
* @return a region of the item that is opaque --- that is, every pixel
* that is visible is painted with an opaque
* that is visible (according to ComputeVisibility) is painted with an opaque
* color. This is useful for determining when one piece
* of content completely obscures another so that we can do occlusion
* culling.
@ -1077,6 +1112,16 @@ public:
* bounds with the same (possibly translucent) color
*/
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; }
/**
* @return false if the painting performed by the item is invariant
* when the item's underlying frame is moved relative to aFrame.
* In other words, if you render the item at locations P and P', the rendering
* only differs by the translation.
* It return true for all wrapped lists.
*/
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{ return false; }
/**
* @return true if the contents of this item are rendered fixed relative
* to the nearest viewport.
@ -1188,7 +1233,8 @@ public:
* is visible.
*/
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
/**
* Try to merge with the other item (which is below us in the display
@ -1235,17 +1281,10 @@ public:
virtual nsDisplayList* GetChildren() { return nullptr; }
/**
* Returns the visible rect.
* Returns the visible rect. Should only be called after ComputeVisibility
* has happened.
*/
const nsRect& GetVisibleRect() const { return mVisibleRect; }
/**
* Returns the visible rect for the children, relative to their
* reference frame. Can be different from mVisibleRect for nsDisplayTransform,
* since the reference frame for the children is different from the reference
* frame for the item itself.
*/
virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
const nsRect& GetVisibleRect() { return mVisibleRect; }
/**
* Stores the given opacity value to be applied when drawing. Returns
@ -1276,7 +1315,7 @@ public:
* -- Subtracts bounds from aVisibleRegion if the item is opaque
*/
bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion);
/**
* Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
@ -1342,6 +1381,13 @@ public:
}
}
// If we return false here it means that if this item creates a layer then
// ProcessDisplayItems will not set the visible region on the layer. The item
// should set the visible region, usually in BuildContainerLayer.
virtual bool SetVisibleRegionOnLayer() { return true; }
bool IsInFixedPos() { return mInFixedPos; }
protected:
friend class nsDisplayList;
@ -1354,12 +1400,12 @@ protected:
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
nsPoint mToReferenceFrame;
// This is the rectangle that needs to be painted.
// Display item construction sets this to the dirty rect.
// nsDisplayList::ComputeVisibility sets this to the visible region
// of the item by intersecting the current visible region with the bounds
// of the item. Paint implementations can use this to limit their drawing.
// Guaranteed to be contained in GetBounds().
nsRect mVisibleRect;
bool mInFixedPos;
#ifdef MOZ_DUMP_PAINTING
// True if this frame has been painted.
bool mPainted;
@ -1390,12 +1436,14 @@ public:
/**
* Create an empty list.
*/
nsDisplayList()
: mIsOpaque(false)
, mForceTransparentSurface(false)
nsDisplayList() :
mIsOpaque(false)
{
mTop = &mSentinel;
mSentinel.mAbove = nullptr;
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
mDidComputeVisibility = false;
#endif
}
~nsDisplayList() {
if (mSentinel.mAbove) {
@ -1561,6 +1609,7 @@ public:
bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds,
const nsRect& aAllowVisibleRegionExpansion,
nsIFrame* aDisplayPortFrame = nullptr);
/**
@ -1580,13 +1629,16 @@ public:
* empty, i.e. everything visible in this list is opaque.
*/
bool IsOpaque() const {
NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
return mIsOpaque;
}
/**
* Returns true if any display item requires the surface to be transparent.
* Returns true if during ComputeVisibility any display item
* set the surface to be transparent.
*/
bool NeedsTransparentSurface() const {
NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
return mForceTransparentSurface;
}
/**
@ -1626,16 +1678,15 @@ public:
PAINT_COMPRESSED = 0x10
};
void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
uint32_t aFlags);
uint32_t aFlags) const;
/**
* Like PaintRoot, but used for internal display sublists.
* aForFrame is the frame that the list is associated with.
*/
void PaintForFrame(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
nsIFrame* aForFrame, uint32_t aFlags);
nsIFrame* aForFrame, uint32_t aFlags) const;
/**
* Get the bounds. Takes the union of the bounds of all children.
* The result is not cached.
*/
nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
/**
@ -1645,38 +1696,36 @@ public:
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
nsDisplayItem::HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames) const;
/**
* Compute the union of the visible rects of the items in the list. The
* result is not cached.
*/
nsRect GetVisibleRect() const;
void SetIsOpaque()
{
mIsOpaque = true;
}
void SetNeedsTransparentSurface()
{
mForceTransparentSurface = true;
}
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
bool DidComputeVisibility() const { return mDidComputeVisibility; }
#endif
nsRect GetVisibleRect() const { return mVisibleRect; }
private:
// This class is only used on stack, so we don't have to worry about leaking
// it. Don't let us be heap-allocated!
void* operator new(size_t sz) CPP_THROW_NEW;
// Utility function used to massage the list during ComputeVisibility.
void FlattenTo(nsTArray<nsDisplayItem*>* aElements);
nsDisplayItemLink mSentinel;
nsDisplayItemLink* mTop;
// This is set by ComputeVisibility
nsRect mVisibleRect;
// This is set to true by FrameLayerBuilder if the final visible region
// 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).
bool mIsOpaque;
// This is set to true by FrameLayerBuilder if any display item in this
// This is set to true by ComputeVisibility if any display item in this
// list needs to force the surface containing this list to be transparent.
bool mForceTransparentSurface;
#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
bool mDidComputeVisibility;
#endif
};
/**
@ -2140,9 +2189,12 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) MOZ_OVERRIDE;
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) MOZ_OVERRIDE;
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
/**
* GetBounds() returns the background painting area.
@ -2344,7 +2396,8 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
@ -2387,7 +2440,8 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
@ -2528,6 +2582,9 @@ private:
* detect and handle this case.
*/
class nsDisplayWrapList : public nsDisplayItem {
// This is never instantiated directly, so no need to count constructors and
// destructors.
public:
/**
* Takes all the items from aList and puts them in our list.
@ -2536,11 +2593,10 @@ public:
nsDisplayList* aList);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayItem* aItem);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayItem* aItem, const nsIFrame* aReferenceFrame, const nsPoint& aToReferenceFrame);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
}
: nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0) {}
virtual ~nsDisplayWrapList();
/**
* Call this if the wrapped list is changed.
@ -2555,19 +2611,20 @@ public:
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) MOZ_OVERRIDE;
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE {
NS_WARNING("This list should already have been flattened!!!");
return false;
}
virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) MOZ_OVERRIDE
{
aFrames->AppendElements(mMergedFrames);
}
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
return true;
}
virtual bool IsInvalid(nsRect& aRect) MOZ_OVERRIDE
{
if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
@ -2623,11 +2680,14 @@ public:
protected:
nsDisplayWrapList() {}
void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther)
void MergeFrom(nsDisplayWrapList* aOther)
{
mList.AppendToBottom(&aOther->mList);
mBounds.UnionRect(mBounds, aOther->mBounds);
mVisibleRect.UnionRect(mVisibleRect, aOther->mVisibleRect);
}
void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther)
{
MergeFrom(aOther);
mMergedFrames.AppendElement(aOther->mFrame);
mMergedFrames.MoveElementsFrom(aOther->mMergedFrames);
}
@ -2688,7 +2748,8 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
@ -2736,11 +2797,9 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
NS_DISPLAY_DECL_NAME("MixBlendMode", TYPE_MIX_BLEND_MODE)
};
@ -2768,9 +2827,6 @@ public:
return mozilla::LAYER_INACTIVE;
}
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
private:
@ -2830,9 +2886,6 @@ public:
// Don't allow merging, each sublist must have its own layer
return false;
}
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
uint32_t GetFlags() { return mFlags; }
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
protected:
@ -2860,7 +2913,10 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return !(mFlags & GENERATE_SCROLLABLE_LAYER); }
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
@ -2919,7 +2975,7 @@ public:
/**
* This potentially creates a layer for the given list of items, whose
* visibility is determined by the displayport for the given frame instead of
* normal visibility computation.
* what is passed in to ComputeVisibility.
*
* Here in content, we can use this to render more content than is actually
* visible. Then, the compositing process can manipulate the generated layer
@ -2977,7 +3033,8 @@ public:
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@ -2993,25 +3050,19 @@ public:
// after merging, all the nsDisplayScrollLayers should flatten away.
intptr_t GetScrollLayerCount();
static bool IsConstructingScrollLayerForScrolledFrame(const nsIFrame* aScrolledFrame);
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
bool IsDisplayPortOpaque() { return mDisplayPortContentsOpaque; }
protected:
nsRect GetScrolledContentRectToDraw(nsDisplayListBuilder* aBuilder,
nsRect* aDisplayPort);
nsIFrame* mScrollFrame;
nsIFrame* mScrolledFrame;
ViewID mScrollParentId;
bool mDisplayPortContentsOpaque;
};
/**
@ -3076,7 +3127,8 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
@ -3117,12 +3169,10 @@ public:
return mEffectsBounds + ToReferenceFrame();
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem) MOZ_OVERRIDE;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
@ -3182,14 +3232,11 @@ public:
* ferries the underlying frame to the nsDisplayItem constructor.
*/
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
nsDisplayList *aList, uint32_t aIndex = 0);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
nsDisplayItem *aItem, uint32_t aIndex = 0);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
nsDisplayList *aList, ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayTransform()
@ -3224,7 +3271,8 @@ public:
const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion) MOZ_OVERRIDE;
nsRegion *aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem) MOZ_OVERRIDE;
virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
@ -3246,11 +3294,6 @@ public:
return nsDisplayItem::ReferenceFrameForChildren();
}
virtual const nsRect& GetVisibleRectForChildren() const MOZ_OVERRIDE
{
return mChildrenVisibleRect;
}
enum {
INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
};
@ -3380,12 +3423,12 @@ 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
private:
void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
@ -3396,7 +3439,6 @@ private:
nsDisplayWrapList mStoredList;
gfx3DMatrix mTransform;
ComputeTransformFunction mTransformGetter;
nsRect mChildrenVisibleRect;
uint32_t mIndex;
};

View File

@ -154,7 +154,10 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
nsDisplayList* list = aItem->GetChildren();
const DisplayItemClip& clip = aItem->GetClip();
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
nsRegion opaque;
if (!list || list->DidComputeVisibility()) {
opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
}
if (aDumpHtml && aItem->Painted()) {
nsCString string(aItem->Name());
string.Append('-');

View File

@ -1481,7 +1481,7 @@ nsLayoutUtils::GetScrollableFrameFor(const nsIFrame *aScrolledFrame)
{
nsIFrame *frame = aScrolledFrame->GetParent();
nsIScrollableFrame *sf = do_QueryFrame(frame);
return (sf && sf->GetScrolledFrame() == aScrolledFrame) ? sf : nullptr;
return sf;
}
/* static */ void
@ -1603,9 +1603,9 @@ IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
return reinterpret_cast<intptr_t>(aThumbFrame->Properties().Get(ScrollbarThumbLayerized()));
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForFrame(nsIFrame* aFrame,
const nsIFrame* aStopAtAncestor)
static nsIFrame*
GetAnimatedGeometryRootForFrame(nsIFrame* aFrame,
const nsIFrame* aStopAtAncestor)
{
nsIFrame* f = aFrame;
nsIFrame* stickyFrame = nullptr;
@ -2323,7 +2323,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
false/*don't build caret*/);
nsDisplayList list;
nsDisplayTransform* item =
new (&builder) nsDisplayTransform(&builder, aFrame, &list, nsRect());
new (&builder) nsDisplayTransform(&builder, aFrame, &list);
*aTransform =
item->GetTransform();
@ -2937,6 +2937,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
}
#endif
list.ComputeVisibilityForRoot(&builder, &visibleRegion,
usingDisplayPort ? rootScrollFrame : nullptr);
uint32_t flags = nsDisplayList::PAINT_DEFAULT;
if (aFlags & PAINT_WIDGET_LAYERS) {
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
@ -2952,6 +2955,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
} else if (!(aFlags & PAINT_DOCUMENT_RELATIVE)) {
nsIWidget *widget = aFrame->GetNearestWidget();
if (widget) {
builder.SetFinalTransparentRegion(visibleRegion);
// If we're finished building display list items for painting of the outermost
// pres shell, notify the widget about any toolbars we've encountered.
widget->UpdateThemeGeometries(builder.GetThemeGeometries());
@ -3019,7 +3023,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
!(aFlags & PAINT_DOCUMENT_RELATIVE)) {
nsIWidget *widget = aFrame->GetNearestWidget();
if (widget) {
nsRegion excludedRegion = builder.GetWindowOpaqueRegion();
nsRegion excludedRegion = builder.GetExcludedGlassRegion();
excludedRegion.Sub(excludedRegion, visibleRegion);
nsIntRegion windowRegion(excludedRegion.ToNearestPixels(presContext->AppUnitsPerDevPixel()));
widget->UpdateOpaqueRegion(windowRegion);
}

View File

@ -499,14 +499,6 @@ public:
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder);
/**
* Finds the nearest ancestor frame to aFrame that is considered to have (or
* will have) "animated geometry". This could be aFrame. Returns
* aStopAtAncestor if no closer ancestor is found.
*/
static nsIFrame* GetAnimatedGeometryRootForFrame(nsIFrame* aFrame,
const nsIFrame* aStopAtAncestor);
/**
* GetScrollableFrameFor returns the scrollable frame for a scrolled frame
*/

View File

@ -5155,6 +5155,7 @@ PresShell::PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
aArea.MoveBy(-rangeInfo->mRootOffset.x, -rangeInfo->mRootOffset.y);
nsRegion visible(aArea);
rangeInfo->mList.ComputeVisibilityForRoot(&rangeInfo->mBuilder, &visible);
rangeInfo->mList.PaintRoot(&rangeInfo->mBuilder, rc, nsDisplayList::PAINT_DEFAULT);
aArea.MoveBy(rangeInfo->mRootOffset.x, rangeInfo->mRootOffset.y);
}

View File

@ -37,9 +37,6 @@ public:
: nsDisplayWrapList(aBuilder, aFrame, aList) {}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
NS_DISPLAY_DECL_NAME("OptionEventGrabber", TYPE_OPTION_EVENT_GRABBER)
};

View File

@ -155,7 +155,8 @@ public:
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE
{
return NS_GET_A(mColor) > 0;
}

View File

@ -1737,9 +1737,7 @@ DisplayDebugBorders(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
#endif
static nsresult
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
nsDisplayList *aList, nsDisplayList *aOutput,
uint32_t& aIndex, nsDisplayList* aTemp)
WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsDisplayList *aList, nsDisplayList *aOutput, uint32_t& aIndex, nsDisplayList* aTemp)
{
if (aIndex > nsDisplayTransform::INDEX_MAX) {
return NS_OK;
@ -1758,8 +1756,7 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
switch (item->GetType()) {
case nsDisplayItem::TYPE_TRANSFORM: {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
}
// Override item's clipping with our current clip state (if any). Since we're
// bubbling up a preserve-3d transformed child to a preserve-3d parent,
@ -1781,8 +1778,7 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
}
case nsDisplayItem::TYPE_OPACITY: {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
}
nsDisplayOpacity *opacity = static_cast<nsDisplayOpacity*>(item);
nsDisplayList output;
@ -1792,8 +1788,7 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
rv = WrapPreserve3DListInternal(aFrame, aBuilder,
opacity->GetChildren(), &output, aIndex, aTemp);
if (!aTemp->IsEmpty()) {
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
}
opacity->GetChildren()->AppendToTop(&output);
opacity->UpdateBounds(aBuilder);
@ -1803,12 +1798,10 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
default: {
if (childFrame->StyleDisplay()->BackfaceIsHidden()) {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
}
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
childFrame, item, item->GetVisibleRect(), aIndex++));
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, childFrame, item, aIndex++));
} else {
aTemp->AppendToTop(item);
}
@ -1833,18 +1826,15 @@ IsScrollFrameActive(nsIScrollableFrame* aScrollableFrame)
}
static nsresult
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
nsDisplayList *aList)
WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsDisplayList *aList)
{
uint32_t index = 0;
nsDisplayList temp;
nsDisplayList output;
nsresult rv = WrapPreserve3DListInternal(aFrame, aBuilder, aList, &output,
index, &temp);
nsresult rv = WrapPreserve3DListInternal(aFrame, aBuilder, aList, &output, index, &temp);
if (!temp.IsEmpty()) {
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame,
&temp, temp.GetVisibleRect(), index++));
output.AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, &temp, index++));
}
aList->AppendToTop(&output);
@ -1917,8 +1907,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
AutoSaveRestoreBlendMode autoRestoreBlendMode(*aBuilder);
aBuilder->SetContainsBlendModes(BlendModeSet());
nsPoint offsetToReferenceFrame = aBuilder->ToReferenceFrame(this);
if (isTransformed) {
const nsRect overflow = GetVisualOverflowRectRelativeToSelf();
if (aBuilder->IsForPainting() &&
@ -1929,10 +1917,11 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
return;
}
dirtyRect += offsetToReferenceFrame;
nsPoint offset = aBuilder->ToReferenceFrame(this);
dirtyRect += offset;
nsRect untransformedDirtyRect;
if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this,
offsetToReferenceFrame, &untransformedDirtyRect)) {
if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this, offset, &untransformedDirtyRect)) {
dirtyRect = untransformedDirtyRect;
} else {
NS_WARNING("Unable to untransform dirty rect!");
@ -1951,8 +1940,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
nsDisplayListBuilder::AutoBuildingDisplayList
buildingDisplayList(aBuilder, this, dirtyRect, true);
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (isTransformed || useOpacity || useBlendMode || usingSVGEffects || useStickyPosition) {
@ -1965,7 +1952,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
}
nsDisplayListCollection set;
{
{
nsDisplayListBuilder::AutoBuildingDisplayList rootSetter(aBuilder, true);
DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
nsDisplayListBuilder::AutoInTransformSetter
inTransformSetter(aBuilder, inTransform);
@ -2006,7 +1994,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
set.PositionedDescendants()->DeleteAll();
set.Outlines()->DeleteAll();
}
// This z-order sort also sorts secondarily by content order. We need to do
// this so that boxes produced by the same element are placed together
// in the sort. Consider a position:relative inline element that breaks
@ -2014,7 +2002,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// children should be z-ordered after all the boxes for the position:relative
// element itself.
set.PositionedDescendants()->SortByZOrder(aBuilder, GetContent());
nsDisplayList resultList;
// Now follow the rules of http://www.w3.org/TR/CSS21/zindex.html
// 1,2: backgrounds and borders
@ -2084,8 +2072,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
new (aBuilder) nsDisplayStickyPosition(aBuilder, this, &resultList));
}
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
* everything in an nsDisplayTransform. If there's nothing in the list, don't add
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
* everything in an nsDisplayTransform. If there's nothing in the list, don't add
* anything.
*
* For the preserve-3d case we want to individually wrap every child in the list with
@ -2098,15 +2086,12 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (isTransformed && !resultList.IsEmpty()) {
// Restore clip state now so nsDisplayTransform is clipped properly.
clipState.Restore();
// Revert to the dirtyrect coming in from the parent, without our transform
// taken into account.
buildingDisplayList.SetDirtyRect(aDirtyRect + offsetToReferenceFrame);
if (Preserves3DChildren()) {
WrapPreserve3DList(this, aBuilder, &resultList);
} else {
resultList.AppendNewToTop(
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect));
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList));
}
}
@ -2300,8 +2285,15 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
NS_ASSERTION(!isStackingContext || pseudoStackingContext,
"Stacking contexts must also be pseudo-stacking-contexts");
bool isInFixedPos = aBuilder->IsInFixedPos() ||
(isPositioned &&
disp->mPosition == NS_STYLE_POSITION_FIXED &&
nsLayoutUtils::IsReallyFixedPos(child));
nsDisplayListBuilder::AutoInFixedPosSetter
buildingInFixedPos(aBuilder, isInFixedPos);
nsDisplayListBuilder::AutoBuildingDisplayList
buildingForChild(aBuilder, child, dirty, pseudoStackingContext);
buildingForChild(aBuilder, child, pseudoStackingContext);
DisplayListClipState::AutoClipMultiple clipState(aBuilder);
CheckForTouchEventHandler(aBuilder, child);
@ -5235,12 +5227,6 @@ nsIFrame::GetScrollableOverflowRectRelativeToParent() const
return GetScrollableOverflowRect() + mRect.TopLeft();
}
nsRect
nsIFrame::GetVisualOverflowRectRelativeToParent() const
{
return GetVisualOverflowRect() + mRect.TopLeft();
}
nsRect
nsIFrame::GetScrollableOverflowRectRelativeToSelf() const
{

View File

@ -271,6 +271,7 @@ 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

@ -2269,15 +2269,6 @@ public:
*/
nsRect GetVisualOverflowRectRelativeToSelf() const;
/**
* Same as GetVisualOverflowRect, except relative to the parent
* frame.
*
* @return the rect relative to the parent frame, in the parent frame's
* coordinate system
*/
nsRect GetVisualOverflowRectRelativeToParent() const;
/**
* Returns this frame's visual overflow rect as it would be before taking
* account of SVG effects or transforms. The rect returned is relative to

View File

@ -1425,6 +1425,7 @@ 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

@ -839,12 +839,6 @@ nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx,
static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
}
/**
* nsDisplayPluginReadback creates an active ReadbackLayer. The ReadbackLayer
* obtains from the compositor the contents of the window underneath
* the ReadbackLayer, which we then use as an opaque buffer for plugins to
* asynchronously draw onto.
*/
class nsDisplayPluginReadback : public nsDisplayItem {
public:
nsDisplayPluginReadback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
@ -860,6 +854,9 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("PluginReadback", TYPE_PLUGIN_READBACK)
@ -892,6 +889,25 @@ nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
return GetDisplayItemBounds(aBuilder, this, mFrame);
}
bool
nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion))
return false;
nsRect expand;
bool snap;
expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder, &snap));
// *Add* our bounds to the visible region so that stuff underneath us is
// likely to be made visible, so we can use it for a background! This is
// a bit crazy since we normally only subtract from the visible region.
aVisibleRegion->Or(*aVisibleRegion, expand);
return true;
}
#ifdef MOZ_WIDGET_ANDROID
class nsDisplayPluginVideo : public nsDisplayItem {
@ -909,6 +925,9 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO)
@ -939,6 +958,15 @@ nsDisplayPluginVideo::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
return GetDisplayItemBounds(aBuilder, this, mFrame);
}
bool
nsDisplayPluginVideo::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
#endif
nsRect
@ -959,7 +987,8 @@ nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
bool
nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
if (aBuilder->IsForPluginGeometry()) {
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
@ -998,7 +1027,8 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
}
}
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion);
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
nsRegion
@ -1582,6 +1612,7 @@ 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

@ -319,7 +319,8 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) MOZ_OVERRIDE;
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)

View File

@ -414,22 +414,22 @@ PruneDisplayListForExtraPage(nsDisplayListBuilder* aBuilder,
aList->AppendToTop(&newList);
}
static void
static nsresult
BuildDisplayListForExtraPage(nsDisplayListBuilder* aBuilder,
nsPageFrame* aPage, nsIFrame* aExtraPage,
const nsRect& aDirtyRect, nsDisplayList* aList)
nsDisplayList* aList)
{
// The only content in aExtraPage we care about is out-of-flow content whose
// placeholders have occurred in aPage. If
// NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO is not set, then aExtraPage has
// no such content.
if (!aExtraPage->HasAnyStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
return;
}
nsDisplayList list;
aExtraPage->BuildDisplayListForStackingContext(aBuilder, aDirtyRect, &list);
// Pass an empty dirty rect since we're only interested in finding
// placeholders whose out-of-flows are in the page
// aBuilder->GetReferenceFrame(), and the paths to those placeholders
// have already been marked as NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO.
// Note that we should still do a prune step since we don't want to
// rely on dirty-rect checking for correctness.
aExtraPage->BuildDisplayListForStackingContext(aBuilder, nsRect(), &list);
PruneDisplayListForExtraPage(aBuilder, aPage, aExtraPage, &list);
aList->AppendToTop(&list);
return NS_OK;
}
static nsIFrame*
@ -506,8 +506,8 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
clipState.Clear();
clipState.ClipContainingBlockDescendants(clipRect, nullptr);
nsRect dirtyRect = child->GetVisualOverflowRectRelativeToSelf();
child->BuildDisplayListForStackingContext(aBuilder, dirtyRect, &content);
child->BuildDisplayListForStackingContext(aBuilder,
child->GetVisualOverflowRectRelativeToSelf(), &content);
// We may need to paint out-of-flow frames whose placeholders are
// on other pages. Add those pages to our display list. Note that
@ -518,16 +518,9 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// following placeholders to their out-of-flows) end up on the list.
nsIFrame* page = child;
while ((page = GetNextPage(page)) != nullptr) {
BuildDisplayListForExtraPage(aBuilder, this, page,
dirtyRect + child->GetOffsetTo(page), &content);
BuildDisplayListForExtraPage(aBuilder, this, page, &content);
}
// Invoke AutoBuildingDisplayList to ensure that the correct dirtyRect
// is used to compute the visible rect if AddCanvasBackgroundColorItem
// creates a display item.
nsDisplayListBuilder::AutoBuildingDisplayList
building(aBuilder, child, dirtyRect, true);
// Add the canvas background color to the bottom of the list. This
// happens after we've built the list so that AddCanvasBackgroundColorItem
// can monkey with the contents if necessary.
@ -537,8 +530,7 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
*aBuilder, content, child, backgroundRect, NS_RGBA(0,0,0,0));
}
content.AppendNewToTop(new (aBuilder) nsDisplayTransform(aBuilder, child,
&content, content.GetVisibleRect(), ::ComputePageTransform));
content.AppendNewToTop(new (aBuilder) nsDisplayTransform(aBuilder, child, &content, ::ComputePageTransform));
set.Content()->AppendToTop(&content);

View File

@ -788,22 +788,16 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
clipState.Clear();
nsIFrame* child = GetFirstPrincipalChild();
nsRect dirty = aDirtyRect;
dirty.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale());
while (child) {
if (child->GetVisualOverflowRectRelativeToParent().Intersects(dirty)) {
child->BuildDisplayListForStackingContext(aBuilder,
dirty - child->GetPosition(), &content);
aBuilder->ResetMarkedFramesForDisplayList();
}
child->BuildDisplayListForStackingContext(aBuilder,
child->GetVisualOverflowRectRelativeToSelf(), &content);
aBuilder->ResetMarkedFramesForDisplayList();
child = child->GetNextSibling();
}
}
content.AppendNewToTop(new (aBuilder)
nsDisplayTransform(aBuilder, this, &content, content.GetVisibleRect(),
::ComputePageSequenceTransform));
nsDisplayTransform(aBuilder, this, &content, ::ComputePageSequenceTransform));
aLists.Content()->AppendToTop(&content);
}

View File

@ -444,6 +444,13 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
haveDisplayPort ||
presContext->IsRootContentDocument() || (sf && sf->IsScrollingActive());
// Don't let in fixed pos propagate down to child documents. This makes
// it a little less effective but doesn't regress an important case of a
// child document being in a fixed pos element where we would do no occlusion
// at all if we let it propagate down.
nsDisplayListBuilder::AutoInFixedPosSetter
buildingInFixedPos(aBuilder, false);
nsDisplayList childItems;
{

View File

@ -219,6 +219,7 @@ 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,6 +873,7 @@ 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.
@ -925,6 +926,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
mBackgroundColor,
aManager, aFrame);
}
mContainer->SetVisibleRegion(aVisibleRect);
return nsRefPtr<Layer>(mContainer).forget();
}

View File

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<div style="width:400px;">
<span style="opacity:0.5;">
<span style="position:relative; display:inline-block; width:400px; height:200px;"></span>
<span style="position:relative; top:-300px; display:inline-block; background:lime; width:400px; height:400px;"></span>
</span>
</div>

View File

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<div style="width:400px;">
<span style="opacity:0.5;">
<span style="position:relative; display:inline-block; background:red; width:400px; height:200px;"></span>
<span style="position:relative; top:-300px; display:inline-block; background:lime; width:400px; height:400px;"></span>
</span>
</div>

View File

@ -1790,7 +1790,7 @@ fuzzy-if(OSX==10.6,2,30) skip-if(B2G&&browserIsRemote) == 933264-1.html 933264-1
== 936670-1.svg 936670-1-ref.svg
== 941940-1.html 941940-1-ref.html
fails == 942017.html 942017-ref.html # bug 942017
fuzzy-if(B2G,1,7) == 942672-1.html 942672-1-ref.html
== 942672-1.html 942672-1-ref.html
== 953334-win32-clipping.html 953334-win32-clipping-ref.html
== 956513-1.svg 956513-1-ref.svg
== 944291-1.html 944291-1-ref.html
@ -1813,5 +1813,4 @@ pref(layout.css.overflow-clip-box.enabled,true) == 992447.html 992447-ref.html
pref(layout.css.sticky.enabled,true) == 1005405-1.html 1005405-1-ref.html
pref(layout.css.will-change.enabled,true) == 1018522-1.html 1018522-1-ref.html
pref(browser.display.use_document_fonts,0) == 1022481-1.html 1022481-1-ref.html
== 1022612-1.html 1022612-1-ref.html
== 1024473-1.html 1024473-1-ref.html

View File

@ -4,7 +4,7 @@
<fieldset style="position:relative; overflow:hidden; width:500px; height:500px;">
<legend>Legend</legend>
<div style="height:1000px;">
<div style="position:absolute; padding:2px; left:20px; top:20px; background:yellow;">Abs-pos</div>
<div style="position:absolute; left:20px; top:20px; background:yellow;">Abs-pos</div>
</div>
</fieldset>
</body>

View File

@ -4,7 +4,7 @@
<fieldset id="f" style="position:relative; overflow:hidden; width:500px; height:500px;">
<legend>Legend</legend>
<div style="height:1000px;">
<div style="position:absolute; padding:2px; left:20px; top:50px; background:yellow;">Abs-pos</div>
<div style="position:absolute; left:20px; top:50px; background:yellow;">Abs-pos</div>
</div>
</fieldset>
<script>

View File

@ -52,7 +52,7 @@ fails-if(Android) skip-if(d2d||cocoaWidget) == subpixel-glyphs-x-1a.html subpixe
skip-if(!(d2d||cocoaWidget)) random-if(d2d) != subpixel-glyphs-x-2a.html subpixel-glyphs-x-2b.html
skip-if(B2G) HTTP(..) == subpixel-glyphs-x-3a.html subpixel-glyphs-x-3b.html
# No platforms do subpixel positioning vertically
fuzzy-if(Android,19,2) == subpixel-glyphs-y-1a.html subpixel-glyphs-y-1b.html
== subpixel-glyphs-y-1a.html subpixel-glyphs-y-1b.html
fuzzy-if((Android||B2G),231,653) == subpixel-lineheight-1a.html subpixel-lineheight-1b.html
== swash-1.html swash-1-ref.html
HTTP(..) != synthetic-bold-metrics-01.html synthetic-bold-metrics-01-notref.html

View File

@ -1088,6 +1088,20 @@ nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
bool
nsDisplayTableItem::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
if (!mPartHasFixedBackground)
return false;
// If aFrame is mFrame or an ancestor in this document, and aFrame is
// not the viewport frame, then moving aFrame will move mFrame
// relative to the viewport, so our fixed-pos background will change.
return mFrame == aFrame ||
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame);
}
/* static */ void
nsDisplayTableItem::UpdateForFrameBackground(nsIFrame* aFrame)
{

View File

@ -50,6 +50,8 @@ public:
nsDisplayItem(aBuilder, aFrame),
mPartHasFixedBackground(false) {}
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) MOZ_OVERRIDE;
// With collapsed borders, parts of the collapsed border can extend outside
// the table part frames, so allow this display element to blow out to our
// overflow rect. This is also useful for row frames that have spanning

View File

@ -1320,8 +1320,8 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// in calculating glass margins on Windows.
const nsStyleDisplay* styles = StyleDisplay();
if (styles && styles->mAppearance == NS_THEME_WIN_EXCLUDE_GLASS) {
aBuilder->AddWindowOpaqueRegion(
nsRect(aBuilder->ToReferenceFrame(this), GetSize()));
nsRect rect = nsRect(aBuilder->ToReferenceFrame(this), GetSize());
aBuilder->AddExcludedGlassRegion(rect);
}
}
@ -2012,9 +2012,6 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
return false;
}
NS_DISPLAY_DECL_NAME("XULEventRedirector", TYPE_XUL_EVENT_REDIRECTOR)
private:
nsIFrame* mTargetFrame;

View File

@ -406,6 +406,8 @@ 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>

View File

@ -206,10 +206,10 @@ RUN_REFTEST_B2G = rm -f ./$@.log && $(PYTHON) _tests/reftest/runreftestb2g.py \
ifeq ($(OS_ARCH),WINNT) #{
# GPU-rendered shadow layers are unsupported here
OOP_CONTENT = --setpref=layers.async-pan-zoom.enabled=true --setpref=browser.tabs.remote=true --setpref=browser.tabs.remote.autostart=true --setpref=layers.acceleration.disabled=true
OOP_CONTENT = --setpref=browser.tabs.remote=true --setpref=browser.tabs.remote.autostart=true --setpref=layers.acceleration.disabled=true
GPU_RENDERING =
else
OOP_CONTENT = --setpref=layers.async-pan-zoom.enabled=true --setpref=browser.tabs.remote=true --setpref=browser.tabs.remote.autostart=true
OOP_CONTENT = --setpref=browser.tabs.remote=true --setpref=browser.tabs.remote.autostart=true
GPU_RENDERING = --setpref=layers.acceleration.force-enabled=true
endif #}