/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "FontRenderer.h"

#include "BakedOpDispatcher.h"
#include "BakedOpRenderer.h"
#include "BakedOpState.h"
#include "Caches.h"
#include "Debug.h"
#include "Extensions.h"
#include "Glop.h"
#include "GlopBuilder.h"
#include "PixelBuffer.h"
#include "Rect.h"
#include "font/Font.h"
#include "renderstate/RenderState.h"
#include "utils/Blur.h"
#include "utils/Timing.h"

#include <RenderScript.h>
#include <SkGlyph.h>
#include <SkUtils.h>
#include <utils/Log.h>
#include <algorithm>

namespace android {
namespace uirenderer {

// blur inputs smaller than this constant will bypass renderscript
#define RS_MIN_INPUT_CUTOFF 10000

///////////////////////////////////////////////////////////////////////////////
// TextSetupFunctor
///////////////////////////////////////////////////////////////////////////////

void TextDrawFunctor::draw(CacheTexture& texture, bool linearFiltering) {
    int textureFillFlags = TextureFillFlags::None;
    if (texture.getFormat() == GL_ALPHA) {
        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
    }
    if (linearFiltering) {
        textureFillFlags |= TextureFillFlags::ForceFilter;
    }
    int transformFlags =
            pureTranslate ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None;
#ifdef ANDROID_ENABLE_LINEAR_BLENDING
    bool gammaCorrection = true;
#else
    bool gammaCorrection = false;
#endif
    Glop glop;
    GlopBuilder(renderer->renderState(), renderer->caches(), &glop)
            .setRoundRectClipState(bakedState->roundRectClipState)
            .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
            .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, bakedState->alpha)
            .setGammaCorrection(gammaCorrection)
            .setTransform(bakedState->computedState.transform, transformFlags)
            .setModelViewIdentityEmptyBounds()
            .build();
    // Note: don't pass dirty bounds here, so user must manage passing dirty bounds to renderer
    renderer->renderGlop(nullptr, clip, glop);
}

///////////////////////////////////////////////////////////////////////////////
// FontRenderer
///////////////////////////////////////////////////////////////////////////////

static bool sLogFontRendererCreate = true;

FontRenderer::FontRenderer(const uint8_t* gammaTable)
        : mGammaTable(gammaTable)
        , mCurrentFont(nullptr)
        , mActiveFonts(LruCache<Font::FontDescription, Font*>::kUnlimitedCapacity)
        , mCurrentCacheTexture(nullptr)
        , mUploadTexture(false)
        , mFunctor(nullptr)
        , mClip(nullptr)
        , mBounds(nullptr)
        , mDrawn(false)
        , mInitialized(false)
        , mLinearFiltering(false) {
    if (sLogFontRendererCreate) {
        INIT_LOGD("Creating FontRenderer");
    }

    auto deviceInfo = DeviceInfo::get();
    auto displayInfo = deviceInfo->displayInfo();
    int maxTextureSize = deviceInfo->maxTextureSize();

    // Adjust cache size based on Pixel's desnsity.
    constexpr float PIXEL_DENSITY = 2.6;
    const float densityRatio = displayInfo.density / PIXEL_DENSITY;

    // TODO: Most devices are hardcoded with this configuration, does it need to be dynamic?
    mSmallCacheWidth =
            OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);
    mSmallCacheHeight =
            OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);
    mLargeCacheWidth =
            OffscreenBuffer::computeIdealDimension(std::min(2048, maxTextureSize) * densityRatio);
    mLargeCacheHeight =
            OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);

    if (sLogFontRendererCreate) {
        INIT_LOGD("  Text cache sizes, in pixels: %i x %i, %i x %i, %i x %i, %i x %i",
                  mSmallCacheWidth, mSmallCacheHeight, mLargeCacheWidth, mLargeCacheHeight >> 1,
                  mLargeCacheWidth, mLargeCacheHeight >> 1, mLargeCacheWidth, mLargeCacheHeight);
    }

    sLogFontRendererCreate = false;
}

void clearCacheTextures(std::vector<CacheTexture*>& cacheTextures) {
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        delete cacheTextures[i];
    }
    cacheTextures.clear();
}

FontRenderer::~FontRenderer() {
    clearCacheTextures(mACacheTextures);
    clearCacheTextures(mRGBACacheTextures);

    LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
    while (it.next()) {
        delete it.value();
    }
    mActiveFonts.clear();
}

