From c03391e792a55219ddcb033475dc6b80e6a3e2f9 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Tue, 31 Mar 2015 11:33:08 -0700 Subject: [PATCH] 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 --- dm/DMSrcSink.cpp | 13 - gyp/gpu.gypi | 2 - include/core/SkPaint.h | 1 - include/core/SkTextBlob.h | 1 - include/gpu/GrContext.h | 3 - src/gpu/GrAADistanceFieldPathRenderer.cpp | 8 +- src/gpu/GrAtlas.cpp | 1 - src/gpu/GrBatchAtlas.cpp | 7 +- src/gpu/GrBatchAtlas.h | 4 - src/gpu/GrBatchFontCache.cpp | 309 ---------- src/gpu/GrBatchFontCache.h | 137 ----- src/gpu/GrBitmapTextContext.cpp | 959 +----------------------------- src/gpu/GrBitmapTextContext.h | 121 ---- src/gpu/GrContext.cpp | 14 - src/gpu/GrDistanceFieldTextContext.cpp | 4 - src/gpu/GrFontAtlasSizes.h | 26 +- src/gpu/GrGlyph.h | 16 +- src/gpu/GrStencilAndCoverTextContext.cpp | 4 - src/gpu/GrTextContext.h | 11 +- src/gpu/SkGpuDevice.h | 1 - 20 files changed, 37 insertions(+), 1605 deletions(-) delete mode 100644 src/gpu/GrBatchFontCache.cpp delete mode 100644 src/gpu/GrBatchFontCache.h 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 @@ Error SKPSrc::draw(SkCanvas* canvas) const { 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 @@ private: 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 @@ private: 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 @@ public: // 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 @@ private: GrGpu* fGpu; GrResourceCache* fResourceCache; - GrBatchFontCache* fBatchFontCache; GrFontCache* fFontCache; SkAutoTDelete 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 @@ public: 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 @@ private: 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 @@ private: } 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 @@ GrPlot* GrAtlas::addToAtlas(ClientPlotUsage* usage, 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 @@ GrBatchAtlas::GrBatchAtlas(GrTexture* texture, int numPlotsX, int numPlotsY) , 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 @@ GrBatchAtlas::GrBatchAtlas(GrTexture* texture, int numPlotsX, int numPlotsY) 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 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget, 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 @@ bool GrBatchAtlas::addToAtlas(AtlasID* id, GrBatchTarget* batchTarget, 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 @@ public: // 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 @@ public: 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 @@ private: 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::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::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(ptr); - - SkTDynamicHash::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::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::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 fCache; - SkAutoTUnref 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 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 kVerticesPerGlyph = 4; 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 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(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 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(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(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(run.fInfos[format].fVertices.begin()); - vertex += vertexStride * glyphIdx * kVerticesPerGlyph; - - // V0 - SkPoint* position = reinterpret_cast(vertex); - position->set(r.fLeft, r.fTop); - if (kA8_GrMaskFormat == format) { - SkColor* colorPtr = reinterpret_cast(vertex + sizeof(SkPoint)); - *colorPtr = color; - } - vertex += vertexStride; - - // V1 - position = reinterpret_cast(vertex); - position->set(r.fLeft, r.fBottom); - if (kA8_GrMaskFormat == format) { - SkColor* colorPtr = reinterpret_cast(vertex + sizeof(SkPoint)); - *colorPtr = color; - } - vertex += vertexStride; - - // V2 - position = reinterpret_cast(vertex); - position->set(r.fRight, r.fBottom); - if (kA8_GrMaskFormat == format) { - SkColor* colorPtr = reinterpret_cast(vertex + sizeof(SkPoint)); - *colorPtr = color; - } - vertex += vertexStride; - - // V3 - position = reinterpret_cast(vertex); - position->set(r.fRight, r.fTop); - if (kA8_GrMaskFormat == format) { - SkColor* colorPtr = reinterpret_cast(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 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 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(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(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(info.fVertices.begin()); - vertex += vertexStride * glyphIdx * kVerticesPerGlyph; - vertex += vertexStride - sizeof(SkIPoint16); - - this->regenerateTextureCoords(glyph, vertex, vertexStride); - } - - if (regenerateColors) { - intptr_t vertex = reinterpret_cast(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(); - 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(vertex); - textureCoords->set(u0, v0); - vertex += vertexStride; - - // V1 - textureCoords = reinterpret_cast(vertex); - textureCoords->set(u0, v1); - vertex += vertexStride; - - // V2 - textureCoords = reinterpret_cast(vertex); - textureCoords->set(u1, v1); - vertex += vertexStride; - - // V3 - textureCoords = reinterpret_cast(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(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(); - - 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 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 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, 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 @@ inline bool GrBitmapTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scale 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 @@ inline void GrBitmapTextContext::finish() { 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 fVertices; - SkTDArray fGlyphIDs; - uint64_t fAtlasGeneration; - }; - SkAutoTUnref fDescriptor; - SkAutoTUnref 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 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 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 @@ GrContext::GrContext(const Options& opts) : fOptions(opts) { fPathRendererChain = NULL; fSoftwarePathRenderer = NULL; fResourceCache = NULL; - fBatchFontCache = NULL; fFontCache = NULL; fDrawBuffer = NULL; fDrawBufferVBAllocPool = NULL; @@ -132,10 +129,6 @@ void GrContext::initCommon() { fDidTestPMConversions = false; this->setupDrawBuffer(); - - // GrBatchFontCache will eventually replace GrFontCache - fBatchFontCache = SkNEW(GrBatchFontCache); - fBatchFontCache->init(this); } GrContext::~GrContext() { @@ -150,7 +143,6 @@ GrContext::~GrContext() { } SkDELETE(fResourceCache); - SkDELETE(fBatchFontCache); SkDELETE(fFontCache); SkDELETE(fDrawBuffer); SkDELETE(fDrawBufferVBAllocPool); @@ -188,7 +180,6 @@ void GrContext::abandonContext() { fAARectRenderer->reset(); fOvalRenderer->reset(); - fBatchFontCache->freeAll(); fFontCache->freeAll(); fLayerCache->freeAll(); } @@ -207,7 +198,6 @@ void GrContext::freeGpuResources() { fAARectRenderer->reset(); fOvalRenderer->reset(); - fBatchFontCache->freeAll(); fFontCache->freeAll(); fLayerCache->freeAll(); // a path renderer may be holding onto resources @@ -236,12 +226,8 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, } } -#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 @@ GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex 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 @@ struct GrGlyph { 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 @@ GrStencilAndCoverTextContext::Create(GrContext* context, SkGpuDevice* gpuDevice, 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 SkDrawFilter; 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 @@ public: 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 @@ protected: // 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 @@ private: static GrRenderTarget* CreateRenderTarget(GrContext*, SkSurface::Budgeted, const SkImageInfo&, int sampleCount); - friend class GrBitmapTextContextB; friend class GrTextContext; typedef SkBaseDevice INHERITED; }; -- 2.7.4