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

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

Merge "Support 3D rotations when drawing text" into jb-mr2-dev

parents f999879c a4adcf02
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -406,7 +406,7 @@ status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, i
    if (addDrawOp(op)) {
        // precache if draw operation is visible
        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
        fontRenderer.precache(paint, text, count, mat4::identity());
    }
    return DrawGlInfo::kStatusDone;
}
@@ -423,7 +423,7 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int
    if (addDrawOp(op)) {
        // precache if draw operation is visible
        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
        fontRenderer.precache(paint, text, count, mat4::identity());
    }
    return DrawGlInfo::kStatusDone;
}
@@ -442,7 +442,9 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou
    if (addDrawOp(op)) {
        // precache if draw operation is visible
        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
        const bool pureTranslate = mSnapshot->transform->isPureTranslate();
        fontRenderer.precache(paint, text, count,
                pureTranslate ? mat4::identity() : *mSnapshot->transform);
    }
    return DrawGlInfo::kStatusDone;
}
+10 −0
Original line number Diff line number Diff line
@@ -180,7 +180,17 @@ CacheTexture* FontRenderer::cacheBitmapInTexture(const SkGlyph& glyph,
void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
        uint32_t* retOriginX, uint32_t* retOriginY, bool precaching) {
    checkInit();

    // If the glyph bitmap is empty let's assum the glyph is valid
    // so we can avoid doing extra work later on
    if (glyph.fWidth == 0 || glyph.fHeight == 0) {
        cachedGlyph->mIsValid = true;
        cachedGlyph->mCacheTexture = NULL;
        return;
    }

    cachedGlyph->mIsValid = false;

    // If the glyph is too tall, don't cache it
    if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
                mCacheTextures[mCacheTextures.size() - 1]->getHeight()) {
+14 −11
Original line number Diff line number Diff line
@@ -2151,6 +2151,10 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const

    alpha *= mSnapshot->alpha;

    const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
            right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);

    if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
        mCaches.activeTexture(0);
        Texture* texture = mCaches.textureCache.get(bitmap);
        if (!texture) return DrawGlInfo::kStatusDone;
@@ -2158,10 +2162,6 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const
        texture->setWrap(GL_CLAMP_TO_EDGE, true);
        texture->setFilter(GL_LINEAR, true);

    const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
            right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);

    if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
        const bool pureTranslate = mSnapshot->transform->isPureTranslate();
        // Mark the current layer dirty where we are going to draw the patch
        if (hasLayer() && mesh->hasEmptyQuads) {
@@ -2666,6 +2666,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    const float oldX = x;
    const float oldY = y;
    const bool pureTranslate = mSnapshot->transform->isPureTranslate();
    const bool isPerspective = mSnapshot->transform->isPerspective();

    if (CC_LIKELY(pureTranslate)) {
        x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
@@ -2687,8 +2688,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    fontRenderer.setFont(paint, pureTranslate ? mat4::identity() : *mSnapshot->transform);

    // Pick the appropriate texture filtering
    bool linearFilter = !mSnapshot->transform->isPureTranslate() ||
            fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
    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);
@@ -2701,13 +2701,13 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    setupDrawShader();
    setupDrawBlending(true, mode);
    setupDrawProgram();
    setupDrawModelView(x, y, x, y, true, true);
    setupDrawModelView(x, y, x, y, !isPerspective, true);
    // See comment above; the font renderer must use texture unit 0
    // assert(mTextureUnit == 0)
    setupDrawTexture(fontRenderer.getTexture(linearFilter));
    setupDrawPureColorUniforms();
    setupDrawColorFilterUniforms();
    setupDrawShaderUniforms(true);
    setupDrawShaderUniforms(!isPerspective);
    setupDrawTextGammaUniforms();

    const Rect* clip = mSnapshot->hasPerspectiveTransform() ? NULL : mSnapshot->clipRect;
@@ -2727,6 +2727,9 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    }

    if (status && hasActiveLayer) {
        if (isPerspective) {
            mSnapshot->transform->mapRect(bounds);
        }
        dirtyLayerUnchecked(bounds, getRegion());
    }

+60 −21
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ Font::FontDescription::FontDescription(const SkPaint* paint, const mat4& matrix)
    mStyle = paint->getStyle();
    mStrokeWidth = paint->getStrokeWidth();
    mAntiAliasing = paint->isAntiAlias();
    mLookupTransform.reset();
    mLookupTransform[SkMatrix::kMScaleX] = matrix.data[mat4::kScaleX];
    mLookupTransform[SkMatrix::kMScaleY] = matrix.data[mat4::kScaleY];
    mLookupTransform[SkMatrix::kMSkewX] = matrix.data[mat4::kSkewX];
@@ -165,7 +166,7 @@ void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    float nPenX = x + glyph->mBitmapLeft;
    float nPenY = y + (glyph->mBitmapTop + glyph->mBitmapHeight);
    float nPenY = y + glyph->mBitmapTop + glyph->mBitmapHeight;

    float width = (float) glyph->mBitmapWidth;
    float height = (float) glyph->mBitmapHeight;
@@ -181,6 +182,38 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
            nPenX, nPenY - height, u1, v1, glyph->mCacheTexture);
}