void FontRenderer::flushAllAndInvalidate() {
    issueDrawCommand();

    LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
    while (it.next()) {
        it.value()->invalidateTextureCache();
    }

    for (uint32_t i = 0; i < mACacheTextures.size(); i++) {
        mACacheTextures[i]->init();

#ifdef BUGREPORT_FONT_CACHE_USAGE
        mHistoryTracker.glyphsCleared(mACacheTextures[i]);
#endif
    }

    for (uint32_t i = 0; i < mRGBACacheTextures.size(); i++) {
        mRGBACacheTextures[i]->init();
#ifdef BUGREPORT_FONT_CACHE_USAGE
        mHistoryTracker.glyphsCleared(mRGBACacheTextures[i]);
#endif
    }

    mDrawn = false;
}

void FontRenderer::flushLargeCaches(std::vector<CacheTexture*>& cacheTextures) {
    // Start from 1; don't deallocate smallest/default texture
    for (uint32_t i = 1; i < cacheTextures.size(); i++) {
        CacheTexture* cacheTexture = cacheTextures[i];
        if (cacheTexture->getPixelBuffer()) {
            cacheTexture->init();
#ifdef BUGREPORT_FONT_CACHE_USAGE
            mHistoryTracker.glyphsCleared(cacheTexture);
#endif
            LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
            while (it.next()) {
                it.value()->invalidateTextureCache(cacheTexture);
            }
            cacheTexture->releasePixelBuffer();
        }
    }
}

void FontRenderer::flushLargeCaches() {
    flushLargeCaches(mACacheTextures);
    flushLargeCaches(mRGBACacheTextures);
}

