aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/text/GrAtlasManager.cpp2
-rw-r--r--src/gpu/text/GrAtlasManager.h15
-rw-r--r--src/gpu/text/GrGlyphCache.cpp34
-rw-r--r--src/gpu/text/GrGlyphCache.h4
4 files changed, 50 insertions, 5 deletions
diff --git a/src/gpu/text/GrAtlasManager.cpp b/src/gpu/text/GrAtlasManager.cpp
index ec07429180..e589b20814 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 38e2781d4d..6c168534ad 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 @@ public:
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 @@ private:
}
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 f6a18c3271..4890804fc0 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 void expand_bits(INT_TYPE* dst,
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 @@ static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, in
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 @@ GrDrawOpAtlas::ErrorCode GrTextStrike::addGlyphToAtlas(
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 @@ GrDrawOpAtlas::ErrorCode GrTextStrike::addGlyphToAtlas(
}
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 7e707ec64c..8375d1f19a 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 @@ public:
return strike;
}
+ const SkMasks& getMasks() const { return *f565Masks; }
+
void freeAll();
static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
@@ -145,6 +148,7 @@ private:
StrikeHash fCache;
GrTextStrike* fPreserveStrike;
SkScalar fGlyphSizeLimit;
+ std::unique_ptr<const SkMasks> f565Masks;
};
#endif