GrTextStrike.cpp revision 67ed64e9aa70f5a95a2d309f9b73dc0009f3ed8c
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 {
53ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrAssert(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);
8567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            GrAssert(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        } else {
9067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            // for the remaining strikes, we just mark them unused
9167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            GrAtlas::MarkAllUnused(strikeToPurge->fAtlas);
9267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
9367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
9467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
9567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    ++g_PurgeCount;
9667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
9767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
9867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
9967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgvoid GrFontCache::freeAtlasExceptFor(GrTextStrike* preserveStrike) {
10067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    GrTextStrike* strike = fTail;
1017359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com    while (strike) {
1027359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        if (strike == preserveStrike) {
1037359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            strike = strike->fPrev;
1047359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            continue;
1057359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        }
1067359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        GrTextStrike* strikeToPurge = strike;
10767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        strike = strikeToPurge->fPrev;
10867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        if (strikeToPurge->removeUnusedAtlases()) {
10967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            if (NULL == strikeToPurge->fAtlas) {
11067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                int index = fCache.slowFindIndex(strikeToPurge);
11167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                GrAssert(index >= 0);
11267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash());
11367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                this->detachStrikeFromList(strikeToPurge);
11467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org                delete strikeToPurge;
11567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            }
11667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            break;
11767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
118ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
119ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
120ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
121ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
122ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const {
123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count = fCache.count();
124ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (0 == count) {
125ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrAssert(!fHead);
126ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrAssert(!fTail);
127ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else if (1 == count) {
128ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrAssert(fHead == fTail);
129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrAssert(fHead != fTail);
131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
133ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count2 = 0;
134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const GrTextStrike* strike = fHead;
135ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
136ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
137ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fNext;
138ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
139ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(count == count2);
140ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
141ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    count2 = 0;
142ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike = fTail;
143ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
144ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fPrev;
146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(count == count2);
148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
151ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///////////////////////////////////////////////////////////////////////////////
152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
153ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    static int gCounter;
155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    The text strike is specific to a given font/style/matrix setup, which is
159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    represented by the GrHostFontScaler object we are given in getGlyph().
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    atlas and a position within that texture.
163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
16698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                           GrMaskFormat format,
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                           GrAtlasMgr* atlasMgr) : fPool(64) {
168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey = key;
169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->ref();
170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontCache = cache;     // no need to ref, it won't go away before we do
172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
173ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlas = NULL;
174ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    fMaskFormat = format;
17698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
1783ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter += 1;
180ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
181ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
182ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
18367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// these signatures are needed because they're used with
18467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// SkTDArray::visitAll() (see destructor & removeUnusedAtlases())
18567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); }
18667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
18767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void invalidate_glyph(GrGlyph*& glyph) {
18867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    if (glyph->fAtlas && !glyph->fAtlas->used()) {
18967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        glyph->fAtlas = NULL;
19067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
19167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
193ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() {
194ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAtlas::FreeLList(fAtlas);
195ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->unref();
19667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(free_glyph);
197ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter -= 1;
2003ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
201ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
202ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
203ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
204ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
205ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     GrFontScaler* scaler) {
206fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect bounds;
207ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
208ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return NULL;
209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrGlyph* glyph = fPool.alloc();
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    glyph->init(packed, bounds);
213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(packed, glyph);
214ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return glyph;
215ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
216ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
21767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgbool GrTextStrike::removeUnusedAtlases() {
21867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(invalidate_glyph);
21967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    return GrAtlas::RemoveUnusedAtlases(fAtlasMgr, &fAtlas);
22067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
22167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    return false;
22267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
22367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
224ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
2250ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0   // testing hack to force us to flush our cache often
2260ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    static int gCounter;
2270ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    if ((++gCounter % 10) == 0) return false;
2280ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif
2290ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com
230ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(glyph);
231ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(scaler);
232ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(fCache.contains(glyph));
233ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (glyph->fAtlas) {
23467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        glyph->fAtlas->setUsed(true);
235ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return true;
236ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
238ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAutoRef ar(scaler);
23998539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
24098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
24198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    size_t size = glyph->fBounds.area() * bytesPerPixel;
2423582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com    SkAutoSMalloc<1024> storage(size);
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
24498539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                     glyph->height(),
24598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                     glyph->width() * bytesPerPixel,
246ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     storage.get())) {
247ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
248ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
25067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    GrAtlas* atlas = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                           glyph->height(), storage.get(),
25298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                                           fMaskFormat,
253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                           &glyph->fAtlasLocation);
254ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL == atlas) {
255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
256ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
257ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
25867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    glyph->fAtlas = atlas;
25967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    atlas->setUsed(true);
260ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
261ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
262