Reland "Reland "added 565 to 8888 conversion for gpu LCD text rendering for macOS""

This reverts commit 5540528f81c0a1ad10b8086a1009b799717329f6.

Reason for revert: Changed unique pointer to not be static

Original change's description:
> Revert "Reland "added 565 to 8888 conversion for gpu LCD text rendering for macOS""
>
> This reverts commit 0513dd8675534afdd605cea32778a4b4671b2c3d.
>
> Reason for revert: Still has static initializer.
>
> Original change's description:
> > Reland "added 565 to 8888 conversion for gpu LCD text rendering for macOS"
> >
> > This reverts commit cf274da6faa9d32e08053180c8113fcaab666028.
> >
> > Reason for revert: removed the static initializer
> >
> > Original change's description:
> > > Revert "added 565 to 8888 conversion for gpu LCD text rendering for macOS"
> > >
> > > This reverts commit e6f2ecafaf0efecacfd4256f280e26ee74cb7e16.
> > >
> > > Reason for revert: breaking chrome roll cause of static initializers
> > >
> > > Original change's description:
> > > > added 565 to 8888 conversion for gpu LCD text rendering for macOS
> > > >
> > > > Bug: skia:
> > > > Change-Id: Ie24160bb098d388bf4ad69d0c2f9f8ed4beb215c
> > > > Reviewed-on: https://skia-review.googlesource.com/134508
> > > > Commit-Queue: Timothy Liang <timliang@google.com>
> > > > Reviewed-by: Jim Van Verth <jvanverth@google.com>
> > >
> > > TBR=egdaniel@google.com,jvanverth@google.com,timliang@google.com
> > >
> > > Change-Id: Ida97a4085c93fcb990999ab71f99364ec2ef86b7
> > > No-Presubmit: true
> > > No-Tree-Checks: true
> > > No-Try: true
> > > Bug: skia:
> > > Reviewed-on: https://skia-review.googlesource.com/135000
> > > Reviewed-by: Greg Daniel <egdaniel@google.com>
> > > Commit-Queue: Greg Daniel <egdaniel@google.com>
> >
> > Change-Id: I40c29b73970c55b3579a0169bbad666a798b2348
> > Bug: skia:
> > Reviewed-on: https://skia-review.googlesource.com/135021
> > Reviewed-by: Jim Van Verth <jvanverth@google.com>
> > Reviewed-by: Greg Daniel <egdaniel@google.com>
> > Commit-Queue: Timothy Liang <timliang@google.com>
>
> TBR=egdaniel@google.com,jvanverth@google.com,timliang@google.com
>
> Change-Id: I2632d02adc9ba791e5a55adafe0ad10a63f50073
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/135240
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Commit-Queue: Ben Wagner <bungeman@google.com>

Bug: skia:
CQ_INCLUDE_TRYBOTS=luci.chromium.try:android-marshmallow-arm64-rel
Change-Id: Ie4fa0e4f862546068ed4ab818d4956de7175cb3d
Reviewed-on: https://skia-review.googlesource.com/135241
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Timothy Liang <timliang@google.com>
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
index ec07429..e589b20 100644
--- a/src/gpu/text/GrAtlasManager.cpp
+++ b/src/gpu/text/GrAtlasManager.cpp
@@ -7,10 +7,8 @@
 
 #include "GrAtlasManager.h"
 
-#include "GrCaps.h"
 #include "GrGlyph.h"
 #include "GrGlyphCache.h"
