blob: 75d5b10046ad3a41fa7d238ee3a38a222f7395b9 [file] [log] [blame]
Romain Guyb45c0c92010-08-26 20:35:23 -07001/*
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
Romain Guyc9855a52011-01-21 21:14:15 -080019#include "Debug.h"
Romain Guyb45c0c92010-08-26 20:35:23 -070020#include "GammaFontRenderer.h"
21#include "Properties.h"
22
23namespace android {
24namespace uirenderer {
25
26///////////////////////////////////////////////////////////////////////////////
Romain Guyb1d0a4e2012-07-13 18:25:35 -070027// Base class GammaFontRenderer
Romain Guyb45c0c92010-08-26 20:35:23 -070028///////////////////////////////////////////////////////////////////////////////
29
Romain Guyb1d0a4e2012-07-13 18:25:35 -070030GammaFontRenderer* GammaFontRenderer::createRenderer() {
31 // Choose the best renderer
32 char property[PROPERTY_VALUE_MAX];
33 if (property_get(PROPERTY_TEXT_GAMMA_SHADER, property, DEFAULT_TEXT_GAMMA_SHADER) > 0) {
34 if (!strcasecmp(property, "true")) {
35 return new ShaderGammaFontRenderer();
36 }
37 }
Romain Guyb45c0c92010-08-26 20:35:23 -070038
Romain Guyb1d0a4e2012-07-13 18:25:35 -070039 return new LookupGammaFontRenderer();
40}
41
42GammaFontRenderer::GammaFontRenderer() {
Romain Guyb45c0c92010-08-26 20:35:23 -070043 // Get the renderer properties
44 char property[PROPERTY_VALUE_MAX];
45
46 // Get the gamma
Romain Guyb1d0a4e2012-07-13 18:25:35 -070047 mGamma = DEFAULT_TEXT_GAMMA;
Romain Guyb45c0c92010-08-26 20:35:23 -070048 if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
Romain Guyc9855a52011-01-21 21:14:15 -080049 INIT_LOGD(" Setting text gamma to %s", property);
Romain Guyb1d0a4e2012-07-13 18:25:35 -070050 mGamma = atof(property);
Romain Guyb45c0c92010-08-26 20:35:23 -070051 } else {
Romain Guyc9855a52011-01-21 21:14:15 -080052 INIT_LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
Romain Guyb45c0c92010-08-26 20:35:23 -070053 }
54
55 // Get the black gamma threshold
56 mBlackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
57 if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
Romain Guyc9855a52011-01-21 21:14:15 -080058 INIT_LOGD(" Setting text black gamma threshold to %s", property);
Romain Guyb45c0c92010-08-26 20:35:23 -070059 mBlackThreshold = atoi(property);
60 } else {
Romain Guyc9855a52011-01-21 21:14:15 -080061 INIT_LOGD(" Using default text black gamma threshold of %d",
Romain Guyb45c0c92010-08-26 20:35:23 -070062 DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD);
63 }
64
65 // Get the white gamma threshold
66 mWhiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
67 if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
Romain Guyc9855a52011-01-21 21:14:15 -080068 INIT_LOGD(" Setting text white gamma threshold to %s", property);
Romain Guyb45c0c92010-08-26 20:35:23 -070069 mWhiteThreshold = atoi(property);
70 } else {
Romain Guyc9855a52011-01-21 21:14:15 -080071 INIT_LOGD(" Using default white black gamma threshold of %d",
Romain Guyb45c0c92010-08-26 20:35:23 -070072 DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
73 }
Romain Guyb1d0a4e2012-07-13 18:25:35 -070074}
75
76GammaFontRenderer::~GammaFontRenderer() {
77}
78
79///////////////////////////////////////////////////////////////////////////////
80// Shader-based renderer
81///////////////////////////////////////////////////////////////////////////////
82
83ShaderGammaFontRenderer::ShaderGammaFontRenderer(): GammaFontRenderer() {
84 INIT_LOGD("Creating shader gamma font renderer");
85}
86
87///////////////////////////////////////////////////////////////////////////////
88// Lookup-based renderer
89///////////////////////////////////////////////////////////////////////////////
90
91LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() {
92 INIT_LOGD("Creating lookup gamma font renderer");
Romain Guyb45c0c92010-08-26 20:35:23 -070093
94 // Compute the gamma tables
Romain Guyb1d0a4e2012-07-13 18:25:35 -070095 const float blackGamma = mGamma;
96 const float whiteGamma = 1.0f / mGamma;
Romain Guyb45c0c92010-08-26 20:35:23 -070097
98 for (uint32_t i = 0; i <= 255; i++) {
Romain Guyeca0ca22011-11-04 15:12:29 -070099 mGammaTable[i] = i;
Romain Guyb45c0c92010-08-26 20:35:23 -0700100
101 const float v = i / 255.0f;
102 const float black = pow(v, blackGamma);
103 const float white = pow(v, whiteGamma);
104
Romain Guyeca0ca22011-11-04 15:12:29 -0700105 mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
106 mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
Romain Guyb45c0c92010-08-26 20:35:23 -0700107 }
108
Romain Guyeca0ca22011-11-04 15:12:29 -0700109 memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount);
110 memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
111}
112
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700113LookupGammaFontRenderer::~LookupGammaFontRenderer() {
Romain Guyeca0ca22011-11-04 15:12:29 -0700114 for (int i = 0; i < kGammaCount; i++) {
115 delete mRenderers[i];
116 }
117}
118
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700119void LookupGammaFontRenderer::clear() {
Romain Guyeca0ca22011-11-04 15:12:29 -0700120 for (int i = 0; i < kGammaCount; i++) {
121 delete mRenderers[i];
122 mRenderers[i] = NULL;
123 }
124}
125
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700126void LookupGammaFontRenderer::flush() {
Romain Guyeca0ca22011-11-04 15:12:29 -0700127 int count = 0;
128 int min = -1;
129 uint32_t minCount = UINT_MAX;
130
131 for (int i = 0; i < kGammaCount; i++) {
132 if (mRenderers[i]) {
133 count++;
134 if (mRenderersUsageCount[i] < minCount) {
135 minCount = mRenderersUsageCount[i];
136 min = i;
137 }
138 }
139 }
140
141 if (count <= 1 || min < 0) return;
142
143 delete mRenderers[min];
144 mRenderers[min] = NULL;
Chet Haase9a824562011-12-16 15:44:59 -0800145
146 // Also eliminate the caches for large glyphs, as they consume significant memory
147 for (int i = 0; i < kGammaCount; ++i) {
148 if (mRenderers[i]) {
149 mRenderers[i]->flushLargeCaches();
150 }
151 }
Romain Guyeca0ca22011-11-04 15:12:29 -0700152}
153
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700154FontRenderer* LookupGammaFontRenderer::getRenderer(Gamma gamma) {
Romain Guyeca0ca22011-11-04 15:12:29 -0700155 FontRenderer* renderer = mRenderers[gamma];
156 if (!renderer) {
157 renderer = new FontRenderer();
158 mRenderers[gamma] = renderer;
159 renderer->setGammaTable(&mGammaTable[gamma * 256]);
160 }
161 mRenderersUsageCount[gamma]++;
162 return renderer;
Romain Guyb45c0c92010-08-26 20:35:23 -0700163}
164
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700165FontRenderer& LookupGammaFontRenderer::getFontRenderer(const SkPaint* paint) {
Romain Guyb45c0c92010-08-26 20:35:23 -0700166 if (paint->getShader() == NULL) {
167 uint32_t c = paint->getColor();
168 const int r = (c >> 16) & 0xFF;
169 const int g = (c >> 8) & 0xFF;
170 const int b = (c ) & 0xFF;
171 const int luminance = (r * 2 + g * 5 + b) >> 3;
172
173 if (luminance <= mBlackThreshold) {
Romain Guyeca0ca22011-11-04 15:12:29 -0700174 return *getRenderer(kGammaBlack);
Romain Guyb45c0c92010-08-26 20:35:23 -0700175 } else if (luminance >= mWhiteThreshold) {
Romain Guyeca0ca22011-11-04 15:12:29 -0700176 return *getRenderer(kGammaWhite);
Romain Guyb45c0c92010-08-26 20:35:23 -0700177 }
178 }
Romain Guyeca0ca22011-11-04 15:12:29 -0700179 return *getRenderer(kGammaDefault);
Romain Guyb45c0c92010-08-26 20:35:23 -0700180}
181
182}; // namespace uirenderer
183}; // namespace android