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

Commit b1d0a4ed authored by Romain Guy's avatar Romain Guy
Browse files

Refactor GammaFontRenderer

This change is the first step to a shader-based text antialias
gamma correction.

Change-Id: I9eb02d4c56cb95d05219f712290c865b46141954
parent dd0d0ba6
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ namespace uirenderer {

Caches::Caches(): Singleton<Caches>(), mInitialized(false) {
    init();
    initFont();
    initExtensions();
    initConstraints();

@@ -74,6 +75,7 @@ void Caches::init() {

    mTexCoordsArrayEnabled = false;

    glDisable(GL_SCISSOR_TEST);
    scissorEnabled = false;
    mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;

@@ -90,6 +92,10 @@ void Caches::init() {
    mInitialized = true;
}

void Caches::initFont() {
    fontRenderer = GammaFontRenderer::createRenderer();
}

void Caches::initExtensions() {
    if (extensions.hasDebugMarker()) {
        eventMark = glInsertEventMarkerEXT;
@@ -170,8 +176,8 @@ void Caches::dumpMemoryUsage(String8 &log) {
            arcShapeCache.getSize(), arcShapeCache.getMaxSize());
    log.appendFormat("  TextDropShadowCache  %8d / %8d\n", dropShadowCache.getSize(),
            dropShadowCache.getMaxSize());
    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
        const uint32_t size = fontRenderer.getFontRendererSize(i);
    for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
        const uint32_t size = fontRenderer->getFontRendererSize(i);
        log.appendFormat("  FontRenderer %d       %8d / %8d\n", i, size, size);
    }
    log.appendFormat("Other:\n");
@@ -191,8 +197,8 @@ void Caches::dumpMemoryUsage(String8 &log) {
    total += ovalShapeCache.getSize();
    total += rectShapeCache.getSize();
    total += arcShapeCache.getSize();
    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
        total += fontRenderer.getFontRendererSize(i);
    for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
        total += fontRenderer->getFontRendererSize(i);
    }

    log.appendFormat("Total memory usage:\n");
@@ -245,10 +251,10 @@ void Caches::flush(FlushMode mode) {
            patchCache.clear();
            dropShadowCache.clear();
            gradientCache.clear();
            fontRenderer.clear();
            fontRenderer->clear();
            // fall through
        case kFlushMode_Moderate:
            fontRenderer.flush();
            fontRenderer->flush();
            textureCache.flush();
            pathCache.clear();
            roundRectShapeCache.clear();
+3 −1
Original line number Diff line number Diff line
@@ -249,9 +249,10 @@ public:
    PatchCache patchCache;
    TextDropShadowCache dropShadowCache;
    FboCache fboCache;
    GammaFontRenderer fontRenderer;
    ResourceCache resourceCache;

    GammaFontRenderer* fontRenderer;

    // Debug methods
    PFNGLINSERTEVENTMARKEREXTPROC eventMark;
    PFNGLPUSHGROUPMARKEREXTPROC startMark;
@@ -261,6 +262,7 @@ public:
    PFNGLGETOBJECTLABELEXTPROC getLabel;

private:
    void initFont();
    void initExtensions();
    void initConstraints();

+13 −4
Original line number Diff line number Diff line
@@ -677,12 +677,21 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
    unsigned int stride = glyph.rowBytes();

    uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
    if (mGammaTable) {
        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] = mGammaTable[tempCol];
            }
        }
    } else {
        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;
            }
        }
    }

    cachedGlyph->mIsValid = true;
}
+41 −12
Original line number Diff line number Diff line
@@ -24,20 +24,30 @@ namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
// Base class GammaFontRenderer
///////////////////////////////////////////////////////////////////////////////

GammaFontRenderer::GammaFontRenderer() {
    INIT_LOGD("Creating gamma font renderer");
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();
        }
    }

    return new LookupGammaFontRenderer();
}

