From 53e1e4d88a06db62898a3bf75751c042729d7160 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Tue, 1 Apr 2014 16:25:11 +0000 Subject: [PATCH] Minor changes to GrFontCache system. The main change is parameterizing the GrAtlasMgr so it can have a different sized backing texture and a different number of plots. This is in support of the saveLayer cache which has a smaller backing texture and only one plot. R=jvanverth@google.com, bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/217423014 git-svn-id: http://skia.googlecode.com/svn/trunk@14011 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/gpu/GrFontScaler.h | 2 +- src/core/SkGlyphCache.h | 2 +- src/gpu/GrAtlas.cpp | 66 ++++++++++++++------------------ src/gpu/GrAtlas.h | 12 +++--- src/gpu/GrRectanizer_skyline.cpp | 35 +++++++++-------- src/gpu/GrTextStrike.cpp | 16 +++++++- src/gpu/GrTextStrike_impl.h | 2 +- 7 files changed, 73 insertions(+), 62 deletions(-) diff --git a/include/gpu/GrFontScaler.h b/include/gpu/GrFontScaler.h index e51c4ac9a5..d307cabb42 100644 --- a/include/gpu/GrFontScaler.h +++ b/include/gpu/GrFontScaler.h @@ -18,7 +18,7 @@ class SkPath; * font scaler. * * The client is responsible for subclassing, and instantiating this. The - * instance is create for a specific font+size+matrix. + * instance is created for a specific font+size+matrix. */ class GrFontScaler : public SkRefCnt { public: diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 7b2ebb844e..135942b28b 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -28,7 +28,7 @@ class SkGlyphCache_Globals; This class represents a strike: a specific combination of typeface, size, matrix, etc., and holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphID... methods will return the requested glyph, - either instantly if it is already cahced, or by first generating it and then + either instantly if it is already cached, or by first generating it and then adding it to the strike. The strikes are held in a global list, available to all threads. To interact diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp index e17171f801..f035155b6b 100644 --- a/src/gpu/GrAtlas.cpp +++ b/src/gpu/GrAtlas.cpp @@ -11,28 +11,6 @@ #include "GrGpu.h" #include "GrRectanizer.h" -#if 0 -#define GR_PLOT_WIDTH 8 -#define GR_PLOT_HEIGHT 4 -#define GR_ATLAS_WIDTH 256 -#define GR_ATLAS_HEIGHT 256 - -#define GR_ATLAS_TEXTURE_WIDTH (GR_PLOT_WIDTH * GR_ATLAS_WIDTH) -#define GR_ATLAS_TEXTURE_HEIGHT (GR_PLOT_HEIGHT * GR_ATLAS_HEIGHT) - -#else - -#define GR_ATLAS_TEXTURE_WIDTH 1024 -#define GR_ATLAS_TEXTURE_HEIGHT 2048 - -#define GR_ATLAS_WIDTH 256 -#define GR_ATLAS_HEIGHT 256 - -#define GR_PLOT_WIDTH (GR_ATLAS_TEXTURE_WIDTH / GR_ATLAS_WIDTH) -#define GR_PLOT_HEIGHT (GR_ATLAS_TEXTURE_HEIGHT / GR_ATLAS_HEIGHT) - -#endif - /////////////////////////////////////////////////////////////////////////////// // for testing @@ -43,11 +21,10 @@ static int g_UploadCount = 0; GrPlot::GrPlot() : fDrawToken(NULL, 0) , fTexture(NULL) + , fRects(NULL) , fAtlasMgr(NULL) , fBytesPerPixel(1) { - fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH, - GR_ATLAS_HEIGHT); fOffset.set(0, 0); } @@ -55,9 +32,16 @@ GrPlot::~GrPlot() { delete fRects; } +void GrPlot::init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, size_t bpp) { + fRects = GrRectanizer::Factory(width, height); + fAtlasMgr = mgr; + fOffset.set(offX * width, offY * height); + fBytesPerPixel = bpp; +} + static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) { - loc->fX += offset.fX * GR_ATLAS_WIDTH; - loc->fY += offset.fY * GR_ATLAS_HEIGHT; + loc->fX += offset.fX; + loc->fY += offset.fY; } bool GrPlot::addSubImage(int width, int height, const void* image, @@ -91,22 +75,30 @@ void GrPlot::resetRects() { /////////////////////////////////////////////////////////////////////////////// -GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) { - fGpu = gpu; +GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config, + const SkISize& backingTextureSize, + int numPlotsX, int numPlotsY) { + fGpu = SkRef(gpu); fPixelConfig = config; - gpu->ref(); + fBackingTextureSize = backingTextureSize; + fNumPlotsX = numPlotsX; + fNumPlotsY = numPlotsY; fTexture = NULL; + int plotWidth = fBackingTextureSize.width() / fNumPlotsX; + int plotHeight = fBackingTextureSize.height() / fNumPlotsY; + + SkASSERT(plotWidth * fNumPlotsX == fBackingTextureSize.width()); + SkASSERT(plotHeight * fNumPlotsY == fBackingTextureSize.height()); + // set up allocated plots size_t bpp = GrBytesPerPixel(fPixelConfig); - fPlotArray = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT)); + fPlotArray = SkNEW_ARRAY(GrPlot, (fNumPlotsX*fNumPlotsY)); GrPlot* currPlot = fPlotArray; - for (int y = GR_PLOT_HEIGHT-1; y >= 0; --y) { - for (int x = GR_PLOT_WIDTH-1; x >= 0; --x) { - currPlot->fAtlasMgr = this; - currPlot->fOffset.set(x, y); - currPlot->fBytesPerPixel = bpp; + for (int y = numPlotsY-1; y >= 0; --y) { + for (int x = numPlotsX-1; x >= 0; --x) { + currPlot->init(this, x, y, plotWidth, plotHeight, bpp); // build LRU list fPlotList.addToHead(currPlot); @@ -152,8 +144,8 @@ GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas, // TODO: Update this to use the cache rather than directly creating a texture. GrTextureDesc desc; desc.fFlags = kDynamicUpdate_GrTextureFlagBit; - desc.fWidth = GR_ATLAS_TEXTURE_WIDTH; - desc.fHeight = GR_ATLAS_TEXTURE_HEIGHT; + desc.fWidth = fBackingTextureSize.width(); + desc.fHeight = fBackingTextureSize.height(); desc.fConfig = fPixelConfig; fTexture = fGpu->createTexture(desc, NULL, 0); diff --git a/src/gpu/GrAtlas.h b/src/gpu/GrAtlas.h index c7536e3800..d7f5334141 100644 --- a/src/gpu/GrAtlas.h +++ b/src/gpu/GrAtlas.h @@ -33,9 +33,6 @@ class GrPlot { public: SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot); - int getOffsetX() const { return fOffset.fX; } - int getOffsetY() const { return fOffset.fY; } - GrTexture* texture() const { return fTexture; } bool addSubImage(int width, int height, const void*, GrIPoint16*); @@ -48,6 +45,7 @@ public: private: GrPlot(); ~GrPlot(); // does not try to delete the fNext field + void init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, size_t bpp); // for recycling GrDrawTarget::DrawToken fDrawToken; @@ -55,7 +53,7 @@ private: GrTexture* fTexture; GrRectanizer* fRects; GrAtlasMgr* fAtlasMgr; - GrIPoint16 fOffset; + GrIPoint16 fOffset; // the offset of the plot in the backing texture size_t fBytesPerPixel; friend class GrAtlasMgr; @@ -65,7 +63,8 @@ typedef SkTInternalLList GrPlotList; class GrAtlasMgr { public: - GrAtlasMgr(GrGpu*, GrPixelConfig); + GrAtlasMgr(GrGpu*, GrPixelConfig, const SkISize& backingTextureSize, + int numPlotsX, int numPlotsY); ~GrAtlasMgr(); // add subimage of width, height dimensions to atlas @@ -89,6 +88,9 @@ private: GrGpu* fGpu; GrPixelConfig fPixelConfig; GrTexture* fTexture; + SkISize fBackingTextureSize; + int fNumPlotsX; + int fNumPlotsY; // allocated array of GrPlots GrPlot* fPlotArray; diff --git a/src/gpu/GrRectanizer_skyline.cpp b/src/gpu/GrRectanizer_skyline.cpp index a55451a896..d485ce3ff0 100755 --- a/src/gpu/GrRectanizer_skyline.cpp +++ b/src/gpu/GrRectanizer_skyline.cpp @@ -14,30 +14,30 @@ class GrRectanizerSkyline : public GrRectanizer { public: - GrRectanizerSkyline(int w, int h) : GrRectanizer(w, h) { - reset(); + GrRectanizerSkyline(int w, int h) : INHERITED(w, h) { + this->reset(); } virtual ~GrRectanizerSkyline() { } - virtual void reset() { + virtual void reset() SK_OVERRIDE { fAreaSoFar = 0; fSkyline.reset(); SkylineSegment* seg = fSkyline.append(1); seg->fX = 0; seg->fY = 0; - seg->fWidth = width(); + seg->fWidth = this->width(); } - virtual bool addRect(int w, int h, GrIPoint16* loc); + virtual bool addRect(int w, int h, GrIPoint16* loc) SK_OVERRIDE; - virtual float percentFull() const { + virtual float percentFull() const SK_OVERRIDE { return fAreaSoFar / ((float)this->width() * this->height()); } - virtual int stripToPurge(int height) const { return -1; } - virtual void purgeStripAtY(int yCoord) { } + virtual int stripToPurge(int height) const SK_OVERRIDE { return -1; } + virtual void purgeStripAtY(int yCoord) SK_OVERRIDE { } /////////////////////////////////////////////////////////////////////////// @@ -53,6 +53,9 @@ public: bool rectangleFits(int skylineIndex, int width, int height, int* y) const; void addSkylineLevel(int skylineIndex, int x, int y, int width, int height); + +private: + typedef GrRectanizer INHERITED; }; bool GrRectanizerSkyline::addRect(int width, int height, GrIPoint16* loc) { @@ -104,13 +107,13 @@ bool GrRectanizerSkyline::rectangleFits(int skylineIndex, int width, int height, int i = skylineIndex; int y = fSkyline[skylineIndex].fY; while (widthLeft > 0) { - y = SkMax32(y, fSkyline[i].fY); + y = SkMax32(y, fSkyline[i].fY); if (y + height > this->height()) { return false; } - widthLeft -= fSkyline[i].fWidth; - ++i; - SkASSERT(i < fSkyline.count() || widthLeft <= 0); + widthLeft -= fSkyline[i].fWidth; + ++i; + SkASSERT(i < fSkyline.count() || widthLeft <= 0); } *ypos = y; @@ -140,12 +143,12 @@ void GrRectanizerSkyline::addSkylineLevel(int skylineIndex, int x, int y, int wi if (fSkyline[i].fWidth <= 0) { fSkyline.remove(i); --i; - } - else + } else { break; - } - else + } + } else { break; + } } // merge fSkylines diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp index 7084b9383d..8c2fa0bdd2 100644 --- a/src/gpu/GrTextStrike.cpp +++ b/src/gpu/GrTextStrike.cpp @@ -16,6 +16,15 @@ /////////////////////////////////////////////////////////////////////////////// +#define GR_ATLAS_TEXTURE_WIDTH 1024 +#define GR_ATLAS_TEXTURE_HEIGHT 2048 + +#define GR_PLOT_WIDTH 256 +#define GR_PLOT_HEIGHT 256 + +#define GR_NUM_PLOTS_X (GR_ATLAS_TEXTURE_WIDTH / GR_PLOT_WIDTH) +#define GR_NUM_PLOTS_Y (GR_ATLAS_TEXTURE_HEIGHT / GR_PLOT_HEIGHT) + #define FONT_CACHE_STATS 0 #if FONT_CACHE_STATS static int g_PurgeCount = 0; @@ -72,7 +81,12 @@ GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler, GrPixelConfig config = mask_format_to_pixel_config(format); int atlasIndex = mask_format_to_atlas_index(format); if (NULL == fAtlasMgr[atlasIndex]) { - fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config)); + SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, + GR_ATLAS_TEXTURE_HEIGHT); + fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config, + textureSize, + GR_NUM_PLOTS_X, + GR_NUM_PLOTS_Y)); } GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, (this, scaler->getKey(), format, fAtlasMgr[atlasIndex])); diff --git a/src/gpu/GrTextStrike_impl.h b/src/gpu/GrTextStrike_impl.h index bc4f8dd817..dcfc04aaae 100644 --- a/src/gpu/GrTextStrike_impl.h +++ b/src/gpu/GrTextStrike_impl.h @@ -57,7 +57,7 @@ GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField strike = this->generateStrike(scaler, key); } else if (strike->fPrev) { // Need to put the strike at the head of its dllist, since that is how - // we age the strikes for purging (we purge from the back of the list + // we age the strikes for purging (we purge from the back of the list) this->detachStrikeFromList(strike); // attach at the head fHead->fPrev = strike; -- 2.34.1