Bug 991285 part 1: Consistently allocate nsRenderingContext instances on the heap. r=roc
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 15 Apr 2014 12:54:10 -0700
changeset 197207 22cf932abe41d839d05f7a194af29581c661a62c
parent 197206 f1660c847ca2959aba71f3a3f81d3c32eb5f9c09
child 197208 920ab5ed8ee5f21b3594373e9ffb5e91b3abd6f8
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs991285
milestone31.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
Bug 991285 part 1: Consistently allocate nsRenderingContext instances on the heap. r=roc
layout/generic/nsCanvasFrame.cpp
layout/svg/nsFilterInstance.cpp
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGMaskFrame.cpp
layout/svg/nsSVGPatternFrame.cpp
layout/svg/nsSVGUtils.cpp
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -210,17 +210,17 @@ static void BlitSurface(DrawTarget* aDes
 void
 nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                       nsRenderingContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
 
-  nsRenderingContext context;
+  nsRefPtr<nsRenderingContext> context;
   nsRefPtr<gfxContext> dest = aCtx->ThebesContext();
   nsRefPtr<gfxASurface> surf;
   RefPtr<DrawTarget> dt;
   nsRefPtr<gfxContext> ctx;
   gfxRect destRect;
 #ifndef MOZ_GFX_OPTIMIZE_MOBILE
   if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
       aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
@@ -249,23 +249,24 @@ nsDisplayCanvasBackgroundImage::Paint(ns
     }
     if (surf || dt) {
       if (surf) {
         ctx = new gfxContext(surf);
       } else {
         ctx = new gfxContext(dt);
       }
       ctx->Translate(-gfxPoint(destRect.x, destRect.y));
-      context.Init(aCtx->DeviceContext(), ctx);
+      context = new nsRenderingContext();
+      context->Init(aCtx->DeviceContext(), ctx);
     }
   }
 #endif
 
   PaintInternal(aBuilder,
-                (surf || dt) ? &context : aCtx,
+                (surf || dt) ? context.get() : aCtx,
                 (surf || dt) ? bgClipRect: mVisibleRect,
                 &bgClipRect);
 
   if (surf) {
     BlitSurface(dest, destRect, surf);
     frame->Properties().Set(nsIFrame::CachedBackgroundImage(),
                             surf.forget().take());
   }
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -313,21 +313,21 @@ nsFilterInstance::BuildSourcePaint(Sourc
     if (!offscreenDT) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     ctx = new gfxContext(offscreenDT);
   }
 
   ctx->Translate(-neededRect.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
+  tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  gfxContext *gfx = tmpCtx.ThebesContext();
+  gfxContext *gfx = tmpCtx->ThebesContext();
   gfx->Multiply(deviceToFilterSpace);
 
   gfx->Save();
 
   gfxMatrix matrix =
     nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_PAINTING,
                             mTransformRoot);
   if (!matrix.IsSingular()) {
@@ -396,18 +396,18 @@ nsFilterInstance::BuildSourceImage(gfxAS
     if (!offscreenDT) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     ctx = new gfxContext(offscreenDT);
   }
 
   ctx->Translate(-neededRect.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
+  tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxRect r = FilterSpaceToUserSpace(neededRect);
   r.RoundOut();
   nsIntRect dirty;
   if (!gfxUtils::GfxRectToIntRect(r, &dirty))
     return NS_ERROR_FAILURE;
 
   // SVG graphics paint to device space, so we need to set an initial device
@@ -417,18 +417,18 @@ nsFilterInstance::BuildSourceImage(gfxAS
   // (In theory it would be better to minimize error by having filtered SVG
   // graphics temporarily paint to user space when painting the sources and
   // only set a user space to filter space transform on the gfxContext
   // (since that would eliminate the transform multiplications from user
   // space to device space and back again). However, that would make the
   // code more complex while being hard to get right without introducing
   // subtle bugs, and in practice it probably makes no real difference.)
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  tmpCtx.ThebesContext()->Multiply(deviceToFilterSpace);
-  mPaintCallback->Paint(&tmpCtx, mTargetFrame, &dirty, mTransformRoot);
+  tmpCtx->ThebesContext()->Multiply(deviceToFilterSpace);
+  mPaintCallback->Paint(tmpCtx, mTargetFrame, &dirty, mTransformRoot);
 
   RefPtr<SourceSurface> sourceGraphicSource;
 
   if (offscreenSurface) {
     sourceGraphicSource =
       gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
   } else {
     sourceGraphicSource = offscreenDT->Snapshot();
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -600,18 +600,18 @@ PaintFrameCallback::operator()(gfxContex
                                const GraphicsFilter& aFilter,
                                const gfxMatrix& aTransform)
 {
   if (mFrame->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)
     return false;
 
   mFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
 
-  nsRenderingContext context;
-  context.Init(mFrame->PresContext()->DeviceContext(), aContext);
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(mFrame->PresContext()->DeviceContext(), aContext);
   aContext->Save();
 
   // Clip to aFillRect so that we don't paint outside.
   aContext->NewPath();
   aContext->Rectangle(aFillRect);
   aContext->Clip();
 
   aContext->Multiply(gfxMatrix(aTransform).Invert());
@@ -639,17 +639,17 @@ PaintFrameCallback::operator()(gfxContex
   nsRect dirty(-offset.x, -offset.y,
                mPaintServerSize.width, mPaintServerSize.height);
 
   uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM |
                    nsLayoutUtils::PAINT_ALL_CONTINUATIONS;
   if (mFlags & nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES) {
     flags |= nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES;
   }
-  nsLayoutUtils::PaintFrame(&context, mFrame,
+  nsLayoutUtils::PaintFrame(context, mFrame,
                             dirty, NS_RGBA(0, 0, 0, 0),
                             flags);
 
   aContext->Restore();
 
   mFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
 
   return true;
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -221,35 +221,35 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
   // 'image'. However, we need to set the same matrix on the temporary context
   // and pattern that we create below as is currently set on 'gfx'.
   // Unfortunately, any device offset set by SetDeviceOffset() is affected by
   // the transform passed to the SetMatrix() calls, so to avoid that we account
   // for the device offset in the transform rather than use SetDeviceOffset().
   gfxMatrix matrix =
     gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft());
 
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(this->PresContext()->DeviceContext(), image);
-  tmpCtx.ThebesContext()->SetMatrix(matrix);
+  nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext);
+  tmpCtx->Init(this->PresContext()->DeviceContext(), image);
+  tmpCtx->ThebesContext()->SetMatrix(matrix);
 
   mMaskParent = aParent;
   if (mMaskParentMatrix) {
     *mMaskParentMatrix = aMatrix;
   } else {
     mMaskParentMatrix = new gfxMatrix(aMatrix);
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     // The CTM of each frame referencing us can be different
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
     if (SVGFrame) {
       SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
     }
-    nsSVGUtils::PaintFrameWithEffects(&tmpCtx, nullptr, kid);
+    nsSVGUtils::PaintFrameWithEffects(tmpCtx, nullptr, kid);
   }
 
   uint8_t *data   = image->Data();
   int32_t  stride = image->Stride();
   nsIntRect rect(0, 0, surfaceSize.width, surfaceSize.height);
 
   if (StyleSVGReset()->mMaskType == NS_STYLE_MASK_TYPE_LUMINANCE) {
     if (StyleSVG()->mColorInterpolation ==
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -367,19 +367,19 @@ nsSVGPatternFrame::PaintPattern(gfxASurf
   }
 
   nsRefPtr<gfxASurface> tmpSurface =
     gfxPlatform::GetPlatform()->CreateOffscreenSurface(surfaceSize,
                                                        gfxContentType::COLOR_ALPHA);
   if (!tmpSurface || tmpSurface->CairoStatus())
     return NS_ERROR_FAILURE;
 
-  nsRenderingContext context;
-  context.Init(aSource->PresContext()->DeviceContext(), tmpSurface);
-  gfxContext* gfx = context.ThebesContext();
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(aSource->PresContext()->DeviceContext(), tmpSurface);
+  gfxContext* gfx = context->ThebesContext();
 
   // Fill with transparent black
   gfx->SetOperator(gfxContext::OPERATOR_CLEAR);
   gfx->Paint();
   gfx->SetOperator(gfxContext::OPERATOR_OVER);
 
   if (aGraphicOpacity != 1.0f) {
     gfx->Save();
@@ -401,17 +401,17 @@ nsSVGPatternFrame::PaintPattern(gfxASurf
     patternFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
     for (nsIFrame* kid = firstKid; kid;
          kid = kid->GetNextSibling()) {
       // The CTM of each frame referencing us can be different
       nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
       if (SVGFrame) {
         SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
       }
-      nsSVGUtils::PaintFrameWithEffects(&context, nullptr, kid);
+      nsSVGUtils::PaintFrameWithEffects(context, nullptr, kid);
     }
     patternFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
   }
 
   patternFrame->mSource = nullptr;
 
   if (aGraphicOpacity != 1.0f) {
     gfx->PopGroupToSource();
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1466,21 +1466,22 @@ nsSVGUtils::PaintSVGGlyph(Element* aElem
                           DrawMode aDrawMode,
                           gfxTextContextPaint* aContextPaint)
 {
   nsIFrame* frame = aElement->GetPrimaryFrame();
   nsISVGChildFrame* svgFrame = do_QueryFrame(frame);
   if (!svgFrame) {
     return false;
   }
-  nsRenderingContext context;
-  context.Init(frame->PresContext()->DeviceContext(), aContext);
-  context.AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint, nullptr);
+  nsRefPtr<nsRenderingContext> context(new nsRenderingContext());
+  context->Init(frame->PresContext()->DeviceContext(), aContext);
+  context->AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint,
+                       nullptr);
   svgFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
-  nsresult rv = svgFrame->PaintSVG(&context, nullptr, frame);
+  nsresult rv = svgFrame->PaintSVG(context, nullptr, frame);
   return NS_SUCCEEDED(rv);
 }
 
 bool
 nsSVGUtils::GetSVGGlyphExtents(Element* aElement,
                                const gfxMatrix& aSVGToAppSpace,
                                gfxRect* aResult)
 {