1b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy/*
2b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * Copyright (C) 2010 The Android Open Source Project
3b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy *
4b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * you may not use this file except in compliance with the License.
6b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * You may obtain a copy of the License at
7b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy *
8b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy *
10b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * Unless required by applicable law or agreed to in writing, software
11b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * See the License for the specific language governing permissions and
14b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy * limitations under the License.
15b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy */
16b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
17b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy#define LOG_TAG "OpenGLRenderer"
18b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
19c9855a53edfac818dc68714557185977556f849dRomain Guy#include "Debug.h"
20b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy#include "GammaFontRenderer.h"
21b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy#include "Properties.h"
22b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
23b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guynamespace android {
24b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guynamespace uirenderer {
25b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
26b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy///////////////////////////////////////////////////////////////////////////////
274121063313ac0d6f69f6253cac821d0c1c122086Romain Guy// Utils
284121063313ac0d6f69f6253cac821d0c1c122086Romain Guy///////////////////////////////////////////////////////////////////////////////
294121063313ac0d6f69f6253cac821d0c1c122086Romain Guy
304121063313ac0d6f69f6253cac821d0c1c122086Romain Guystatic int luminance(const SkPaint* paint) {
314121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    uint32_t c = paint->getColor();
324121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    const int r = (c >> 16) & 0xFF;
334121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    const int g = (c >>  8) & 0xFF;
344121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    const int b = (c      ) & 0xFF;
354121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    return (r * 2 + g * 5 + b) >> 3;
364121063313ac0d6f69f6253cac821d0c1c122086Romain Guy}
374121063313ac0d6f69f6253cac821d0c1c122086Romain Guy
384121063313ac0d6f69f6253cac821d0c1c122086Romain Guy///////////////////////////////////////////////////////////////////////////////
39b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy// Base class GammaFontRenderer
40b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy///////////////////////////////////////////////////////////////////////////////
41b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
42b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain GuyGammaFontRenderer* GammaFontRenderer::createRenderer() {
43b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    // Choose the best renderer
44b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    char property[PROPERTY_VALUE_MAX];
45dfab50d8b97a90dca279b119ebe439f595616ffaRomain Guy    if (property_get(PROPERTY_TEXT_GAMMA_METHOD, property, DEFAULT_TEXT_GAMMA_METHOD) > 0) {
46dfab50d8b97a90dca279b119ebe439f595616ffaRomain Guy        if (!strcasecmp(property, "lookup")) {
47dfab50d8b97a90dca279b119ebe439f595616ffaRomain Guy            return new LookupGammaFontRenderer();
48dfab50d8b97a90dca279b119ebe439f595616ffaRomain Guy        } else if (!strcasecmp(property, "shader")) {
496e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            return new ShaderGammaFontRenderer(false);
506e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy        } else if (!strcasecmp(property, "shader3")) {
516e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            return new ShaderGammaFontRenderer(true);
52b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy        }
53b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    }
54b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
556e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    return new Lookup3GammaFontRenderer();
56b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy}
57b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
58b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain GuyGammaFontRenderer::GammaFontRenderer() {
59b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    // Get the renderer properties
60b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    char property[PROPERTY_VALUE_MAX];
61b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
62b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    // Get the gamma
63b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    mGamma = DEFAULT_TEXT_GAMMA;
64b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
65c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Setting text gamma to %s", property);
66b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy        mGamma = atof(property);
67b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    } else {
68c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
69b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    }
70b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
71b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    // Get the black gamma threshold
72b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    mBlackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
73b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
74c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Setting text black gamma threshold to %s", property);
75b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        mBlackThreshold = atoi(property);
76b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    } else {
77c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Using default text black gamma threshold of %d",
78b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy                DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD);
79b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    }
80b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
81b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    // Get the white gamma threshold
82b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    mWhiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
83b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
84c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Setting text white gamma threshold to %s", property);
85b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        mWhiteThreshold = atoi(property);
86b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    } else {
87c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Using default white black gamma threshold of %d",
88b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy                DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
89b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    }
90b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy}
91b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
92b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain GuyGammaFontRenderer::~GammaFontRenderer() {
93b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy}
94b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
95b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy///////////////////////////////////////////////////////////////////////////////
96b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy// Shader-based renderer
97b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy///////////////////////////////////////////////////////////////////////////////
98b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
996e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain GuyShaderGammaFontRenderer::ShaderGammaFontRenderer(bool multiGamma): GammaFontRenderer() {
100b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    INIT_LOGD("Creating shader gamma font renderer");
1014121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    mRenderer = NULL;
1026e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    mMultiGamma = multiGamma;
1034121063313ac0d6f69f6253cac821d0c1c122086Romain Guy}
1044121063313ac0d6f69f6253cac821d0c1c122086Romain Guy
1054121063313ac0d6f69f6253cac821d0c1c122086Romain Guyvoid ShaderGammaFontRenderer::describe(ProgramDescription& description,
1064121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        const SkPaint* paint) const {
1074121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    if (paint->getShader() == NULL) {
1086e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy        if (mMultiGamma) {
1096e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            const int l = luminance(paint);
1106e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
1116e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            if (l <= mBlackThreshold) {
1126e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy                description.hasGammaCorrection = true;
1136e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy                description.gamma = mGamma;
1146e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            } else if (l >= mWhiteThreshold) {
1156e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy                description.hasGammaCorrection = true;
1166e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy                description.gamma = 1.0f / mGamma;
1176e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy            }
1186e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy        } else {
1194121063313ac0d6f69f6253cac821d0c1c122086Romain Guy            description.hasGammaCorrection = true;
1204121063313ac0d6f69f6253cac821d0c1c122086Romain Guy            description.gamma = 1.0f / mGamma;
1214121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        }
1224121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    }
1234121063313ac0d6f69f6253cac821d0c1c122086Romain Guy}
1244121063313ac0d6f69f6253cac821d0c1c122086Romain Guy
1254121063313ac0d6f69f6253cac821d0c1c122086Romain Guyvoid ShaderGammaFontRenderer::setupProgram(ProgramDescription& description,
1264121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        Program* program) const {
1274121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    if (description.hasGammaCorrection) {
1284121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        glUniform1f(program->getUniform("gamma"), description.gamma);
1294121063313ac0d6f69f6253cac821d0c1c122086Romain Guy    }
130b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy}
131b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
132cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid ShaderGammaFontRenderer::endPrecaching() {
133cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mRenderer) {
134cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mRenderer->endPrecaching();
135cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
136cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
137cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
138b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy///////////////////////////////////////////////////////////////////////////////
139b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy// Lookup-based renderer
140b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy///////////////////////////////////////////////////////////////////////////////
141b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
142b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain GuyLookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() {
143b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    INIT_LOGD("Creating lookup gamma font renderer");
144b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
145b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    // Compute the gamma tables
1466e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    const float gamma = 1.0f / mGamma;
1476e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
1486e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    for (uint32_t i = 0; i <= 255; i++) {
1496e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy        mGammaTable[i] = uint8_t((float)::floor(pow(i / 255.0f, gamma) * 255.0f + 0.5f));
1506e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    }
1516e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
1526e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    mRenderer = NULL;
1536e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy}
1546e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
155cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid LookupGammaFontRenderer::endPrecaching() {
156cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mRenderer) {
157cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mRenderer->endPrecaching();
158cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
159cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
160cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
1616e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy///////////////////////////////////////////////////////////////////////////////
1626e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy// Lookup-based renderer, using 3 different correction tables
1636e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy///////////////////////////////////////////////////////////////////////////////
1646e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
1656e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain GuyLookup3GammaFontRenderer::Lookup3GammaFontRenderer(): GammaFontRenderer() {
1666e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    INIT_LOGD("Creating lookup3 gamma font renderer");
1676e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy
1686e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy    // Compute the gamma tables
169b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    const float blackGamma = mGamma;
170b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    const float whiteGamma = 1.0f / mGamma;
171b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
172b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    for (uint32_t i = 0; i <= 255; i++) {
173b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        const float v = i / 255.0f;
174b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        const float black = pow(v, blackGamma);
175b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        const float white = pow(v, whiteGamma);
176b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
1776e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guy        mGammaTable[i] = i;
178eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
179eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
180b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    }
181b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
182eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount);
183eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
184eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy}
185eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
1866e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain GuyLookup3GammaFontRenderer::~Lookup3GammaFontRenderer() {
187eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    for (int i = 0; i < kGammaCount; i++) {
188eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        delete mRenderers[i];
189eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    }
190eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy}
191eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
192cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guyvoid Lookup3GammaFontRenderer::endPrecaching() {
193cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    for (int i = 0; i < kGammaCount; i++) {
194cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        if (mRenderers[i]) {
195cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy            mRenderers[i]->endPrecaching();
196cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        }
197cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
198cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
199cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
2006e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guyvoid Lookup3GammaFontRenderer::clear() {
201eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    for (int i = 0; i < kGammaCount; i++) {
202eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        delete mRenderers[i];
203eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        mRenderers[i] = NULL;
204eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    }
205eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy}
206eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
2076e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain Guyvoid Lookup3GammaFontRenderer::flush() {
208eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    int count = 0;
209eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    int min = -1;
210eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    uint32_t minCount = UINT_MAX;
211eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
212eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    for (int i = 0; i < kGammaCount; i++) {
213eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        if (mRenderers[i]) {
214eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            count++;
215eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            if (mRenderersUsageCount[i] < minCount) {
216eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy                minCount = mRenderersUsageCount[i];
217eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy                min = i;
218eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            }
219eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        }
220eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    }
221eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
222eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    if (count <= 1 || min < 0) return;
223eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
224eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    delete mRenderers[min];
225eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    mRenderers[min] = NULL;
2269a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase
2279a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase    // Also eliminate the caches for large glyphs, as they consume significant memory
2289a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase    for (int i = 0; i < kGammaCount; ++i) {
2299a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase        if (mRenderers[i]) {
2309a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase            mRenderers[i]->flushLargeCaches();
2319a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase        }
2329a8245629d69d81e0b62e52970feaf9c02580e75Chet Haase    }
233eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy}
234eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy
2356e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain GuyFontRenderer* Lookup3GammaFontRenderer::getRenderer(Gamma gamma) {
236eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    FontRenderer* renderer = mRenderers[gamma];
237eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    if (!renderer) {
238eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        renderer = new FontRenderer();
239eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        mRenderers[gamma] = renderer;
240eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy        renderer->setGammaTable(&mGammaTable[gamma * 256]);
241eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    }
242eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    mRenderersUsageCount[gamma]++;
243eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    return renderer;
244b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy}
245b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
2466e25e38e43f9e7f71397dfab7ed32c81c7bf7d46Romain GuyFontRenderer& Lookup3GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
247b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    if (paint->getShader() == NULL) {
2484121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        const int l = luminance(paint);
249b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
2504121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        if (l <= mBlackThreshold) {
251eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            return *getRenderer(kGammaBlack);
2524121063313ac0d6f69f6253cac821d0c1c122086Romain Guy        } else if (l >= mWhiteThreshold) {
253eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            return *getRenderer(kGammaWhite);
254b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy        }
255b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy    }
256eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy    return *getRenderer(kGammaDefault);
257b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy}
258b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy
259b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy}; // namespace uirenderer
260b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy}; // namespace android
261