void Font::drawCachedGlyphPerspective(CachedGlyphInfo* glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    SkMatrix i;
    if (!mDescription.mLookupTransform.invert(&i)) {
        return;
    }

    SkPoint p[4];
    p[0].set(glyph->mBitmapLeft, glyph->mBitmapTop + glyph->mBitmapHeight);
    p[1].set(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop + glyph->mBitmapHeight);
    p[2].set(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop);
    p[3].set(glyph->mBitmapLeft, glyph->mBitmapTop);

    i.mapPoints(p, 4);

    p[0].offset(x, y);
    p[1].offset(x, y);
    p[2].offset(x, y);
    p[3].offset(x, y);

    float u1 = glyph->mBitmapMinU;
    float u2 = glyph->mBitmapMaxU;
    float v1 = glyph->mBitmapMinV;
    float v2 = glyph->mBitmapMaxV;

    mState->appendRotatedMeshQuad(
            p[0].fX, p[0].fY, u1, v2,
            p[1].fX, p[1].fY, u2, v2,
            p[2].fX, p[2].fY, u2, v1,
            p[3].fX, p[3].fY, u1, v1, glyph->mCacheTexture);
}

void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    int nPenX = x + glyph->mBitmapLeft;
@@ -307,7 +340,7 @@ void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len
        penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
        prevRsbDelta = cachedGlyph->mRsbDelta;

        if (cachedGlyph->mIsValid) {
        if (cachedGlyph->mIsValid && cachedGlyph->mCacheTexture) {
            drawCachedGlyph(cachedGlyph, penX, hOffset, vOffset, measure, &position, &tangent);
        }

@@ -328,7 +361,6 @@ void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t le
}

void Font::precache(SkPaint* paint, const char* text, int numGlyphs) {

    if (numGlyphs == 0 || text == NULL) {
        return;
    }
@@ -357,14 +389,18 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len

    static RenderGlyph gRenderGlyph[] = {
            &android::uirenderer::Font::drawCachedGlyph,
            &android::uirenderer::Font::drawCachedGlyphPerspective,
            &android::uirenderer::Font::drawCachedGlyphBitmap,
            &android::uirenderer::Font::drawCachedGlyphBitmap,
            &android::uirenderer::Font::measureCachedGlyph,
            &android::uirenderer::Font::measureCachedGlyph
    };
    RenderGlyph render = gRenderGlyph[mode];
    RenderGlyph render = gRenderGlyph[(mode << 1) + mTransform.isPerspective()];

    text += start;
    int glyphsCount = 0;

    const bool applyTransform = !mTransform.isIdentity() && !mTransform.isPerspective();
    const SkPaint::Align align = paint->getTextAlign();

    while (glyphsCount < numGlyphs) {
@@ -377,12 +413,13 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len

        CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);

        // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
        if (cachedGlyph->mIsValid) {
        // If it's still not valid, we couldn't cache it, so we shouldn't
        // draw garbage; also skip empty glyphs (spaces)
        if (cachedGlyph->mIsValid && cachedGlyph->mCacheTexture) {
            float penX = x + positions[(glyphsCount << 1)];
            float penY = y + positions[(glyphsCount << 1) + 1];

            if (!mTransform.isIdentity()) {
            if (applyTransform) {
                mTransform.mapPoint(penX, penY);
            }

@@ -424,6 +461,8 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
    glyph->mBitmapWidth = skiaGlyph.fWidth;
    glyph->mBitmapHeight = skiaGlyph.fHeight;

    bool empty = skiaGlyph.fWidth == 0 || skiaGlyph.fHeight == 0;
    if (!empty) {
        uint32_t cacheWidth = glyph->mCacheTexture->getWidth();
        uint32_t cacheHeight = glyph->mCacheTexture->getHeight();

@@ -434,14 +473,15 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp

        mState->setTextureDirty();
    }
}

CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching) {
    CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
    mCachedGlyphs.add(glyph, newGlyph);

    const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph, &mDescription.mLookupTransform);
    newGlyph->mGlyphIndex = skiaGlyph.fID;
    newGlyph->mIsValid = false;
    newGlyph->mGlyphIndex = skiaGlyph.fID;

    updateGlyphCache(paint, skiaGlyph, newGlyph, precaching);

@@ -452,14 +492,13 @@ Font* Font::create(FontRenderer* state, const SkPaint* paint, const mat4& matrix
    FontDescription description(paint, matrix);
    Font* font = state->mActiveFonts.get(description);

    if (font) {
        font->mTransform.load(matrix);
        return font;
    if (!font) {
        font = new Font(state, description);
        state->mActiveFonts.put(description, font);
    }
    font->mTransform.load(matrix);

    Font* newFont = new Font(state, description);
    state->mActiveFonts.put(description, newFont);
    return newFont;
    return font;
}

}; // namespace uirenderer
+3 −0
Original line number Diff line number Diff line
@@ -124,6 +124,9 @@ private:
    void drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
            uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
            Rect* bounds, const float* pos);
    void drawCachedGlyphPerspective(CachedGlyphInfo* glyph, int x, int y,
            uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
            Rect* bounds, const float* pos);
    void drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
            uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
            Rect* bounds, const float* pos);
Loading