diff options
author | herb <herb@google.com> | 2015-12-07 12:12:29 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-07 12:12:29 -0800 |
commit | d4c24f67496ff2e5e83bc7ce7945cbb85484bfa6 (patch) | |
tree | 45d549ae162159aa0100652ab2759acd305ebc05 /src/core/SkFindAndPlaceGlyph.h | |
parent | ba923d38a5ea092aaa37967c5367ae19e2e4f017 (diff) |
Simplify D1G so that it can inline DrawOneGlyph, and fix a bug in codegen
that only happens on ARM64 using GCC 4.9.
Review URL: https://codereview.chromium.org/1507633004
Diffstat (limited to 'src/core/SkFindAndPlaceGlyph.h')
-rw-r--r-- | src/core/SkFindAndPlaceGlyph.h | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/core/SkFindAndPlaceGlyph.h b/src/core/SkFindAndPlaceGlyph.h index 278be07e0b..bd6338d587 100644 --- a/src/core/SkFindAndPlaceGlyph.h +++ b/src/core/SkFindAndPlaceGlyph.h @@ -30,6 +30,16 @@ struct SkMaxSizeOf<H, Ts...> { sizeof(H) >= SkMaxSizeOf<Ts...>::value ? sizeof(H) : SkMaxSizeOf<Ts...>::value; }; + +// This is a temporary helper function to work around a bug in the code generation +// for aarch64 (arm) on GCC 4.9. This bug does not show up on other platforms, so it +// seems to be an aarch64 backend problem. +// +// GCC 4.9 on ARM64 does not generate the proper constructor code for PositionReader or +// GlyphFindAndPlace. The vtable is not set properly without adding the fixme code. +// The implementation is in SkDraw.cpp. +extern void FixGCC49Arm64Bug(int v); + class SkFindAndPlaceGlyph { public: template<typename ProcessOneGlyph> @@ -229,6 +239,9 @@ private: public: virtual ~PositionReaderInterface() { } virtual SkPoint nextPoint() = 0; + // This is only here to fix a GCC 4.9 aarch64 code gen bug. + // See comment at the top of the file. + virtual int forceUseForBug() = 0; }; class HorizontalPositions final : public PositionReaderInterface { @@ -241,6 +254,8 @@ private: return {x, 0}; } + int forceUseForBug() override { return 1; } + private: const SkScalar* fPositions; }; @@ -256,6 +271,8 @@ private: return to_return; } + int forceUseForBug() override { return 2; } + private: const SkScalar* fPositions; }; @@ -410,7 +427,9 @@ private: class GlyphFindAndPlaceSubpixel final : public GlyphFindAndPlaceInterface<ProcessOneGlyph> { public: GlyphFindAndPlaceSubpixel(LookupGlyph& glyphFinder) - : fGlyphFinder(glyphFinder) { } + : fGlyphFinder(glyphFinder) { + FixGCC49Arm64Bug(1); + } SkPoint findAndPositionGlyph( const char** text, SkPoint position, ProcessOneGlyph&& processOneGlyph) override { @@ -464,6 +483,7 @@ private: public: GlyphFindAndPlaceFullPixel(LookupGlyph& glyphFinder) : fGlyphFinder(glyphFinder) { + FixGCC49Arm64Bug(2); // Kerning can only be used with SkPaint::kLeft_Align static_assert(!kUseKerning || SkPaint::kLeft_Align == kTextAlignment, "Kerning can only be used with left aligned text."); @@ -601,6 +621,7 @@ inline void SkFindAndPlaceGlyph::ProcessPosText( } else { to_init->initialize<HorizontalPositions>(pos); } + positionReader->forceUseForBug(); } }; @@ -617,7 +638,7 @@ inline void SkFindAndPlaceGlyph::ProcessPosText( } }; - GlyphFindAndPlace<ProcessOneGlyph> findAndPosition{ + GlyphFindAndPlace<ProcessOneGlyph> findAndPosition { [&](typename GlyphFindAndPlace<ProcessOneGlyph>::Variants* to_init) { if (cache->isSubpixel()) { switch (textAlignment) { |