GrTextStrike.cpp revision 53e1e4d88a06db62898a3bf75751c042729d7160
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 158065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org#include "SkDistanceFieldGen.h" 16d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 17fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com/////////////////////////////////////////////////////////////////////////////// 18fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com 1953e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_ATLAS_TEXTURE_WIDTH 1024 2053e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_ATLAS_TEXTURE_HEIGHT 2048 2153e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org 2253e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_PLOT_WIDTH 256 2353e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_PLOT_HEIGHT 256 2453e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org 2553e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_NUM_PLOTS_X (GR_ATLAS_TEXTURE_WIDTH / GR_PLOT_WIDTH) 2653e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org#define GR_NUM_PLOTS_Y (GR_ATLAS_TEXTURE_HEIGHT / GR_PLOT_HEIGHT) 2753e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org 2867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#define FONT_CACHE_STATS 0 2967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 3067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic int g_PurgeCount = 0; 3167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 3267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) { 34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gpu->ref(); 35f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org for (int i = 0; i < kAtlasCount; ++i) { 363fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org fAtlasMgr[i] = NULL; 373fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = fTail = NULL; 40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() { 43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 44f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org for (int i = 0; i < kAtlasCount; ++i) { 453fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org delete fAtlasMgr[i]; 463fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fGpu->unref(); 4867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 4967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org GrPrintf("Num purges: %d\n", g_PurgeCount); 5067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 53952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.orgstatic GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format) { 546e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com static const GrPixelConfig sPixelConfigs[] = { 556e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com kAlpha_8_GrPixelConfig, 566e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com kRGB_565_GrPixelConfig, 57f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org kSkia8888_GrPixelConfig, 58f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org kSkia8888_GrPixelConfig 59f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org }; 60f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sPixelConfigs) == kMaskFormatCount, array_size_mismatch); 61f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org 62f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org return sPixelConfigs[format]; 63f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org} 64f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org 65f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.orgstatic int mask_format_to_atlas_index(GrMaskFormat format) { 666e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com static const int sAtlasIndices[] = { 676e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com GrFontCache::kA8_AtlasType, 686e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com GrFontCache::k565_AtlasType, 696e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com GrFontCache::k8888_AtlasType, 706e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com GrFontCache::k8888_AtlasType 71f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org }; 72f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_size_mismatch); 73f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org 74f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org SkASSERT(sAtlasIndices[format] < GrFontCache::kAtlasCount); 75f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org return sAtlasIndices[format]; 76952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org} 77952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org 78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler, 79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const Key& key) { 803fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org GrMaskFormat format = scaler->getMaskFormat(); 81952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org GrPixelConfig config = mask_format_to_pixel_config(format); 82f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org int atlasIndex = mask_format_to_atlas_index(format); 83f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org if (NULL == fAtlasMgr[atlasIndex]) { 8453e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, 8553e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org GR_ATLAS_TEXTURE_HEIGHT); 8653e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config, 8753e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org textureSize, 8853e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org GR_NUM_PLOTS_X, 8953e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org GR_NUM_PLOTS_Y)); 90ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 91c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, 92f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org (this, scaler->getKey(), format, fAtlasMgr[atlasIndex])); 93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(key, strike); 94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (fHead) { 96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead->fPrev = strike; 97ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 98f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fTail); 99ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fTail = strike; 100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fPrev = NULL; 102ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike->fNext = fHead; 103ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fHead = strike; 104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return strike; 106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 107ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() { 109ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.deleteAll(); 110f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org for (int i = 0; i < kAtlasCount; ++i) { 1113fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org delete fAtlasMgr[i]; 1123fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org fAtlasMgr[i] = NULL; 1133fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org } 1148fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fHead = NULL; 1158fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTail = NULL; 116ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 118b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.orgvoid GrFontCache::purgeStrike(GrTextStrike* strike) { 119b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org const GrFontCache::Key key(strike->fFontScalerKey); 120b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org fCache.remove(key, strike); 121b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org this->detachStrikeFromList(strike); 122b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org delete strike; 123b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org} 124b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org 125c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgbool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) { 126bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com SkASSERT(NULL != preserveStrike); 127c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 128c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org GrAtlasMgr* atlasMgr = preserveStrike->fAtlasMgr; 129c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org GrPlot* plot = atlasMgr->getUnusedPlot(); 130c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org if (NULL == plot) { 131c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org return false; 132c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org } 133c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org plot->resetRects(); 134c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 135c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org GrTextStrike* strike = fHead; 136bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com GrMaskFormat maskFormat = preserveStrike->fMaskFormat; 13767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org while (strike) { 138c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org if (maskFormat != strike->fMaskFormat) { 139c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org strike = strike->fNext; 14067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org continue; 14167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 142c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 14367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org GrTextStrike* strikeToPurge = strike; 144c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org strike = strikeToPurge->fNext; 145c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org strikeToPurge->removePlot(plot); 146c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 147c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org // clear out any empty strikes (except this one) 148c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org if (strikeToPurge != preserveStrike && strikeToPurge->fAtlas.isEmpty()) { 149b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org this->purgeStrike(strikeToPurge); 15067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 15167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org } 152c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 15367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS 15467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org ++g_PurgeCount; 15567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif 15667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 157c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org return true; 158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 160515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const { 162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count = fCache.count(); 163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (0 == count) { 164f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!fHead); 165f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!fTail); 166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else if (1 == count) { 167f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fHead == fTail); 168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } else { 169f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fHead != fTail); 170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com int count2 = 0; 173ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com const GrTextStrike* strike = fHead; 174ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fNext; 177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 178f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(count == count2); 179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 180ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 = 0; 181ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = fTail; 182ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com while (strike) { 183ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com count2 += 1; 184ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com strike = strike->fPrev; 185ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 186f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(count == count2); 187ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 188ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 189ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 19003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER 19103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrFontCache::dump() const { 19203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org static int gDumpCount = 0; 193f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org for (int i = 0; i < kAtlasCount; ++i) { 19403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org if (NULL != fAtlasMgr[i]) { 19503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org GrTexture* texture = fAtlasMgr[i]->getTexture(); 19603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org if (NULL != texture) { 19703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org SkString filename; 1984362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 1994362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org filename.printf("/sdcard/fontcache_%d%d.png", gDumpCount, i); 2004362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org#else 20103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org filename.printf("fontcache_%d%d.png", gDumpCount, i); 2024362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org#endif 20303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org texture->savePixels(filename.c_str()); 20403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 20503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 20603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org } 20703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org ++gDumpCount; 20803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org} 20903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif 21003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org 211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 213515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 214ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com static int gCounter; 215ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 216ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2178065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org// this acts as the max magnitude for the distance field, 2188065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org// as well as the pad we need around the glyph 2198065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org#define DISTANCE_FIELD_RANGE 4 220d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 221ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/* 222ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com The text strike is specific to a given font/style/matrix setup, which is 223ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com represented by the GrHostFontScaler object we are given in getGlyph(). 224ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 225ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com We map a 32bit glyphID to a GrGlyph record, which in turn points to a 226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com atlas and a position within that texture. 227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 23098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com GrMaskFormat format, 231c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org GrAtlasMgr* atlasMgr) : fPool(64) { 232ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey = key; 233ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->ref(); 234ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 235ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontCache = cache; // no need to ref, it won't go away before we do 236ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do 237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 23898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com fMaskFormat = format; 23998539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 240515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 2413ef80cf14c3222f705c291123106991e52061678reed@google.com// GrPrintf(" GrTextStrike %p %d\n", this, gCounter); 242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter += 1; 243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 244ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 245ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 246c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org// this signature is needed because it's used with 247c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org// SkTDArray::visitAll() (see destructor) 24867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); } 24967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() { 251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fFontScalerKey->unref(); 25267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org fCache.getArray().visitAll(free_glyph); 253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 254515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com gCounter -= 1; 2563ef80cf14c3222f705c291123106991e52061678reed@google.com// GrPrintf("~GrTextStrike %p %d\n", this, gCounter); 257ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 258ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 259ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 260ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, 261ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrFontScaler* scaler) { 262fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect bounds; 263ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 264ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return NULL; 265ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 266ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 267ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com GrGlyph* glyph = fPool.alloc(); 268d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com // expand bounds to hold full distance field data 2694362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // + room for bilerp 2704362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org int pad = DISTANCE_FIELD_RANGE+1; 271d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if (fUseDistanceField) { 2724362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org bounds.fLeft -= pad; 2734362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org bounds.fRight += pad; 2744362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org bounds.fTop -= pad; 2754362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org bounds.fBottom += pad; 276d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 277ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com glyph->init(packed, bounds); 278ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache.insert(packed, glyph); 279ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return glyph; 280ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 281ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 282c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgvoid GrTextStrike::removePlot(const GrPlot* plot) { 283c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org SkTDArray<GrGlyph*>& glyphArray = fCache.getArray(); 284c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org for (int i = 0; i < glyphArray.count(); ++i) { 285c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org if (plot == glyphArray[i]->fPlot) { 286c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org glyphArray[i]->fPlot = NULL; 287c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org } 288c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org } 289c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org 290c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org fAtlasMgr->removePlot(&fAtlas, plot); 29167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org} 29267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org 293d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 294c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgbool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) { 2950ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0 // testing hack to force us to flush our cache often 2960ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com static int gCounter; 2970ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com if ((++gCounter % 10) == 0) return false; 2980ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif 2990ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com 300f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(glyph); 301f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(scaler); 302f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fCache.contains(glyph)); 30349e80830e9c633dcb8e7596bda17ea004ae48bd4commit-bot@chromium.org SkASSERT(NULL == glyph->fPlot); 304ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 305a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkAutoRef ar(scaler); 30698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 30798539c607b05f7e25406ae873bf1b24154a36a6freed@google.com int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 308d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 309d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrPlot* plot; 310d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if (fUseDistanceField) { 311d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com // we've already expanded the glyph dimensions to match the final size 312d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com // but must shrink back down to get the packed glyph data 313d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com int dfWidth = glyph->width(); 314d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com int dfHeight = glyph->height(); 3154362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org int pad = DISTANCE_FIELD_RANGE+1; 3164362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org int width = dfWidth - 2*pad; 3174362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org int height = dfHeight - 2*pad; 3188065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org int stride = width*bytesPerPixel; 319d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 320d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com size_t size = width * height * bytesPerPixel; 321d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkAutoSMalloc<1024> storage(size); 322d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride, storage.get())) { 323d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com return false; 324d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 325d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 326d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com // alloc storage for distance field glyph 327d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com size_t dfSize = dfWidth * dfHeight * bytesPerPixel; 328d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkAutoSMalloc<1024> dfStorage(dfSize); 3290b70816eb157ed6492623eea1e55005ef40c908cskia.committer@gmail.com 3308065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org if (1 == bytesPerPixel) { 3318065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org (void) SkGenerateDistanceFieldFromImage((unsigned char*)dfStorage.get(), 3328065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org (unsigned char*)storage.get(), 3338065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org width, height, DISTANCE_FIELD_RANGE); 3348065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org } else { 3358065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org // TODO: Fix color emoji 3368065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org // for now, copy glyph into distance field storage 3378065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org // this is not correct, but it won't crash 3388065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org sk_bzero(dfStorage.get(), dfSize); 3398065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org unsigned char* ptr = (unsigned char*) storage.get(); 3408065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org unsigned char* dfPtr = (unsigned char*) dfStorage.get(); 3418065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org size_t dfStride = dfWidth*bytesPerPixel; 3428065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org dfPtr += DISTANCE_FIELD_RANGE*dfStride; 3438065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org dfPtr += DISTANCE_FIELD_RANGE*bytesPerPixel; 3448065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org 3458065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org for (int i = 0; i < height; ++i) { 3468065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org memcpy(dfPtr, ptr, stride); 3478065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org 3488065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org dfPtr += dfStride; 3498065ec50f1937c1562810bfe2b216abfb98362b3commit-bot@chromium.org ptr += stride; 350d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 351d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 35211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com 353d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com // copy to atlas 35411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get(), 355d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com &glyph->fAtlasLocation); 356d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 357d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } else { 358d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com size_t size = glyph->fBounds.area() * bytesPerPixel; 359d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkAutoSMalloc<1024> storage(size); 360d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), 361d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com glyph->height(), 362d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com glyph->width() * bytesPerPixel, 363d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com storage.get())) { 364d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com return false; 365d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 366d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 36711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), 36811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com glyph->height(), storage.get(), 369d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com &glyph->fAtlasLocation); 370ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3727d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org if (NULL == plot) { 373ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 374ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 375ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3767d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org glyph->fPlot = plot; 377ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return true; 378ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 379