-#include "GrProxyProvider.h"
 
 void GrAtlasManager::ComputeAtlasLimits(int maxTextureSize, size_t maxTextureBytes, int* maxDim,
                                         int* minDim, int* maxPlot, int* minPlot) {
diff --git a/src/gpu/text/GrAtlasManager.h b/src/gpu/text/GrAtlasManager.h
index 38e2781..6c16853 100644
--- a/src/gpu/text/GrAtlasManager.h
+++ b/src/gpu/text/GrAtlasManager.h
@@ -8,8 +8,10 @@
 #ifndef GrAtlasManager_DEFINED
 #define GrAtlasManager_DEFINED
 
+#include "GrCaps.h"
 #include "GrDrawOpAtlas.h"
 #include "GrOnFlushResourceProvider.h"
+#include "GrProxyProvider.h"
 
 class GrAtlasGlypCache;
 class GrTextStrike;
@@ -28,11 +30,23 @@
                    float maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
     ~GrAtlasManager() override;
 
+    // Change an expected 565 mask format to 8888 if 565 is not supported (will happen when using
+    // Metal on macOS). The actual conversion of the data is handled in get_packed_glyph_image() in
+    // GrGlyphCache.cpp
+    GrMaskFormat resolveMaskFormat(GrMaskFormat format) const {
+        if (kA565_GrMaskFormat == format &&
+            !fProxyProvider->caps()->isConfigTexturable(kRGB_565_GrPixelConfig)) {
+            format = kARGB_GrMaskFormat;
+        }
+        return format;
+    }
+
     // if getProxies returns nullptr, the client must not try to use other functions on the
     // GrGlyphCache which use the atlas.  This function *must* be called first, before other
     // functions which use the atlas. Note that we can have proxies available but none active
     // (i.e., none instantiated).
     const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numActiveProxies) {
+        format = this->resolveMaskFormat(format);
         if (this->initAtlas(format)) {
             *numActiveProxies = this->getAtlas(format)->numActivePages();
             return this->getAtlas(format)->getProxies();
@@ -127,6 +141,7 @@
     }
 
     GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
+        format = this->resolveMaskFormat(format);
         int atlasIndex = MaskFormatToAtlasIndex(format);
         SkASSERT(fAtlases[atlasIndex]);
         return fAtlases[atlasIndex].get();
diff --git a/src/gpu/text/GrGlyphCache.cpp b/src/gpu/text/GrGlyphCache.cpp
index f6a18c3..4890804 100644
--- a/src/gpu/text/GrGlyphCache.cpp
+++ b/src/gpu/text/GrGlyphCache.cpp
@@ -8,13 +8,17 @@
 #include "GrGlyphCache.h"
 #include "GrAtlasManager.h"
 #include "GrCaps.h"
+#include "GrColor.h"
 #include "GrDistanceFieldGenFromVector.h"
 
 #include "SkAutoMalloc.h"
 #include "SkDistanceFieldGen.h"
 
 GrGlyphCache::GrGlyphCache(const GrCaps* caps, size_t maxTextureBytes)
-        : fPreserveStrike(nullptr), fGlyphSizeLimit(0) {
+        : fPreserveStrike(nullptr)
+        , fGlyphSizeLimit(0)
+        , f565Masks(SkMasks::CreateMasks({0xF800, 0x07E0, 0x001F, 0},
+                    GrMaskFormatBytesPerPixel(kA565_GrMaskFormat) * 8)) {
     fGlyphSizeLimit = ComputeGlyphSizeLimit(caps->maxTextureSize(), maxTextureBytes);
 }
 
@@ -120,7 +124,7 @@
 
 static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, int width,
                                    int height, int dstRB, GrMaskFormat expectedMaskFormat,
-                                   void* dst) {
+                                   void* dst, const SkMasks& masks) {
     SkASSERT(glyph.fWidth == width);
     SkASSERT(glyph.fHeight == height);
     const void* src = cache->findImage(glyph);
@@ -128,6 +132,29 @@
         return false;
     }
 
+    // Convert if the glyph uses a 565 mask format since it is using LCD text rendering but the
+    // expected format is 8888 (will happen on macOS with Metal since that combination does not
+    // support 565).
+    if (kA565_GrMaskFormat == get_packed_glyph_mask_format(glyph) &&
+        kARGB_GrMaskFormat == expectedMaskFormat) {
+        const int a565Bpp = GrMaskFormatBytesPerPixel(kA565_GrMaskFormat);
+        const int argbBpp = GrMaskFormatBytesPerPixel(kARGB_GrMaskFormat);
+        for (int y = 0; y < height; y++) {
+            for (int x = 0; x < width; x++) {
+                uint16_t color565 = 0;
+                memcpy(&color565, src, a565Bpp);
+                uint32_t colorRGBA = GrColorPackRGBA(masks.getRed(color565),
+                                                     masks.getGreen(color565),
+                                                     masks.getBlue(color565),
+                                                     0xFF);
+                memcpy(dst, &colorRGBA, argbBpp);
+                src = (char*)src + a565Bpp;
+                dst = (char*)dst + argbBpp;
+            }
+        }
+        return true;
+    }
+
     // crbug:510931
     // Retrieving the image from the cache can actually change the mask format.  This case is very
     // uncommon so for now we just draw a clear box for these glyphs.
@@ -237,6 +264,7 @@
     SkASSERT(cache);
     SkASSERT(fCache.find(glyph->fPackedID));
 
+    expectedMaskFormat = fullAtlasManager->resolveMaskFormat(expectedMaskFormat);
     int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
     int width = glyph->width();
     int height = glyph->height();
@@ -262,7 +290,7 @@
     }
     if (!get_packed_glyph_image(cache, skGlyph, glyph->width(), glyph->height(),
                                 rowBytes, expectedMaskFormat,
-                                dataPtr)) {
+                                dataPtr, glyphCache->getMasks())) {
         return GrDrawOpAtlas::ErrorCode::kError;
     }
 
diff --git a/src/gpu/text/GrGlyphCache.h b/src/gpu/text/GrGlyphCache.h
index 7e707ec..8375d1f 100644
--- a/src/gpu/text/GrGlyphCache.h
+++ b/src/gpu/text/GrGlyphCache.h
@@ -12,6 +12,7 @@
 #include "GrGlyph.h"
 #include "SkArenaAlloc.h"
 #include "SkGlyphCache.h"
+#include "SkMasks.h"
 #include "SkTDynamicHash.h"
 
 class GrGlyphCache;
@@ -127,6 +128,8 @@
         return strike;
     }
 
+    const SkMasks& getMasks() const { return *f565Masks; }
+
     void freeAll();
 
     static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
@@ -145,6 +148,7 @@
     StrikeHash fCache;
     GrTextStrike* fPreserveStrike;
     SkScalar fGlyphSizeLimit;
+    std::unique_ptr<const SkMasks> f565Masks;
 };
 
 #endif