GammaFontRenderer.cpp revision 9a8245629d69d81e0b62e52970feaf9c02580e75
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "OpenGLRenderer" 18 19#include "Debug.h" 20#include "GammaFontRenderer.h" 21#include "Properties.h" 22 23namespace android { 24namespace uirenderer { 25 26/////////////////////////////////////////////////////////////////////////////// 27// Constructors/destructor 28/////////////////////////////////////////////////////////////////////////////// 29 30GammaFontRenderer::GammaFontRenderer() { 31 INIT_LOGD("Creating gamma font renderer"); 32 33 // Get the renderer properties 34 char property[PROPERTY_VALUE_MAX]; 35 36 // Get the gamma 37 float gamma = DEFAULT_TEXT_GAMMA; 38 if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) { 39 INIT_LOGD(" Setting text gamma to %s", property); 40 gamma = atof(property); 41 } else { 42 INIT_LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA); 43 } 44 45 // Get the black gamma threshold 46 mBlackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD; 47 if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) { 48 INIT_LOGD(" Setting text black gamma threshold to %s", property); 49 mBlackThreshold = atoi(property); 50 } else { 51 INIT_LOGD(" Using default text black gamma threshold of %d", 52 DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD); 53 } 54 55 // Get the white gamma threshold 56 mWhiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD; 57 if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) { 58 INIT_LOGD(" Setting text white gamma threshold to %s", property); 59 mWhiteThreshold = atoi(property); 60 } else { 61 INIT_LOGD(" Using default white black gamma threshold of %d", 62 DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD); 63 } 64 65 // Compute the gamma tables 66 const float blackGamma = gamma; 67 const float whiteGamma = 1.0f / gamma; 68 69 for (uint32_t i = 0; i <= 255; i++) { 70 mGammaTable[i] = i; 71 72 const float v = i / 255.0f; 73 const float black = pow(v, blackGamma); 74 const float white = pow(v, whiteGamma); 75 76 mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f)); 77 mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f)); 78 } 79 80 memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount); 81 memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount); 82} 83 84GammaFontRenderer::~GammaFontRenderer() { 85 for (int i = 0; i < kGammaCount; i++) { 86 delete mRenderers[i]; 87 } 88} 89 90void GammaFontRenderer::clear() { 91 for (int i = 0; i < kGammaCount; i++) { 92 delete mRenderers[i]; 93 mRenderers[i] = NULL; 94 } 95} 96 97void GammaFontRenderer::flush() { 98 int count = 0; 99 int min = -1; 100 uint32_t minCount = UINT_MAX; 101 102 for (int i = 0; i < kGammaCount; i++) { 103 if (mRenderers[i]) { 104 count++; 105 if (mRenderersUsageCount[i] < minCount) { 106 minCount = mRenderersUsageCount[i]; 107 min = i; 108 } 109 } 110 } 111 112 if (count <= 1 || min < 0) return; 113 114 delete mRenderers[min]; 115 mRenderers[min] = NULL; 116 117 // Also eliminate the caches for large glyphs, as they consume significant memory 118 for (int i = 0; i < kGammaCount; ++i) { 119 if (mRenderers[i]) { 120 mRenderers[i]->flushLargeCaches(); 121 } 122 } 123} 124 125FontRenderer* GammaFontRenderer::getRenderer(Gamma gamma) { 126 FontRenderer* renderer = mRenderers[gamma]; 127 if (!renderer) { 128 renderer = new FontRenderer(); 129 mRenderers[gamma] = renderer; 130 renderer->setGammaTable(&mGammaTable[gamma * 256]); 131 } 132 mRenderersUsageCount[gamma]++; 133 return renderer; 134} 135 136FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) { 137 if (paint->getShader() == NULL) { 138 uint32_t c = paint->getColor(); 139 const int r = (c >> 16) & 0xFF; 140 const int g = (c >> 8) & 0xFF; 141 const int b = (c ) & 0xFF; 142 const int luminance = (r * 2 + g * 5 + b) >> 3; 143 144 if (luminance <= mBlackThreshold) { 145 return *getRenderer(kGammaBlack); 146 } else if (luminance >= mWhiteThreshold) { 147 return *getRenderer(kGammaWhite); 148 } 149 } 150 return *getRenderer(kGammaDefault); 151} 152 153}; // namespace uirenderer 154}; // namespace android 155