/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrAtlasTextBatch.h"

#include "GrBatchFlushState.h"
#include "GrResourceProvider.h"

#include "SkGlyphCache.h"

#include "effects/GrBitmapTextGeoProc.h"
#include "effects/GrDistanceFieldGeoProc.h"
#include "text/GrBatchFontCache.h"

///////////////////////////////////////////////////////////////////////////////////////////////////

static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
    unsigned r = SkColorGetR(c);
    unsigned g = SkColorGetG(c);
    unsigned b = SkColorGetB(c);
    return GrColorPackRGBA(r, g, b, 0xff);
}

static const int kDistanceAdjustLumShift = 5;

SkString GrAtlasTextBatch::dumpInfo() const {
    SkString str;

    for (int i = 0; i < fGeoCount; ++i) {
        str.appendf("%d: Color: 0x%08x Trans: %.2f,%.2f Runs: %d\n",
                    i,
                    fGeoData[i].fColor,
                    fGeoData[i].fTransX,
                    fGeoData[i].fTransY,
                    fGeoData[i].fBlob->runCount());
    }

    str.append(INHERITED::dumpInfo());
    return str;
}

void GrAtlasTextBatch::computePipelineOptimizations(GrInitInvariantOutput* color, 
                                                    GrInitInvariantOutput* coverage,
                                                    GrBatchToXPOverrides* overrides) const {
    if (kColorBitmapMask_MaskType == fMaskType) {
        color->setUnknownFourComponents();
    } else {
        color->setKnownFourComponents(fBatch.fColor);
    }
    switch (fMaskType) {
        case kGrayscaleDistanceField_MaskType:
        case kGrayscaleCoverageMask_MaskType:
            coverage->setUnknownSingleComponent();
            break;
        case kLCDCoverageMask_MaskType:
        case kLCDDistanceField_MaskType:
            coverage->setUnknownOpaqueFourComponents();
            coverage->setUsingLCDCoverage();
            break;
        case kColorBitmapMask_MaskType:
            coverage->setKnownSingleComponent(0xff);
    }
}

void GrAtlasTextBatch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
    // Handle any color overrides
    if (!overrides.readsColor()) {
        fGeoData[0].fColor = GrColor_ILLEGAL;
    }
    overrides.getOverrideColorIfSet(&fGeoData[0].fColor);

    // setup batch properties
    fBatch.fColorIgnored = !overrides.readsColor();
    fBatch.fColor = fGeoData[0].fColor;
    fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
    fBatch.fCoverageIgnored = !overrides.readsCoverage();
}

void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
    // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix.
    // TODO actually only invert if we don't have RGBA
    SkMatrix localMatrix;
    if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) {
        SkDebugf("Cannot invert viewmatrix\n");
        return;
    }

    GrTexture* texture = fFontCache->getTexture(this->maskFormat());
    if (!texture) {
        SkDebugf("Could not allocate backing texture for atlas\n");
        return;
    }

    GrMaskFormat maskFormat = this->maskFormat();

    SkAutoTUnref<const GrGeometryProcessor> gp;
    if (this->usesDistanceFields()) {
        gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this->color(),
                                        texture));
    } else {
        GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
        gp.reset(GrBitmapTextGeoProc::Create(this->color(),
                                             texture,
                                             params,
                                             maskFormat,
                                             localMatrix,
                                             this->usesLocalCoords()));
    }

    FlushInfo flushInfo;
    flushInfo.fGlyphsToFlush = 0;
    size_t vertexStride = gp->getVertexStride();
    SkASSERT(vertexStride == GrAtlasTextBlob::GetVertexStride(maskFormat));

    target->initDraw(gp, this->pipeline());

    int glyphCount = this->numGlyphs();
    const GrVertexBuffer* vertexBuffer;

    void* vertices = target->makeVertexSpace(vertexStride,
                                             glyphCount * kVerticesPerGlyph,
                                             &vertexBuffer,
                                             &flushInfo.fVertexOffset);
    flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
    flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuffer());
    if (!vertices || !flushInfo.fVertexBuffer) {
        SkDebugf("Could not allocate vertices\n");
        return;
    }

    unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);

    // We cache some values to avoid going to the glyphcache for the same fontScaler twice
    // in a row
    const SkDescriptor* desc = nullptr;
    SkGlyphCache* cache = nullptr;
    GrFontScaler* scaler = nullptr;
    SkTypeface* typeface = nullptr;

    GrBlobRegenHelper helper(this, target, &flushInfo, gp);

    for (int i = 0; i < fGeoCount; i++) {
        const Geometry& args = fGeoData[i];
        Blob* blob = args.fBlob;
        size_t byteCount;
        void* blobVertices;
        int glyphCount;
        blob->regenInBatch(target, fFontCache, &helper, args.fRun, args.fSubRun, &cache,
                           &typeface, &scaler, &desc, vertexStride, args.fColor, args.fTransX,
                           args.fTransY, &blobVertices, &byteCount, &glyphCount);

        // now copy all vertices
        memcpy(currVertex, blobVertices, byteCount);

#ifdef SK_DEBUG
        // bounds sanity check
        SkRect rect;
        rect.setLargestInverted();
        SkPoint* vertex = (SkPoint*) ((char*)blobVertices);
        rect.growToInclude(vertex, vertexStride, kVerticesPerGlyph * glyphCount);

        if (this->usesDistanceFields()) {
            fBatch.fViewMatrix.mapRect(&rect);
        }
        SkASSERT(fBounds.contains(rect));
#endif

        currVertex += byteCount;
    }

    // Make sure to attach the last cache if applicable
    if (cache) {
        SkGlyphCache::AttachCache(cache);
    }
    this->flush(target, &flushInfo);
}

