diff options
author | Romain Guy <romainguy@google.com> | 2010-08-26 20:35:23 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-08-27 11:31:24 -0700 |
commit | b45c0c9774bd19a9dbe77d149abae4e124b08bf6 (patch) | |
tree | 809e63c596802906242c982ed67f463481b57230 | |
parent | c70bd1921bbc4046d0caf84959e5f1c2d526769a (diff) | |
download | frameworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.zip frameworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.tar.gz frameworks_base-b45c0c9774bd19a9dbe77d149abae4e124b08bf6.tar.bz2 |
Apply gamma correction to font rendering.
Change-Id: I1b05f40e356221b2a5eb9400e67d77ecd98ed6c4
-rw-r--r-- | libs/hwui/Android.mk | 1 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 5 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 9 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.h | 6 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.cpp | 103 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.h | 48 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 9 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 1 |
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 { |