Bug 1422466. Drop a copy from TextDrawTarget::FillGlyphs. r=Gankro draft
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Sat, 02 Dec 2017 13:45:57 -0500
changeset 706601 926c92e2500bc1cfb177a19947e0a39ef71a8a9f
parent 706129 1c0622aa18cd7fc26367b170c53563c55ea9e570
child 742701 d31cd0d59f8726f3d68c2d410ade234e3ea7ace2
push id91847
push userbmo:jmuizelaar@mozilla.com
push dateSat, 02 Dec 2017 19:02:08 +0000
reviewersGankro
bugs1422466
milestone59.0a1
Bug 1422466. Drop a copy from TextDrawTarget::FillGlyphs. r=Gankro We try hard to ensure that the glyph buffers are of the same type.
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
layout/generic/TextDrawTarget.h
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -283,33 +283,33 @@ WriteFontDescriptor(const uint8_t* aData
   FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton);
 
   *sink->mFontKey = sink->mWrBridge->GetNextFontKey();
 
   sink->mResources->AddFontDescriptor(*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength), aIndex);
 }
 
 void
-WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<wr::GlyphInstance>& aGlyphs,
+WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, Range<const wr::GlyphInstance> aGlyphs,
                                  gfx::ScaledFont* aFont, const wr::ColorF& aColor, const StackingContextHelper& aSc,
                                  const wr::LayerRect& aBounds, const wr::LayerRect& aClip, bool aBackfaceVisible,
                                  const wr::GlyphOptions* aGlyphOptions)
 {
   MOZ_ASSERT(aFont);
   MOZ_ASSERT(!aGlyphs.IsEmpty());
 
   wr::WrFontInstanceKey key = GetFontKeyForScaledFont(aFont);
   MOZ_ASSERT(key.mNamespace.mHandle && key.mHandle);
 
   aBuilder.PushText(aBounds,
                     aClip,
                     aBackfaceVisible,
                     aColor,
                     key,
-                    Range<const wr::GlyphInstance>(aGlyphs.Elements(), aGlyphs.Length()),
+                    aGlyphs,
                     aGlyphOptions);
 }
 
 wr::FontInstanceKey
 WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(aScaledFont);
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -125,17 +125,17 @@ public:
     return wr::FontInstanceKey { GetNamespace(), GetNextResourceId() };
   }
 
   wr::WrImageKey GetNextImageKey()
   {
     return wr::WrImageKey{ GetNamespace(), GetNextResourceId() };
   }
 
-  void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<wr::GlyphInstance>& aGlyphs,
+  void PushGlyphs(wr::DisplayListBuilder& aBuilder, Range<const wr::GlyphInstance> aGlyphs,
                   gfx::ScaledFont* aFont, const wr::ColorF& aColor,
                   const StackingContextHelper& aSc,
                   const wr::LayerRect& aBounds, const wr::LayerRect& aClip,
                   bool aBackfaceVisible,
                   const wr::GlyphOptions* aGlyphOptions = nullptr);
 
   wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
   wr::FontKey GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont);
--- a/layout/generic/TextDrawTarget.h
+++ b/layout/generic/TextDrawTarget.h
@@ -100,37 +100,41 @@ public:
              const GlyphBuffer& aBuffer,
              const Pattern& aPattern,
              const DrawOptions& aOptions) override
   {
     // Make sure we're only given boring color patterns
     MOZ_RELEASE_ASSERT(aOptions.mCompositionOp == CompositionOp::OP_OVER);
     MOZ_RELEASE_ASSERT(aOptions.mAlpha == 1.0f);
     MOZ_RELEASE_ASSERT(aPattern.GetType() == PatternType::COLOR);
-    auto* colorPat = static_cast<const ColorPattern*>(&aPattern);
-    auto color = wr::ToColorF(colorPat->mColor);
 
     // Make sure the font exists, and can be serialized
     MOZ_RELEASE_ASSERT(aFont);
     if (!aFont->CanSerialize()) {
       FoundUnsupportedFeature();
       return;
     }
 
-    // 170 is the maximum size gfxFont is expected to hand us
-    AutoTArray<wr::GlyphInstance, 170> glyphs;
-    glyphs.SetLength(aBuffer.mNumGlyphs);
+    auto* colorPat = static_cast<const ColorPattern*>(&aPattern);
+    auto color = wr::ToColorF(colorPat->mColor);
+    auto glyphs = Range<const wr::GlyphInstance>(reinterpret_cast<const wr::GlyphInstance*>(aBuffer.mGlyphs), aBuffer.mNumGlyphs);
 
-    for (size_t i = 0; i < aBuffer.mNumGlyphs; i++) {
-      wr::GlyphInstance& targetGlyph = glyphs[i];
-      const gfx::Glyph& sourceGlyph = aBuffer.mGlyphs[i];
-      targetGlyph.index = sourceGlyph.mIndex;
-      targetGlyph.point = mSc.ToRelativeLayoutPoint(
-          LayoutDevicePoint::FromUnknownPoint(sourceGlyph.mPosition));
-    }
+    // Compare gfx::Glyph and wr::GlyphInstance to make sure that they are
+    // structurally equivalent to ensure that our cast above was ok
+    static_assert(std::is_same<decltype(aBuffer.mGlyphs[0].mIndex), decltype(glyphs[0].index)>()
+                  && std::is_same<decltype(aBuffer.mGlyphs[0].mPosition.x), decltype(glyphs[0].point.x)>()
+                  && std::is_same<decltype(aBuffer.mGlyphs[0].mPosition.y), decltype(glyphs[0].point.y)>()
+                  && offsetof(std::remove_reference<decltype(aBuffer.mGlyphs[0])>::type, mIndex) == offsetof(wr::GlyphInstance, index)
+                  && offsetof(std::remove_reference<decltype(aBuffer.mGlyphs[0])>::type, mPosition) == offsetof(wr::GlyphInstance, point)
+                  && offsetof(decltype(aBuffer.mGlyphs[0].mPosition), x) == offsetof(decltype(glyphs[0].point), x)
+                  && offsetof(decltype(aBuffer.mGlyphs[0].mPosition), y) == offsetof(decltype(glyphs[0].point), y)
+                  && std::is_standard_layout<decltype(aBuffer.mGlyphs[0])>::value == std::is_standard_layout<decltype(glyphs[0])>::value
+                  && sizeof(aBuffer.mGlyphs[0]) == sizeof(glyphs[0])
+                  && sizeof(aBuffer.mGlyphs[0].mPosition) == sizeof(glyphs[0].point)
+                  , "glyph buf types don't match");
 
     wr::GlyphOptions glyphOptions;
     glyphOptions.render_mode = wr::ToFontRenderMode(aOptions.mAntialiasMode, GetPermitSubpixelAA());
 
     mManager->WrBridge()->PushGlyphs(mBuilder, glyphs, aFont,
                                      color, mSc, mBoundsRect, mClipRect,
                                      mBackfaceVisible, &glyphOptions);
   }