Bug 1422466. Drop a copy from TextDrawTarget::FillGlyphs. r=Gankro
We try hard to ensure that the glyph buffers are of the same type.
--- 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);
}