GrTextStrike.cpp revision 03e3e89641c93df603dfb705d518848dfe81427e
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" 1303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#include "SkString.h" 14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 15fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrFontScaler) 16fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrKey) 17fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com 18fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com/////////////////////////////////////////////////////////////////////////////// 19fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com 2067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#define FONT_CACHE_STATS 0 2167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 2267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic int g_PurgeCount = 0; 2367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 2467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) { 26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gpu->ref(); 273fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org for (int i = 0; i < kMaskFormatCount; ++i) { 283fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org fAtlasMgr[i] = NULL; 293fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = fTail = NULL; 32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() { 35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 363fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org for (int i = 0; i < kMaskFormatCount; ++i) { 373fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org delete fAtlasMgr[i]; 383fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fGpu->unref(); 4067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 4167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org GrPrintf("Num purges: %d\n", g_PurgeCount); 4267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 45952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.orgstatic GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format) { 46952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org switch (format) { 47952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org case kA8_GrMaskFormat: 48952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org return kAlpha_8_GrPixelConfig; 49952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org case kA565_GrMaskFormat: 50952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org return kRGB_565_GrPixelConfig; 51952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org case kA888_GrMaskFormat: 52952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org return kSkia8888_GrPixelConfig; 53952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org default: 54952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org SkDEBUGFAIL("unknown maskformat"); 55952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org } 56952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org return kUnknown_GrPixelConfig; 57952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org} 58952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org 59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler, 60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const Key& key) { 613fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org GrMaskFormat format = scaler->getMaskFormat(); 62952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org GrPixelConfig config = mask_format_to_pixel_config(format); 633fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org if (NULL == fAtlasMgr[format]) { 64952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org fAtlasMgr[format] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config)); 65ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 66c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, 67952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org (this, scaler->getKey(), format, fAtlasMgr[format])); 68ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(key, strike); 69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fHead) { 71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead->fPrev = strike; 72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 73f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fTail); 74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fTail = strike; 75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fPrev = NULL; 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fNext = fHead; 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = strike; 79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return strike; 81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() { 84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 853fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org for (int i = 0; i < kMaskFormatCount; ++i) { 863fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org delete fAtlasMgr[i]; 873fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org fAtlasMgr[i] = NULL; 883fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fHead = NULL; 908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTail = NULL; 91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) { 94bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com SkASSERT(NULL != preserveStrike); 95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrTextStrike* strike = fTail; 9667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org bool purge = true; 97bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com GrMaskFormat maskFormat = preserveStrike->fMaskFormat; 9867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org while (strike) { 99bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com if (strike == preserveStrike || maskFormat != strike->fMaskFormat) { 10067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org strike = strike->fPrev; 10167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org continue; 10267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 10367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org GrTextStrike* strikeToPurge = strike; 10467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org strike = strikeToPurge->fPrev; 10567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org if (purge) { 10667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org // keep purging if we won't free up any atlases with this strike. 1077d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org purge = strikeToPurge->fAtlas.isEmpty(); 10867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org int index = fCache.slowFindIndex(strikeToPurge); 109f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(index >= 0); 11067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash()); 11167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org this->detachStrikeFromList(strikeToPurge); 11267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org delete strikeToPurge; 11367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 11467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 11567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 11667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org ++g_PurgeCount; 11767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 11867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org} 11967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 1207d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgvoid GrFontCache::freePlotExceptFor(GrTextStrike* preserveStrike) { 121bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com SkASSERT(NULL != preserveStrike); 12267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org GrTextStrike* strike = fTail; 123bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com GrMaskFormat maskFormat = preserveStrike->fMaskFormat; 1247359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com while (strike) { 125bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com if (strike == preserveStrike || maskFormat != strike->fMaskFormat) { 1267359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com strike = strike->fPrev; 1277359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com continue; 1287359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com } 1297359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com GrTextStrike* strikeToPurge = strike; 13067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org strike = strikeToPurge->fPrev; 1317d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (strikeToPurge->removeUnusedPlots()) { 1327d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (strikeToPurge->fAtlas.isEmpty()) { 13367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org int index = fCache.slowFindIndex(strikeToPurge); 134f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(index >= 0); 13567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash()); 13667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org this->detachStrikeFromList(strikeToPurge); 13767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org delete strikeToPurge; 13867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 13967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org break; 14067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 141ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 142ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 143ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 144515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const { 146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count = fCache.count(); 147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (0 == count) { 148f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!fHead); 149f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!fTail); 150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else if (1 == count) { 151f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fHead == fTail); 152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 153f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fHead != fTail); 154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count2 = 0; 157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const GrTextStrike* strike = fHead; 158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fNext; 161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 162f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(count == count2); 163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 = 0; 165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = fTail; 166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fPrev; 169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 170f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(count == count2); 171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 173ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 17403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER 17503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrFontCache::dump() const { 17603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org static int gDumpCount = 0; 17703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org for (int i = 0; i < kMaskFormatCount; ++i) { 17803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org if (NULL != fAtlasMgr[i]) { 17903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org GrTexture* texture = fAtlasMgr[i]->getTexture(); 18003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org if (NULL != texture) { 18103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org SkString filename; 18203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org filename.printf("fontcache_%d%d.png", gDumpCount, i); 18303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org texture->savePixels(filename.c_str()); 18403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 18503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 18603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 18703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org ++gDumpCount; 18803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org} 18903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif 19003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org 191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 193515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 194ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com static int gCounter; 195ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 196ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 197ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* 198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com The text strike is specific to a given font/style/matrix setup, which is 199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com represented by the GrHostFontScaler object we are given in getGlyph(). 200ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 201ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com We map a 32bit glyphID to a GrGlyph record, which in turn points to a 202ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com atlas and a position within that texture. 203ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 204ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 205ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 20698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com GrMaskFormat format, 2077d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org GrAtlasMgr* atlasMgr) : fPool(64), fAtlas(atlasMgr) { 208ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey = key; 209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->ref(); 210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontCache = cache; // no need to ref, it won't go away before we do 212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do 213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 21498539c607b05f7e25406ae873bf1b24154a36a6freed@google.com fMaskFormat = format; 21598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 216515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 2173ef80cf14c3222f705c291123106991e52061678reed@google.com// GrPrintf(" GrTextStrike %p %d\n", this, gCounter); 218ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter += 1; 219ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 220ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 221ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 22267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// these signatures are needed because they're used with 22367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// SkTDArray::visitAll() (see destructor & removeUnusedAtlases()) 22467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); } 22567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 22667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void invalidate_glyph(GrGlyph*& glyph) { 2277d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (glyph->fPlot && glyph->fPlot->drawToken().isIssued()) { 2287d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org glyph->fPlot = NULL; 22967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 23067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org} 231ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 232ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() { 233ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->unref(); 23467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org fCache.getArray().visitAll(free_glyph); 235ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 236515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter -= 1; 2383ef80cf14c3222f705c291123106991e52061678reed@google.com// GrPrintf("~GrTextStrike %p %d\n", this, gCounter); 239ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 240ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, 243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrFontScaler* scaler) { 244fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect bounds; 245ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 246ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return NULL; 247ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 248ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrGlyph* glyph = fPool.alloc(); 250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com glyph->init(packed, bounds); 251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(packed, glyph); 252ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return glyph; 253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 254ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2557d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgbool GrTextStrike::removeUnusedPlots() { 25667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org fCache.getArray().visitAll(invalidate_glyph); 2577d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org return fAtlasMgr->removeUnusedPlots(&fAtlas); 25867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org} 25967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 260a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.orgbool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler, 261a8916ffd90c04dc6cc1fb9ba94af2ff950284fadcommit-bot@chromium.org GrDrawTarget::DrawToken currentDrawToken) { 2620ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0 // testing hack to force us to flush our cache often 2630ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com static int gCounter; 2640ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com if ((++gCounter % 10) == 0) return false; 2650ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif 2660ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com 267f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(glyph); 268f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(scaler); 269f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fCache.contains(glyph)); 2707d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (glyph->fPlot) { 2717d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org glyph->fPlot->setDrawToken(currentDrawToken); 272ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 273ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 274ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 275a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkAutoRef ar(scaler); 27698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 27798539c607b05f7e25406ae873bf1b24154a36a6freed@google.com int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 27898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com size_t size = glyph->fBounds.area() * bytesPerPixel; 2793582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<1024> storage(size); 280ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), 28198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com glyph->height(), 28298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com glyph->width() * bytesPerPixel, 283ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com storage.get())) { 284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 285ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 286ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2877d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), 2887d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org glyph->height(), storage.get(), 2897d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org &glyph->fAtlasLocation); 2907d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (NULL == plot) { 291ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 293ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2947d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org glyph->fPlot = plot; 2957d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org plot->setDrawToken(currentDrawToken); 296ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 297ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 298