aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--expectations/gm/ignored-tests.txt4
-rw-r--r--include/gpu/GrFontScaler.h3
-rw-r--r--include/gpu/GrGlyph.h18
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp14
-rw-r--r--src/gpu/GrBitmapTextContext.h7
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp9
-rw-r--r--src/gpu/GrFontScaler.cpp24
-rw-r--r--src/gpu/GrTextStrike.cpp65
-rw-r--r--src/gpu/GrTextStrike.h17
9 files changed, 99 insertions, 62 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 5793ba217b..27182c904a 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -33,6 +33,10 @@
## epoger will rebaseline by 25 Dec 2013
#gradtext
+# jvanverth
+# color emoji fix
+coloremoji
+
# rileya - https://codereview.chromium.org/516463005/ will rebaseline after bots cycle
yuv_to_rgb_effect
diff --git a/include/gpu/GrFontScaler.h b/include/gpu/GrFontScaler.h
index 0376038135..54d1e3f9cc 100644
--- a/include/gpu/GrFontScaler.h
+++ b/include/gpu/GrFontScaler.h
@@ -66,7 +66,8 @@ public:
virtual ~GrFontScaler();
const GrFontDescKey* getKey();
- GrMaskFormat getMaskFormat();
+ GrMaskFormat getMaskFormat() const;
+ GrMaskFormat getPackedGlyphMaskFormat(GrGlyph::PackedID) const;
bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds);
bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
int rowBytes, void* image);
diff --git a/include/gpu/GrGlyph.h b/include/gpu/GrGlyph.h
index a379144a42..0e534d694a 100644
--- a/include/gpu/GrGlyph.h
+++ b/include/gpu/GrGlyph.h
@@ -9,8 +9,10 @@
#define GrGlyph_DEFINED
#include "GrRect.h"
-#include "SkPath.h"
+#include "GrTypes.h"
+
#include "SkChecksum.h"
+#include "SkPath.h"
class GrPlot;
@@ -23,17 +25,19 @@ class GrPlot;
struct GrGlyph {
typedef uint32_t PackedID;
- GrPlot* fPlot;
- SkPath* fPath;
- PackedID fPackedID;
- GrIRect16 fBounds;
- SkIPoint16 fAtlasLocation;
+ GrPlot* fPlot;
+ SkPath* fPath;
+ PackedID fPackedID;
+ GrMaskFormat fMaskFormat;
+ GrIRect16 fBounds;
+ SkIPoint16 fAtlasLocation;
- void init(GrGlyph::PackedID packed, const SkIRect& bounds) {
+ void init(GrGlyph::PackedID packed, const SkIRect& bounds, GrMaskFormat format) {
fPlot = NULL;
fPath = NULL;
fPackedID = packed;
fBounds.set(bounds);
+ fMaskFormat = format;
fAtlasLocation.set(0, 0);
}
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 9478d0436c..7cfe91771f 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -370,7 +370,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
}
// try to clear out an unused plot before we flush
- if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+ if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
@@ -386,7 +386,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
fContext->flush();
// we should have an unused plot now
- if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+ if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
@@ -422,6 +422,7 @@ HAS_ATLAS:
width = SkIntToFixed(width);
height = SkIntToFixed(height);
+ // the current texture/maskformat must match what the glyph needs
GrTexture* texture = glyph->fPlot->texture();
SkASSERT(texture);
@@ -429,9 +430,10 @@ HAS_ATLAS:
this->flush();
fCurrTexture = texture;
fCurrTexture->ref();
+ fCurrMaskFormat = glyph->fMaskFormat;
}
- bool useColorVerts = kA8_GrMaskFormat == fStrike->getMaskFormat();
+ bool useColorVerts = kA8_GrMaskFormat == fCurrMaskFormat;
if (NULL == fVertices) {
// If we need to reserve vertices allow the draw target to suggest
@@ -549,12 +551,12 @@ void GrBitmapTextContext::flush() {
// This effect could be stored with one of the cache objects (atlas?)
drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
SkASSERT(fStrike);
- switch (fStrike->getMaskFormat()) {
+ switch (fCurrMaskFormat) {
// Color bitmap text
case kARGB_GrMaskFormat:
SkASSERT(!drawState->hasColorVertexAttribute());
drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- drawState->setColor(0xffffffff);
+ drawState->setAlpha(fSkPaint.getAlpha());
break;
// LCD text
case kA888_GrMaskFormat:
@@ -585,7 +587,7 @@ void GrBitmapTextContext::flush() {
SkASSERT(drawState->hasColorVertexAttribute());
break;
default:
- SkFAIL("Unexepected mask format.");
+ SkFAIL("Unexpected mask format.");
}
int nGlyphs = fCurrVertex / 4;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index 4bff399ade..a9805cb0fb 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -40,13 +40,14 @@ private:
GrTextStrike* fStrike;
void* fVertices;
- int32_t fMaxVertices;
+ int fCurrVertex;
+ int fMaxVertices;
+ SkRect fVertexBounds;
GrTexture* fCurrTexture;
+ GrMaskFormat fCurrMaskFormat;
SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor;
// Used to check whether fCachedEffect is still valid.
uint32_t fEffectTextureUniqueID;
- int fCurrVertex;
- SkRect fVertexBounds;
void init(const GrPaint&, const SkPaint&);
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index baba10d570..a1f5ce6660 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -412,6 +412,11 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
return;
}
+ // TODO: support color glyphs
+ if (kA8_GrMaskFormat != glyph->fMaskFormat) {
+ return;
+ }
+
SkScalar sx = SkFixedToScalar(vx);
SkScalar sy = SkFixedToScalar(vy);
/*
@@ -440,7 +445,7 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
}
// try to clear out an unused plot before we flush
- if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+ if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
@@ -456,7 +461,7 @@ void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
fContext->flush();
// we should have an unused plot now
- if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
+ if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
diff --git a/src/gpu/GrFontScaler.cpp b/src/gpu/GrFontScaler.cpp
index 164768f3b0..b16b498ac1 100644
--- a/src/gpu/GrFontScaler.cpp
+++ b/src/gpu/GrFontScaler.cpp
@@ -59,7 +59,7 @@ GrFontScaler::~GrFontScaler() {
SkSafeUnref(fKey);
}
-GrMaskFormat GrFontScaler::getMaskFormat() {
+GrMaskFormat GrFontScaler::getMaskFormat() const {
SkMask::Format format = fStrike->getMaskFormat();
switch (format) {
case SkMask::kBW_Format:
@@ -85,6 +85,28 @@ const GrFontDescKey* GrFontScaler::getKey() {
return fKey;
}
+GrMaskFormat GrFontScaler::getPackedGlyphMaskFormat(GrGlyph::PackedID packed) const {
+ const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
+ GrGlyph::UnpackFixedX(packed),
+ GrGlyph::UnpackFixedY(packed));
+ SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
+ switch (format) {
+ case SkMask::kBW_Format:
+ // fall through to kA8 -- we store BW glyphs in our 8-bit cache
+ case SkMask::kA8_Format:
+ return kA8_GrMaskFormat;
+ case SkMask::kLCD16_Format:
+ return kA565_GrMaskFormat;
+ case SkMask::kLCD32_Format:
+ return kA888_GrMaskFormat;
+ case SkMask::kARGB32_Format:
+ return kARGB_GrMaskFormat;
+ default:
+ SkDEBUGFAIL("unsupported SkMask::Format");
+ return kA8_GrMaskFormat;
+ }
+}
+
bool GrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
GrGlyph::UnpackFixedX(packed),
diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp
index 8ae10cc8dd..81be3418f7 100644
--- a/src/gpu/GrTextStrike.cpp
+++ b/src/gpu/GrTextStrike.cpp
@@ -80,20 +80,7 @@ static int mask_format_to_atlas_index(GrMaskFormat format) {
}
GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler) {
- GrMaskFormat format = scaler->getMaskFormat();
- GrPixelConfig config = mask_format_to_pixel_config(format);
- int atlasIndex = mask_format_to_atlas_index(format);
- if (NULL == fAtlases[atlasIndex]) {
- SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH,
- GR_ATLAS_TEXTURE_HEIGHT);
- fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextureFlags,
- textureSize,
- GR_NUM_PLOTS_X,
- GR_NUM_PLOTS_Y,
- true));
- }
- GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
- (this, scaler->getKey(), format, fAtlases[atlasIndex]));
+ GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, (this, scaler->getKey()));
fCache.add(strike);
if (fHead) {
@@ -130,10 +117,30 @@ void GrFontCache::purgeStrike(GrTextStrike* strike) {
delete strike;
}
-bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
+
+GrPlot* GrFontCache::addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage,
+ int width, int height, const void* image,
+ SkIPoint16* loc) {
+ GrPixelConfig config = mask_format_to_pixel_config(format);
+ int atlasIndex = mask_format_to_atlas_index(format);
+ if (NULL == fAtlases[atlasIndex]) {
+ SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH,
+ GR_ATLAS_TEXTURE_HEIGHT);
+ fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextureFlags,
+ textureSize,
+ GR_NUM_PLOTS_X,
+ GR_NUM_PLOTS_Y,
+ true));
+ }
+ return fAtlases[atlasIndex]->addToAtlas(usage, width, height, image, loc);
+}
+
+
+bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* glyph) {
SkASSERT(preserveStrike);
- GrAtlas* atlas = preserveStrike->fAtlas;
+ int index = mask_format_to_atlas_index(glyph->fMaskFormat);
+ GrAtlas* atlas = fAtlases[index];
GrPlot* plot = atlas->getUnusedPlot();
if (NULL == plot) {
return false;
@@ -141,13 +148,7 @@ bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
plot->resetRects();
GrTextStrike* strike = fHead;
- GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
while (strike) {
- if (maskFormat != strike->fMaskFormat) {
- strike = strike->fNext;
- continue;
- }
-
GrTextStrike* strikeToPurge = strike;
strike = strikeToPurge->fNext;
strikeToPurge->removePlot(plot);
@@ -228,16 +229,11 @@ void GrFontCache::dump() const {
atlas and a position within that texture.
*/
-GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key,
- GrMaskFormat format,
- GrAtlas* atlas) : fPool(64) {
+GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key) : fPool(64) {
fFontScalerKey = key;
fFontScalerKey->ref();
fFontCache = cache; // no need to ref, it won't go away before we do
- fAtlas = atlas; // no need to ref, it won't go away before we do
-
- fMaskFormat = format;
#ifdef SK_DEBUG
// GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
@@ -271,9 +267,10 @@ GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
return NULL;
}
}
-
+ GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed);
+
GrGlyph* glyph = fPool.alloc();
- glyph->init(packed, bounds);
+ glyph->init(packed, bounds, format);
fCache.add(glyph);
return glyph;
}
@@ -317,7 +314,7 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
SkAutoUnref ar(SkSafeRef(scaler));
- int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
+ int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat);
size_t size = glyph->fBounds.area() * bytesPerPixel;
GrAutoMalloc<1024> storage(size);
@@ -337,9 +334,9 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
}
}
- GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, glyph->width(),
- glyph->height(), storage.get(),
- &glyph->fAtlasLocation);
+ GrPlot* plot = fFontCache->addToAtlas(glyph->fMaskFormat, &fPlotUsage,
+ glyph->width(), glyph->height(),
+ storage.get(), &glyph->fAtlasLocation);
if (NULL == plot) {
return false;
diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrTextStrike.h
index 401bd73259..779d676e43 100644
--- a/src/gpu/GrTextStrike.h
+++ b/src/gpu/GrTextStrike.h
@@ -23,18 +23,16 @@ class GrGpu;
class GrFontPurgeListener;
/**
- * The textcache maps a hostfontscaler instance to a dictionary of
+ * The textstrike maps a hostfontscaler instance to a dictionary of
* glyphid->strike
*/
class GrTextStrike {
public:
- GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey, GrMaskFormat, GrAtlas*);
+ GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey);
~GrTextStrike();
const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
GrFontCache* getFontCache() const { return fFontCache; }
- GrMaskFormat getMaskFormat() const { return fMaskFormat; }
- GrTexture* getTexture() const { return fAtlas->getTexture(); }
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
// returns true if glyph (or glyph+padding for distance field)
@@ -67,8 +65,6 @@ private:
GrTAllocPool<GrGlyph> fPool;
GrFontCache* fFontCache;
- GrAtlas* fAtlas;
- GrMaskFormat fMaskFormat;
bool fUseDistanceField;
GrAtlas::ClientPlotUsage fPlotUsage;
@@ -85,10 +81,15 @@ public:
inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField);
+ // add to texture atlas that matches this format
+ GrPlot* addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage,
+ int width, int height, const void* image,
+ SkIPoint16* loc);
+
void freeAll();
- // make an unused plot available
- bool freeUnusedPlot(GrTextStrike* preserveStrike);
+ // make an unused plot available for this glyph
+ bool freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* glyph);
// testing
int countStrikes() const { return fCache.count(); }