Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e25e38e authored by Romain Guy's avatar Romain Guy
Browse files

Add a new method for text gamma correction

To select the gamma correction method, adb shell setprop hwui.text_gamma_correction
with one of the following values:

lookup3
lookup
shader3
shader

See Properties.h for more information about these different methods.
You can also control gamma correction using the following properties:

hwui.text_gamma
hwui.text_gamma.black_threshold
hwui.text_gamma.white_threshold

Change-Id: I47970b804d2c590c37d3da5008db094241579e25
parent accf721e
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -65,9 +65,6 @@
// Turn on to enable additional debugging in the font renderers
#define DEBUG_FONT_RENDERER 0

// Force gamma correction in shaders
#define DEBUG_FONT_RENDERER_FORCE_SHADER_GAMMA 0

// Turn on to dump display list state
#define DEBUG_DISPLAY_LIST 0

+43 −21
Original line number Diff line number Diff line
@@ -43,16 +43,16 @@ GammaFontRenderer* GammaFontRenderer::createRenderer() {
    // Choose the best renderer
    char property[PROPERTY_VALUE_MAX];
    if (property_get(PROPERTY_TEXT_GAMMA_SHADER, property, DEFAULT_TEXT_GAMMA_SHADER) > 0) {
        if (!strcasecmp(property, "true")) {
            return new ShaderGammaFontRenderer();
        if (!strcasecmp(property, "shader")) {
            return new ShaderGammaFontRenderer(false);
        } else if (!strcasecmp(property, "shader3")) {
            return new ShaderGammaFontRenderer(true);
        } else if (!strcasecmp(property, "lookup")) {
            return new LookupGammaFontRenderer();
        }
    }

#if DEBUG_FONT_RENDERER_FORCE_SHADER_GAMMA
    return new ShaderGammaFontRenderer();
#else
    return new LookupGammaFontRenderer();
#endif
    return new Lookup3GammaFontRenderer();
}

GammaFontRenderer::GammaFontRenderer() {
@@ -96,14 +96,16 @@ GammaFontRenderer::~GammaFontRenderer() {
// Shader-based renderer
///////////////////////////////////////////////////////////////////////////////

ShaderGammaFontRenderer::ShaderGammaFontRenderer(): GammaFontRenderer() {
ShaderGammaFontRenderer::ShaderGammaFontRenderer(bool multiGamma): GammaFontRenderer() {
    INIT_LOGD("Creating shader gamma font renderer");
    mRenderer = NULL;
    mMultiGamma = multiGamma;
}

void ShaderGammaFontRenderer::describe(ProgramDescription& description,
        const SkPaint* paint) const {
    if (paint->getShader() == NULL) {
        if (mMultiGamma) {
            const int l = luminance(paint);

            if (l <= mBlackThreshold) {
@@ -113,6 +115,10 @@ void ShaderGammaFontRenderer::describe(ProgramDescription& description,
                description.hasGammaCorrection = true;
                description.gamma = 1.0f / mGamma;
            }
        } else {
            description.hasGammaCorrection = true;
            description.gamma = 1.0f / mGamma;
        }
    }
}

@@ -130,17 +136,33 @@ void ShaderGammaFontRenderer::setupProgram(ProgramDescription& description,
LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() {
    INIT_LOGD("Creating lookup gamma font renderer");

    // Compute the gamma tables
    const float gamma = 1.0f / mGamma;

    for (uint32_t i = 0; i <= 255; i++) {
        mGammaTable[i] = uint8_t((float)::floor(pow(i / 255.0f, gamma) * 255.0f + 0.5f));
    }

    mRenderer = NULL;
}

///////////////////////////////////////////////////////////////////////////////
// Lookup-based renderer, using 3 different correction tables
///////////////////////////////////////////////////////////////////////////////

Lookup3GammaFontRenderer::Lookup3GammaFontRenderer(): GammaFontRenderer() {
    INIT_LOGD("Creating lookup3 gamma font renderer");

    // Compute the gamma tables
    const float blackGamma = mGamma;
    const float whiteGamma = 1.0f / mGamma;

    for (uint32_t i = 0; i <= 255; i++) {
        mGammaTable[i] = i;

        const float v = i / 255.0f;
        const float black = pow(v, blackGamma);
        const float white = pow(v, whiteGamma);

        mGammaTable[i] = i;
        mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
        mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
    }
@@ -149,20 +171,20 @@ LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() {
    memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
}

LookupGammaFontRenderer::~LookupGammaFontRenderer() {
Lookup3GammaFontRenderer::~Lookup3GammaFontRenderer() {
    for (int i = 0; i < kGammaCount; i++) {
        delete mRenderers[i];
    }
}

void LookupGammaFontRenderer::clear() {
void Lookup3GammaFontRenderer::clear() {
    for (int i = 0; i < kGammaCount; i++) {
        delete mRenderers[i];
        mRenderers[i] = NULL;
    }
}

void LookupGammaFontRenderer::flush() {
void Lookup3GammaFontRenderer::flush() {
    int count = 0;
    int min = -1;
    uint32_t minCount = UINT_MAX;
@@ -190,7 +212,7 @@ void LookupGammaFontRenderer::flush() {
    }
}

FontRenderer* LookupGammaFontRenderer::getRenderer(Gamma gamma) {
FontRenderer* Lookup3GammaFontRenderer::getRenderer(Gamma gamma) {
    FontRenderer* renderer = mRenderers[gamma];
    if (!renderer) {
        renderer = new FontRenderer();
@@ -201,7 +223,7 @@ FontRenderer* LookupGammaFontRenderer::getRenderer(Gamma gamma) {
    return renderer;
}

FontRenderer& LookupGammaFontRenderer::getFontRenderer(const SkPaint* paint) {
FontRenderer& Lookup3GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
    if (paint->getShader() == NULL) {
        const int l = luminance(paint);

+52 −4
Original line number Diff line number Diff line
@@ -79,23 +79,71 @@ public:
    }

    uint32_t getFontRendererSize(uint32_t fontRenderer) const {
        return mRenderer->getCacheSize();
        return mRenderer ? mRenderer->getCacheSize() : 0;
    }

    void describe(ProgramDescription& description, const SkPaint* paint) const;
    void setupProgram(ProgramDescription& description, Program* program) const;

private:
    ShaderGammaFontRenderer();
    ShaderGammaFontRenderer(bool multiGamma);

    FontRenderer* mRenderer;
    bool mMultiGamma;

    friend class GammaFontRenderer;
};

class LookupGammaFontRenderer: public GammaFontRenderer {
public:
    ~LookupGammaFontRenderer();
    ~LookupGammaFontRenderer() {
        delete mRenderer;
    }

    void clear() {
        delete mRenderer;
    }

    void flush() {
        if (mRenderer) {
            mRenderer->flushLargeCaches();
        }
    }

    FontRenderer& getFontRenderer(const SkPaint* paint) {
        if (!mRenderer) {
            mRenderer = new FontRenderer;
            mRenderer->setGammaTable(&mGammaTable[0]);
        }
        return *mRenderer;
    }

    uint32_t getFontRendererCount() const {
        return 1;
    }

    uint32_t getFontRendererSize(uint32_t fontRenderer) const {
        return mRenderer ? mRenderer->getCacheSize() : 0;
    }

    void describe(ProgramDescription& description, const SkPaint* paint) const {
    }

    void setupProgram(ProgramDescription& description, Program* program) const {
    }

private:
    LookupGammaFontRenderer();

    FontRenderer* mRenderer;
    uint8_t mGammaTable[256];

    friend class GammaFontRenderer;
};

class Lookup3GammaFontRenderer: public GammaFontRenderer {
public:
    ~Lookup3GammaFontRenderer();

    void clear();
    void flush();
@@ -122,7 +170,7 @@ public:
    }

private:
    LookupGammaFontRenderer();
    Lookup3GammaFontRenderer();

    enum Gamma {
        kGammaDefault = 0,
+20 −5
Original line number Diff line number Diff line
@@ -74,13 +74,28 @@ enum DebugLevel {
#define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"

// Indicates whether gamma correction should be applied in the shaders
// or in lookup tables. Accepted values: true, false
#define PROPERTY_TEXT_GAMMA_SHADER "ro.hwui.text_gamma_shader"
// or in lookup tables. Accepted values:
//
//     - "lookup3", correction based on lookup tables. Gamma correction
//        is different for black and white text (see thresholds below)
//
//     - "lookup", correction based on a single lookup table
//
//     - "shader3", correction applied by a GLSL shader. Gamma correction
//        is different for black and white text (see thresholds below)
//
//     - "shader", correction applied by a GLSL shader
//
// See PROPERTY_TEXT_GAMMA, PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD and
// PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD for more control.
#define PROPERTY_TEXT_GAMMA_SHADER "hwui.text_gamma_correction"

// 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"
#define PROPERTY_TEXT_GAMMA "hwui.text_gamma"
// Luminance threshold below which black gamma correction is applied. Range: [0..255]
#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "hwui.text_gamma.black_threshold"
// Lumincance threshold above which white gamma correction is applied. Range: [0..255]
#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "hwui.text_gamma.white_threshold"

// Converts a number of mega-bytes into bytes
#define MB(s) s * 1024 * 1024