Index: src/core/SkFindAndPlaceGlyph.h |
diff --git a/src/core/SkFindAndPlaceGlyph.h b/src/core/SkFindAndPlaceGlyph.h |
index 278be07e0b878538de9e5e7924d809be6fc1570f..bd6338d587448af77766122327e1236e6f531b99 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) { |