author | Jonathan Watt <jwatt@jwatt.org> |
Fri, 31 Oct 2014 20:08:54 +0000 | |
changeset 213455 | 3313505b1b0ebdeea0c615bae0e14a7167137498 |
parent 213454 | dc72e58dd4c2da22053d4aedcf0aaa9194ed2e68 |
child 213456 | ddc50e4998ca4c49a5bf96c9c2c5c378b56025b8 |
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/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3143,35 +3143,37 @@ nsDisplaySVGText::HitTest(nsDisplayListB aOutFrames->AppendElement(target); } } void nsDisplaySVGText::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { + gfxContext* ctx = aCtx->ThebesContext(); + gfxContextAutoDisableSubpixelAntialiasing - disable(aCtx->ThebesContext(), mDisableSubpixelAA); + disable(ctx, mDisableSubpixelAA); uint32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); // ToReferenceFrame includes our mRect offset, but painting takes // account of that too. To avoid double counting, we subtract that // here. nsPoint offset = ToReferenceFrame() - mFrame->GetPosition(); gfxPoint devPixelOffset = nsLayoutUtils::PointToGfxPoint(offset, appUnitsPerDevPixel); gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(mFrame) * gfxMatrix::Translation(devPixelOffset); - aCtx->ThebesContext()->Save(); - static_cast<SVGTextFrame*>(mFrame)->PaintSVG(aCtx, tm); - aCtx->ThebesContext()->Restore(); + ctx->Save(); + static_cast<SVGTextFrame*>(mFrame)->PaintSVG(*ctx, tm); + ctx->Restore(); } // --------------------------------------------------------------------- // nsQueryFrame methods NS_QUERYFRAME_HEAD(SVGTextFrame) NS_QUERYFRAME_ENTRY(SVGTextFrame) NS_QUERYFRAME_TAIL_INHERITING(SVGTextFrameBase) @@ -3590,28 +3592,29 @@ ShouldPaintCaret(const TextRenderedRun& aThisRun.mTextFrameContentLength) { return true; } return false; } nsresult -SVGTextFrame::PaintSVG(nsRenderingContext* aContext, +SVGTextFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect) { + DrawTarget& aDrawTarget = *aContext.GetDrawTarget(); + nsIFrame* kid = GetFirstPrincipalChild(); if (!kid) return NS_OK; nsPresContext* presContext = PresContext(); - gfxContext *gfx = aContext->ThebesContext(); - gfxMatrix initialMatrix = gfx->CurrentMatrix(); + gfxMatrix initialMatrix = aContext.CurrentMatrix(); if (mState & NS_FRAME_IS_NONDISPLAY) { // If we are in a canvas DrawWindow call that used the // DRAWWINDOW_DO_NOT_FLUSH flag, then we may still have out // of date frames. Just don't paint anything if they are // dirty. if (presContext->PresShell()->InDrawWindowNotFlushing() && NS_SUBTREE_DIRTY(this)) { @@ -3659,78 +3662,82 @@ SVGTextFrame::PaintSVG(nsRenderingContex // dev pixels. Here we multiply a CSS-px-to-dev-pixel factor onto aTransform // so our non-SVG nsTextFrame children paint correctly. float cssPxPerDevPx = presContext-> AppUnitsToFloatCSSPixels(presContext->AppUnitsPerDevPixel()); gfxMatrix canvasTMForChildren = aTransform; canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx); initialMatrix.Scale(1 / cssPxPerDevPx, 1 / cssPxPerDevPx); - gfxContextAutoSaveRestore save(gfx); - gfx->NewPath(); - gfx->Multiply(canvasTMForChildren); - gfxMatrix currentMatrix = gfx->CurrentMatrix(); + gfxContextAutoSaveRestore save(&aContext); + aContext.NewPath(); + aContext.Multiply(canvasTMForChildren); + gfxMatrix currentMatrix = aContext.CurrentMatrix(); nsRefPtr<nsCaret> caret = presContext->PresShell()->GetCaret(); nsRect caretRect; nsIFrame* caretFrame = caret->GetPaintGeometry(&caretRect); TextRenderedRunIterator it(this, TextRenderedRunIterator::eVisibleFrames); TextRenderedRun run = it.Current(); + + gfxTextContextPaint *outerContextPaint = + (gfxTextContextPaint*)aDrawTarget.GetUserData(&gfxTextContextPaint::sUserDataKey); + + nsRenderingContext rendCtx(&aContext); + while (run.mFrame) { nsTextFrame* frame = run.mFrame; // Determine how much of the left and right edges of the text frame we // need to ignore. SVGCharClipDisplayItem item(run); // Set up the fill and stroke so that SVG glyphs can get painted correctly // when they use context-fill etc. - gfx->SetMatrix(initialMatrix); - gfxTextContextPaint *outerContextPaint = - (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey); + aContext.SetMatrix(initialMatrix); SVGTextContextPaint contextPaint; DrawMode drawMode = - SetupContextPaint(gfx->GetDrawTarget(), gfx->CurrentMatrix(), + SetupContextPaint(&aDrawTarget, aContext.CurrentMatrix(), frame, outerContextPaint, &contextPaint); if (int(drawMode) & int(DrawMode::GLYPH_STROKE)) { // This may change the gfxContext's transform (for non-scaling stroke), // in which case this needs to happen before we call SetMatrix() below. - nsSVGUtils::SetupCairoStrokeGeometry(frame, gfx, outerContextPaint); + nsSVGUtils::SetupCairoStrokeGeometry(frame, &aContext, outerContextPaint); } // Set up the transform for painting the text frame for the substring // indicated by the run. gfxMatrix runTransform = run.GetTransformFromUserSpaceForPainting(presContext, item) * currentMatrix; - gfx->SetMatrix(runTransform); + aContext.SetMatrix(runTransform); if (drawMode != DrawMode(0)) { nsRect frameRect = frame->GetVisualOverflowRect(); bool paintSVGGlyphs; - if (ShouldRenderAsPath(aContext, frame, paintSVGGlyphs)) { - SVGTextDrawPathCallbacks callbacks(aContext, frame, + if (ShouldRenderAsPath(&rendCtx, frame, paintSVGGlyphs)) { + SVGTextDrawPathCallbacks callbacks(&rendCtx, frame, matrixForPaintServers, paintSVGGlyphs); - frame->PaintText(aContext, nsPoint(), frameRect, item, + frame->PaintText(&rendCtx, nsPoint(), frameRect, item, &contextPaint, &callbacks); } else { - frame->PaintText(aContext, nsPoint(), frameRect, item, + frame->PaintText(&rendCtx, nsPoint(), frameRect, item, &contextPaint, nullptr); } } if (frame == caretFrame && ShouldPaintCaret(run, caret)) { // XXX Should we be looking at the fill/stroke colours to paint the // caret with, rather than using the color property? - caret->PaintCaret(nullptr, *aContext->GetDrawTarget(), frame, nsPoint()); - gfx->NewPath(); + caret->PaintCaret(nullptr, aDrawTarget, frame, nsPoint()); + aContext.NewPath(); } run = it.Next(); } return NS_OK; }
--- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -11,18 +11,18 @@ #include "mozilla/gfx/2D.h" #include "gfxMatrix.h" #include "gfxRect.h" #include "gfxSVGGlyphs.h" #include "nsIContent.h" // for GetContent #include "nsStubMutationObserver.h" #include "nsSVGPaintServerFrame.h" +class gfxContext; class nsDisplaySVGText; -class nsRenderingContext; class SVGTextFrame; class nsTextFrame; typedef nsSVGDisplayContainerFrame SVGTextFrameBase; namespace mozilla { class CharIterator; @@ -319,17 +319,17 @@ public: */ virtual void FindCloserFrameForSelection(nsPoint aPoint, FrameWithDistance* aCurrentBestFrame) MOZ_OVERRIDE; // nsISVGChildFrame interface: virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; - virtual nsresult PaintSVG(nsRenderingContext* aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE;
--- a/layout/svg/nsISVGChildFrame.h +++ b/layout/svg/nsISVGChildFrame.h @@ -4,19 +4,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef __NS_ISVGCHILDFRAME_H__ #define __NS_ISVGCHILDFRAME_H__ #include "gfxRect.h" #include "nsQueryFrame.h" +class gfxContext; class gfxMatrix; class nsIFrame; -class nsRenderingContext; class SVGBBox; struct nsPoint; struct nsRect; struct nsIntRect; namespace mozilla { class SVGAnimatedLengthList; @@ -70,17 +70,17 @@ public: * the DrawTarget when possible and instead just pass a transform down to * their children. This is preferable because changing the transform is * very expensive for certain DrawTarget backends so it is best to minimize * the number of transform changes. * * @param aDirtyRect The area being redrawn, in frame offset pixel * coordinates. */ - virtual nsresult PaintSVG(nsRenderingContext* aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) = 0; /** * Returns the frame that should handle pointer events at aPoint. aPoint is * expected to be in the SVG user space of the frame on which this method is * called. The frame returned may be the frame on which this method is * called, any of its descendants or else nullptr.
--- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -5,17 +5,16 @@ // Main header first: #include "nsSVGClipPathFrame.h" // Keep others in (case-insensitive) order: #include "gfxContext.h" #include "mozilla/dom/SVGClipPathElement.h" #include "nsGkAtoms.h" -#include "nsRenderingContext.h" #include "nsSVGEffects.h" #include "nsSVGPathGeometryElement.h" #include "nsSVGPathGeometryFrame.h" #include "nsSVGUtils.h" using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; @@ -95,18 +94,16 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip aContext.Save(); if (referencedClipIsTrivial) { clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix); } else { 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; @@ -132,17 +129,17 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip nsIFrame* child = do_QueryFrame(SVGFrame); nsIContent* childContent = child->GetContent(); if (childContent->IsSVG()) { toChildsUserSpace = static_cast<const nsSVGElement*>(childContent)-> PrependLocalTransformsTo(mMatrixForChildren, nsSVGElement::eUserSpaceToParent); } - SVGFrame->PaintSVG(&rendCtx, toChildsUserSpace); + SVGFrame->PaintSVG(aContext, toChildsUserSpace); if (clipPathFrame) { if (!isTrivial) { aContext.PopGroupToSource(); aContext.PushGroup(gfxContentType::ALPHA); clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix);
--- a/layout/svg/nsSVGContainerFrame.cpp +++ b/layout/svg/nsSVGContainerFrame.cpp @@ -243,17 +243,17 @@ nsSVGDisplayContainerFrame::IsSVGTransfo } return foundTransform; } //---------------------------------------------------------------------- // nsISVGChildFrame methods nsresult -nsSVGDisplayContainerFrame::PaintSVG(nsRenderingContext* aContext, +nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect) { NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY) || PresContext()->IsGlyph(), "If display lists are enabled, only painting of non-display " "SVG should take this code path"); @@ -285,17 +285,17 @@ nsSVGDisplayContainerFrame::PaintSVG(nsR continue; // nothing to paint for kid } m = element-> PrependLocalTransformsTo(m, nsSVGElement::eUserSpaceToParent); if (m.IsSingular()) { continue; } } - nsSVGUtils::PaintFrameWithEffects(kid, *aContext->ThebesContext(), m, aDirtyRect); + nsSVGUtils::PaintFrameWithEffects(kid, aContext, m, aDirtyRect); } return NS_OK; } nsIFrame* nsSVGDisplayContainerFrame::GetFrameForPoint(const gfxPoint& aPoint) {
--- a/layout/svg/nsSVGContainerFrame.h +++ b/layout/svg/nsSVGContainerFrame.h @@ -10,20 +10,20 @@ #include "nsContainerFrame.h" #include "nsFrame.h" #include "nsIFrame.h" #include "nsISVGChildFrame.h" #include "nsQueryFrame.h" #include "nsRect.h" #include "nsSVGUtils.h" +class gfxContext; class nsFrameList; class nsIContent; class nsIPresShell; -class nsRenderingContext; class nsStyleContext; struct nsPoint; struct nsRect; struct nsIntRect; typedef nsContainerFrame nsSVGContainerFrameBase; @@ -139,17 +139,17 @@ public: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; virtual bool IsSVGTransformed(Matrix *aOwnTransform = nullptr, Matrix *aFromParentTransform = nullptr) const MOZ_OVERRIDE; // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext* aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; virtual nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE;
--- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -187,17 +187,17 @@ nsSVGForeignObjectFrame::IsSVGTransforme nsSVGElement::eUserSpaceToParent)); } foundTransform = true; } return foundTransform; } nsresult -nsSVGForeignObjectFrame::PaintSVG(nsRenderingContext *aContext, +nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY), "If display lists are enabled, only painting of non-display " "SVG should take this code path"); @@ -236,48 +236,47 @@ nsSVGForeignObjectFrame::PaintSVG(nsRend // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect, // not with kidDirtyRect. I.e. // int32_t appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); // mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect) if (kidDirtyRect.IsEmpty()) return NS_OK; } - gfxContext *gfx = aContext->ThebesContext(); - - gfx->Save(); + aContext.Save(); if (StyleDisplay()->IsScrollableOverflow()) { float x, y, width, height; static_cast<nsSVGElement*>(mContent)-> GetAnimatedLengthValues(&x, &y, &width, &height, nullptr); gfxRect clipRect = nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height); - nsSVGUtils::SetClipRect(gfx, aTransform, clipRect); + nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect); } // SVG paints in CSS px, but normally frames paint in dev pixels. Here we // multiply a CSS-px-to-dev-pixel factor onto aTransform so our children // paint correctly. float cssPxPerDevPx = PresContext()-> AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel()); gfxMatrix canvasTMForChildren = aTransform; canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx); - gfx->Multiply(canvasTMForChildren); + aContext.Multiply(canvasTMForChildren); uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM; - if (SVGAutoRenderState::IsPaintingToWindow(aContext->GetDrawTarget())) { + if (SVGAutoRenderState::IsPaintingToWindow(aContext.GetDrawTarget())) { flags |= nsLayoutUtils::PAINT_TO_WINDOW; } - nsresult rv = nsLayoutUtils::PaintFrame(aContext, kid, nsRegion(kidDirtyRect), + nsRenderingContext rendCtx(&aContext); + nsresult rv = nsLayoutUtils::PaintFrame(&rendCtx, kid, nsRegion(kidDirtyRect), NS_RGBA(0,0,0,0), flags); - gfx->Restore(); + aContext.Restore(); return rv; } nsIFrame* nsSVGForeignObjectFrame::GetFrameForPoint(const gfxPoint& aPoint) { NS_ASSERTION(!NS_SVGDisplayListHitTestingEnabled() ||
--- a/layout/svg/nsSVGForeignObjectFrame.h +++ b/layout/svg/nsSVGForeignObjectFrame.h @@ -8,17 +8,17 @@ #include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIPresShell.h" #include "nsISVGChildFrame.h" #include "nsRegion.h" #include "nsSVGUtils.h" -class nsRenderingContext; +class gfxContext; class nsSVGOuterSVGFrame; typedef nsContainerFrame nsSVGForeignObjectFrameBase; class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase, public nsISVGChildFrame { friend nsContainerFrame* @@ -71,17 +71,17 @@ public: #ifdef DEBUG_FRAME_DUMP virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { return MakeFrameName(NS_LITERAL_STRING("SVGForeignObject"), aResult); } #endif // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext *aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; virtual nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE;
--- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -57,17 +57,17 @@ protected: explicit nsSVGImageFrame(nsStyleContext* aContext) : nsSVGImageFrameBase(aContext), mReflowCallbackPosted(false) {} virtual ~nsSVGImageFrame(); public: NS_DECL_FRAMEARENA_HELPERS // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext *aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; // nsSVGPathGeometryFrame methods: virtual uint16_t GetHitTestFlags() MOZ_OVERRIDE; @@ -286,17 +286,17 @@ nsSVGImageFrame::TransformContextForPain aGfxContext->Multiply(ThebesMatrix(imageTransform)); return true; } //---------------------------------------------------------------------- // nsISVGChildFrame methods: nsresult -nsSVGImageFrame::PaintSVG(nsRenderingContext *aContext, +nsSVGImageFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect) { nsresult rv = NS_OK; if (!StyleVisibility()->IsVisible()) return NS_OK; @@ -313,39 +313,38 @@ nsSVGImageFrame::PaintSVG(nsRenderingCon imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, getter_AddRefs(currentRequest)); if (currentRequest) currentRequest->GetImage(getter_AddRefs(mImageContainer)); } if (mImageContainer) { - gfxContext* ctx = aContext->ThebesContext(); - gfxContextAutoSaveRestore autoRestorer(ctx); + gfxContextAutoSaveRestore autoRestorer(&aContext); if (StyleDisplay()->IsScrollableOverflow()) { gfxRect clipRect = nsSVGUtils::GetClipRectForFrame(this, x, y, width, height); - nsSVGUtils::SetClipRect(ctx, aTransform, clipRect); + nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect); } - if (!TransformContextForPainting(ctx, aTransform)) { + if (!TransformContextForPainting(&aContext, aTransform)) { return NS_ERROR_FAILURE; } // fill-opacity doesn't affect <image>, so if we're allowed to // optimize group opacity, the opacity used for compositing the // image into the current canvas is just the group opacity. float opacity = 1.0f; if (nsSVGUtils::CanOptimizeOpacity(this)) { opacity = StyleDisplay()->mOpacity; } if (opacity != 1.0f || StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { - ctx->PushGroup(gfxContentType::COLOR_ALPHA); + aContext.PushGroup(gfxContentType::COLOR_ALPHA); } nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); nsRect dirtyRect; // only used if aDirtyRect is non-null if (aDirtyRect) { NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY), "Display lists handle dirty rect intersection test"); @@ -358,53 +357,55 @@ nsSVGImageFrame::PaintSVG(nsRenderingCon } // XXXbholley - I don't think huge images in SVGs are common enough to // warrant worrying about the responsiveness impact of doing synchronous // decodes. The extra code complexity of determinining when we want to // force sync probably just isn't worth it, so always pass FLAG_SYNC_DECODE uint32_t drawFlags = imgIContainer::FLAG_SYNC_DECODE; + nsRenderingContext rendCtx(&aContext); + if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) { // Package up the attributes of this image element which can override the // attributes of mImageContainer's internal SVG document. SVGImageContext context(nsIntSize(width, height), Some(imgElem->mPreserveAspectRatio.GetAnimValue())); nsRect destRect(0, 0, appUnitsPerDevPx * width, appUnitsPerDevPx * height); // Note: Can't use DrawSingleUnscaledImage for the TYPE_VECTOR case. // That method needs our image to have a fixed native width & height, // and that's not always true for TYPE_VECTOR images. nsLayoutUtils::DrawSingleImage( - aContext, + &rendCtx, PresContext(), mImageContainer, nsLayoutUtils::GetGraphicsFilterForFrame(this), destRect, aDirtyRect ? dirtyRect : destRect, &context, drawFlags); } else { // mImageContainer->GetType() == TYPE_RASTER nsLayoutUtils::DrawSingleUnscaledImage( - aContext, + &rendCtx, PresContext(), mImageContainer, nsLayoutUtils::GetGraphicsFilterForFrame(this), nsPoint(0, 0), aDirtyRect ? &dirtyRect : nullptr, drawFlags); } if (opacity != 1.0f || StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { - ctx->PopGroupToSource(); - ctx->SetOperator(gfxContext::OPERATOR_OVER); - ctx->Paint(opacity); + aContext.PopGroupToSource(); + aContext.SetOperator(gfxContext::OPERATOR_OVER); + aContext.Paint(opacity); } // gfxContextAutoSaveRestore goes out of scope & cleans up our gfxContext } return rv; } nsIFrame*
--- a/layout/svg/nsSVGInnerSVGFrame.cpp +++ b/layout/svg/nsSVGInnerSVGFrame.cpp @@ -6,17 +6,16 @@ // Main header first: #include "nsSVGInnerSVGFrame.h" // Keep others in (case-insensitive) order: #include "gfx2DGlue.h" #include "gfxContext.h" #include "nsIFrame.h" #include "nsISVGChildFrame.h" -#include "nsRenderingContext.h" #include "nsSVGContainerFrame.h" #include "nsSVGEffects.h" #include "nsSVGIntegrationUtils.h" #include "mozilla/dom/SVGSVGElement.h" using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; @@ -55,17 +54,17 @@ nsSVGInnerSVGFrame::GetType() const { return nsGkAtoms::svgInnerSVGFrame; } //---------------------------------------------------------------------- // nsISVGChildFrame methods nsresult -nsSVGInnerSVGFrame::PaintSVG(nsRenderingContext *aContext, +nsSVGInnerSVGFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect) { NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY), "If display lists are enabled, only painting of non-display " "SVG should take this code path"); @@ -75,21 +74,20 @@ nsSVGInnerSVGFrame::PaintSVG(nsRendering float x, y, width, height; static_cast<SVGSVGElement*>(mContent)-> GetAnimatedLengthValues(&x, &y, &width, &height, nullptr); if (width <= 0 || height <= 0) { return NS_OK; } - gfxContext *gfx = aContext->ThebesContext(); - autoSR.SetContext(gfx); + autoSR.SetContext(&aContext); gfxRect clipRect = nsSVGUtils::GetClipRectForFrame(this, x, y, width, height); - nsSVGUtils::SetClipRect(gfx, aTransform, clipRect); + nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect); } return nsSVGInnerSVGFrameBase::PaintSVG(aContext, aTransform, aDirtyRect); } nsRect nsSVGInnerSVGFrame::GetCoveredRegion() {
--- a/layout/svg/nsSVGInnerSVGFrame.h +++ b/layout/svg/nsSVGInnerSVGFrame.h @@ -5,17 +5,17 @@ #ifndef __NS_SVGINNERSVGFRAME_H__ #define __NS_SVGINNERSVGFRAME_H__ #include "mozilla/Attributes.h" #include "nsSVGContainerFrame.h" #include "nsISVGSVGFrame.h" -class nsRenderingContext; +class gfxContext; typedef nsSVGDisplayContainerFrame nsSVGInnerSVGFrameBase; class nsSVGInnerSVGFrame : public nsSVGInnerSVGFrameBase, public nsISVGSVGFrame { friend nsIFrame* NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); @@ -48,17 +48,17 @@ public: } #endif virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) MOZ_OVERRIDE; // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext *aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; // nsSVGContainerFrame methods:
--- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -814,17 +814,17 @@ nsSVGOuterSVGFrame::NotifyViewportOrTran nsSVGUtils::NotifyChildrenOfSVGChange(GetFirstPrincipalChild(), aFlags); } //---------------------------------------------------------------------- // nsISVGChildFrame methods: nsresult -nsSVGOuterSVGFrame::PaintSVG(nsRenderingContext* aContext, +nsSVGOuterSVGFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { NS_ASSERTION(GetFirstPrincipalChild()->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame && !GetFirstPrincipalChild()->GetNextSibling(), "We should have a single, anonymous, child"); nsSVGOuterSVGAnonChildFrame *anonKid =
--- a/layout/svg/nsSVGOuterSVGFrame.h +++ b/layout/svg/nsSVGOuterSVGFrame.h @@ -6,16 +6,17 @@ #ifndef __NS_SVGOUTERSVGFRAME_H__ #define __NS_SVGOUTERSVGFRAME_H__ #include "mozilla/Attributes.h" #include "nsISVGSVGFrame.h" #include "nsSVGContainerFrame.h" #include "nsRegion.h" +class gfxContext; class nsSVGForeignObjectFrame; //////////////////////////////////////////////////////////////////////// // nsSVGOuterSVGFrame class typedef nsSVGDisplayContainerFrame nsSVGOuterSVGFrameBase; class nsSVGOuterSVGFrame MOZ_FINAL : public nsSVGOuterSVGFrameBase, @@ -109,17 +110,17 @@ public: // themselves. return GetFirstPrincipalChild()->IsSVGTransformed(); } // nsISVGSVGFrame interface: virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) MOZ_OVERRIDE; // nsISVGChildFrame methods: - virtual nsresult PaintSVG(nsRenderingContext* aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE; // nsSVGContainerFrame methods: virtual gfxMatrix GetCanvasTM() MOZ_OVERRIDE;
--- a/layout/svg/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/nsSVGPathGeometryFrame.cpp @@ -106,17 +106,17 @@ nsDisplaySVGPathGeometry::Paint(nsDispla // here. nsPoint offset = ToReferenceFrame() - mFrame->GetPosition(); gfxPoint devPixelOffset = nsLayoutUtils::PointToGfxPoint(offset, appUnitsPerDevPixel); gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(mFrame) * gfxMatrix::Translation(devPixelOffset); - static_cast<nsSVGPathGeometryFrame*>(mFrame)->PaintSVG(aCtx, tm); + static_cast<nsSVGPathGeometryFrame*>(mFrame)->PaintSVG(*aCtx->ThebesContext(), tm); } //---------------------------------------------------------------------- // nsIFrame methods void nsSVGPathGeometryFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, @@ -235,46 +235,44 @@ nsSVGPathGeometryFrame::BuildDisplayList aLists.Content()->AppendNewToTop( new (aBuilder) nsDisplaySVGPathGeometry(aBuilder, this)); } //---------------------------------------------------------------------- // nsISVGChildFrame methods nsresult -nsSVGPathGeometryFrame::PaintSVG(nsRenderingContext *aContext, +nsSVGPathGeometryFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { if (!StyleVisibility()->IsVisible()) return NS_OK; - gfxContext* gfx = aContext->ThebesContext(); - // Matrix to the geometry's user space: gfxMatrix newMatrix = - gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers(); + aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers(); if (newMatrix.IsSingular()) { return NS_OK; } uint32_t paintOrder = StyleSVG()->mPaintOrder; if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) { - Render(gfx, eRenderFill | eRenderStroke, newMatrix); + Render(&aContext, eRenderFill | eRenderStroke, newMatrix); PaintMarkers(aContext, aTransform); } else { while (paintOrder) { uint32_t component = paintOrder & ((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1); switch (component) { case NS_STYLE_PAINT_ORDER_FILL: - Render(gfx, eRenderFill, newMatrix); + Render(&aContext, eRenderFill, newMatrix); break; case NS_STYLE_PAINT_ORDER_STROKE: - Render(gfx, eRenderStroke, newMatrix); + Render(&aContext, eRenderStroke, newMatrix); break; case NS_STYLE_PAINT_ORDER_MARKERS: PaintMarkers(aContext, aTransform); break; } paintOrder >>= NS_STYLE_PAINT_ORDER_BITWIDTH; } } @@ -800,47 +798,49 @@ nsSVGPathGeometryFrame::Render(gfxContex } else { drawTarget->Stroke(path, strokePattern, strokeOptions, drawOptions); } } } } void -nsSVGPathGeometryFrame::PaintMarkers(nsRenderingContext* aContext, +nsSVGPathGeometryFrame::PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform) { gfxTextContextPaint *contextPaint = - (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey); + (gfxTextContextPaint*)aContext.GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey); if (static_cast<nsSVGPathGeometryElement*>(mContent)->IsMarkable()) { MarkerProperties properties = GetMarkerProperties(this); if (properties.MarkersExist()) { float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint); nsTArray<nsSVGMark> marks; static_cast<nsSVGPathGeometryElement*> (mContent)->GetMarkPoints(&marks); uint32_t num = marks.Length(); if (num) { + nsRenderingContext rendCtx(&aContext); + // These are in the same order as the nsSVGMark::Type constants. nsSVGMarkerFrame* markerFrames[] = { properties.GetMarkerStartFrame(), properties.GetMarkerMidFrame(), properties.GetMarkerEndFrame(), }; PR_STATIC_ASSERT(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount); for (uint32_t i = 0; i < num; i++) { nsSVGMark& mark = marks[i]; nsSVGMarkerFrame* frame = markerFrames[mark.type]; if (frame) { - frame->PaintMark(aContext, aTransform, this, &mark, strokeWidth); + frame->PaintMark(&rendCtx, aTransform, this, &mark, strokeWidth); } } } } } } uint16_t
--- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -21,17 +21,16 @@ class DrawTarget; } } class gfxContext; class nsDisplaySVGPathGeometry; class nsIAtom; class nsIFrame; class nsIPresShell; -class nsRenderingContext; class nsStyleContext; class nsSVGMarkerFrame; class nsSVGMarkerProperty; struct nsPoint; struct nsRect; struct nsIntRect; @@ -95,17 +94,17 @@ public: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; // nsSVGPathGeometryFrame methods gfxMatrix GetCanvasTM(); protected: // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext *aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; virtual nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE; @@ -122,17 +121,17 @@ private: enum { eRenderFill = 1, eRenderStroke = 2 }; void Render(gfxContext* aContext, uint32_t aRenderComponents, const gfxMatrix& aTransform); /** * @param aMatrix The transform that must be multiplied onto aContext to * establish this frame's SVG user space. */ - void PaintMarkers(nsRenderingContext *aContext, const gfxMatrix& aMatrix); + void PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix); struct MarkerProperties { nsSVGMarkerProperty* mMarkerStart; nsSVGMarkerProperty* mMarkerMid; nsSVGMarkerProperty* mMarkerEnd; bool MarkersExist() const { return mMarkerStart || mMarkerMid || mMarkerEnd;
--- a/layout/svg/nsSVGPatternFrame.cpp +++ b/layout/svg/nsSVGPatternFrame.cpp @@ -11,17 +11,16 @@ #include "gfxContext.h" #include "gfxMatrix.h" #include "gfxPattern.h" #include "gfxPlatform.h" #include "mozilla/gfx/2D.h" #include "nsContentUtils.h" #include "nsGkAtoms.h" #include "nsISVGChildFrame.h" -#include "nsRenderingContext.h" #include "nsStyleContext.h" #include "nsSVGEffects.h" #include "nsSVGPathGeometryFrame.h" #include "mozilla/dom/SVGPatternElement.h" #include "nsSVGUtils.h" #include "nsSVGAnimatedTransformList.h" #include "SVGContentUtils.h" #include "gfxColor.h" @@ -373,18 +372,17 @@ nsSVGPatternFrame::PaintPattern(const Dr } RefPtr<DrawTarget> dt = aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8); if (!dt) { return nullptr; } - nsRenderingContext context(dt); - gfxContext* gfx = context.ThebesContext(); + nsRefPtr<gfxContext> gfx = new gfxContext(dt); // Fill with transparent black gfx->SetOperator(gfxContext::OPERATOR_CLEAR); gfx->Paint(); gfx->SetOperator(gfxContext::OPERATOR_OVER); if (aGraphicOpacity != 1.0f) { gfx->Save();
--- a/layout/svg/nsSVGSwitchFrame.cpp +++ b/layout/svg/nsSVGSwitchFrame.cpp @@ -5,18 +5,16 @@ // Keep in (case-insensitive) order: #include "gfxRect.h" #include "nsSVGEffects.h" #include "nsSVGGFrame.h" #include "mozilla/dom/SVGSwitchElement.h" #include "nsSVGUtils.h" -class nsRenderingContext; - using namespace mozilla::gfx; typedef nsSVGGFrame nsSVGSwitchFrameBase; class nsSVGSwitchFrame : public nsSVGSwitchFrameBase { friend nsIFrame* NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); @@ -47,17 +45,17 @@ public: } #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) MOZ_OVERRIDE; // nsISVGChildFrame interface: - virtual nsresult PaintSVG(nsRenderingContext* aContext, + virtual nsresult PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE; nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE; nsRect GetCoveredRegion() MOZ_OVERRIDE; virtual void ReflowSVG() MOZ_OVERRIDE; virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace, uint32_t aFlags) MOZ_OVERRIDE; @@ -102,17 +100,17 @@ nsSVGSwitchFrame::BuildDisplayList(nsDis { nsIFrame* kid = GetActiveChildFrame(); if (kid) { BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } } nsresult -nsSVGSwitchFrame::PaintSVG(nsRenderingContext* aContext, +nsSVGSwitchFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || (mState & NS_FRAME_IS_NONDISPLAY), "If display lists are enabled, only painting of non-display " "SVG should take this code path"); @@ -121,17 +119,17 @@ nsSVGSwitchFrame::PaintSVG(nsRenderingCo nsIFrame *kid = GetActiveChildFrame(); if (kid) { gfxMatrix tm = aTransform; if (kid->GetContent()->IsSVG()) { tm = static_cast<nsSVGElement*>(kid->GetContent())-> PrependLocalTransformsTo(tm, nsSVGElement::eUserSpaceToParent); } - nsSVGUtils::PaintFrameWithEffects(kid, *aContext->ThebesContext(), tm, aDirtyRect); + nsSVGUtils::PaintFrameWithEffects(kid, aContext, tm, aDirtyRect); } return NS_OK; } nsIFrame* nsSVGSwitchFrame::GetFrameForPoint(const gfxPoint& aPoint) {
--- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -461,17 +461,17 @@ public: gfxRect dirtyBounds = userToDeviceSpace.TransformBounds( gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height)); dirtyBounds.RoundOut(); if (gfxUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect)) { dirtyRect = &tmpDirtyRect; } } - svgChildFrame->PaintSVG(aContext, aTransform, dirtyRect); + svgChildFrame->PaintSVG(*aContext->ThebesContext(), aTransform, dirtyRect); } }; void nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame, gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect *aDirtyRect) @@ -598,18 +598,16 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra /* 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) { aContext.Save(); clipPathFrame->ApplyClipOrPaintClipMask(aContext, aFrame, aTransform); } - nsRenderingContext rendCtx(&aContext); - /* 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 // it in frame space. gfxMatrix userToDeviceSpace = GetUserToCanvasTM(aFrame); @@ -626,17 +624,17 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) - aFrame->GetPosition(); dirtyRegion = &tmpDirtyRegion; } SVGPaintCallback paintCallback; nsFilterInstance::PaintFilteredFrame(aFrame, aContext, aTransform, &paintCallback, dirtyRegion); } else { - svgChildFrame->PaintSVG(&rendCtx, aTransform, aDirtyRect); + svgChildFrame->PaintSVG(aContext, aTransform, aDirtyRect); } if (clipPathFrame && isTrivialClip) { aContext.Restore(); } /* No more effects, we're done. */ if (!complexEffects) @@ -1585,26 +1583,24 @@ nsSVGUtils::PaintSVGGlyph(Element* aElem { nsIFrame* frame = aElement->GetPrimaryFrame(); nsISVGChildFrame* svgFrame = do_QueryFrame(frame); if (!svgFrame) { return false; } aContext->GetDrawTarget()->AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint, nullptr); - nsRenderingContext context(aContext); - svgFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); gfxMatrix m; if (frame->GetContent()->IsSVG()) { // PaintSVG() expects the passed transform to be the transform to its own // SVG user space, so we need to account for any 'transform' attribute: m = static_cast<nsSVGElement*>(frame->GetContent())-> PrependLocalTransformsTo(gfxMatrix(), nsSVGElement::eUserSpaceToParent); } - nsresult rv = svgFrame->PaintSVG(&context, m); + nsresult rv = svgFrame->PaintSVG(*aContext, m); return NS_SUCCEEDED(rv); } bool nsSVGUtils::GetSVGGlyphExtents(Element* aElement, const gfxMatrix& aSVGToAppSpace, gfxRect* aResult) {