CacheTexture* FontRenderer::cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures,
                                                 const SkGlyph& glyph, uint32_t* startX,
                                                 uint32_t* startY) {
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        if (cacheTextures[i]->fitBitmap(glyph, startX, startY)) {
            return cacheTextures[i];
        }
    }
    // Could not fit glyph into current cache textures
    return nullptr;
}

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 = nullptr;
        return;
    }

    cachedGlyph->mIsValid = false;

    // choose an appropriate cache texture list for this glyph format
    SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
    std::vector<CacheTexture*>* cacheTextures = nullptr;
    switch (format) {
        case SkMask::kA8_Format:
        case SkMask::kBW_Format:
            cacheTextures = &mACacheTextures;
            break;
        case SkMask::kARGB32_Format:
            cacheTextures = &mRGBACacheTextures;
            break;
        default:
#if DEBUG_FONT_RENDERER
            ALOGD("getCacheTexturesForFormat: unknown SkMask format %x", format);
#endif
            return;
    }

    // If the glyph is too tall, don't cache it
    if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
        (*cacheTextures)[cacheTextures->size() - 1]->getHeight()) {
        ALOGE("Font size too large to fit in cache. width, height = %i, %i", (int)glyph.fWidth,
              (int)glyph.fHeight);
        return;
    }

    // Now copy the bitmap into the cache texture
    uint32_t startX = 0;
    uint32_t startY = 0;

    CacheTexture* cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);

    if (!cacheTexture) {
        if (!precaching) {
            // If the new glyph didn't fit and we are not just trying to precache it,
            // clear out the cache and try again
            flushAllAndInvalidate();
            cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);
        }

        if (!cacheTexture) {
            // either the glyph didn't fit or we're precaching and will cache it when we draw
            return;
        }
    }

    cachedGlyph->mCacheTexture = cacheTexture;

    *retOriginX = startX;
    *retOriginY = startY;

    uint32_t endX = startX + glyph.fWidth;
    uint32_t endY = startY + glyph.fHeight;

    uint32_t cacheWidth = cacheTexture->getWidth();

    if (!cacheTexture->getPixelBuffer()) {
        Caches::getInstance().textureState().activateTexture(0);
        // Large-glyph texture memory is allocated only as needed
        cacheTexture->allocatePixelBuffer();
    }
    if (!cacheTexture->mesh()) {
        cacheTexture->allocateMesh();
    }

    uint8_t* cacheBuffer = cacheTexture->getPixelBuffer()->map();
    uint8_t* bitmapBuffer = (uint8_t*)glyph.fImage;
    int srcStride = glyph.rowBytes();

    // Copy the glyph image, taking the mask format into account
    switch (format) {
        case SkMask::kA8_Format: {
            uint32_t row =
                    (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
            // write leading border line
            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
            // write glyph data
            if (mGammaTable) {
                for (uint32_t cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
                    row = cacheY * cacheWidth;
                    cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
                    for (uint32_t cacheX = startX, bX = 0; cacheX < endX; cacheX++, bX++) {
                        uint8_t tempCol = bitmapBuffer[bY + bX];
                        cacheBuffer[row + cacheX] = mGammaTable[tempCol];
                    }
                    cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
                }
            } else {
                for (uint32_t cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
                    row = cacheY * cacheWidth;
                    memcpy(&cacheBuffer[row + startX], &bitmapBuffer[bY], glyph.fWidth);
                    cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
                    cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
                }
            }
            // write trailing border line
            row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
            break;
        }
        case SkMask::kARGB32_Format: {
            // prep data lengths
            const size_t formatSize = PixelBuffer::formatSize(GL_RGBA);
            const size_t borderSize = formatSize * TEXTURE_BORDER_SIZE;
            size_t rowSize = formatSize * glyph.fWidth;
            // prep advances
            size_t dstStride = formatSize * cacheWidth;
            // prep indices
            // - we actually start one row early, and then increment before first copy
            uint8_t* src = &bitmapBuffer[0 - srcStride];
            uint8_t* dst = &cacheBuffer[cacheTexture->getOffset(startX, startY - 1)];
            uint8_t* dstEnd = &cacheBuffer[cacheTexture->getOffset(startX, endY - 1)];
            uint8_t* dstL = dst - borderSize;
            uint8_t* dstR = dst + rowSize;
            // write leading border line
            memset(dstL, 0, rowSize + 2 * borderSize);
            // write glyph data
            while (dst < dstEnd) {
                memset(dstL += dstStride, 0, borderSize);             // leading border column
                memcpy(dst += dstStride, src += srcStride, rowSize);  // glyph data
                memset(dstR += dstStride, 0, borderSize);             // trailing border column
            }
            // write trailing border line
            memset(dstL += dstStride, 0, rowSize + 2 * borderSize);
            break;
        }
        case SkMask::kBW_Format: {
            uint32_t cacheX = 0, cacheY = 0;
            uint32_t row =
                    (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
            static const uint8_t COLORS[2] = {0, 255};
            // write leading border line
            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
            // write glyph data
            for (cacheY = startY; cacheY < endY; cacheY++) {
                cacheX = startX;
                int rowBytes = srcStride;
                uint8_t* buffer = bitmapBuffer;

                row = cacheY * cacheWidth;
                cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
                while (--rowBytes >= 0) {
                    uint8_t b = *buffer++;
                    for (int8_t mask = 7; mask >= 0 && cacheX < endX; mask--) {
                        cacheBuffer[cacheY * cacheWidth + cacheX++] = COLORS[(b >> mask) & 0x1];
                    }
                }
                cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;

                bitmapBuffer += srcStride;
            }
            // write trailing border line
            row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
            break;
        }
        default:
            ALOGW("Unknown glyph format: 0x%x", format);
            break;
    }

    cachedGlyph->mIsValid = true;

#ifdef BUGREPORT_FONT_CACHE_USAGE
    mHistoryTracker.glyphUploaded(cacheTexture, startX, startY, glyph.fWidth, glyph.fHeight);
#endif
}

CacheTexture* FontRenderer::createCacheTexture(int width, int height, GLenum format,
                                               bool allocate) {
    CacheTexture* cacheTexture = new CacheTexture(width, height, format, kMaxNumberOfQuads);

    if (allocate) {
        Caches::getInstance().textureState().activateTexture(0);
        cacheTexture->allocatePixelBuffer();
        cacheTexture->allocateMesh();
    }

    return cacheTexture;
}

void FontRenderer::initTextTexture() {
    clearCacheTextures(mACacheTextures);
    clearCacheTextures(mRGBACacheTextures);

    mUploadTexture = false;
    mACacheTextures.push_back(
            createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_ALPHA, true));
    mACacheTextures.push_back(
            createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false));
    mACacheTextures.push_back(
            createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false));
    mACacheTextures.push_back(
            createCacheTexture(mLargeCacheWidth, mLargeCacheHeight, GL_ALPHA, false));
    mRGBACacheTextures.push_back(
            createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_RGBA, false));
    mRGBACacheTextures.push_back(
            createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_RGBA, false));
    mCurrentCacheTexture = mACacheTextures[0];
}

