Revert of BitmapTextBatch and BitmapTextBlob (patchset #18 id:360001 of https://codereview.chromium.org/1011403004/)
Reason for revert:
Breaks a unit test on mac
Original issue's description:
> BitmapTextBatch and BitmapTextBlob
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/eed1dae04932483579b02c10f0706127d3f5d984
TBR=fmalita@chromium.org,reed@google.com,jvanverth@google.com,robertphillips@google.com,bsalomon@google.com,jvanverth@chromium.org,joshualitt@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/1050633002
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 929ff05..8bb1b25 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -243,21 +243,8 @@
return SkStringPrintf("Couldn't decode %s as a picture.", fPath.c_str());
}
stream.reset((SkStream*)NULL); // Might as well drop this when we're done with it.
-
canvas->clipRect(kSKPViewport);
- // Testing TextBlob batching requires that we see individual text blobs more than once
- // TODO remove this and add a flag to DM so we can run skps multiple times
-//#define DOUBLE_LOOP
-#ifdef DOUBLE_LOOP
- {
- SkAutoCanvasRestore acr(canvas, true);
-#endif
- canvas->drawPicture(pic);
-#ifdef DOUBLE_LOOP
- }
- canvas->clear(0);
canvas->drawPicture(pic);
-#endif
return "";
}
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 0d9c4fe..98c9175 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -65,8 +65,6 @@
'<(skia_src_path)/gpu/GrBatch.h',
'<(skia_src_path)/gpu/GrBatchAtlas.cpp',
'<(skia_src_path)/gpu/GrBatchAtlas.h',
- '<(skia_src_path)/gpu/GrBatchFontCache.cpp',
- '<(skia_src_path)/gpu/GrBatchFontCache.h',
'<(skia_src_path)/gpu/GrBatchTarget.cpp',
'<(skia_src_path)/gpu/GrBatchTarget.h',
'<(skia_src_path)/gpu/GrBitmapTextContext.cpp',
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 5015c49..4bf8c05 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -1122,7 +1122,6 @@
friend class SkGraphics; // So Term() can be called.
friend class SkPDFDevice;
friend class GrBitmapTextContext;
- friend class GrBitmapTextContextB;
friend class GrDistanceFieldTextContext;
friend class GrStencilAndCoverTextContext;
friend class GrPathRendering;
diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h
index 4ec9c5f..d31ec5c 100644
--- a/include/core/SkTextBlob.h
+++ b/include/core/SkTextBlob.h
@@ -91,7 +91,6 @@
static unsigned ScalarsPerGlyph(GlyphPositioning pos);
- friend class GrBitmapTextContextB;
friend class GrTextContext;
friend class SkBaseDevice;
friend class SkTextBlobBuilder;
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index f631f56..335b416 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -19,7 +19,6 @@
#include "SkTypes.h"
class GrAARectRenderer;
-class GrBatchFontCache;
class GrDrawTarget;
class GrFontCache;
class GrFragmentProcessor;
@@ -655,7 +654,6 @@
// Functions intended for internal use only.
GrGpu* getGpu() { return fGpu; }
const GrGpu* getGpu() const { return fGpu; }
- GrBatchFontCache* getBatchFontCache() { return fBatchFontCache; }
GrFontCache* getFontCache() { return fFontCache; }
GrLayerCache* getLayerCache() { return fLayerCache.get(); }
GrDrawTarget* getTextTarget();
@@ -697,7 +695,6 @@
GrGpu* fGpu;
GrResourceCache* fResourceCache;
- GrBatchFontCache* fBatchFontCache;
GrFontCache* fFontCache;
SkAutoTDelete<GrLayerCache> fLayerCache;
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 789406b..8b119f0 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -293,7 +293,8 @@
instancesToFlush++;
}
- this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
+ this->flush(batchTarget, dfProcessor, pipeline, &drawInfo, instancesToFlush,
+ maxInstancesPerDraw);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -420,7 +421,8 @@
bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(),
&atlasLocation);
if (!success) {
- this->flush(batchTarget, drawInfo, *instancesToFlush, maxInstancesPerDraw);
+ this->flush(batchTarget, dfProcessor, pipeline, drawInfo, *instancesToFlush,
+ maxInstancesPerDraw);
this->initDraw(batchTarget, dfProcessor, pipeline);
*instancesToFlush = 0;
@@ -514,6 +516,8 @@
}
void flush(GrBatchTarget* batchTarget,
+ const GrGeometryProcessor* dfProcessor,
+ const GrPipeline* pipeline,
GrDrawTarget::DrawInfo* drawInfo,
int instanceCount,
int maxInstancesPerDraw) {
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index e18b157..7ebdf6e 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -226,7 +226,6 @@
desc.fConfig = fPixelConfig;
fTexture = fGpu->createTexture(desc, true, NULL, 0);
-
if (NULL == fTexture) {
return NULL;
}
diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp
index 3374e00..566cd5d 100644
--- a/src/gpu/GrBatchAtlas.cpp
+++ b/src/gpu/GrBatchAtlas.cpp
@@ -227,8 +227,7 @@
, fNumPlotsX(numPlotsX)
, fNumPlotsY(numPlotsY)
, fPlotWidth(texture->width() / numPlotsX)
- , fPlotHeight(texture->height() / numPlotsY)
- , fAtlasGeneration(kInvalidAtlasGeneration + 1) {
+ , fPlotHeight(texture->height() / numPlotsY) {
SkASSERT(fPlotWidth * fNumPlotsX == texture->width());
SkASSERT(fPlotHeight * fNumPlotsY == texture->height());
@@ -244,7 +243,7 @@
for (int x = fNumPlotsX - 1, c = 0; x >= 0; --x, ++c) {
int id = r * fNumPlotsX + c;
currPlot->reset(SkNEW(BatchPlot));
- (*currPlot)->init(this, texture, id, 1, x, y, fPlotWidth, fPlotHeight, fBPP);
+ (*currPlot)->init(this, texture, id, 0, x, y, fPlotWidth, fPlotHeight, fBPP);
// build LRU list
fPlotList.addToHead(currPlot->get());
@@ -319,7 +318,6 @@
SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc, fBPP * width);
SkASSERT(verify);
this->updatePlot(batchTarget, id, plot);
- fAtlasGeneration++;
return true;
}
@@ -354,7 +352,6 @@
batchTarget->upload(uploader);
*id = newPlot->id();
plot->unref();
- fAtlasGeneration++;
return true;
}
diff --git a/src/gpu/GrBatchAtlas.h b/src/gpu/GrBatchAtlas.h
index cd8123f..b514b9d 100644
--- a/src/gpu/GrBatchAtlas.h
+++ b/src/gpu/GrBatchAtlas.h
@@ -25,8 +25,6 @@
// An AtlasID is an opaque handle which callers can use to determine if the atlas contains
// a specific piece of data
typedef uint32_t AtlasID;
- static const uint32_t kInvalidAtlasID = 0;
- static const uint64_t kInvalidAtlasGeneration = 0;
// A function pointer for use as a callback during eviction. Whenever GrBatchAtlas evicts a
// specific AtlasID, it will call all of the registered listeners so they can optionally process
@@ -45,7 +43,6 @@
GrTexture* getTexture() const { return fTexture; }
- uint64_t atlasGeneration() const { return fAtlasGeneration; }
bool hasID(AtlasID id);
void setLastRefToken(AtlasID id, BatchToken batchToken);
void registerEvictionCallback(EvictionFunc func, void* userData) {
@@ -75,7 +72,6 @@
int fPlotWidth;
int fPlotHeight;
size_t fBPP;
- uint64_t fAtlasGeneration;
struct EvictionData {
EvictionFunc fFunc;
diff --git a/src/gpu/GrBatchFontCache.cpp b/src/gpu/GrBatchFontCache.cpp
deleted file mode 100644
index bfa9a2e..0000000
--- a/src/gpu/GrBatchFontCache.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrBatchFontCache.h"
-#include "GrFontAtlasSizes.h"
-#include "GrGpu.h"
-#include "GrRectanizer.h"
-#include "GrSurfacePriv.h"
-#include "SkString.h"
-
-#include "SkDistanceFieldGen.h"
-
-///////////////////////////////////////////////////////////////////////////////
-
-static GrBatchAtlas* make_atlas(GrContext* context, GrPixelConfig config,
- int textureWidth, int textureHeight,
- int numPlotsX, int numPlotsY) {
- GrSurfaceDesc desc;
- desc.fFlags = kNone_GrSurfaceFlags;
- desc.fWidth = textureWidth;
- desc.fHeight = textureHeight;
- desc.fConfig = config;
-
- // We don't want to flush the context so we claim we're in the middle of flushing so as to
- // guarantee we do not recieve a texture with pending IO
- GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch, true);
- return SkNEW_ARGS(GrBatchAtlas, (texture, numPlotsX, numPlotsY));
-}
-
-int GrBatchFontCache::MaskFormatToAtlasIndex(GrMaskFormat format) {
- static const int sAtlasIndices[] = {
- kA8_GrMaskFormat,
- kA565_GrMaskFormat,
- kARGB_GrMaskFormat,
- };
- SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_size_mismatch);
-
- SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
- return sAtlasIndices[format];
-}
-
-GrMaskFormat GrBatchFontCache::AtlasIndexToMaskFormat(int atlasIndex) {
- static GrMaskFormat sMaskFormats[] = {
- kA8_GrMaskFormat,
- kA565_GrMaskFormat,
- kARGB_GrMaskFormat,
- };
- SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sMaskFormats) == kMaskFormatCount, array_size_mismatch);
-
- SkASSERT(sMaskFormats[atlasIndex] < kMaskFormatCount);
- return sMaskFormats[atlasIndex];
-}
-
-GrBatchFontCache::GrBatchFontCache()
- : fPreserveStrike(NULL) {
-}
-
-void GrBatchFontCache::init(GrContext* context) {
- for (int i = 0; i < kMaskFormatCount; i++) {
- GrMaskFormat format = AtlasIndexToMaskFormat(i);
- GrPixelConfig config = this->getPixelConfig(format);
-
- if (kA8_GrMaskFormat == format) {
- fAtlases[i] = make_atlas(context, config,
- GR_FONT_ATLAS_A8_TEXTURE_WIDTH,
- GR_FONT_ATLAS_TEXTURE_HEIGHT,
- GR_FONT_ATLAS_A8_NUM_PLOTS_X,
- GR_FONT_ATLAS_NUM_PLOTS_Y);
- } else {
- fAtlases[i] = make_atlas(context, config,
- GR_FONT_ATLAS_TEXTURE_WIDTH,
- GR_FONT_ATLAS_TEXTURE_HEIGHT,
- GR_FONT_ATLAS_NUM_PLOTS_X,
- GR_FONT_ATLAS_NUM_PLOTS_Y);
- }
-
- fAtlases[i]->registerEvictionCallback(&GrBatchFontCache::HandleEviction, (void*)this);
- }
-}
-
-GrBatchFontCache::~GrBatchFontCache() {
- SkTDynamicHash<GrBatchTextStrike, GrFontDescKey>::Iter iter(&fCache);
- while (!iter.done()) {
- SkDELETE(&(*iter));
- ++iter;
- }
- for (int i = 0; i < kMaskFormatCount; ++i) {
- SkDELETE(fAtlases[i]);
- }
-}
-
-GrBatchTextStrike* GrBatchFontCache::generateStrike(GrFontScaler* scaler) {
- GrBatchTextStrike* strike = SkNEW_ARGS(GrBatchTextStrike, (this, scaler->getKey()));
- fCache.add(strike);
- return strike;
-}
-
-void GrBatchFontCache::freeAll() {
- SkTDynamicHash<GrBatchTextStrike, GrFontDescKey>::Iter iter(&fCache);
- while (!iter.done()) {
- SkDELETE(&(*iter));
- ++iter;
- }
- fCache.rewind();
- for (int i = 0; i < kMaskFormatCount; ++i) {
- SkDELETE(fAtlases[i]);
- fAtlases[i] = NULL;
- }
-}
-
-inline GrBatchAtlas* GrBatchFontCache::getAtlas(GrMaskFormat format) const {
- int atlasIndex = MaskFormatToAtlasIndex(format);
- SkASSERT(fAtlases[atlasIndex]);
- return fAtlases[atlasIndex];
-}
-
-bool GrBatchFontCache::hasGlyph(GrGlyph* glyph) {
- SkASSERT(glyph);
- return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
-}
-
-void GrBatchFontCache::setGlyphRefToken(GrGlyph* glyph, GrBatchAtlas::BatchToken batchToken) {
- SkASSERT(glyph);
- SkASSERT(this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID));
- this->getAtlas(glyph->fMaskFormat)->setLastRefToken(glyph->fID, batchToken);
-}
-
-bool GrBatchFontCache::addToAtlas(GrBatchTextStrike* strike, GrBatchAtlas::AtlasID* id,
- GrBatchTarget* batchTarget,
- GrMaskFormat format, int width, int height, const void* image,
- SkIPoint16* loc) {
- fPreserveStrike = strike;
- return this->getAtlas(format)->addToAtlas(id, batchTarget, width, height, image, loc);
-}
-
-uint64_t GrBatchFontCache::atlasGeneration(GrMaskFormat format) const {
- return this->getAtlas(format)->atlasGeneration();
-}
-
-GrTexture* GrBatchFontCache::getTexture(GrMaskFormat format) {
- int atlasIndex = MaskFormatToAtlasIndex(format);
- SkASSERT(fAtlases[atlasIndex]);
- return fAtlases[atlasIndex]->getTexture();
-}
-
-GrPixelConfig GrBatchFontCache::getPixelConfig(GrMaskFormat format) const {
- static const GrPixelConfig kPixelConfigs[] = {
- kAlpha_8_GrPixelConfig,
- kRGB_565_GrPixelConfig,
- kSkia8888_GrPixelConfig
- };
- SK_COMPILE_ASSERT(SK_ARRAY_COUNT(kPixelConfigs) == kMaskFormatCount, array_size_mismatch);
-
- return kPixelConfigs[format];
-}
-
-void GrBatchFontCache::HandleEviction(GrBatchAtlas::AtlasID id, void* ptr) {
- GrBatchFontCache* fontCache = reinterpret_cast<GrBatchFontCache*>(ptr);
-
- SkTDynamicHash<GrBatchTextStrike, GrFontDescKey>::Iter iter(&fontCache->fCache);
- for (; !iter.done(); ++iter) {
- GrBatchTextStrike* strike = &*iter;
- strike->removeID(id);
-
- // clear out any empty strikes. We will preserve the strike whose call to addToAtlas
- // triggered the eviction
- if (strike != fontCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
- fontCache->fCache.remove(*(strike->fFontScalerKey));
- SkDELETE(strike);
- }
- }
-}
-
-void GrBatchFontCache::dump() const {
- static int gDumpCount = 0;
- for (int i = 0; i < kMaskFormatCount; ++i) {
- if (fAtlases[i]) {
- GrTexture* texture = fAtlases[i]->getTexture();
- if (texture) {
- SkString filename;
-#ifdef SK_BUILD_FOR_ANDROID
- filename.printf("/sdcard/fontcache_%d%d.png", gDumpCount, i);
-#else
- filename.printf("fontcache_%d%d.png", gDumpCount, i);
-#endif
- texture->surfacePriv().savePixels(filename.c_str());
- }
- }
- }
- ++gDumpCount;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/*
- The text strike is specific to a given font/style/matrix setup, which is
- represented by the GrHostFontScaler object we are given in getGlyph().
-
- We map a 32bit glyphID to a GrGlyph record, which in turn points to a
- atlas and a position within that texture.
- */
-
-GrBatchTextStrike::GrBatchTextStrike(GrBatchFontCache* cache, const GrFontDescKey* key)
- : fFontScalerKey(SkRef(key))
- , fPool(9/*start allocations at 512 bytes*/)
- , fAtlasedGlyphs(0) {
-
- fBatchFontCache = cache; // no need to ref, it won't go away before we do
-}
-
-GrBatchTextStrike::~GrBatchTextStrike() {
- SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
- while (!iter.done()) {
- (*iter).free();
- ++iter;
- }
-}
-
-GrGlyph* GrBatchTextStrike::generateGlyph(GrGlyph::PackedID packed,
- GrFontScaler* scaler) {
- SkIRect bounds;
- if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(packed)) {
- if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) {
- return NULL;
- }
- } else {
- if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
- return NULL;
- }
- }
- GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed);
-
- GrGlyph* glyph = (GrGlyph*)fPool.alloc(sizeof(GrGlyph), SK_MALLOC_THROW);
- glyph->init(packed, bounds, format);
- fCache.add(glyph);
- return glyph;
-}
-
-void GrBatchTextStrike::removeID(GrBatchAtlas::AtlasID id) {
- SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
- while (!iter.done()) {
- if (id == (*iter).fID) {
- (*iter).fID = GrBatchAtlas::kInvalidAtlasID;
- fAtlasedGlyphs--;
- SkASSERT(fAtlasedGlyphs >= 0);
- }
- ++iter;
- }
-}
-
-bool GrBatchTextStrike::glyphTooLargeForAtlas(GrGlyph* glyph) {
- int width = glyph->fBounds.width();
- int height = glyph->fBounds.height();
- bool useDistanceField =
- (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID));
- int pad = useDistanceField ? 2 * SK_DistanceFieldPad : 0;
- int plotWidth = (kA8_GrMaskFormat == glyph->fMaskFormat) ? GR_FONT_ATLAS_A8_PLOT_WIDTH
- : GR_FONT_ATLAS_PLOT_WIDTH;
- if (width + pad > plotWidth) {
- return true;
- }
- if (height + pad > GR_FONT_ATLAS_PLOT_HEIGHT) {
- return true;
- }
-
- return false;
-}
-
-bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* glyph,
- GrFontScaler* scaler) {
- SkASSERT(glyph);
- SkASSERT(scaler);
- SkASSERT(fCache.find(glyph->fPackedID));
- SkASSERT(NULL == glyph->fPlot);
-
- SkAutoUnref ar(SkSafeRef(scaler));
-
- int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat);
-
- size_t size = glyph->fBounds.area() * bytesPerPixel;
- GrAutoMalloc<1024> storage(size);
-
- if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID)) {
- if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(),
- glyph->height(),
- storage.get())) {
- return false;
- }
- } else {
- if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
- glyph->height(),
- glyph->width() * bytesPerPixel,
- storage.get())) {
- return false;
- }
- }
-
- bool success = fBatchFontCache->addToAtlas(this, &glyph->fID, batchTarget, glyph->fMaskFormat,
- glyph->width(), glyph->height(),
- storage.get(), &glyph->fAtlasLocation);
- if (success) {
- fAtlasedGlyphs++;
- }
- return success;
-}
diff --git a/src/gpu/GrBatchFontCache.h b/src/gpu/GrBatchFontCache.h
deleted file mode 100644
index 6300fbe..0000000
--- a/src/gpu/GrBatchFontCache.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrBatchFontCache_DEFINED
-#define GrBatchFontCache_DEFINED
-
-#include "GrBatchAtlas.h"
-#include "GrDrawTarget.h"
-#include "GrFontScaler.h"
-#include "GrGlyph.h"
-#include "SkTDynamicHash.h"
-#include "SkVarAlloc.h"
-
-class GrBatchFontCache;
-class GrBatchTarget;
-class GrGpu;
-
-/**
- * The GrBatchTextStrike manages a pool of CPU backing memory for Glyph Masks. This backing memory
- * is abstracted by GrGlyph, and indexed by a PackedID and GrFontScaler. The GrFontScaler is what
- * actually creates the mask.
- */
-class GrBatchTextStrike {
-public:
- GrBatchTextStrike(GrBatchFontCache*, const GrFontDescKey* fontScalerKey);
- ~GrBatchTextStrike();
-
- const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
- GrBatchFontCache* getBatchFontCache() const { return fBatchFontCache; }
-
- inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) {
- GrGlyph* glyph = fCache.find(packed);
- if (NULL == glyph) {
- glyph = this->generateGlyph(packed, scaler);
- }
- return glyph;
- }
-
- // returns true if glyph (or glyph+padding for distance field)
- // is too large to ever fit in texture atlas subregions (GrPlots)
- bool glyphTooLargeForAtlas(GrGlyph*);
- // returns true if glyph successfully added to texture atlas, false otherwise
- bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*);
-
- // testing
- int countGlyphs() const { return fCache.count(); }
-
- // remove any references to this plot
- void removeID(GrBatchAtlas::AtlasID);
-
- static const GrFontDescKey& GetKey(const GrBatchTextStrike& ts) {
- return *(ts.fFontScalerKey);
- }
- static uint32_t Hash(const GrFontDescKey& key) {
- return key.getHash();
- }
-
-private:
- SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
- SkAutoTUnref<const GrFontDescKey> fFontScalerKey;
- SkVarAlloc fPool;
-
- GrBatchFontCache* fBatchFontCache;
- int fAtlasedGlyphs;
-
- GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
-
- friend class GrBatchFontCache;
-};
-
-/*
- * GrBatchFontCache manages strikes which are indexed by a GrFontScaler. These strikes can then be
- * used to individual Glyph Masks. The GrBatchFontCache also manages GrBatchAtlases, though this is
- * more or less transparent to the client(aside from atlasGeneration, described below)
- */
-class GrBatchFontCache {
-public:
- GrBatchFontCache();
- ~GrBatchFontCache();
-
- // Initializes the GrBatchFontCache on the owning GrContext
- void init(GrContext*);
-
- inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) {
-
- GrBatchTextStrike* strike = fCache.find(*(scaler->getKey()));
- if (NULL == strike) {
- strike = this->generateStrike(scaler);
- }
- return strike;
- }
-
- bool hasGlyph(GrGlyph* glyph);
-
- // To ensure the GrBatchAtlas does not evict the Glyph Mask from its texture backing store,
- // the client must pass in the currentToken from the GrBatchTarget along with the GrGlyph
- void setGlyphRefToken(GrGlyph*, GrBatchAtlas::BatchToken);
-
- // add to texture atlas that matches this format
- bool addToAtlas(GrBatchTextStrike*, GrBatchAtlas::AtlasID*, GrBatchTarget*,
- GrMaskFormat, int width, int height, const void* image,
- SkIPoint16* loc);
-
- // Some clients may wish to verify the integrity of the texture backing store of the
- // GrBatchAtlas. The atlasGeneration returned below is a monitonically increasing number which
- // changes everytime something is removed from the texture backing store.
- uint64_t atlasGeneration(GrMaskFormat) const;
-
- void freeAll();
-
- GrTexture* getTexture(GrMaskFormat);
- GrPixelConfig getPixelConfig(GrMaskFormat) const;
-
- void dump() const;
-
-private:
- // There is a 1:1 mapping between GrMaskFormats and atlas indices
- static int MaskFormatToAtlasIndex(GrMaskFormat);
- static GrMaskFormat AtlasIndexToMaskFormat(int atlasIndex);
-
- GrBatchTextStrike* generateStrike(GrFontScaler*);
-
- inline GrBatchAtlas* getAtlas(GrMaskFormat) const;
-
- static void HandleEviction(GrBatchAtlas::AtlasID, void*);
-
- SkTDynamicHash<GrBatchTextStrike, GrFontDescKey> fCache;
-
- GrBatchAtlas* fAtlases[kMaskFormatCount];
- GrBatchTextStrike* fPreserveStrike;
-};
-
-#endif
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index b21d7ea..dd01e7d 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -4,12 +4,9 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-#include "GrBitmapTextContext.h"
+#include "GrBitmapTextContext.h"
#include "GrAtlas.h"
-#include "GrBatch.h"
-#include "GrBatchFontCache.h"
-#include "GrBatchTarget.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrDrawTarget.h"
#include "GrFontCache.h"
@@ -21,7 +18,6 @@
#include "SkAutoKern.h"
#include "SkColorPriv.h"
#include "SkDraw.h"
-#include "SkDrawFilter.h"
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
#include "SkGpuDevice.h"
@@ -29,7 +25,6 @@
#include "SkPath.h"
#include "SkRTConf.h"
#include "SkStrokeRec.h"
-#include "SkTextBlob.h"
#include "SkTextMapStateProc.h"
#include "effects/GrBitmapTextGeoProc.h"
@@ -50,934 +45,6 @@
static const int kIndicesPerGlyph = 6;
};
-// TODO
-// More tests
-// move to SkCache
-// handle textblobs where the whole run is larger than the cache size
-// TODO implement micro speedy hash map for fast refing of glyphs
-
-GrBitmapTextContextB::GrBitmapTextContextB(GrContext* context,
- SkGpuDevice* gpuDevice,
- const SkDeviceProperties& properties)
- : INHERITED(context, gpuDevice, properties) {
- fCurrStrike = NULL;
-}
-
-void GrBitmapTextContextB::ClearCacheEntry(uint32_t key, BitmapTextBlob** blob) {
- (*blob)->unref();
-}
-
-GrBitmapTextContextB::~GrBitmapTextContextB() {
- fCache.foreach(&GrBitmapTextContextB::ClearCacheEntry);
-}
-
-GrBitmapTextContextB* GrBitmapTextContextB::Create(GrContext* context,
- SkGpuDevice* gpuDevice,
- const SkDeviceProperties& props) {
- return SkNEW_ARGS(GrBitmapTextContextB, (context, gpuDevice, props));
-}
-
-bool GrBitmapTextContextB::canDraw(const GrRenderTarget*,
- const GrClip&,
- const GrPaint&,
- const SkPaint& skPaint,
- const SkMatrix& viewMatrix) {
- return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
-}
-
-inline void GrBitmapTextContextB::init(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint,
- const SkIRect& regionClipBounds) {
- INHERITED::init(rt, clip, paint, skPaint, regionClipBounds);
-
- fCurrStrike = NULL;
-}
-
-bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const SkPaint& paint,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
- // We always regenerate blobs with patheffects or mask filters we could cache these
- // TODO find some way to cache the maskfilter / patheffects on the textblob
- return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y ||
- paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() != blob.fStyle;
-}
-
-void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
- const SkTextBlob* blob, SkScalar x, SkScalar y,
- SkDrawFilter* drawFilter, const SkIRect& clipBounds) {
- BitmapTextBlob* cacheBlob;
- BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID());
-
- SkIRect clipRect;
- clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
-
- if (foundBlob) {
- cacheBlob = *foundBlob;
- if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) {
- // We can get away with reusing the blob if there are no outstanding refs on it.
- // However, we still have to reset all of the runs.
- if (!cacheBlob->unique()) {
- cacheBlob->unref();
- cacheBlob = SkNEW(BitmapTextBlob);
- fCache.set(blob->uniqueID(), cacheBlob);
- }
- this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter,
- clipRect);
- }
- } else {
- cacheBlob = SkNEW(BitmapTextBlob);
- fCache.set(blob->uniqueID(), cacheBlob);
- this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, clipRect);
- }
-
- // Though for the time being runs in the textblob can override the paint, they only touch font
- // info.
- GrPaint grPaint;
- SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
-
- this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMatrix,
- fSkPaint.getAlpha());
-}
-
-void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
- const SkTextBlob* blob, SkScalar x, SkScalar y,
- SkDrawFilter* drawFilter, const SkIRect& clipRect) {
- cacheBlob->fViewMatrix = viewMatrix;
- cacheBlob->fX = x;
- cacheBlob->fY = y;
- cacheBlob->fStyle = skPaint.getStyle();
- cacheBlob->fRuns.reset(blob->fRunCount);
-
- // Regenerate textblob
- SkPaint runPaint = skPaint;
- SkTextBlob::RunIterator it(blob);
- for (int run = 0; !it.done(); it.next(), run++) {
- size_t textLen = it.glyphCount() * sizeof(uint16_t);
- const SkPoint& offset = it.offset();
- // applyFontToPaint() always overwrites the exact same attributes,
- // so it is safe to not re-seed the paint for this reason.
- it.applyFontToPaint(&runPaint);
-
- if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) {
- // A false return from filter() means we should abort the current draw.
- runPaint = skPaint;
- continue;
- }
-
- runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint));
-
- switch (it.positioning()) {
- case SkTextBlob::kDefault_Positioning:
- this->internalDrawText(cacheBlob, run, runPaint, viewMatrix,
- (const char *)it.glyphs(), textLen,
- x + offset.x(), y + offset.y(), clipRect);
- break;
- case SkTextBlob::kHorizontal_Positioning:
- this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix,
- (const char*)it.glyphs(), textLen, it.pos(), 1,
- SkPoint::Make(x, y + offset.y()), clipRect);
- break;
- case SkTextBlob::kFull_Positioning:
- this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix,
- (const char*)it.glyphs(), textLen, it.pos(), 2,
- SkPoint::Make(x, y), clipRect);
- break;
- }
-
- if (drawFilter) {
- // A draw filter may change the paint arbitrarily, so we must re-seed in this case.
- runPaint = skPaint;
- }
- }
-}
-
-void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
- SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob));
- blob->fViewMatrix = viewMatrix;
- blob->fX = x;
- blob->fY = y;
- blob->fStyle = skPaint.getStyle();
- blob->fRuns.push_back();
-
- SkIRect clipRect;
- clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
- this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y, clipRect);
- this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, skPaint.getAlpha());
-}
-
-void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex,
- const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y, const SkIRect& clipRect) {
- SkASSERT(byteLength == 0 || text != NULL);
-
- // nothing to draw
- if (text == NULL || byteLength == 0) {
- return;
- }
-
- fCurrStrike = NULL;
- SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
-
- // Get GrFontScaler from cache
- BitmapTextBlob::Run& run = blob->fRuns[runIndex];
- run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix,
- false));
- run.fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
- const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data());
- SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
- GrFontScaler* fontScaler = GetGrFontScaler(cache);
-
- // transform our starting point
- {
- SkPoint loc;
- viewMatrix.mapXY(x, y, &loc);
- x = loc.fX;
- y = loc.fY;
- }
-
- // need to measure first
- if (skPaint.getTextAlign() != SkPaint::kLeft_Align) {
- SkVector stopVector;
- MeasureText(cache, glyphCacheProc, text, byteLength, &stopVector);
-
- SkScalar stopX = stopVector.fX;
- SkScalar stopY = stopVector.fY;
-
- if (skPaint.getTextAlign() == SkPaint::kCenter_Align) {
- stopX = SkScalarHalf(stopX);
- stopY = SkScalarHalf(stopY);
- }
- x -= stopX;
- y -= stopY;
- }
-
- const char* stop = text + byteLength;
-
- SkAutoKern autokern;
-
- SkFixed fxMask = ~0;
- SkFixed fyMask = ~0;
- SkScalar halfSampleX, halfSampleY;
- if (cache->isSubpixel()) {
- halfSampleX = halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound);
- SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix);
- if (kX_SkAxisAlignment == baseline) {
- fyMask = 0;
- halfSampleY = SK_ScalarHalf;
- } else if (kY_SkAxisAlignment == baseline) {
- fxMask = 0;
- halfSampleX = SK_ScalarHalf;
- }
- } else {
- halfSampleX = halfSampleY = SK_ScalarHalf;
- }
-
- Sk48Dot16 fx = SkScalarTo48Dot16(x + halfSampleX);
- Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY);
-
- while (text < stop) {
- const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
-
- fx += autokern.adjust(glyph);
-
- if (glyph.fWidth) {
- this->appendGlyph(blob,
- runIndex,
- GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed(),
- GrGlyph::kCoverage_MaskStyle),
- Sk48Dot16FloorToInt(fx),
- Sk48Dot16FloorToInt(fy),
- fontScaler,
- clipRect);
- }
-
- fx += glyph.fAdvanceX;
- fy += glyph.fAdvanceY;
- }
-
- SkGlyphCache::AttachCache(cache);
-}
-
-void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& regionClipBounds) {
- SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob));
- blob->fStyle = skPaint.getStyle();
- blob->fRuns.push_back();
- blob->fViewMatrix = viewMatrix;
-
- SkIRect clipRect;
- clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
- this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, pos,
- scalarsPerPosition, offset, clipRect);
- this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fSkPaint.getAlpha());
-}
-
-void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
- const SkPaint& skPaint,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& clipRect) {
- SkASSERT(byteLength == 0 || text != NULL);
- SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
-
- // nothing to draw
- if (text == NULL || byteLength == 0) {
- return;
- }
-
- fCurrStrike = NULL;
- SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
-
- // Get GrFontScaler from cache
- BitmapTextBlob::Run& run = blob->fRuns[runIndex];
- run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix,
- false));
- run.fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
- const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data());
- SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
- GrFontScaler* fontScaler = GetGrFontScaler(cache);
-
- const char* stop = text + byteLength;
- SkTextAlignProc alignProc(skPaint.getTextAlign());
- SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition);
- SkScalar halfSampleX = 0, halfSampleY = 0;
-
- if (cache->isSubpixel()) {
- // maybe we should skip the rounding if linearText is set
- SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix);
-
- SkFixed fxMask = ~0;
- SkFixed fyMask = ~0;
- if (kX_SkAxisAlignment == baseline) {
- fyMask = 0;
- halfSampleY = SK_ScalarHalf;
- } else if (kY_SkAxisAlignment == baseline) {
- fxMask = 0;
- halfSampleX = SK_ScalarHalf;
- }
-
- if (SkPaint::kLeft_Align == skPaint.getTextAlign()) {
- while (text < stop) {
- SkPoint tmsLoc;
- tmsProc(pos, &tmsLoc);
- Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX);
- Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY);
-
- const SkGlyph& glyph = glyphCacheProc(cache, &text,
- fx & fxMask, fy & fyMask);
-
- if (glyph.fWidth) {
- this->appendGlyph(blob,
- runIndex,
- GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed(),
- GrGlyph::kCoverage_MaskStyle),
- Sk48Dot16FloorToInt(fx),
- Sk48Dot16FloorToInt(fy),
- fontScaler,
- clipRect);
- }
- pos += scalarsPerPosition;
- }
- } else {
- while (text < stop) {
- const char* currentText = text;
- const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
-
- if (metricGlyph.fWidth) {
- SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
- SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
- SkPoint tmsLoc;
- tmsProc(pos, &tmsLoc);
- SkPoint alignLoc;
- alignProc(tmsLoc, metricGlyph, &alignLoc);
-
- Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + halfSampleX);
- Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + halfSampleY);
-
- // have to call again, now that we've been "aligned"
- const SkGlyph& glyph = glyphCacheProc(cache, ¤tText,
- fx & fxMask, fy & fyMask);
- // the assumption is that the metrics haven't changed
- SkASSERT(prevAdvX == glyph.fAdvanceX);
- SkASSERT(prevAdvY == glyph.fAdvanceY);
- SkASSERT(glyph.fWidth);
-
- this->appendGlyph(blob,
- runIndex,
- GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed(),
- GrGlyph::kCoverage_MaskStyle),
- Sk48Dot16FloorToInt(fx),
- Sk48Dot16FloorToInt(fy),
- fontScaler,
- clipRect);
- }
- pos += scalarsPerPosition;
- }
- }
- } else { // not subpixel
-
- if (SkPaint::kLeft_Align == skPaint.getTextAlign()) {
- while (text < stop) {
- // the last 2 parameters are ignored
- const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
-
- if (glyph.fWidth) {
- SkPoint tmsLoc;
- tmsProc(pos, &tmsLoc);
-
- Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf); //halfSampleX;
- Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); //halfSampleY;
- this->appendGlyph(blob,
- runIndex,
- GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed(),
- GrGlyph::kCoverage_MaskStyle),
- Sk48Dot16FloorToInt(fx),
- Sk48Dot16FloorToInt(fy),
- fontScaler,
- clipRect);
- }
- pos += scalarsPerPosition;
- }
- } else {
- while (text < stop) {
- // the last 2 parameters are ignored
- const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
-
- if (glyph.fWidth) {
- SkPoint tmsLoc;
- tmsProc(pos, &tmsLoc);
-
- SkPoint alignLoc;
- alignProc(tmsLoc, glyph, &alignLoc);
-
- Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf); //halfSampleX;
- Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf); //halfSampleY;
- this->appendGlyph(blob,
- runIndex,
- GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed(),
- GrGlyph::kCoverage_MaskStyle),
- Sk48Dot16FloorToInt(fx),
- Sk48Dot16FloorToInt(fy),
- fontScaler,
- clipRect);
- }
- pos += scalarsPerPosition;
- }
- }
- }
- SkGlyphCache::AttachCache(cache);
-}
-
-static size_t get_vertex_stride(GrMaskFormat maskFormat) {
- switch (maskFormat) {
- case kA8_GrMaskFormat:
- return kGrayTextVASize;
- case kARGB_GrMaskFormat:
- return kColorTextVASize;
- default:
- return kLCDTextVASize;
- }
-}
-
-void GrBitmapTextContextB::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGlyph::PackedID packed,
- int vx, int vy, GrFontScaler* scaler,
- const SkIRect& clipRect) {
- if (NULL == fCurrStrike) {
- fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler);
- }
-
- GrGlyph* glyph = fCurrStrike->getGlyph(packed, scaler);
- if (NULL == glyph || glyph->fBounds.isEmpty()) {
- return;
- }
-
- int x = vx + glyph->fBounds.fLeft;
- int y = vy + glyph->fBounds.fTop;
-
- // keep them as ints until we've done the clip-test
- int width = glyph->fBounds.width();
- int height = glyph->fBounds.height();
-
- // check if we clipped out
- if (clipRect.quickReject(x, y, x + width, y + height)) {
- return;
- }
-
- // If the glyph is too large we fall back to paths
- if (fCurrStrike->glyphTooLargeForAtlas(glyph)) {
- if (NULL == glyph->fPath) {
- SkPath* path = SkNEW(SkPath);
- if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
- // flag the glyph as being dead?
- SkDELETE(path);
- return;
- }
- glyph->fPath = path;
- }
- SkASSERT(glyph->fPath);
- blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, vy));
- return;
- }
- GrMaskFormat format = glyph->fMaskFormat;
- size_t vertexStride = get_vertex_stride(format);
-
- BitmapTextBlob::Run& run = blob->fRuns[runIndex];
- int glyphIdx = run.fInfos[format].fGlyphIDs.count();
- *run.fInfos[format].fGlyphIDs.append() = packed;
- run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVerticesPerGlyph));
-
- SkRect r;
- r.fLeft = SkIntToScalar(x);
- r.fTop = SkIntToScalar(y);
- r.fRight = r.fLeft + SkIntToScalar(width);
- r.fBottom = r.fTop + SkIntToScalar(height);
-
- run.fVertexBounds.joinNonEmptyArg(r);
- GrColor color = fPaint.getColor();
- run.fColor = color;
-
- intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.begin());
- vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
-
- // V0
- SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
- position->set(r.fLeft, r.fTop);
- if (kA8_GrMaskFormat == format) {
- SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- }
- vertex += vertexStride;
-
- // V1
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(r.fLeft, r.fBottom);
- if (kA8_GrMaskFormat == format) {
- SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- }
- vertex += vertexStride;
-
- // V2
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(r.fRight, r.fBottom);
- if (kA8_GrMaskFormat == format) {
- SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- }
- vertex += vertexStride;
-
- // V3
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(r.fRight, r.fTop);
- if (kA8_GrMaskFormat == format) {
- SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- }
-}
-
-class BitmapTextBatch : public GrBatch {
-public:
- typedef GrBitmapTextContextB::BitmapTextBlob Blob;
- typedef Blob::Run Run;
- typedef Run::PerFormatInfo TextInfo;
- struct Geometry {
- Geometry() {}
- Geometry(const Geometry& geometry)
- : fBlob(SkRef(geometry.fBlob.get()))
- , fRun(geometry.fRun)
- , fColor(geometry.fColor) {}
- SkAutoTUnref<Blob> fBlob;
- int fRun;
- GrColor fColor;
- };
-
- static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat,
- GrBatchFontCache* fontCache) {
- return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCache));
- }
-
- const char* name() const override { return "BitmapTextBatch"; }
-
- void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- if (kARGB_GrMaskFormat == fMaskFormat) {
- out->setUnknownFourComponents();
- } else {
- out->setKnownFourComponents(fBatch.fColor);
- }
- }
-
- void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- if (kARGB_GrMaskFormat != fMaskFormat) {
- if (GrPixelConfigIsAlphaOnly(fPixelConfig)) {
- out->setUnknownSingleComponent();
- } else if (GrPixelConfigIsOpaque(fPixelConfig)) {
- out->setUnknownOpaqueFourComponents();
- out->setUsingLCDCoverage();
- } else {
- out->setUnknownFourComponents();
- out->setUsingLCDCoverage();
- }
- } else {
- out->setKnownSingleComponent(0xff);
- }
- }
-
- void initBatchTracker(const GrPipelineInfo& init) override {
- // Handle any color overrides
- if (init.fColorIgnored) {
- fBatch.fColor = GrColor_ILLEGAL;
- } else if (GrColor_ILLEGAL != init.fOverrideColor) {
- fBatch.fColor = init.fOverrideColor;
- }
-
- // setup batch properties
- fBatch.fColorIgnored = init.fColorIgnored;
- fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
- fBatch.fCoverageIgnored = init.fCoverageIgnored;
- }
-
- void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix.
- // TODO actually only invert if we don't have RGBA
- SkMatrix localMatrix;
- if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) {
- SkDebugf("Cannot invert viewmatrix\n");
- return;
- }
-
- GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
- // This will be ignored in the non A8 case
- bool opaqueVertexColors = GrColorIsOpaque(this->color());
- SkAutoTUnref<const GrGeometryProcessor> gp(
- GrBitmapTextGeoProc::Create(this->color(),
- fFontCache->getTexture(fMaskFormat),
- params,
- fMaskFormat,
- opaqueVertexColors,
- localMatrix));
-
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == get_vertex_stride(fMaskFormat));
-
- this->initDraw(batchTarget, gp, pipeline);
-
- int glyphCount = this->numGlyphs();
- int instanceCount = fGeoData.count();
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- glyphCount * kVerticesPerGlyph,
- &vertexBuffer,
- &firstVertex);
- if (!vertices) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
-
- unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
-
- // setup drawinfo
- const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
- int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVerticesPerGlyph);
- drawInfo.setIndicesPerInstance(kIndicesPerGlyph);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(quadIndexBuffer);
-
- int instancesToFlush = 0;
- for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
- Blob* blob = args.fBlob;
- Run& run = blob->fRuns[args.fRun];
- TextInfo& info = run.fInfos[fMaskFormat];
-
- uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
- bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen;
- bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor;
- int glyphCount = info.fGlyphIDs.count();
-
- // We regenerate both texture coords and colors in the blob itself, and update the
- // atlas generation. If we don't end up purging any unused plots, we can avoid
- // regenerating the coords. We could take a finer grained approach to updating texture
- // coords but its not clear if the extra bookkeeping would offset any gains.
- // To avoid looping over the glyphs twice, we do one loop and conditionally update color
- // or coords as needed. One final note, if we have to break a run for an atlas eviction
- // then we can't really trust the atlas has all of the correct data. Atlas evictions
- // should be pretty rare, so we just always regenerate in those cases
- if (regenerateTextureCoords || regenerateColors) {
- // first regenerate texture coordinates / colors if need be
- const SkDescriptor* desc = NULL;
- SkGlyphCache* cache = NULL;
- GrFontScaler* scaler = NULL;
- GrBatchTextStrike* strike = NULL;
- bool brokenRun = false;
- if (regenerateTextureCoords) {
- desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data());
- cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
- scaler = GrTextContext::GetGrFontScaler(cache);
- strike = fFontCache->getStrike(scaler);
- }
- for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
- GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx];
-
- if (regenerateTextureCoords) {
- // Upload the glyph only if needed
- GrGlyph* glyph = strike->getGlyph(glyphID, scaler);
- SkASSERT(glyph);
-
- if (!fFontCache->hasGlyph(glyph) &&
- !strike->addGlyphToAtlas(batchTarget, glyph, scaler)) {
- this->flush(batchTarget, &drawInfo, instancesToFlush,
- maxInstancesPerDraw);
- this->initDraw(batchTarget, gp, pipeline);
- instancesToFlush = 0;
- brokenRun = glyphIdx > 0;
-
- SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget, glyph,
- scaler);
- SkASSERT(success);
- }
-
- fFontCache->setGlyphRefToken(glyph, batchTarget->currentToken());
-
- // Texture coords are the last vertex attribute so we get a pointer to the
- // first one and then map with stride in regenerateTextureCoords
- intptr_t vertex = reinterpret_cast<intptr_t>(info.fVertices.begin());
- vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
- vertex += vertexStride - sizeof(SkIPoint16);
-
- this->regenerateTextureCoords(glyph, vertex, vertexStride);
- }
-
- if (regenerateColors) {
- intptr_t vertex = reinterpret_cast<intptr_t>(info.fVertices.begin());
- vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint);
- this->regenerateColors(vertex, vertexStride, args.fColor);
- }
-
- instancesToFlush++;
- }
-
- if (regenerateTextureCoords) {
- SkGlyphCache::AttachCache(cache);
- info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasGeneration :
- fFontCache->atlasGeneration(fMaskFormat);
- }
- } else {
- instancesToFlush += glyphCount;
- }
-
- // now copy all vertices
- int byteCount = info.fVertices.count();
- memcpy(currVertex, info.fVertices.begin(), byteCount);
-
- currVertex += byteCount;
- }
-
- this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
- }
-
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
-
-private:
- BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat,
- GrBatchFontCache* fontCache)
- : fMaskFormat(maskFormat)
- , fPixelConfig(fontCache->getPixelConfig(maskFormat))
- , fFontCache(fontCache) {
- this->initClassID<BitmapTextBatch>();
- fGeoData.push_back(geometry);
- fBatch.fColor = color;
- fBatch.fViewMatrix = geometry.fBlob->fViewMatrix;
- int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat].fGlyphIDs.count();
- fBatch.fNumGlyphs = numGlyphs;
- }
-
- void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexStride) {
- int width = glyph->fBounds.width();
- int height = glyph->fBounds.height();
- int u0 = glyph->fAtlasLocation.fX;
- int v0 = glyph->fAtlasLocation.fY;
- int u1 = u0 + width;
- int v1 = v0 + height;
-
- // we assume texture coords are the last vertex attribute, this is a bit fragile.
- // TODO pass in this offset or something
- SkIPoint16* textureCoords;
- // V0
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
- textureCoords->set(u0, v0);
- vertex += vertexStride;
-
- // V1
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
- textureCoords->set(u0, v1);
- vertex += vertexStride;
-
- // V2
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
- textureCoords->set(u1, v1);
- vertex += vertexStride;
-
- // V3
- textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
- textureCoords->set(u1, v0);
- }
-
- void regenerateColors(intptr_t vertex, size_t vertexStride, GrColor color) {
- for (int i = 0; i < kVerticesPerGlyph; i++) {
- SkColor* vcolor = reinterpret_cast<SkColor*>(vertex);
- *vcolor = color;
- vertex += vertexStride;
- }
- }
-
- void initDraw(GrBatchTarget* batchTarget,
- const GrGeometryProcessor* gp,
- const GrPipeline* pipeline) {
- batchTarget->initDraw(gp, pipeline);
-
- // TODO remove this when batch is everywhere
- GrPipelineInfo init;
- init.fColorIgnored = fBatch.fColorIgnored;
- init.fOverrideColor = GrColor_ILLEGAL;
- init.fCoverageIgnored = fBatch.fCoverageIgnored;
- init.fUsesLocalCoords = this->usesLocalCoords();
- gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
- }
-
- void flush(GrBatchTarget* batchTarget,
- GrDrawTarget::DrawInfo* drawInfo,
- int instanceCount,
- int maxInstancesPerDraw) {
- while (instanceCount) {
- drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verticesPerInstance());
- drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indicesPerInstance());
-
- batchTarget->draw(*drawInfo);
-
- drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexCount());
- instanceCount -= drawInfo->instanceCount();
- }
- }
-
- GrColor color() const { return fBatch.fColor; }
- const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
- bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
- int numGlyphs() const { return fBatch.fNumGlyphs; }
-
- bool onCombineIfPossible(GrBatch* t) override {
- BitmapTextBatch* that = t->cast<BitmapTextBatch>();
-
- if (this->fMaskFormat != that->fMaskFormat) {
- return false;
- }
-
- if (this->fMaskFormat != kA8_GrMaskFormat && this->color() != that->color()) {
- return false;
- }
-
- if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
- return false;
- }
-
- fBatch.fNumGlyphs += that->numGlyphs();
- fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
- return true;
- }
-
- struct BatchTracker {
- GrColor fColor;
- SkMatrix fViewMatrix;
- bool fUsesLocalCoords;
- bool fColorIgnored;
- bool fCoverageIgnored;
- int fNumGlyphs;
- };
-
- BatchTracker fBatch;
- SkSTArray<1, Geometry, true> fGeoData;
- GrMaskFormat fMaskFormat;
- GrPixelConfig fPixelConfig;
- GrBatchFontCache* fFontCache;
-};
-
-void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blob, int i,
- GrPipelineBuilder* pipelineBuilder, GrMaskFormat format,
- GrColor color, int paintAlpha) {
- if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) {
- return;
- }
-
- if (kARGB_GrMaskFormat == format) {
- color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha);
- }
-
- BitmapTextBatch::Geometry geometry;
- geometry.fBlob.reset(SkRef(blob));
- geometry.fRun = i;
- geometry.fColor = color;
- SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format,
- fContext->getBatchFontCache()));
-
- target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds);
-}
-
-void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrRenderTarget* rt,
- const GrPaint& paint, const GrClip& clip,
- const SkMatrix& viewMatrix, int paintAlpha) {
- GrPipelineBuilder pipelineBuilder;
- pipelineBuilder.setFromPaint(paint, rt, clip);
-
- GrColor color = paint.getColor();
- for (int i = 0; i < blob->fRuns.count(); i++) {
- this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, color, paintAlpha);
- this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat, color, paintAlpha);
- this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat, color, paintAlpha);
- }
-
- // Now flush big glyphs
- for (int i = 0; i < blob->fBigGlyphs.count(); i++) {
- BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i];
- SkMatrix translate;
- translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGlyph.fVy));
- SkPath tmpPath(bigGlyph.fPath);
- tmpPath.transform(translate);
- GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
- fContext->drawPath(rt, clip, paint, SkMatrix::I(), tmpPath, strokeInfo);
- }
-}
-
GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
SkGpuDevice* gpuDevice,
const SkDeviceProperties& properties)
@@ -1285,6 +352,17 @@
this->finish();
}
+static size_t get_vertex_stride(GrMaskFormat maskFormat) {
+ switch (maskFormat) {
+ case kA8_GrMaskFormat:
+ return kGrayTextVASize;
+ case kARGB_GrMaskFormat:
+ return kColorTextVASize;
+ default:
+ return kLCDTextVASize;
+ }
+}
+
static void* alloc_vertices(GrDrawTarget* drawTarget,
int numVertices,
GrMaskFormat maskFormat) {
@@ -1308,33 +386,33 @@
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
-
+
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
-
+
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
#endif
}
-
+
// before we purge the cache, we must flush any accumulated draws
this->flush();
fContext->flush();
-
+
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
-
+
// we should never get here
SkASSERT(false);
}
-
+
return false;
}
@@ -1560,3 +638,4 @@
GrTextContext::finish();
}
+
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index 3bf3a94..f843fc7 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -11,127 +11,6 @@
#include "GrTextContext.h"
#include "GrGeometryProcessor.h"
-#include "SkTHash.h"
-
-class GrBatchTextStrike;
-class GrPipelineBuilder;
-
-/*
- * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
- * TODO replace GrBitmapTextContext
- */
-class GrBitmapTextContextB : public GrTextContext {
-public:
- static GrBitmapTextContextB* Create(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
-
- virtual ~GrBitmapTextContextB();
-
-private:
- GrBitmapTextContextB(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
-
- bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
- const SkPaint&, const SkMatrix& viewMatrix) override;
-
- void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
- const SkMatrix& viewMatrix, const char text[], size_t byteLength,
- SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
- void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& regionClipBounds) override;
- void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
- const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
- SkDrawFilter*, const SkIRect& clipBounds) override;
-
- void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
- const SkIRect& regionClipBounds);
-
- /*
- * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
- * on the GPU. These are initially created with valid positions and colors, but invalid
- * texture coordinates. The BitmapTextBlob itself has a few Blob-wide properties, and also
- * consists of a number of runs. Runs inside a blob are flushed individually so they can be
- * reordered.
- *
- * The only thing(aside from a memcopy) required to flush a BitmapTextBlob is to ensure that
- * the GrAtlas will not evict anything the Blob needs.
- * TODO this is currently a bug
- */
- struct BitmapTextBlob : public SkRefCnt {
- // Each Run inside of the blob can have its texture coordinates regenerated if required.
- // To determine if regeneration is necessary, fAtlasGeneration is used. If there have been
- // any evictions inside of the atlas, then we will simply regenerate Runs. We could track
- // this at a more fine grained level, but its not clear if this is worth it, as evictions
- // should be fairly rare.
- // One additional point, each run can contain glyphs with any of the three mask formats.
- // We maintain separate arrays for each format type, and flush them separately. In practice
- // most of the time a run will have the same format type
- struct Run {
- Run() : fColor(GrColor_ILLEGAL) { fVertexBounds.setLargestInverted(); }
- struct PerFormatInfo {
- PerFormatInfo() : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) {}
- SkTDArray<unsigned char> fVertices;
- SkTDArray<GrGlyph::PackedID> fGlyphIDs;
- uint64_t fAtlasGeneration;
- };
- SkAutoTUnref<const SkData> fDescriptor;
- SkAutoTUnref<SkTypeface> fTypeface;
- PerFormatInfo fInfos[kMaskFormatCount];
- SkRect fVertexBounds;
- GrColor fColor;
- };
- SkSTArray<1, Run, true> fRuns;
- struct BigGlyph {
- BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx), fVy(vy) {}
- SkPath fPath;
- int fVx;
- int fVy;
- };
- SkTArray<BigGlyph> fBigGlyphs;
- SkTextBlob* fBlob;
- SkMatrix fViewMatrix;
- SkScalar fX;
- SkScalar fY;
- SkPaint::Style fStyle;
-
- static uint32_t Hash(const uint32_t& key) {
- return SkChecksum::Mix(key);
- }
- };
-
- void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left, int top,
- GrFontScaler*, const SkIRect& clipRect);
- void flushSubRun(GrDrawTarget*, BitmapTextBlob*, int i, GrPipelineBuilder*, GrMaskFormat,
- GrColor color, int paintAlpha);
- void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const GrPaint&, const GrClip&,
- const SkMatrix& viewMatrix, int paintAlpha);
-
- void internalDrawText(BitmapTextBlob*, int runIndex, const SkPaint&,
- const SkMatrix& viewMatrix, const char text[], size_t byteLength,
- SkScalar x, SkScalar y, const SkIRect& clipRect);
- void internalDrawPosText(BitmapTextBlob*, int runIndex, const SkPaint&,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& clipRect);
-
- static inline bool MustRegenerateBlob(const BitmapTextBlob&, const SkPaint&,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
- void regenerateTextBlob(BitmapTextBlob* bmp, const SkPaint& skPaint, const SkMatrix& viewMatrix,
- const SkTextBlob* blob, SkScalar x, SkScalar y,
- SkDrawFilter* drawFilter, const SkIRect& clipRect);
-
- GrBatchTextStrike* fCurrStrike;
-
- // TODO use real cache
- static void ClearCacheEntry(uint32_t key, BitmapTextBlob**);
- SkTHashMap<uint32_t, BitmapTextBlob*, BitmapTextBlob::Hash> fCache;
-
- friend class BitmapTextBatch;
-
- typedef GrTextContext INHERITED;
-};
class GrTextStrike;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a1f1c25..4c7f3ea 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -10,9 +10,7 @@
#include "GrAARectRenderer.h"
#include "GrBatch.h"
-#include "GrBatchFontCache.h"
#include "GrBatchTarget.h"
-#include "GrBitmapTextContext.h"
#include "GrBufferAllocPool.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrFontCache.h"
@@ -96,7 +94,6 @@
fPathRendererChain = NULL;
fSoftwarePathRenderer = NULL;
fResourceCache = NULL;
- fBatchFontCache = NULL;
fFontCache = NULL;
fDrawBuffer = NULL;
fDrawBufferVBAllocPool = NULL;
@@ -132,10 +129,6 @@
fDidTestPMConversions = false;
this->setupDrawBuffer();
-
- // GrBatchFontCache will eventually replace GrFontCache
- fBatchFontCache = SkNEW(GrBatchFontCache);
- fBatchFontCache->init(this);
}
GrContext::~GrContext() {
@@ -150,7 +143,6 @@
}
SkDELETE(fResourceCache);
- SkDELETE(fBatchFontCache);
SkDELETE(fFontCache);
SkDELETE(fDrawBuffer);
SkDELETE(fDrawBufferVBAllocPool);
@@ -188,7 +180,6 @@
fAARectRenderer->reset();
fOvalRenderer->reset();
- fBatchFontCache->freeAll();
fFontCache->freeAll();
fLayerCache->freeAll();
}
@@ -207,7 +198,6 @@
fAARectRenderer->reset();
fOvalRenderer->reset();
- fBatchFontCache->freeAll();
fFontCache->freeAll();
fLayerCache->freeAll();
// a path renderer may be holding onto resources
@@ -236,12 +226,8 @@
}
}
-#ifdef USE_BITMAP_TEXTBLOBS
- return GrBitmapTextContextB::Create(this, gpuDevice, leakyProperties);
-#else
return GrDistanceFieldTextContext::Create(this, gpuDevice, leakyProperties,
enableDistanceFieldFonts);
-#endif
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index acab0cf..f0915a7 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -74,11 +74,7 @@
bool enable) {
GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextContext,
(context, gpuDevice, props, enable));
-#ifdef USE_BITMAP_TEXTBLOBS
- textContext->fFallbackTextContext = GrBitmapTextContextB::Create(context, gpuDevice, props);
-#else
textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, gpuDevice, props);
-#endif
return textContext;
}
diff --git a/src/gpu/GrFontAtlasSizes.h b/src/gpu/GrFontAtlasSizes.h
index 8a3091c..d5c5e28 100644
--- a/src/gpu/GrFontAtlasSizes.h
+++ b/src/gpu/GrFontAtlasSizes.h
@@ -9,30 +9,6 @@
#ifndef GrFontAtlasSizes_DEFINED
#define GrFontAtlasSizes_DEFINED
-// For debugging atlas which evict all of the time
-//#define DEBUG_CONSTANT_EVICT
-#ifdef DEBUG_CONSTANT_EVICT
-#define GR_FONT_ATLAS_TEXTURE_WIDTH 256//1024
-#define GR_FONT_ATLAS_A8_TEXTURE_WIDTH 256//2048
-#define GR_FONT_ATLAS_TEXTURE_HEIGHT 256//2048
-
-#define GR_FONT_ATLAS_PLOT_WIDTH 256
-#define GR_FONT_ATLAS_A8_PLOT_WIDTH 256//512
-#define GR_FONT_ATLAS_PLOT_HEIGHT 256
-
-#define GR_FONT_ATLAS_NUM_PLOTS_X (GR_FONT_ATLAS_TEXTURE_WIDTH / GR_FONT_ATLAS_PLOT_WIDTH)
-#define GR_FONT_ATLAS_A8_NUM_PLOTS_X (GR_FONT_ATLAS_A8_TEXTURE_WIDTH / GR_FONT_ATLAS_A8_PLOT_WIDTH)
-#define GR_FONT_ATLAS_NUM_PLOTS_Y (GR_FONT_ATLAS_TEXTURE_HEIGHT / GR_FONT_ATLAS_PLOT_HEIGHT)
-
-// one over width and height
-#define GR_FONT_ATLAS_RECIP_WIDTH "0.00390625"//"0.0009765625"
-#define GR_FONT_ATLAS_A8_RECIP_WIDTH "0.00390625"//"0.00048828125"
-#define GR_FONT_ATLAS_RECIP_HEIGHT "0.00390625"//"0.00048828125"
-
-// 1/(3*width)
-// only used for distance fields, which are A8
-#define GR_FONT_ATLAS_LCD_DELTA "0.001302083"//"0.000162760417"
-#else
#define GR_FONT_ATLAS_TEXTURE_WIDTH 1024
#define GR_FONT_ATLAS_A8_TEXTURE_WIDTH 2048
#define GR_FONT_ATLAS_TEXTURE_HEIGHT 2048
@@ -53,5 +29,5 @@
// 1/(3*width)
// only used for distance fields, which are A8
#define GR_FONT_ATLAS_LCD_DELTA "0.000162760417"
-#endif
+
#endif
diff --git a/src/gpu/GrGlyph.h b/src/gpu/GrGlyph.h
index 2d3e945..108f2f0 100644
--- a/src/gpu/GrGlyph.h
+++ b/src/gpu/GrGlyph.h
@@ -8,7 +8,6 @@
#ifndef GrGlyph_DEFINED
#define GrGlyph_DEFINED
-#include "GrBatchAtlas.h"
#include "GrRect.h"
#include "GrTypes.h"
@@ -31,17 +30,14 @@
typedef uint32_t PackedID;
- // TODO either plot or AtlasID will be valid, not both
- GrBatchAtlas::AtlasID fID;
- GrPlot* fPlot;
- SkPath* fPath;
- PackedID fPackedID;
- GrMaskFormat fMaskFormat;
- GrIRect16 fBounds;
- SkIPoint16 fAtlasLocation;
+ GrPlot* fPlot;
+ SkPath* fPath;
+ PackedID fPackedID;
+ GrMaskFormat fMaskFormat;
+ GrIRect16 fBounds;
+ SkIPoint16 fAtlasLocation;
void init(GrGlyph::PackedID packed, const SkIRect& bounds, GrMaskFormat format) {
- fID = GrBatchAtlas::kInvalidAtlasID;
fPlot = NULL;
fPath = NULL;
fPackedID = packed;
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index bf47abd..172a856 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -34,11 +34,7 @@
const SkDeviceProperties& props) {
GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverTextContext,
(context, gpuDevice, props));
-#ifdef USE_BITMAP_TEXTBLOBS
- textContext->fFallbackTextContext = GrBitmapTextContextB::Create(context, gpuDevice, props);
-#else
textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, gpuDevice, props);
-#endif
return textContext;
}
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index 54b3efd..0a4beae 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -23,9 +23,6 @@
class SkGpuDevice;
class SkTextBlob;
-// For testing textblobs on GPU.
-//#define USE_BITMAP_TEXTBLOBS
-
/*
* This class wraps the state for a single text render
*/
@@ -41,9 +38,9 @@
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds);
- virtual void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
- const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
- SkDrawFilter*, const SkIRect& clipBounds);
+ void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
+ const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
+ SkDrawFilter*, const SkIRect& clipBounds);
protected:
GrTextContext* fFallbackTextContext;
@@ -93,8 +90,6 @@
// sets extent in stopVector and returns glyph count
static int MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
const char text[], size_t byteLength, SkVector* stopVector);
-
- friend class BitmapTextBatch;
};
#endif
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 8c3414b..522cba8 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -219,7 +219,6 @@
static GrRenderTarget* CreateRenderTarget(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
int sampleCount);
- friend class GrBitmapTextContextB;
friend class GrTextContext;
typedef SkBaseDevice INHERITED;
};