summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2010-08-26 20:35:23 -0700
committerRomain Guy <romainguy@google.com>2010-08-27 11:31:24 -0700
commitb45c0c9774bd19a9dbe77d149abae4e124b08bf6 (patch)
tree809e63c596802906242c982ed67f463481b57230 /libs
parentc70bd1921bbc4046d0caf84959e5f1c2d526769a (diff)
downloadframeworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.zip
frameworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.tar.gz
frameworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.tar.bz2
Apply gamma correction to font rendering.
Change-Id: I1b05f40e356221b2a5eb9400e67d77ecd98ed6c4
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Caches.h5
-rw-r--r--libs/hwui/FontRenderer.cpp9
-rw-r--r--libs/hwui/FontRenderer.h6
-rw-r--r--libs/hwui/GammaFontRenderer.cpp103
-rw-r--r--libs/hwui/GammaFontRenderer.h48
-rw-r--r--libs/hwui/OpenGLRenderer.cpp8
-rw-r--r--libs/hwui/Properties.h9
-rw-r--r--libs/hwui/TextDropShadowCache.cpp1
9 files changed, 180 insertions, 10 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 8ed3d7b..0469508 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -6,6 +6,7 @@ include $(CLEAR_VARS)
ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SRC_FILES:= \
FontRenderer.cpp \
+ GammaFontRenderer.cpp \
GradientCache.cpp \
LayerCache.cpp \
Matrix.cpp \
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 151e29f..fda57b8 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -25,7 +25,7 @@
#include "LayerCache.h"
#include "GradientCache.h"
#include "PatchCache.h"
-#include "FontRenderer.h"
+#include "GammaFontRenderer.h"
#include "ProgramCache.h"
#include "PathCache.h"
#include "TextDropShadowCache.h"
@@ -42,7 +42,6 @@ struct CacheLogger {
class Caches: public Singleton<Caches> {
Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO),
lastDstMode(GL_ZERO), currentProgram(NULL) {
- dropShadowCache.setFontRenderer(fontRenderer);
}
friend class Singleton<Caches>;
@@ -62,7 +61,7 @@ public:
PathCache pathCache;
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
- FontRenderer fontRenderer;
+ GammaFontRenderer fontRenderer;
}; // class Caches
}; // namespace uirenderer
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index ccc92eb..5d7f8bf 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -101,8 +101,8 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y) {
nPenX, nPenY - height, 0, u1, v1);
}
-void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
- uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
+void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
+ uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH) {
int nPenX = x + glyph->mBitmapLeft;
int nPenY = y + glyph->mBitmapTop;
@@ -116,7 +116,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
int32_t bX = 0, bY = 0;
for (cacheX = glyph->mStartX, bX = nPenX; cacheX < endX; cacheX++, bX++) {
for (cacheY = glyph->mStartY, bY = nPenY; cacheY < endY; cacheY++, bY++) {
- if (bX < 0 || bY < 0 || bX >= (int32_t)bitmapW || bY >= (int32_t)bitmapH) {
+ if (bX < 0 || bY < 0 || bX >= (int32_t) bitmapW || bY >= (int32_t) bitmapH) {
LOGE("Skipping invalid index");
continue;
}
@@ -286,6 +286,7 @@ Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize) {
FontRenderer::FontRenderer() {
LOGD("Creating FontRenderer");
+ mGammaTable = NULL;
mInitialized = false;
mMaxNumberOfQuads = 1024;
mCurrentQuadIndex = 0;
@@ -405,7 +406,7 @@ bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint3
for (cacheX = startX, bX = 0; cacheX < endX; cacheX++, bX++) {
for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY++) {
uint8_t tempCol = bitmapBuffer[bY * stride + bX];
- cacheBuffer[cacheY * cacheWidth + cacheX] = tempCol;
+ cacheBuffer[cacheY * cacheWidth + cacheX] = mGammaTable[tempCol];
}
}
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 96c92d5..a03ea92 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -124,6 +124,10 @@ public:
void init();
void deinit();
+ void setGammaTable(const uint8_t* gammaTable) {
+ mGammaTable = gammaTable;
+ }
+
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, int x, int y);
@@ -157,6 +161,8 @@ public:
protected:
friend class Font;
+ const uint8_t* mGammaTable;
+
struct CacheTextureLine {
uint16_t mMaxHeight;
uint16_t mMaxWidth;
diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp
new file mode 100644
index 0000000..6d087e3
--- /dev/null
+++ b/libs/hwui/GammaFontRenderer.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "GammaFontRenderer.h"
+#include "Properties.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+GammaFontRenderer::GammaFontRenderer() {
+ LOGD("Creating gamma font renderer");
+
+ // Get the renderer properties
+ char property[PROPERTY_VALUE_MAX];
+
+ // Get the gamma
+ float gamma = DEFAULT_TEXT_GAMMA;
+ if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
+ LOGD(" Setting text gamma to %s", property);
+ gamma = atof(property);
+ } else {
+ LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
+ }
+
+ // Get the black gamma threshold
+ mBlackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
+ if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
+ LOGD(" Setting text black gamma threshold to %s", property);
+ mBlackThreshold = atoi(property);
+ } else {
+ LOGD(" Using default text black gamma threshold of %d",
+ DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD);
+ }
+
+ // Get the white gamma threshold
+ mWhiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
+ if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
+ LOGD(" Setting text white gamma threshold to %s", property);
+ mWhiteThreshold = atoi(property);
+ } else {
+ LOGD(" Using default white black gamma threshold of %d",
+ DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
+ }
+
+ // Compute the gamma tables
+ const float blackGamma = gamma;
+ const float whiteGamma = 1.0f / gamma;
+
+ for (uint32_t i = 0; i <= 255; i++) {
+ mDefault[i] = i;
+
+ const float v = i / 255.0f;
+ const float black = pow(v, blackGamma);
+ const float white = pow(v, whiteGamma);
+
+ mBlackGamma[i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
+ mWhiteGamma[i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
+ }
+
+ // Configure the font renderers
+ mDefaultRenderer.setGammaTable(&mDefault[0]);
+ mBlackGammaRenderer.setGammaTable(&mBlackGamma[0]);
+ mWhiteGammaRenderer.setGammaTable(&mWhiteGamma[0]);
+}
+
+FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
+ if (paint->getShader() == NULL) {
+ uint32_t c = paint->getColor();
+ const int r = (c >> 16) & 0xFF;
+ const int g = (c >> 8) & 0xFF;
+ const int b = (c ) & 0xFF;
+ const int luminance = (r * 2 + g * 5 + b) >> 3;
+
+ if (luminance <= mBlackThreshold) {
+ return mBlackGammaRenderer;
+ } else if (luminance >= mWhiteThreshold) {
+ return mWhiteGammaRenderer;
+ }
+ }
+ return mDefaultRenderer;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
new file mode 100644
index 0000000..5fa45cf
--- /dev/null
+++ b/libs/hwui/GammaFontRenderer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_GAMMA_FONT_RENDERER_H
+#define ANDROID_UI_GAMMA_FONT_RENDERER_H
+
+#include <SkPaint.h>
+
+#include "FontRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+struct GammaFontRenderer {
+ GammaFontRenderer();
+
+ FontRenderer& getFontRenderer(const SkPaint* paint);
+
+private:
+ FontRenderer mDefaultRenderer;
+ FontRenderer mBlackGammaRenderer;
+ FontRenderer mWhiteGammaRenderer;
+
+ int mBlackThreshold;
+ int mWhiteThreshold;
+
+ uint8_t mDefault[256];
+ uint8_t mBlackGamma[256];
+ uint8_t mWhiteGamma[256];
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_GAMMA_FONT_RENDERER_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 033d8e2..4ce30b0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -544,10 +544,12 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f;
const GLfloat b = a * ((color ) & 0xFF) / 255.0f;
- mCaches.fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
+ FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
+ fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
paint->getTextSize());
if (mHasShadow) {
glActiveTexture(gTextureUnits[0]);
+ mCaches.dropShadowCache.setFontRenderer(fontRenderer);
const ShadowTexture* shadow = mCaches.dropShadowCache.get(paint, text, bytesCount,
count, mShadowRadius);
const AutoTexture autoCleanup(shadow);
@@ -562,11 +564,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
GLuint textureUnit = 0;
glActiveTexture(gTextureUnits[textureUnit]);
- setupTextureAlpha8(mCaches.fontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a,
+ setupTextureAlpha8(fontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a,
mode, false, true);
const Rect& clip = mSnapshot->getLocalClip();
- mCaches.fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
+ fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords"));
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index dfe022a..4e2f091 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -35,6 +35,11 @@
#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
#define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"
+// Gamma (>= 1.0, <= 10.0)
+#define PROPERTY_TEXT_GAMMA "ro.text_gamma"
+#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold"
+#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"
+
// Converts a number of mega-bytes into bytes
#define MB(s) s * 1024 * 1024
@@ -45,4 +50,8 @@
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
+#define DEFAULT_TEXT_GAMMA 1.4f
+#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
+#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192
+
#endif // ANDROID_UI_PROPERTIES_H
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index f95d2be..9d54277 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "OpenGLRenderer"
#include "TextDropShadowCache.h"
+#include "Properties.h"
namespace android {
namespace uirenderer {