// We don't want to allocate anything unless we actually draw text
void FontRenderer::checkInit() {
    if (mInitialized) {
        return;
    }

    initTextTexture();

    mInitialized = true;
}

void checkTextureUpdateForCache(Caches& caches, std::vector<CacheTexture*>& cacheTextures,
                                bool& resetPixelStore, GLuint& lastTextureId) {
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        CacheTexture* cacheTexture = cacheTextures[i];
        if (cacheTexture->isDirty() && cacheTexture->getPixelBuffer()) {
            if (cacheTexture->getTextureId() != lastTextureId) {
                lastTextureId = cacheTexture->getTextureId();
                caches.textureState().activateTexture(0);
                caches.textureState().bindTexture(lastTextureId);
            }

            if (cacheTexture->upload()) {
                resetPixelStore = true;
            }
        }
    }
}

void FontRenderer::checkTextureUpdate() {
    if (!mUploadTexture) {
        return;
    }

    Caches& caches = Caches::getInstance();
    GLuint lastTextureId = 0;

    bool resetPixelStore = false;

    // Iterate over all the cache textures and see which ones need to be updated
    checkTextureUpdateForCache(caches, mACacheTextures, resetPixelStore, lastTextureId);
    checkTextureUpdateForCache(caches, mRGBACacheTextures, resetPixelStore, lastTextureId);

    // Unbind any PBO we might have used to update textures
    caches.pixelBufferState().unbind();

    // Reset to default unpack row length to avoid affecting texture
    // uploads in other parts of the renderer
    if (resetPixelStore) {
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    }

    mUploadTexture = false;
}

void FontRenderer::issueDrawCommand(std::vector<CacheTexture*>& cacheTextures) {
    if (!mFunctor) return;

    bool first = true;
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        CacheTexture* texture = cacheTextures[i];
        if (texture->canDraw()) {
            if (first) {
                checkTextureUpdate();
                first = false;
                mDrawn = true;
            }

            mFunctor->draw(*texture, mLinearFiltering);

            texture->resetMesh();
        }
    }
}

void FontRenderer::issueDrawCommand() {
    issueDrawCommand(mACacheTextures);
    issueDrawCommand(mRGBACacheTextures);
}

void FontRenderer::appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2,
                                        float u2, float v2, float x3, float y3, float u3, float v3,
                                        float x4, float y4, float u4, float v4,
                                        CacheTexture* texture) {
    if (texture != mCurrentCacheTexture) {
        // Now use the new texture id
        mCurrentCacheTexture = texture;
    }

    mCurrentCacheTexture->addQuad(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4);
}

void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2,
                                  float u2, float v2, float x3, float y3, float u3, float v3,
                                  float x4, float y4, float u4, float v4, CacheTexture* texture) {
    if (mClip && (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
        return;
    }

    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);

    if (mBounds) {
        mBounds->left = std::min(mBounds->left, x1);
        mBounds->top = std::min(mBounds->top, y3);
        mBounds->right = std::max(mBounds->right, x3);
        mBounds->bottom = std::max(mBounds->bottom, y1);
    }

    if (mCurrentCacheTexture->endOfMesh()) {
        issueDrawCommand();
    }
}

void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2,
                                         float u2, float v2, float x3, float y3, float u3, float v3,
                                         float x4, float y4, float u4, float v4,
                                         CacheTexture* texture) {
    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);

    if (mBounds) {
        mBounds->left = std::min(mBounds->left, std::min(x1, std::min(x2, std::min(x3, x4))));
        mBounds->top = std::min(mBounds->top, std::min(y1, std::min(y2, std::min(y3, y4))));
        mBounds->right = std::max(mBounds->right, std::max(x1, std::max(x2, std::max(x3, x4))));
        mBounds->bottom = std::max(mBounds->bottom, std::max(y1, std::max(y2, std::max(y3, y4))));
    }

    if (mCurrentCacheTexture->endOfMesh()) {
        issueDrawCommand();
    }
}

