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 23 namespace android { 24 namespace uirenderer { 25 26 /////////////////////////////////////////////////////////////////////////////// 27 // Constructors/destructor 28 /////////////////////////////////////////////////////////////////////////////// 29 30 GammaFontRenderer::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 84 GammaFontRenderer::~GammaFontRenderer() { 85 for (int i = 0; i < kGammaCount; i++) { 86 delete mRenderers[i]; 87 } 88 } 89 90 void GammaFontRenderer::clear() { 91 for (int i = 0; i < kGammaCount; i++) { 92 delete mRenderers[i]; 93 mRenderers[i] = NULL; 94 } 95 } 96 97 void 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 118 FontRenderer* GammaFontRenderer::getRenderer(Gamma gamma) { 119 FontRenderer* renderer = mRenderers[gamma]; 120 if (!renderer) { 121 renderer = new FontRenderer(); 122 mRenderers[gamma] = renderer; 123 renderer->setGammaTable(&mGammaTable[gamma * 256]); 124 } 125 mRenderersUsageCount[gamma]++; 126 return renderer; 127 } 128 129 FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) { 130 if (paint->getShader() == NULL) { 131 uint32_t c = paint->getColor(); 132 const int r = (c >> 16) & 0xFF; 133 const int g = (c >> 8) & 0xFF; 134 const int b = (c ) & 0xFF; 135 const int luminance = (r * 2 + g * 5 + b) >> 3; 136 137 if (luminance <= mBlackThreshold) { 138 return *getRenderer(kGammaBlack); 139 } else if (luminance >= mWhiteThreshold) { 140 return *getRenderer(kGammaWhite); 141 } 142 } 143 return *getRenderer(kGammaDefault); 144 } 145 146 }; // namespace uirenderer 147 }; // namespace android 148