Bug 1342720 - Optimize away the cost of creating and destroying nsBidi from CanvasRenderingContext2D::DrawOrMeasureText(); r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 25 Feb 2017 20:40:09 -0500
changeset 374258 a1d03f028cb1f12ae824a49e692d87617eca1377
parent 374257 5b35dfe81b6843650b28fddb727b515310311dc9
child 374259 02fb91584ef6c701b002a1ab5a132fe2a0c047be
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1342720
milestone54.0a1
Bug 1342720 - Optimize away the cost of creating and destroying nsBidi from CanvasRenderingContext2D::DrawOrMeasureText(); r=baku The ICU implementation of ~nsBidi is particularly expensive because it calls free() several times.
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasRenderingContext2D.h
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -52,17 +52,16 @@
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxFont.h"
 #include "gfxBlur.h"
 #include "gfxPrefs.h"
 #include "gfxUtils.h"
 
 #include "nsFrameLoader.h"
-#include "nsBidi.h"
 #include "nsBidiPresUtils.h"
 #include "Layers.h"
 #include "LayerUserData.h"
 #include "CanvasUtils.h"
 #include "nsIMemoryReporter.h"
 #include "nsStyleUtil.h"
 #include "CanvasImageCache.h"
 
@@ -4271,27 +4270,26 @@ CanvasRenderingContext2D::DrawOrMeasureT
   processor.mDoMeasureBoundingBox = doCalculateBounds || !mIsEntireFrameInvalid;
   processor.mState = &CurrentState();
   processor.mFontgrp = currentFontStyle;
 
   nscoord totalWidthCoord;
 
   // calls bidi algo twice since it needs the full text width and the
   // bounding boxes before rendering anything
-  nsBidi bidiEngine;
   rv = nsBidiPresUtils::ProcessText(textToDraw.get(),
                                     textToDraw.Length(),
                                     isRTL ? NSBIDI_RTL : NSBIDI_LTR,
                                     presShell->GetPresContext(),
                                     processor,
                                     nsBidiPresUtils::MODE_MEASURE,
                                     nullptr,
                                     0,
                                     &totalWidthCoord,
-                                    &bidiEngine);
+                                    &mBidiEngine);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   float totalWidth = float(totalWidthCoord) / processor.mAppUnitsPerDevPixel;
   if (aWidth) {
     *aWidth = totalWidth;
   }
@@ -4396,17 +4394,17 @@ CanvasRenderingContext2D::DrawOrMeasureT
                                     textToDraw.Length(),
                                     isRTL ? NSBIDI_RTL : NSBIDI_LTR,
                                     presShell->GetPresContext(),
                                     processor,
                                     nsBidiPresUtils::MODE_DRAW,
                                     nullptr,
                                     0,
                                     nullptr,
-                                    &bidiEngine);
+                                    &mBidiEngine);
 
 
   mTarget->SetTransform(oldTransform);
 
   if (aOp == CanvasRenderingContext2D::TextDrawOperation::FILL &&
       !doCalculateBounds) {
     RedrawUser(boundingBox);
     return NS_OK;
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -24,16 +24,17 @@
 #include "mozilla/UniquePtr.h"
 #include "gfx2DGlue.h"
 #include "imgIEncoder.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/EnumeratedArray.h"
 #include "FilterSupport.h"
 #include "nsSVGEffects.h"
 #include "Layers.h"
+#include "nsBidi.h"
 
 class nsGlobalWindow;
 class nsXULElement;
 
 namespace mozilla {
 namespace gl {
 class SourceSurface;
 } // namespace gl
@@ -859,16 +860,18 @@ protected:
     // fallback element for a11y
     RefPtr<Element> mElement;
     // Path of the hit region in the 2d context coordinate space (not user space)
     RefPtr<gfx::Path> mPath;
   };
 
   nsTArray<RegionInfo> mHitRegionsOptions;
 
+  nsBidi mBidiEngine;
+
   /**
     * Returns true if a shadow should be drawn along with a
     * drawing operation.
     */
   bool NeedToDrawShadow()
   {
     const ContextState& state = CurrentState();