void FontRenderer::setFont(const SkPaint* paint, const SkMatrix& matrix) {
    mCurrentFont = Font::create(this, paint, matrix);
}

FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const glyph_t* glyphs,
                                                        int numGlyphs, float radius,
                                                        const float* positions) {
    checkInit();

    DropShadow image;
    image.width = 0;
    image.height = 0;
    image.image = nullptr;
    image.penX = 0;
    image.penY = 0;

    if (!mCurrentFont) {
        return image;
    }

    mDrawn = false;
    mClip = nullptr;
    mBounds = nullptr;

    Rect bounds;
    mCurrentFont->measure(paint, glyphs, numGlyphs, &bounds, positions);

    uint32_t intRadius = Blur::convertRadiusToInt(radius);
    uint32_t paddedWidth = (uint32_t)(bounds.right - bounds.left) + 2 * intRadius;
    uint32_t paddedHeight = (uint32_t)(bounds.top - bounds.bottom) + 2 * intRadius;

    uint32_t maxSize = Caches::getInstance().maxTextureSize;
    if (paddedWidth > maxSize || paddedHeight > maxSize) {
        return image;
    }

    // Align buffers for renderscript usage
    if (paddedWidth & (RS_CPU_ALLOCATION_ALIGNMENT - 1)) {
        paddedWidth += RS_CPU_ALLOCATION_ALIGNMENT - paddedWidth % RS_CPU_ALLOCATION_ALIGNMENT;
    }
    int size = paddedWidth * paddedHeight;
    uint8_t* dataBuffer = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, size);

    memset(dataBuffer, 0, size);

    int penX = intRadius - bounds.left;
    int penY = intRadius - bounds.bottom;

    if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) {
        // text has non-whitespace, so draw and blur to create the shadow
        // NOTE: bounds.isEmpty() can't be used here, since vertical coordinates are inverted
        // TODO: don't draw pure whitespace in the first place, and avoid needing this check
        mCurrentFont->render(paint, glyphs, numGlyphs, penX, penY, Font::BITMAP, dataBuffer,
                             paddedWidth, paddedHeight, nullptr, positions);

        // Unbind any PBO we might have used
        Caches::getInstance().pixelBufferState().unbind();

        blurImage(&dataBuffer, paddedWidth, paddedHeight, radius);
    }

    image.width = paddedWidth;
    image.height = paddedHeight;
    image.image = dataBuffer;
    image.penX = penX;
    image.penY = penY;

    return image;
}

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

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

void FontRenderer::finishRender() {
    mBounds = nullptr;
    mClip = nullptr;

    issueDrawCommand();
}

void FontRenderer::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
                            const SkMatrix& matrix) {
    Font* font = Font::create(this, paint, matrix);
    font->precache(paint, glyphs, numGlyphs);
}

void FontRenderer::endPrecaching() {
    checkTextureUpdate();
}

bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
                                 int numGlyphs, int x, int y, const float* positions, Rect* bounds,
                                 TextDrawFunctor* functor, bool forceFinish) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds, functor);
    mCurrentFont->render(paint, glyphs, numGlyphs, x, y, positions);

    if (forceFinish) {
        finishRender();
    }

    return mDrawn;
}

bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
                                    int numGlyphs, const SkPath* path, float hOffset, float vOffset,
                                    Rect* bounds, TextDrawFunctor* functor) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds, functor);
    mCurrentFont->render(paint, glyphs, numGlyphs, path, hOffset, vOffset);
    finishRender();

    return mDrawn;
}

