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

Commit 9eac5269 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Optimize text GL setup" into jb-mr2-dev

parents 7564c716 257ae350
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <cutils/properties.h>

#include <utils/Functor.h>
#include <utils/Log.h>

#include <RenderScript.h>
@@ -416,6 +417,8 @@ void FontRenderer::issueDrawCommand() {
        CacheTexture* texture = mCacheTextures[i];
        if (texture->canDraw()) {
            if (first) {
                if (mFunctor) (*mFunctor)(0, NULL);

                checkTextureUpdate();
                caches.bindIndicesBuffer(mIndexBufferID);

@@ -561,11 +564,12 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch
    return image;
}

void FontRenderer::initRender(const Rect* clip, Rect* bounds) {
void FontRenderer::initRender(const Rect* clip, Rect* bounds, Functor* functor) {
    checkInit();

    mDrawn = false;
    mBounds = bounds;
    mFunctor = functor;
    mClip = clip;
}

@@ -583,13 +587,13 @@ void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, con

bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
        uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
        const float* positions, Rect* bounds) {
        const float* positions, Rect* bounds, Functor* functor) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds);
    initRender(clip, bounds, functor);
    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y, positions);
    finishRender();

@@ -604,7 +608,7 @@ bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char
        return false;
    }

    initRender(clip, bounds);
    initRender(clip, bounds, NULL);
    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, path, hOffset, vOffset);
    finishRender();

+7 −8
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ namespace RSC {
    class ScriptIntrinsicBlur;
}

class Functor;

namespace android {
namespace uirenderer {

@@ -62,7 +64,8 @@ public:

    // bounds is an out parameter
    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds,
            Functor* functor);
    // bounds is an out parameter
    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
@@ -88,13 +91,8 @@ public:
    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
            uint32_t len, int numGlyphs, uint32_t radius, const float* positions);

    GLuint getTexture(bool linearFiltering = false) {
        checkInit();

        mCurrentCacheTexture->setLinearFiltering(linearFiltering);
    void setTextureFiltering(bool linearFiltering) {
        mLinearFiltering = linearFiltering;

        return mCurrentCacheTexture->getTextureId();
    }

    uint32_t getCacheSize() const {
@@ -125,7 +123,7 @@ private:
    void initVertexArrayBuffers();

    void checkInit();
    void initRender(const Rect* clip, Rect* bounds);
    void initRender(const Rect* clip, Rect* bounds, Functor* functor);
    void finishRender();

    void issueDrawCommand();
@@ -167,6 +165,7 @@ private:
    uint32_t mMaxNumberOfQuads;
    uint32_t mIndexBufferID;

    Functor* mFunctor;
    const Rect* mClip;
    Rect* mBounds;
    bool mDrawn;
+66 −48
Original line number Diff line number Diff line
@@ -1752,7 +1752,7 @@ void OpenGLRenderer::setupDrawSimpleMesh() {
}

void OpenGLRenderer::setupDrawTexture(GLuint texture) {
    bindTexture(texture);
    if (texture) bindTexture(texture);
    mTextureUnit++;
    mCaches.enableTexCoordsVertexArray();
}
@@ -2411,7 +2411,8 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex

status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
        float rx, float ry, SkPaint* p) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
        return DrawGlInfo::kStatusDone;
    }

@@ -2436,7 +2437,8 @@ status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float

status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(x - radius, y - radius,
            x + radius, y + radius, p)) {
            x + radius, y + radius, p) ||
            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
        return DrawGlInfo::kStatusDone;
    }
    if (p->getPathEffect() != 0) {
@@ -2456,7 +2458,8 @@ status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p)

status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
        SkPaint* p) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
        return DrawGlInfo::kStatusDone;
    }

@@ -2477,7 +2480,8 @@ status_t OpenGLRenderer::drawOval(float left, float top, float right, float bott

status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
        float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
        return DrawGlInfo::kStatusDone;
    }

@@ -2513,7 +2517,8 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto
#define SkPaintDefaults_MiterLimit SkIntToScalar(4)

status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
            (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
        return DrawGlInfo::kStatusDone;
    }

@@ -2589,6 +2594,48 @@ bool OpenGLRenderer::canSkipText(const SkPaint* paint) const {
    return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
}

