author | Jonathan Watt <jwatt@jwatt.org> |
Fri, 31 Oct 2014 20:08:53 +0000 | |
changeset 213452 | e84b632bc007f317b619235985dfabf116a71a33 |
parent 213451 | 097629b2eb2ac994b54da0977e1c0cafc94be0fc |
child 213453 | 1653558849c3b01a3a820f5e3822d964e3891551 |
push id | 27753 |
push user | philringnalda@gmail.com |
push date | Sun, 02 Nov 2014 16:27:30 +0000 |
treeherder | mozilla-central@443853a35898 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | longsonr |
bugs | 1091321 |
milestone | 36.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
|
--- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -27,92 +27,86 @@ nsIFrame* NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsSVGClipPathFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsSVGClipPathFrame) nsresult -nsSVGClipPathFrame::ApplyClipOrPaintClipMask(nsRenderingContext* aContext, +nsSVGClipPathFrame::ApplyClipOrPaintClipMask(gfxContext& aContext, nsIFrame* aClippedFrame, const gfxMatrix& aMatrix) { + DrawTarget& aDrawTarget = *aContext.GetDrawTarget(); + // If the flag is set when we get here, it means this clipPath frame // has already been used painting the current clip, and the document // has a clip reference loop. if (mInUse) { NS_WARNING("Clip loop detected!"); return NS_OK; } AutoClipPathReferencer clipRef(this); mMatrixForChildren = GetClipPathTransform(aClippedFrame) * aMatrix; - gfxContext* gfx = aContext->ThebesContext(); - nsISVGChildFrame* singleClipPathChild = nullptr; if (IsTrivial(&singleClipPathChild)) { - gfxContextMatrixAutoSaveRestore autoRestore(gfx); + gfxContextMatrixAutoSaveRestore autoRestore(&aContext); RefPtr<Path> clipPath; if (singleClipPathChild) { nsSVGPathGeometryFrame* pathFrame = do_QueryFrame(singleClipPathChild); if (pathFrame) { nsSVGPathGeometryElement* pathElement = static_cast<nsSVGPathGeometryElement*>(pathFrame->GetContent()); gfxMatrix toChildsUserSpace = pathElement-> PrependLocalTransformsTo(mMatrixForChildren, nsSVGElement::eUserSpaceToParent); gfxMatrix newMatrix = - gfx->CurrentMatrix().PreMultiply(toChildsUserSpace).NudgeToIntegers(); + aContext.CurrentMatrix().PreMultiply(toChildsUserSpace).NudgeToIntegers(); if (!newMatrix.IsSingular()) { - gfx->SetMatrix(newMatrix); - clipPath = pathElement->GetOrBuildPath(*gfx->GetDrawTarget(), + aContext.SetMatrix(newMatrix); + clipPath = pathElement->GetOrBuildPath(aDrawTarget, nsSVGUtils::ToFillRule(pathFrame->StyleSVG()->mClipRule)); } } } - gfx->NewPath(); if (clipPath) { - gfx->SetPath(clipPath); - // gfxContext::Clip() resets the FillRule on any Path set by - // gfxContext::SetPath() call to the contexts own current FillRule. - // So as long as we're doing the clipping via the gfxContext we need to - // set the FillRule on the context (even though that's a Path state): - gfx->SetFillRule(clipPath->GetFillRule()); + aContext.Clip(clipPath); } else { // The spec says clip away everything if we have no children or the // clipping path otherwise can't be resolved: - gfx->Rectangle(gfxRect()); + aContext.Clip(Rect()); } - gfx->Clip(); - gfx->NewPath(); return NS_OK; } // This is a non-trivial clipPath, so we need to paint its contents into a // temporary surface and use that to mask the clipped content. Note that // nsSVGPathGeometryFrame::Render checks for the NS_STATE_SVG_CLIPPATH_CHILD // state bit and paints into our mask surface using opaque black in that case. // Check if this clipPath is itself clipped by another clipPath: nsSVGClipPathFrame *clipPathFrame = nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr); bool referencedClipIsTrivial; if (clipPathFrame) { referencedClipIsTrivial = clipPathFrame->IsTrivial(); - gfx->Save(); + aContext.Save(); if (referencedClipIsTrivial) { clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix); } else { - gfx->PushGroup(gfxContentType::ALPHA); + aContext.PushGroup(gfxContentType::ALPHA); } } + nsRenderingContext rendCtx(&aContext); + for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { nsISVGChildFrame* SVGFrame = do_QueryFrame(kid); if (SVGFrame) { // The CTM of each frame referencing us can be different. SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); bool isOK = true; @@ -121,69 +115,69 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip if (!isOK) { continue; } bool isTrivial; if (clipPathFrame) { isTrivial = clipPathFrame->IsTrivial(); - gfx->Save(); + aContext.Save(); if (isTrivial) { clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix); } else { - gfx->PushGroup(gfxContentType::ALPHA); + aContext.PushGroup(gfxContentType::ALPHA); } } gfxMatrix toChildsUserSpace = mMatrixForChildren; nsIFrame* child = do_QueryFrame(SVGFrame); nsIContent* childContent = child->GetContent(); if (childContent->IsSVG()) { toChildsUserSpace = static_cast<const nsSVGElement*>(childContent)-> PrependLocalTransformsTo(mMatrixForChildren, nsSVGElement::eUserSpaceToParent); } - SVGFrame->PaintSVG(aContext, toChildsUserSpace); + SVGFrame->PaintSVG(&rendCtx, toChildsUserSpace); if (clipPathFrame) { if (!isTrivial) { - gfx->PopGroupToSource(); + aContext.PopGroupToSource(); - gfx->PushGroup(gfxContentType::ALPHA); + aContext.PushGroup(gfxContentType::ALPHA); clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix); Matrix maskTransform; - RefPtr<SourceSurface> clipMaskSurface = gfx->PopGroupToSurface(&maskTransform); + RefPtr<SourceSurface> clipMaskSurface = aContext.PopGroupToSurface(&maskTransform); if (clipMaskSurface) { - gfx->Mask(clipMaskSurface, maskTransform); + aContext.Mask(clipMaskSurface, maskTransform); } } - gfx->Restore(); + aContext.Restore(); } } } if (clipPathFrame) { if (!referencedClipIsTrivial) { - gfx->PopGroupToSource(); + aContext.PopGroupToSource(); - gfx->PushGroup(gfxContentType::ALPHA); + aContext.PushGroup(gfxContentType::ALPHA); clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix); Matrix maskTransform; - RefPtr<SourceSurface> clipMaskSurface = gfx->PopGroupToSurface(&maskTransform); + RefPtr<SourceSurface> clipMaskSurface = aContext.PopGroupToSurface(&maskTransform); if (clipMaskSurface) { - gfx->Mask(clipMaskSurface, maskTransform); + aContext.Mask(clipMaskSurface, maskTransform); } } - gfx->Restore(); + aContext.Restore(); } return NS_OK; } bool nsSVGClipPathFrame::PointIsInsideClipPath(nsIFrame* aClippedFrame, const gfxPoint &aPoint)
--- a/layout/svg/nsSVGClipPathFrame.h +++ b/layout/svg/nsSVGClipPathFrame.h @@ -6,17 +6,17 @@ #ifndef __NS_SVGCLIPPATHFRAME_H__ #define __NS_SVGCLIPPATHFRAME_H__ #include "mozilla/Attributes.h" #include "gfxMatrix.h" #include "nsSVGContainerFrame.h" #include "nsSVGUtils.h" -class nsRenderingContext; +class gfxContext; class nsISVGChildFrame; typedef nsSVGContainerFrame nsSVGClipPathFrameBase; class nsSVGClipPathFrame : public nsSVGClipPathFrameBase { friend nsIFrame* NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); @@ -44,17 +44,17 @@ public: * SVG clipPath is not simple then calling this method will paint the * clipPath's contents (geometry being filled only, with opaque black) to the * DrawTarget. In this latter case callers are expected to first push a * group before calling this method, then pop the group after calling and use * it as a mask to mask the clipped frame. * * XXXjwatt Maybe split this into two methods. */ - nsresult ApplyClipOrPaintClipMask(nsRenderingContext* aContext, + nsresult ApplyClipOrPaintClipMask(gfxContext& aContext, nsIFrame* aClippedFrame, const gfxMatrix &aMatrix); /** * aPoint is expected to be in aClippedFrame's SVG user space. */ bool PointIsInsideClipPath(nsIFrame* aClippedFrame, const gfxPoint &aPoint);
--- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -528,17 +528,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf gfx->PushGroup(gfxContentType::COLOR_ALPHA); } /* If this frame has only a trivial clipPath, set up cairo's clipping now so * we can just do normal painting and get it clipped appropriately. */ if (clipPathFrame && isTrivialClip) { gfx->Save(); - clipPathFrame->ApplyClipOrPaintClipMask(aCtx, aFrame, cssPxToDevPxMatrix); + clipPathFrame->ApplyClipOrPaintClipMask(*gfx, aFrame, cssPxToDevPxMatrix); } /* Paint the child */ if (effectProperties.HasValidFilter()) { RegularFramePaintCallback callback(aBuilder, aLayerManager, offsetToUserSpace); nsRegion dirtyRegion = aDirtyRect - offsetToBoundingBox; @@ -566,17 +566,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf maskFrame ? maskFrame->GetMaskForMaskedFrame(aCtx->ThebesContext(), aFrame, cssPxToDevPxMatrix, opacity, &maskTransform) : nullptr; if (clipPathFrame && !isTrivialClip) { gfx->PushGroup(gfxContentType::COLOR_ALPHA); - nsresult rv = clipPathFrame->ApplyClipOrPaintClipMask(aCtx, aFrame, cssPxToDevPxMatrix); + nsresult rv = clipPathFrame->ApplyClipOrPaintClipMask(*gfx, aFrame, cssPxToDevPxMatrix); Matrix clippedMaskTransform; RefPtr<SourceSurface> clipMaskSurface = gfx->PopGroupToSurface(&clippedMaskTransform); if (NS_SUCCEEDED(rv) && clipMaskSurface) { // Still more set after clipping, so clip to another surface if (maskSurface || opacity != 1.0f) { gfx->PushGroup(gfxContentType::COLOR_ALPHA); gfx->Mask(clipMaskSurface, clippedMaskTransform);
--- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -596,17 +596,17 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra gfx->PushGroup(gfxContentType::COLOR_ALPHA); } /* If this frame has only a trivial clipPath, set up cairo's clipping now so * we can just do normal painting and get it clipped appropriately. */ if (clipPathFrame && isTrivialClip) { gfx->Save(); - clipPathFrame->ApplyClipOrPaintClipMask(aContext, aFrame, aTransform); + clipPathFrame->ApplyClipOrPaintClipMask(*gfx, aFrame, aTransform); } /* Paint the child */ if (effectProperties.HasValidFilter()) { nsRegion* dirtyRegion = nullptr; nsRegion tmpDirtyRegion; if (aDirtyRect) { // aDirtyRect is in outer-<svg> device pixels, but the filter code needs @@ -647,17 +647,17 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra RefPtr<SourceSurface> maskSurface = maskFrame ? maskFrame->GetMaskForMaskedFrame(aContext->ThebesContext(), aFrame, aTransform, opacity, &maskTransform) : nullptr; if (clipPathFrame && !isTrivialClip) { gfx->PushGroup(gfxContentType::COLOR_ALPHA); - nsresult rv = clipPathFrame->ApplyClipOrPaintClipMask(aContext, aFrame, aTransform); + nsresult rv = clipPathFrame->ApplyClipOrPaintClipMask(*gfx, aFrame, aTransform); Matrix clippedMaskTransform; RefPtr<SourceSurface> clipMaskSurface = gfx->PopGroupToSurface(&clippedMaskTransform); if (NS_SUCCEEDED(rv) && clipMaskSurface) { // Still more set after clipping, so clip to another surface if (maskSurface || opacity != 1.0f) { gfx->PushGroup(gfxContentType::COLOR_ALPHA); gfx->Mask(clipMaskSurface, clippedMaskTransform);