Make single ctor for SkGlyph and remove reset

* Spruce up SkTLazy

Change-Id: Ice2b66009004a8d1894edd25790eca03ee451da2
Reviewed-on: https://skia-review.googlesource.com/c/183103
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
index 26ee922..29a8b49 100644
--- a/include/core/SkTLazy.h
+++ b/include/core/SkTLazy.h
@@ -19,23 +19,16 @@
  */
 template <typename T> class SkTLazy {
 public:
-    SkTLazy() : fPtr(nullptr) {}
+    SkTLazy() = default;
+    explicit SkTLazy(const T* src) : fPtr(src ? new (&fStorage) T(*src) : nullptr) {}
+    SkTLazy(const SkTLazy& that) { *this = that; }
+    SkTLazy(SkTLazy&& that) { *this = std::move(that); }
 
-    explicit SkTLazy(const T* src)
-        : fPtr(src ? new (fStorage.get()) T(*src) : nullptr) {}
-
-    SkTLazy(const SkTLazy& that) : fPtr(nullptr) { *this = that; }
-    SkTLazy(SkTLazy&& that) : fPtr(nullptr) { *this = std::move(that); }
-
-    ~SkTLazy() {
-        if (this->isValid()) {
-            fPtr->~T();
-        }
-    }
+    ~SkTLazy() { this->reset(); }
 
     SkTLazy& operator=(const SkTLazy& that) {
         if (that.isValid()) {
-            this->set(*that.get());
+            this->set(*that);
         } else {
             this->reset();
         }
@@ -44,7 +37,7 @@
 
     SkTLazy& operator=(SkTLazy&& that) {
         if (that.isValid()) {
-            this->set(std::move(*that.get()));
+            this->set(std::move(*that));
         } else {
             this->reset();
         }
@@ -58,10 +51,8 @@
      *  instance is always returned.
      */
     template <typename... Args> T* init(Args&&... args) {
-        if (this->isValid()) {
-            fPtr->~T();
-        }
-        fPtr = new (reinterpret_cast<T*>(fStorage.get())) T(std::forward<Args>(args)...);
+        this->reset();
+        fPtr = new (&fStorage) T(std::forward<Args>(args)...);
         return fPtr;
     }
 
@@ -75,7 +66,7 @@
         if (this->isValid()) {
             *fPtr = src;
         } else {
-            fPtr = new (reinterpret_cast<T*>(fStorage.get())) T(src);
+            fPtr = new (&fStorage) T(src);
         }
         return fPtr;
     }
@@ -84,7 +75,7 @@
         if (this->isValid()) {
             *fPtr = std::move(src);
         } else {
-            fPtr = new (reinterpret_cast<T*>(fStorage.get())) T(std::move(src));
+            fPtr = new (&fStorage) T(std::move(src));
         }
         return fPtr;
     }
@@ -110,6 +101,8 @@
      * knows that the object has been initialized.
      */
     T* get() const { SkASSERT(this->isValid()); return fPtr; }
+    T* operator->() const { return this->get(); }
+    T& operator*() const { return *this->get(); }
 
     /**
      * Like above but doesn't assert if object isn't initialized (in which case
@@ -118,8 +111,8 @@
     T* getMaybeNull() const { return fPtr; }
 
 private:
-    SkAlignedSTStorage<1, T> fStorage;
-    T*                       fPtr; // nullptr or fStorage
+    typename std::aligned_storage<sizeof(T), alignof(T)>::type fStorage;
+    T*                                                         fPtr{nullptr}; // nullptr or fStorage
 };
 
 /**
diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h
index 7834baf..72957db 100644
--- a/src/core/SkGlyph.h
+++ b/src/core/SkGlyph.h
@@ -137,7 +137,7 @@
     struct PathData;
 
 public:
-    constexpr explicit SkGlyph(SkPackedGlyphID id = dotUndef) : fID{id} {}
+    constexpr explicit SkGlyph(SkPackedGlyphID id) : fID{id} {}
     static constexpr SkFixed kSubpixelRound = SK_FixedHalf >> SkPackedID::kSubBits;
 
     bool isEmpty() const { return fWidth == 0 || fHeight == 0; }
@@ -148,10 +148,6 @@
     SkFixed getSubXFixed() const { return fID.getSubXFixed(); }
     SkFixed getSubYFixed() const { return fID.getSubYFixed(); }
 
-    void reset(SkPackedGlyphID glyphID) {
-        this->SkGlyph::~SkGlyph();
-        new (this) SkGlyph{glyphID};
-    }
     size_t formatAlignment() const;
     size_t allocImage(SkArenaAlloc* alloc);
     size_t rowBytes() const;
@@ -203,9 +199,6 @@
 
 private:
 
-    // The undefined glyph, which seems to be perfectly well defined.
-    static constexpr SkGlyphID dotUndef = 0;
-
     // Support horizontal and vertical skipping strike-through / underlines.
     // The caller walks the linked list looking for a match. For a horizontal underline,
     // the fBounds contains the top and bottom of the underline. The fInterval pair contains the
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp
index 01d0de7..7aaebde 100644
--- a/src/core/SkRemoteGlyphCache.cpp
+++ b/src/core/SkRemoteGlyphCache.cpp
@@ -19,6 +19,7 @@
 #include "SkGlyphCache.h"
 #include "SkRemoteGlyphCacheImpl.h"
 #include "SkStrikeCache.h"
+#include "SkTLazy.h"
 #include "SkTraceEvent.h"
 #include "SkTypeface_remote.h"
 
@@ -592,10 +593,10 @@
         return false;                     \
     }
 
-static bool readGlyph(SkGlyph* glyph, Deserializer* deserializer) {
+static bool readGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer) {
     SkPackedGlyphID glyphID;
     if (!deserializer->read<SkPackedGlyphID>(&glyphID)) return false;
-    glyph->reset(glyphID);
+    glyph.init(glyphID);
     if (!deserializer->read<float>(&glyph->fAdvanceX)) return false;
     if (!deserializer->read<float>(&glyph->fAdvanceY)) return false;
     if (!deserializer->read<uint16_t>(&glyph->fWidth)) return false;
@@ -671,20 +672,20 @@
         uint64_t glyphImagesCount = 0u;
         if (!deserializer.read<uint64_t>(&glyphImagesCount)) READ_FAILURE
         for (size_t j = 0; j < glyphImagesCount; j++) {
-            SkGlyph glyph;
-            if (!readGlyph(&glyph, &deserializer)) READ_FAILURE
+            SkTLazy<SkGlyph> glyph;
+            if (!readGlyph(glyph, &deserializer)) READ_FAILURE
 
-            SkGlyph* allocatedGlyph = strike->getRawGlyphByID(glyph.getPackedID());
+            SkGlyph* allocatedGlyph = strike->getRawGlyphByID(glyph->getPackedID());
 
             // Update the glyph unless it's already got an image (from fallback),
             // preserving any path that might be present.
             if (allocatedGlyph->fImage == nullptr) {
                 auto* glyphPath = allocatedGlyph->fPathData;
-                *allocatedGlyph = glyph;
+                *allocatedGlyph = *glyph;
                 allocatedGlyph->fPathData = glyphPath;
             }
 
-            auto imageSize = glyph.computeImageSize();
+            auto imageSize = glyph->computeImageSize();
             if (imageSize == 0u) continue;
 
             auto* image = deserializer.read(imageSize, allocatedGlyph->formatAlignment());
@@ -695,16 +696,16 @@
         uint64_t glyphPathsCount = 0u;
         if (!deserializer.read<uint64_t>(&glyphPathsCount)) READ_FAILURE
         for (size_t j = 0; j < glyphPathsCount; j++) {
-            SkGlyph glyph;
-            if (!readGlyph(&glyph, &deserializer)) READ_FAILURE
+            SkTLazy<SkGlyph> glyph;
+            if (!readGlyph(glyph, &deserializer)) READ_FAILURE
 
-            SkGlyph* allocatedGlyph = strike->getRawGlyphByID(glyph.getPackedID());
+            SkGlyph* allocatedGlyph = strike->getRawGlyphByID(glyph->getPackedID());
 
             // Update the glyph unless it's already got a path (from fallback),
             // preserving any image that might be present.
             if (allocatedGlyph->fPathData == nullptr) {
                 auto* glyphImage = allocatedGlyph->fImage;
-                *allocatedGlyph = glyph;
+                *allocatedGlyph = *glyph;
                 allocatedGlyph->fImage = glyphImage;
             }