Bug 1126230 part 7 - Implement painting part for the top layer. r=roc

This commit is contained in:
Xidorn Quan 2015-10-02 16:34:09 +10:00
parent e405b3cf72
commit dbaf72f4f9
3 changed files with 77 additions and 9 deletions

View File

@ -2314,9 +2314,12 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// dirty rect in child-relative coordinates
nsRect dirty = aDirtyRect - child->GetOffsetTo(this);
const nsStyleDisplay* disp;
nsIAtom* childType = child->GetType();
nsDisplayListBuilder::OutOfFlowDisplayData* savedOutOfFlowData = nullptr;
if (childType == nsGkAtoms::placeholderFrame) {
if (childType != nsGkAtoms::placeholderFrame) {
disp = child->StyleDisplay();
} else {
nsPlaceholderFrame* placeholder = static_cast<nsPlaceholderFrame*>(child);
child = placeholder->GetOutOfFlowFrame();
NS_ASSERTION(child, "No out of flow frame?");
@ -2326,6 +2329,16 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
if (!child || nsLayoutUtils::IsPopup(child) ||
(child->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT))
return;
MOZ_ASSERT(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW);
disp = child->StyleDisplay();
// If the out-of-flow frame is in the top layer, the viewport frame
// will paint it. Skip it here. Note that, only out-of-flow frames
// with this property should be skipped, because non-HTML elements
// may stop their children from being out-of-flow. Those frames
// should still be handled in the normal in-flow path.
if (disp->mTopLayer != NS_STYLE_TOP_LAYER_NONE) {
return;
}
// Make sure that any attempt to use childType below is disappointed. We
// could call GetType again but since we don't currently need it, let's
// avoid the virtual call.
@ -2403,7 +2416,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// Child is composited if it's transformed, partially transparent, or has
// SVG effects or a blend mode..
const nsStyleDisplay* disp = child->StyleDisplay();
const nsStylePosition* pos = child->StylePosition();
bool isVisuallyAtomic = child->HasOpacity()
|| child->IsTransformed()

View File

@ -51,14 +51,67 @@ ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
PROFILER_LABEL("ViewportFrame", "BuildDisplayList",
js::ProfileEntry::Category::GRAPHICS);
nsIFrame* kid = mFrames.FirstChild();
if (!kid)
return;
if (nsIFrame* kid = mFrames.FirstChild()) {
// make the kid's BorderBackground our own. This ensures that the canvas
// frame's background becomes our own background and therefore appears
// below negative z-index elements.
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
}
// make the kid's BorderBackground our own. This ensures that the canvas
// frame's background becomes our own background and therefore appears
// below negative z-index elements.
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
nsDisplayList topLayerList;
BuildDisplayListForTopLayer(aBuilder, &topLayerList);
if (!topLayerList.IsEmpty()) {
// Wrap the whole top layer in a single item with maximum z-index,
// and append it at the very end, so that it stays at the topmost.
nsDisplayWrapList* wrapList =
new (aBuilder) nsDisplayWrapList(aBuilder, this, &topLayerList);
wrapList->SetOverrideZIndex(
std::numeric_limits<decltype(wrapList->ZIndex())>::max());
aLists.PositionedDescendants()->AppendNewToTop(wrapList);
}
}
void
ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList)
{
nsIDocument* doc = PresContext()->Document();
nsTArray<Element*> fullscreenStack = doc->GetFullscreenStack();
for (Element* elem : fullscreenStack) {
// Root element cannot be put in the top layer.
if (!elem->GetParent()) {
continue;
}
if (nsIFrame* frame = elem->GetPrimaryFrame()) {
// When building display list for purpose other than painting, it
// is possible that the style and layout info is inconsistent with
// the content tree. Skip inconsistent frames in that case.
if (frame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_NONE) {
MOZ_ASSERT(!aBuilder->IsForPainting(), "Fullscreen element should "
"always be in the top layer for painting");
continue;
}
// Inner SVG, MathML elements, as well as children of some XUL
// elements are not allowed to be out-of-flow. They should not
// be handled as top layer element here.
if (!(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
MOZ_ASSERT(!elem->GetParent()->IsHTMLElement(), "HTML element "
"should always be out-of-flow if in the top layer");
continue;
}
MOZ_ASSERT(frame->GetParent() == this);
nsRect dirty;
nsDisplayListBuilder::OutOfFlowDisplayData*
savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(frame);
if (savedOutOfFlowData) {
dirty = savedOutOfFlowData->mDirtyRect;
}
nsDisplayList list;
frame->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
aList->AppendToTop(&list);
}
}
}
#ifdef DEBUG

View File

@ -63,6 +63,9 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
void BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList);
virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
virtual void Reflow(nsPresContext* aPresContext,