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

Commit d06cfccf authored by Romain Guy's avatar Romain Guy Committed by Android Git Automerger
Browse files

am 1361dff5: Merge "Support 3D rotations when drawing text" into jb-mr2-dev

* commit '1361dff5':
  Support 3D rotations when drawing text
parents fcdfff57 1361dff5
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