GammaFontRenderer::GammaFontRenderer() {
    // Get the renderer properties
    char property[PROPERTY_VALUE_MAX];

    // Get the gamma
    float gamma = DEFAULT_TEXT_GAMMA;
    mGamma = DEFAULT_TEXT_GAMMA;
    if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) {
        INIT_LOGD("  Setting text gamma to %s", property);
        gamma = atof(property);
        mGamma = atof(property);
    } else {
        INIT_LOGD("  Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA);
    }
@@ -61,10 +71,29 @@ GammaFontRenderer::GammaFontRenderer() {
        INIT_LOGD("  Using default white black gamma threshold of %d",
                DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD);
    }
}

GammaFontRenderer::~GammaFontRenderer() {
}

///////////////////////////////////////////////////////////////////////////////
// Shader-based renderer
///////////////////////////////////////////////////////////////////////////////

ShaderGammaFontRenderer::ShaderGammaFontRenderer(): GammaFontRenderer() {
    INIT_LOGD("Creating shader gamma font renderer");
}

///////////////////////////////////////////////////////////////////////////////
// Lookup-based renderer
///////////////////////////////////////////////////////////////////////////////

LookupGammaFontRenderer::LookupGammaFontRenderer(): GammaFontRenderer() {
    INIT_LOGD("Creating lookup gamma font renderer");

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

    for (uint32_t i = 0; i <= 255; i++) {
        mGammaTable[i] = i;
@@ -81,20 +110,20 @@ GammaFontRenderer::GammaFontRenderer() {
    memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
}

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

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

void GammaFontRenderer::flush() {
void LookupGammaFontRenderer::flush() {
    int count = 0;
    int min = -1;
    uint32_t minCount = UINT_MAX;
@@ -122,7 +151,7 @@ void GammaFontRenderer::flush() {
    }
}

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

FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
FontRenderer& LookupGammaFontRenderer::getFontRenderer(const SkPaint* paint) {
    if (paint->getShader() == NULL) {
        uint32_t c = paint->getColor();
        const int r = (c >> 16) & 0xFF;
+75 −11
Original line number Diff line number Diff line
@@ -24,17 +24,73 @@
namespace android {
namespace uirenderer {

struct GammaFontRenderer {
class GammaFontRenderer {
public:
    virtual ~GammaFontRenderer();

    virtual void clear() = 0;
    virtual void flush() = 0;

    virtual FontRenderer& getFontRenderer(const SkPaint* paint) = 0;

    virtual uint32_t getFontRendererCount() const = 0;

    virtual uint32_t getFontRendererSize(uint32_t fontRenderer) const = 0;

    static GammaFontRenderer* createRenderer();

protected:
    GammaFontRenderer();
    ~GammaFontRenderer();

    enum Gamma {
        kGammaDefault = 0,
        kGammaBlack = 1,
        kGammaWhite = 2,
        kGammaCount = 3
    int mBlackThreshold;
    int mWhiteThreshold;

    float mGamma;
};

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

    void clear() {
        delete mRenderer;
    }

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

    FontRenderer& getFontRenderer(const SkPaint* paint) {
        if (!mRenderer) {
            mRenderer = new FontRenderer;
        }
        return *mRenderer;
    }

    uint32_t getFontRendererCount() const {
        return 1;
    }

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

private:
    ShaderGammaFontRenderer();

    FontRenderer* mRenderer;

    friend class GammaFontRenderer;
};

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

    void clear();
    void flush();

@@ -54,15 +110,23 @@ struct GammaFontRenderer {
    }

private:
    LookupGammaFontRenderer();

    enum Gamma {
        kGammaDefault = 0,
        kGammaBlack = 1,
        kGammaWhite = 2,
        kGammaCount = 3
    };

    FontRenderer* getRenderer(Gamma gamma);

    uint32_t mRenderersUsageCount[kGammaCount];
    FontRenderer* mRenderers[kGammaCount];

    int mBlackThreshold;
    int mWhiteThreshold;

    uint8_t mGammaTable[256 * kGammaCount];

    friend class GammaFontRenderer;
};

}; // namespace uirenderer
Loading