GrTextStrike.cpp revision a4de8c257ea0be8ff7081f645249b6afe5c48e7e
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrAtlas.h"
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpu.h"
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrRectanizer.h"
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike.h"
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike_impl.h"
13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
14fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrFontScaler)
15fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrKey)
16fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
17fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com///////////////////////////////////////////////////////////////////////////////
18fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
1967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#define FONT_CACHE_STATS 0
2067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
2167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic int g_PurgeCount = 0;
2267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
2367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gpu->ref();
26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = NULL;
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = fTail = NULL;
29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() {
32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    delete fAtlasMgr;
34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGpu->unref();
3567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
3667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org      GrPrintf("Num purges: %d\n", g_PurgeCount);
3767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          const Key& key) {
42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL == fAtlasMgr) {
43c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com        fAtlasMgr = SkNEW_ARGS(GrAtlasMgr, (fGpu));
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
45c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com    GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
46c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com                                      (this, scaler->getKey(),
47c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com                                       scaler->getMaskFormat(), fAtlasMgr));
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(key, strike);
49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (fHead) {
51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fHead->fPrev = strike;
52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
53f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(NULL == fTail);
54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fTail = strike;
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fPrev = NULL;
57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fNext = fHead;
58ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = strike;
59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return strike;
61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() {
64ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
65ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    delete fAtlasMgr;
66ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = NULL;
678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fHead = NULL;
688fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fTail = NULL;
69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrTextStrike* strike = fTail;
7367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    bool purge = true;
7467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    while (strike) {
7567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        if (strike == preserveStrike) {
7667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            strike = strike->fPrev;
7767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            continue;
7867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
7967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        GrTextStrike* strikeToPurge = strike;
8067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        strike = strikeToPurge->fPrev;
8167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        if (purge) {
8267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            // keep purging if we won't free up any atlases with this strike.
8367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            purge = (NULL == strikeToPurge->fAtlas);
8467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            int index = fCache.slowFindIndex(strikeToPurge);
85f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(index >= 0);
8667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash());
8767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            this->detachStrikeFromList(strikeToPurge);
8867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            delete strikeToPurge;
8967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
9067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
9167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
9267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    ++g_PurgeCount;
9367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
9467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
9567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
9667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgvoid GrFontCache::freeAtlasExceptFor(GrTextStrike* preserveStrike) {
9767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    GrTextStrike* strike = fTail;
987359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com    while (strike) {
997359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        if (strike == preserveStrike) {
1007359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            strike = strike->fPrev;
1017359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            continue;
1027359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        }
1037359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        GrTextStrike* strikeToPurge = strike;
10467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        strike = strikeToPurge->fPrev;
10567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        if (strikeToPurge->removeUnusedAtlases()) {
10667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            if (NULL == strikeToPurge->fAtlas) {
10767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                int index = fCache.slowFindIndex(strikeToPurge);
108f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(index >= 0);
10967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash());
11067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                this->detachStrikeFromList(strikeToPurge);
11167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                delete strikeToPurge;
11267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            }
11367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            break;
11467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
115ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
118515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
119ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const {
120ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count = fCache.count();
121ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (0 == count) {
122f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fHead);
123f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fTail);
124ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else if (1 == count) {
125f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead == fTail);
126ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
127f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead != fTail);
128ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count2 = 0;
131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const GrTextStrike* strike = fHead;
132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
133ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fNext;
135ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
136f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
137ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
138ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    count2 = 0;
139ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike = fTail;
140ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
141ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
142ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fPrev;
143ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
144f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///////////////////////////////////////////////////////////////////////////////
149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
150515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
151ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    static int gCounter;
152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
153ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*
155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    The text strike is specific to a given font/style/matrix setup, which is
156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    represented by the GrHostFontScaler object we are given in getGlyph().
157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    atlas and a position within that texture.
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
16398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                           GrMaskFormat format,
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                           GrAtlasMgr* atlasMgr) : fPool(64) {
165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey = key;
166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->ref();
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontCache = cache;     // no need to ref, it won't go away before we do
169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlas = NULL;
171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    fMaskFormat = format;
17398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
174515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
1753ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter += 1;
177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
178ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
18067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// these signatures are needed because they're used with
18167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// SkTDArray::visitAll() (see destructor & removeUnusedAtlases())
18267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); }
18367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
18467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void invalidate_glyph(GrGlyph*& glyph) {
185a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.org    if (glyph->fAtlas && glyph->fAtlas->drawToken().isIssued()) {
18667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        glyph->fAtlas = NULL;
18767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
18867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
189ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
190ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() {
191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAtlas::FreeLList(fAtlas);
192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->unref();
19367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(free_glyph);
194ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
195515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
196ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter -= 1;
1973ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
200ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
201ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
202ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     GrFontScaler* scaler) {
203fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect bounds;
204ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
205ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return NULL;
206ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
207ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
208ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrGlyph* glyph = fPool.alloc();
209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    glyph->init(packed, bounds);
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(packed, glyph);
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return glyph;
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
21467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgbool GrTextStrike::removeUnusedAtlases() {
21567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(invalidate_glyph);
21667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    return GrAtlas::RemoveUnusedAtlases(fAtlasMgr, &fAtlas);
21767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
21867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
219a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.orgbool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler,
220a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.org                                 GrDrawTarget::DrawToken currentDrawToken) {
2210ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0   // testing hack to force us to flush our cache often
2220ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    static int gCounter;
2230ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    if ((++gCounter % 10) == 0) return false;
2240ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif
2250ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com
226f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(glyph);
227f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(scaler);
228f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fCache.contains(glyph));
229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (glyph->fAtlas) {
230a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.org        glyph->fAtlas->setDrawToken(currentDrawToken);
231ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return true;
232ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
233ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
234a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkAutoRef ar(scaler);
23598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
23698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
23798539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    size_t size = glyph->fBounds.area() * bytesPerPixel;
2383582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com    SkAutoSMalloc<1024> storage(size);
239ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
24098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                     glyph->height(),
24198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                     glyph->width() * bytesPerPixel,
242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     storage.get())) {
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
244ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
245ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    GrAtlas* atlas = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
247ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                           glyph->height(), storage.get(),
24898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                           fMaskFormat,
249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                           &glyph->fAtlasLocation);
250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL == atlas) {
251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
252ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
25467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    glyph->fAtlas = atlas;
255a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.org    atlas->setDrawToken(currentDrawToken);
256ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
257ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
258