class TextSetupFunctor: public Functor {
public:
    TextSetupFunctor(OpenGLRenderer& renderer, float x, float y, bool pureTranslate,
            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
            renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
            alpha(alpha), mode(mode), paint(paint) {
    }
    ~TextSetupFunctor() { }

    status_t operator ()(int what, void* data) {
        renderer.setupDraw();
        renderer.setupDrawTextGamma(paint);
        renderer.setupDrawDirtyRegionsDisabled();
        renderer.setupDrawWithTexture(true);
        renderer.setupDrawAlpha8Color(paint->getColor(), alpha);
        renderer.setupDrawColorFilter();
        renderer.setupDrawShader();
        renderer.setupDrawBlending(true, mode);
        renderer.setupDrawProgram();
        renderer.setupDrawModelView(x, y, x, y, pureTranslate, true);
        // Calling setupDrawTexture with the name 0 will enable the
        // uv attributes and increase the texture unit count
        // texture binding will be performed by the font renderer as
        // needed
        renderer.setupDrawTexture(0);
        renderer.setupDrawPureColorUniforms();
        renderer.setupDrawColorFilterUniforms();
        renderer.setupDrawShaderUniforms(pureTranslate);
        renderer.setupDrawTextGammaUniforms();

        return NO_ERROR;
    }

    OpenGLRenderer& renderer;
    float x;
    float y;
    bool pureTranslate;
    int alpha;
    SkXfermode::Mode mode;
    SkPaint* paint;
};

status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
        const float* positions, SkPaint* paint) {
    if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
@@ -2625,31 +2672,16 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
    if (pureTranslate && !linearFilter) {
        linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
    }

    mCaches.activeTexture(0);
    setupDraw();
    setupDrawTextGamma(paint);
    setupDrawDirtyRegionsDisabled();
    setupDrawWithTexture(true);
    setupDrawAlpha8Color(paint->getColor(), alpha);
    setupDrawColorFilter();
    setupDrawShader();
    setupDrawBlending(true, mode);
    setupDrawProgram();
    setupDrawModelView(x, y, x, y, pureTranslate, true);
    setupDrawTexture(fontRenderer.getTexture(linearFilter));
    setupDrawPureColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderUniforms(pureTranslate);
    setupDrawTextGammaUniforms();
    fontRenderer.setTextureFiltering(linearFilter);

    const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);

    const bool hasActiveLayer = hasLayer();

    TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
    if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
            positions, hasActiveLayer ? &bounds : NULL)) {
            positions, hasActiveLayer ? &bounds : NULL, &functor)) {
        if (hasActiveLayer) {
            if (!pureTranslate) {
                currentTransform().mapRect(bounds);
@@ -2742,40 +2774,22 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,

    // Pick the appropriate texture filtering
    bool linearFilter = !pureTranslate || fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;

    // The font renderer will always use texture unit 0
    mCaches.activeTexture(0);
    setupDraw();
    setupDrawTextGamma(paint);
    setupDrawDirtyRegionsDisabled();
    setupDrawWithTexture(true);
    setupDrawAlpha8Color(paint->getColor(), alpha);
    setupDrawColorFilter();
    setupDrawShader();
    setupDrawBlending(true, mode);
    setupDrawProgram();
    setupDrawModelView(x, y, x, y, pureTranslate, true);
    // See comment above; the font renderer must use texture unit 0
    // assert(mTextureUnit == 0)
    setupDrawTexture(fontRenderer.getTexture(linearFilter));
    setupDrawPureColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderUniforms(pureTranslate);
    setupDrawTextGammaUniforms();
    fontRenderer.setTextureFiltering(linearFilter);

    // TODO: Implement better clipping for scaled/rotated text
    const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);

    bool status;
    TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
    if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
        SkPaint paintCopy(*paint);
        paintCopy.setTextAlign(SkPaint::kLeft_Align);
        status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
                positions, hasActiveLayer ? &bounds : NULL);
                positions, hasActiveLayer ? &bounds : NULL, &functor);
    } else {
        status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
                positions, hasActiveLayer ? &bounds : NULL);
                positions, hasActiveLayer ? &bounds : NULL, &functor);
    }

    if (status && hasActiveLayer) {
@@ -2798,12 +2812,12 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co

    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
    fontRenderer.setFont(paint, mat4::identity());
    fontRenderer.setTextureFiltering(true);

    int alpha;
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);

    mCaches.activeTexture(0);
    setupDraw();
    setupDrawTextGamma(paint);
    setupDrawDirtyRegionsDisabled();
@@ -2814,7 +2828,11 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co
    setupDrawBlending(true, mode);
    setupDrawProgram();
    setupDrawModelView(0.0f, 0.0f, 0.0f, 0.0f, false, true);
    setupDrawTexture(fontRenderer.getTexture(true));
    // Calling setupDrawTexture with the name 0 will enable the
    // uv attributes and increase the texture unit count
    // texture binding will be performed by the font renderer as
    // needed
    setupDrawTexture(0);
    setupDrawPureColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderUniforms(false);
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct DeferredDisplayState {
///////////////////////////////////////////////////////////////////////////////

class DisplayList;
class TextSetupFunctor;
class VertexBuffer;

/**
@@ -995,6 +996,7 @@ private:
    String8 mName;

    friend class DisplayListRenderer;
    friend class TextSetupFunctor;

}; // class OpenGLRenderer