void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, float radius) {
    uint32_t intRadius = Blur::convertRadiusToInt(radius);
    if (width * height * intRadius >= RS_MIN_INPUT_CUTOFF && radius <= 25.0f) {
        uint8_t* outImage = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height);

        if (mRs == nullptr) {
            mRs = new RSC::RS();
            // a null path is OK because there are no custom kernels used
            // hence nothing gets cached by RS
            if (!mRs->init("", RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) {
                mRs.clear();
                ALOGE("blur RS failed to init");
            } else {
                mRsElement = RSC::Element::A_8(mRs);
                mRsScript = RSC::ScriptIntrinsicBlur::create(mRs, mRsElement);
            }
        }
        if (mRs != nullptr) {
            RSC::sp<const RSC::Type> t = RSC::Type::create(mRs, mRsElement, width, height, 0);
            RSC::sp<RSC::Allocation> ain = RSC::Allocation::createTyped(
                    mRs, t, RS_ALLOCATION_MIPMAP_NONE,
                    RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, *image);
            RSC::sp<RSC::Allocation> aout = RSC::Allocation::createTyped(
                    mRs, t, RS_ALLOCATION_MIPMAP_NONE,
                    RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, outImage);

            mRsScript->setRadius(radius);
            mRsScript->setInput(ain);
            mRsScript->forEach(aout);

            // replace the original image's pointer, avoiding a copy back to the original buffer
            free(*image);
            *image = outImage;

            return;
        }
    }

    std::unique_ptr<float[]> gaussian(new float[2 * intRadius + 1]);
    Blur::generateGaussianWeights(gaussian.get(), radius);

    std::unique_ptr<uint8_t[]> scratch(new uint8_t[width * height]);
    Blur::horizontal(gaussian.get(), intRadius, *image, scratch.get(), width, height);
    Blur::vertical(gaussian.get(), intRadius, scratch.get(), *image, width, height);
}

static uint32_t calculateCacheSize(const std::vector<CacheTexture*>& cacheTextures) {
    uint32_t size = 0;
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        CacheTexture* cacheTexture = cacheTextures[i];
        if (cacheTexture && cacheTexture->getPixelBuffer()) {
            size += cacheTexture->getPixelBuffer()->getSize();
        }
    }
    return size;
}

static uint32_t calculateFreeCacheSize(const std::vector<CacheTexture*>& cacheTextures) {
    uint32_t size = 0;
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        CacheTexture* cacheTexture = cacheTextures[i];
        if (cacheTexture && cacheTexture->getPixelBuffer()) {
            size += cacheTexture->calculateFreeMemory();
        }
    }
    return size;
}

const std::vector<CacheTexture*>& FontRenderer::cacheTexturesForFormat(GLenum format) const {
    switch (format) {
        case GL_ALPHA: {
            return mACacheTextures;
        }
        case GL_RGBA: {
            return mRGBACacheTextures;
        }
        default: {
            LOG_ALWAYS_FATAL("Unsupported format: %d", format);
            // Impossible to hit this, but the compiler doesn't know that
            return *(new std::vector<CacheTexture*>());
        }
    }
}

static void dumpTextures(String8& log, const char* tag,
                         const std::vector<CacheTexture*>& cacheTextures) {
    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
        CacheTexture* cacheTexture = cacheTextures[i];
        if (cacheTexture && cacheTexture->getPixelBuffer()) {
            uint32_t free = cacheTexture->calculateFreeMemory();
            uint32_t total = cacheTexture->getPixelBuffer()->getSize();
            log.appendFormat("    %-4s texture %d     %8d / %8d\n", tag, i, total - free, total);
        }
    }
}

void FontRenderer::dumpMemoryUsage(String8& log) const {
    const uint32_t sizeA8 = getCacheSize(GL_ALPHA);
    const uint32_t usedA8 = sizeA8 - getFreeCacheSize(GL_ALPHA);
    const uint32_t sizeRGBA = getCacheSize(GL_RGBA);
    const uint32_t usedRGBA = sizeRGBA - getFreeCacheSize(GL_RGBA);
    log.appendFormat("  FontRenderer A8      %8d / %8d\n", usedA8, sizeA8);
    dumpTextures(log, "A8", cacheTexturesForFormat(GL_ALPHA));
    log.appendFormat("  FontRenderer RGBA    %8d / %8d\n", usedRGBA, sizeRGBA);
    dumpTextures(log, "RGBA", cacheTexturesForFormat(GL_RGBA));
    log.appendFormat("  FontRenderer total   %8d / %8d\n", usedA8 + usedRGBA, sizeA8 + sizeRGBA);
}

uint32_t FontRenderer::getCacheSize(GLenum format) const {
    return calculateCacheSize(cacheTexturesForFormat(format));
}

uint32_t FontRenderer::getFreeCacheSize(GLenum format) const {
    return calculateFreeCacheSize(cacheTexturesForFormat(format));
}

uint32_t FontRenderer::getSize() const {
    return getCacheSize(GL_ALPHA) + getCacheSize(GL_RGBA);
}

};  // namespace uirenderer
};  // namespace android
