GrTextStrike.cpp revision 8fe72477f204b1a45393e6a64caa84fd287b805b
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* 2ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Copyright 2010 Google Inc. 3ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Licensed under the Apache License, Version 2.0 (the "License"); 5ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com you may not use this file except in compliance with the License. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com You may obtain a copy of the License at 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com http://www.apache.org/licenses/LICENSE-2.0 9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Unless required by applicable law or agreed to in writing, software 11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com distributed under the License is distributed on an "AS IS" BASIS, 12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com See the License for the specific language governing permissions and 14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com limitations under the License. 15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrAtlas.h" 19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpu.h" 20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrMemory.h" 21ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrRectanizer.h" 22ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike.h" 23ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike_impl.h" 24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrRect.h" 25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) { 27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gpu->ref(); 28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = NULL; 29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = fTail = NULL; 31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() { 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com delete fAtlasMgr; 36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fGpu->unref(); 37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler, 40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const Key& key) { 41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (NULL == fAtlasMgr) { 42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = new GrAtlasMgr(fGpu); 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 4498539c607b05f7e25406ae873bf1b24154a36a6freed@google.com GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(), 4598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com scaler->getMaskFormat(), fAtlasMgr); 46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(key, strike); 47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fHead) { 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead->fPrev = strike; 50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(NULL == fTail); 52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fTail = strike; 53ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fPrev = NULL; 55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fNext = fHead; 56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = strike; 57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 58ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return strike; 59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() { 62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com delete fAtlasMgr; 64ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = NULL; 658fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fHead = NULL; 668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTail = NULL; 67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 68ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) { 70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrTextStrike* strike = fTail; 71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (strike == preserveStrike) { 72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fPrev; 73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (strike) { 75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int index = fCache.slowFindIndex(strike); 76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(index >= 0); 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.removeAt(index, strike->fFontScalerKey->getHash()); 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com this->detachStrikeFromList(strike); 79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com delete strike; 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG 84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const { 85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count = fCache.count(); 86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (0 == count) { 87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(!fHead); 88ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(!fTail); 89ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else if (1 == count) { 90ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(fHead == fTail); 91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(fHead != fTail); 93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count2 = 0; 96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const GrTextStrike* strike = fHead; 97ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 98ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 99ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fNext; 100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(count == count2); 102ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 103ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 = 0; 104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = fTail; 105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 107ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fPrev; 108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 109ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(count == count2); 110ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 111ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 112ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 113ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 114ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 115ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG 116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com static int gCounter; 117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 118ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 119ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* 120ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com The text strike is specific to a given font/style/matrix setup, which is 121ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com represented by the GrHostFontScaler object we are given in getGlyph(). 122ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com We map a 32bit glyphID to a GrGlyph record, which in turn points to a 124ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com atlas and a position within that texture. 125ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 126ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 127ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 12898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com GrMaskFormat format, 129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAtlasMgr* atlasMgr) : fPool(64) { 130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey = key; 131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->ref(); 132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 133ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontCache = cache; // no need to ref, it won't go away before we do 134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do 135ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlas = NULL; 136ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 13798539c607b05f7e25406ae873bf1b24154a36a6freed@google.com fMaskFormat = format; 13898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 139ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG 140ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrPrintf(" GrTextStrike %p %d\n", this, gCounter); 141ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter += 1; 142ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 143ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 144ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comstatic void FreeGlyph(GrGlyph*& glyph) { glyph->free(); } 146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() { 148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAtlas::FreeLList(fAtlas); 149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->unref(); 150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.getArray().visit(FreeGlyph); 151ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG 153ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter -= 1; 154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrPrintf("~GrTextStrike %p %d\n", this, gCounter); 155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, 159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrFontScaler* scaler) { 160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrIRect bounds; 161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return NULL; 163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrGlyph* glyph = fPool.alloc(); 166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com glyph->init(packed, bounds); 167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(packed, glyph); 168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return glyph; 169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { 172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(glyph); 173ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(scaler); 174ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAssert(fCache.contains(glyph)); 175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (glyph->fAtlas) { 176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 178ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAutoRef ar(scaler); 18098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 18198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 18298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com size_t size = glyph->fBounds.area() * bytesPerPixel; 183ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAutoSMalloc<1024> storage(size); 184ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), 18598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com glyph->height(), 18698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com glyph->width() * bytesPerPixel, 187ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com storage.get())) { 188ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 189ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 190ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(), 192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com glyph->height(), storage.get(), 19398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com fMaskFormat, 194ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com &glyph->fAtlasLocation); 195ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (NULL == atlas) { 196ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 197ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // update fAtlas as well, since they may be chained in a linklist 200ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com glyph->fAtlas = fAtlas = atlas; 201ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 202ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 203ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 204ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 205