void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const {
    GrVertices vertices;
    int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
    vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
                           flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
                           kVerticesPerGlyph, kIndicesPerGlyph, flushInfo->fGlyphsToFlush,
                           maxGlyphsPerDraw);
    target->draw(vertices);
    flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
    flushInfo->fGlyphsToFlush = 0;
}

bool GrAtlasTextBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
    GrAtlasTextBatch* that = t->cast<GrAtlasTextBatch>();
    if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
                                that->bounds(), caps)) {
        return false;
    }

    if (fMaskType != that->fMaskType) {
        return false;
    }

    if (!this->usesDistanceFields()) {
        if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->color()) {
            return false;
        }
        if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
            return false;
        }
    } else {
        if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
            return false;
        }

        if (fFilteredColor != that->fFilteredColor) {
            return false;
        }

        if (fUseBGR != that->fUseBGR) {
            return false;
        }
    }

    fBatch.fNumGlyphs += that->numGlyphs();

    // Reallocate space for geo data if necessary and then import that's geo data.
    int newGeoCount = that->fGeoCount + fGeoCount;
    // We assume (and here enforce) that the allocation size is the smallest power of two that
    // is greater than or equal to the number of geometries (and at least
    // kMinGeometryAllocated).
    int newAllocSize = GrNextPow2(newGeoCount);
    int currAllocSize = SkTMax<int>(kMinGeometryAllocated, GrNextPow2(fGeoCount));

    if (newGeoCount > currAllocSize) {
        fGeoData.realloc(newAllocSize);
    }

    memcpy(&fGeoData[fGeoCount], that->fGeoData.get(), that->fGeoCount * sizeof(Geometry));
    // We steal the ref on the blobs from the other TextBatch and set its count to 0 so that
    // it doesn't try to unref them.
#ifdef SK_DEBUG
    for (int i = 0; i < that->fGeoCount; ++i) {
        that->fGeoData.get()[i].fBlob = (Blob*)0x1;
    }
#endif
    that->fGeoCount = 0;
    fGeoCount = newGeoCount;

    this->joinBounds(that->bounds());
    return true;
}

// TODO just use class params
// TODO trying to figure out why lcd is so whack
GrGeometryProcessor* GrAtlasTextBatch::setupDfProcessor(const SkMatrix& viewMatrix,
                                                        SkColor filteredColor,
                                                        GrColor color, GrTexture* texture) const {
    GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
    bool isLCD = this->isLCD();
    // set up any flags
    uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;

    // see if we need to create a new effect
    if (isLCD) {
        flags |= kUseLCD_DistanceFieldEffectFlag;
        flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFlag : 0;
        flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0;

        GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);

        float redCorrection =
            (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistanceAdjustLumShift];
        float greenCorrection =
            (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistanceAdjustLumShift];
        float blueCorrection =
            (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistanceAdjustLumShift];
        GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust =
            GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(redCorrection,
                                                                greenCorrection,
                                                                blueCorrection);

        return GrDistanceFieldLCDTextGeoProc::Create(color,
                                                     viewMatrix,
                                                     texture,
                                                     params,
                                                     widthAdjust,
                                                     flags,
                                                     this->usesLocalCoords());
    } else {
#ifdef SK_GAMMA_APPLY_TO_A8
        U8CPU lum = SkColorSpaceLuminance::computeLuminance(SK_GAMMA_EXPONENT, filteredColor);
        float correction = (*fDistanceAdjustTable)[lum >> kDistanceAdjustLumShift];
        return GrDistanceFieldA8TextGeoProc::Create(color,
                                                    viewMatrix,
                                                    texture,
                                                    params,
                                                    correction,
                                                    flags,
                                                    this->usesLocalCoords());
#else
        return GrDistanceFieldA8TextGeoProc::Create(color,
                                                    viewMatrix,
                                                    texture,
                                                    params,
                                                    flags,
                                                    this->usesLocalCoords());
#endif
    }

}

void GrBlobRegenHelper::flush() {
    fBatch->flush(fTarget, fFlushInfo);
    fTarget->initDraw(fGP, fBatch->pipeline());
}
