author | Jonathan Watt <jwatt@jwatt.org> |
Fri, 02 Mar 2012 23:38:36 +0000 | |
changeset 88183 | 2b4aed5ee94e035a7cee32c308ca9b8590a426bb |
parent 88182 | 5a9bd18c627ae6a01f83194345c8785f95b2c664 |
child 88184 | c228a0a6f2ceb822edc5700c9a73b89d9159a3cf |
push id | 22173 |
push user | bmo@edmorley.co.uk |
push date | Sat, 03 Mar 2012 13:14:42 +0000 |
treeherder | mozilla-central@ed57abebd328 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | longsonr |
bugs | 732429 |
milestone | 13.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/svg/base/src/nsSVGOuterSVGFrame.cpp | file | annotate | diff | comparison | revisions | |
layout/svg/base/src/nsSVGOuterSVGFrame.h | file | annotate | diff | comparison | revisions |
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -500,20 +500,80 @@ nsDisplaySVG::HitTest(nsDisplayListBuild outerSVGFrame->GetContentRect().TopLeft()); if (frame) { aOutFrames->AppendElement(frame); } } void nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx) + nsRenderingContext* aContext) { - static_cast<nsSVGOuterSVGFrame*>(mFrame)-> - Paint(aBuilder, aCtx, mVisibleRect, ToReferenceFrame()); + nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame); + + if (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) + return; + +#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) + PRTime start = PR_Now(); +#endif + + aContext->PushState(); + +#ifdef XP_MACOSX + if (frame->BitmapFallbackEnabled()) { + // nquartz fallback paths, which svg tends to trigger, need + // a non-window context target + aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); + } +#endif + + frame->Paint(aBuilder, aContext, mVisibleRect, ToReferenceFrame()); + +#ifdef XP_MACOSX + if (frame->BitmapFallbackEnabled()) { + // show the surface we pushed earlier for fallbacks + aContext->ThebesContext()->PopGroupToSource(); + aContext->ThebesContext()->Paint(); + } + + if (aContext->ThebesContext()->HasError() && !frame->BitmapFallbackEnabled()) { + frame->SetBitmapFallbackEnabled(true); + // It's not really clear what area to invalidate here. We might have + // stuffed up rendering for the entire window in this paint pass, + // so we can't just invalidate our own rect. Invalidate everything + // in sight. + // This won't work for printing, by the way, but failure to print the + // odd document is probably no worse than printing horribly for all + // documents. Better to fix things so we don't need fallback. + nsIFrame* ancestor = frame; + PRUint32 flags = 0; + while (true) { + nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(ancestor); + if (!next) + break; + if (ancestor->GetParent() != next) { + // We're crossing a document boundary. Logically, the invalidation is + // being triggered by a subdocument of the root document. This will + // prevent an untrusted root document being told about invalidation + // that happened because a child was using SVG... + flags |= nsIFrame::INVALIDATE_CROSS_DOC; + } + ancestor = next; + } + ancestor->InvalidateWithFlags(nsRect(nsPoint(0, 0), ancestor->GetSize()), flags); + } +#endif + + aContext->PopState(); + +#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) + PRTime end = PR_Now(); + printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0); +#endif } // helper static inline bool DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame) { const nsStylePosition *pos = aEmbeddingFrame->GetStylePosition(); const nsStyleCoord &width = pos->mWidth; @@ -583,97 +643,37 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsD new (aBuilder) nsDisplaySVG(aBuilder, this)); } void nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder, nsRenderingContext* aContext, const nsRect& aDirtyRect, nsPoint aPt) { - if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) - return; - - // initialize Mozilla rendering context - aContext->PushState(); - nsRect viewportRect = GetContentRect(); nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition(); viewportRect.MoveTo(viewportOffset); nsRect clipRect; clipRect.IntersectRect(aDirtyRect, viewportRect); aContext->IntersectClip(clipRect); aContext->Translate(viewportRect.TopLeft()); nsRect dirtyRect = clipRect - viewportOffset; -#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) - PRTime start = PR_Now(); -#endif - nsIntRect dirtyPxRect = dirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel()); // Create an SVGAutoRenderState so we can call SetPaintingToWindow on // it, but don't change the render mode: SVGAutoRenderState state(aContext, SVGAutoRenderState::GetRenderMode(aContext)); if (aBuilder->IsPaintingToWindow()) { state.SetPaintingToWindow(true); } -#ifdef XP_MACOSX - if (mEnableBitmapFallback) { - // nquartz fallback paths, which svg tends to trigger, need - // a non-window context target - aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); - } -#endif - nsSVGUtils::PaintFrameWithEffects(aContext, &dirtyPxRect, this); - -#ifdef XP_MACOSX - if (mEnableBitmapFallback) { - // show the surface we pushed earlier for fallbacks - aContext->ThebesContext()->PopGroupToSource(); - aContext->ThebesContext()->Paint(); - } - - if (aContext->ThebesContext()->HasError() && !mEnableBitmapFallback) { - mEnableBitmapFallback = true; - // It's not really clear what area to invalidate here. We might have - // stuffed up rendering for the entire window in this paint pass, - // so we can't just invalidate our own rect. Invalidate everything - // in sight. - // This won't work for printing, by the way, but failure to print the - // odd document is probably no worse than printing horribly for all - // documents. Better to fix things so we don't need fallback. - nsIFrame* frame = this; - PRUint32 flags = 0; - while (true) { - nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(frame); - if (!next) - break; - if (frame->GetParent() != next) { - // We're crossing a document boundary. Logically, the invalidation is - // being triggered by a subdocument of the root document. This will - // prevent an untrusted root document being told about invalidation - // that happened because a child was using SVG... - flags |= INVALIDATE_CROSS_DOC; - } - frame = next; - } - frame->InvalidateWithFlags(nsRect(nsPoint(0, 0), frame->GetSize()), flags); - } -#endif - -#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) - PRTime end = PR_Now(); - printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0); -#endif - - aContext->PopState(); } nsSplittableType nsSVGOuterSVGFrame::GetSplittableType() const { return NS_FRAME_NOT_SPLITTABLE; }
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.h +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h @@ -135,16 +135,26 @@ public: /* Methods to allow descendant nsSVGForeignObjectFrame frames to register and * unregister themselves with their nearest nsSVGOuterSVGFrame ancestor so * they can be reflowed. The methods return true on success or false on * failure. */ void RegisterForeignObject(nsSVGForeignObjectFrame* aFrame); void UnregisterForeignObject(nsSVGForeignObjectFrame* aFrame); +#ifdef XP_MACOSX + bool BitmapFallbackEnabled() const { + return mEnableBitmapFallback; + } + void SetBitmapFallbackEnabled(bool aVal) { + NS_NOTREACHED("don't think me need this any more"); // comment in bug 732429 if we do + mEnableBitmapFallback = aVal; + } +#endif + protected: /* Returns true if our content is the document element and our document is * embedded in an HTML 'object', 'embed' or 'applet' element. Set * aEmbeddingFrame to obtain the nsIFrame for the embedding HTML element. */ bool IsRootOfReplacedElementSubDoc(nsIFrame **aEmbeddingFrame = nsnull);