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

#ifndef GrAtlasTextContext_DEFINED
#define GrAtlasTextContext_DEFINED

#include "GrTextContext.h"

#include "GrBatchAtlas.h"
#include "GrBatchFontCache.h"
#include "GrGeometryProcessor.h"
#include "SkDescriptor.h"
#include "GrMemoryPool.h"
#include "SkMaskFilter.h"
#include "SkTextBlob.h"
#include "SkTInternalLList.h"

#ifdef GR_TEST_UTILS
#include "GrBatchTest.h"
#endif

class BitmapTextBatch;
class GrDrawContext;
class GrDrawTarget;
class GrPipelineBuilder;
class GrTextBlobCache;

/*
 * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
 * TODO replace GrBitmapTextContext
 */
class GrAtlasTextContext : public GrTextContext {
public:
    static GrAtlasTextContext* Create(GrContext*, GrDrawContext*, const SkSurfaceProps&);

private:
    GrAtlasTextContext(GrContext*, GrDrawContext*, const SkSurfaceProps&);
    ~GrAtlasTextContext() override {}

    bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
                 const SkPaint&, const SkMatrix& viewMatrix) override;

    void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                    const SkMatrix& viewMatrix, const char text[], size_t byteLength,
                    SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
    void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&,
                       const SkPaint&, const SkMatrix& viewMatrix,
                       const char text[], size_t byteLength,
                       const SkScalar pos[], int scalarsPerPosition,
                       const SkPoint& offset, const SkIRect& regionClipBounds) override;
    void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
                      const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
                      SkDrawFilter*, const SkIRect& clipBounds) override;

    /*
     * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
     * on the GPU.  These are initially created with valid positions and colors, but invalid
     * texture coordinates.  The BitmapTextBlob itself has a few Blob-wide properties, and also
     * consists of a number of runs.  Runs inside a blob are flushed individually so they can be
     * reordered.
     *
     * The only thing(aside from a memcopy) required to flush a BitmapTextBlob is to ensure that
     * the GrAtlas will not evict anything the Blob needs.
     */
    struct BitmapTextBlob : public SkRefCnt {
        SK_DECLARE_INTERNAL_LLIST_INTERFACE(BitmapTextBlob);

        /*
         * Each Run inside of the blob can have its texture coordinates regenerated if required.
         * To determine if regeneration is necessary, fAtlasGeneration is used.  If there have been
         * any evictions inside of the atlas, then we will simply regenerate Runs.  We could track
         * this at a more fine grained level, but its not clear if this is worth it, as evictions
         * should be fairly rare.
         *
         * One additional point, each run can contain glyphs with any of the three mask formats.
         * We call these SubRuns.  Because a subrun must be a contiguous range, we have to create
         * a new subrun each time the mask format changes in a run.  In theory, a run can have as
         * many SubRuns as it has glyphs, ie if a run alternates between color emoji and A8.  In
         * practice, the vast majority of runs have only a single subrun.
         *
         * Finally, for runs where the entire thing is too large for the GrAtlasTextContext to
         * handle, we have a bit to mark the run as flusahable via rendering as paths.  It is worth
         * pointing. It would be a bit expensive to figure out ahead of time whether or not a run
         * can flush in this manner, so we always allocate vertices for the run, regardless of
         * whether or not it is too large.  The benefit of this strategy is that we can always reuse
         * a blob allocation regardless of viewmatrix changes.  We could store positions for these
         * glyphs.  However, its not clear if this is a win because we'd still have to either go the
         * glyph cache to get the path at flush time, or hold onto the path in the cache, which
         * would greatly increase the memory of these cached items.
         */
        struct Run {
            Run()
                : fColor(GrColor_ILLEGAL)
                , fInitialized(false)
                , fDrawAsPaths(false) {
                fVertexBounds.setLargestInverted();
                // To ensure we always have one subrun, we push back a fresh run here
                fSubRunInfo.push_back();
            }
            struct SubRunInfo {
                SubRunInfo()
                    : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration)
                    , fVertexStartIndex(0)
                    , fVertexEndIndex(0)
                    , fGlyphStartIndex(0)
                    , fGlyphEndIndex(0)
                    , fDrawAsDistanceFields(false) {}
                SubRunInfo(const SubRunInfo& that)
                    : fBulkUseToken(that.fBulkUseToken)
                    , fStrike(SkSafeRef(that.fStrike.get()))
                    , fAtlasGeneration(that.fAtlasGeneration)
                    , fVertexStartIndex(that.fVertexStartIndex)
                    , fVertexEndIndex(that.fVertexEndIndex)
                    , fGlyphStartIndex(that.fGlyphStartIndex)
                    , fGlyphEndIndex(that.fGlyphEndIndex)
                    , fTextRatio(that.fTextRatio)
                    , fMaskFormat(that.fMaskFormat)
                    , fDrawAsDistanceFields(that.fDrawAsDistanceFields)
                    , fUseLCDText(that.fUseLCDText) {
                }
                // Distance field text cannot draw coloremoji, and so has to fall back.  However,
                // though the distance field text and the coloremoji may share the same run, they
                // will have different descriptors.  If fOverrideDescriptor is non-NULL, then it
                // will be used in place of the run's descriptor to regen texture coords
                // TODO we could have a descriptor cache, it would reduce the size of these blobs
                // significantly, and then the subrun could just have a refed pointer to the
                // correct descriptor.
                GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken;
                SkAutoTUnref<GrBatchTextStrike> fStrike;
                uint64_t fAtlasGeneration;
                size_t fVertexStartIndex;
                size_t fVertexEndIndex;
                uint32_t fGlyphStartIndex;
                uint32_t fGlyphEndIndex;
                SkScalar fTextRatio; // df property
                GrMaskFormat fMaskFormat;
                bool fDrawAsDistanceFields; // df property
                bool fUseLCDText; // df property
            };

            SubRunInfo& push_back() {
                // Forward glyph / vertex information to seed the new sub run
                SubRunInfo& newSubRun = fSubRunInfo.push_back();
                SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1);

                newSubRun.fGlyphStartIndex = prevSubRun.fGlyphEndIndex;
                newSubRun.fGlyphEndIndex = prevSubRun.fGlyphEndIndex;

                newSubRun.fVertexStartIndex = prevSubRun.fVertexEndIndex;
                newSubRun.fVertexEndIndex = prevSubRun.fVertexEndIndex;
                return newSubRun;
            }
            static const int kMinSubRuns = 1;
            SkAutoTUnref<SkTypeface> fTypeface;
            SkRect fVertexBounds;
            SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo;
            SkAutoDescriptor fDescriptor;
            SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties
            GrColor fColor;
            bool fInitialized;
            bool fDrawAsPaths;
        };

        struct BigGlyph {
            BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy)
                : fPath(path)
                , fVx(vx)
                , fVy(vy) {}
            SkPath fPath;
            SkScalar fVx;
            SkScalar fVy;
        };

        struct Key {
            Key() {
                sk_bzero(this, sizeof(Key));
            }
            uint32_t fUniqueID;
            // Color may affect the gamma of the mask we generate, but in a fairly limited way.
            // Each color is assigned to on of a fixed number of buckets based on its
            // luminance. For each luminance bucket there is a "canonical color" that
            // represents the bucket.  This functionality is currently only supported for A8
            SkColor fCanonicalColor;
            SkPaint::Style fStyle;
            SkPixelGeometry fPixelGeometry;
            bool fHasBlur;

            bool operator==(const Key& other) const {
                return 0 == memcmp(this, &other, sizeof(Key));
            }
        };

        struct StrokeInfo {
            SkScalar fFrameWidth;
            SkScalar fMiterLimit;
            SkPaint::Join fJoin;
        };

        enum TextType {
            kHasDistanceField_TextType = 0x1,
            kHasBitmap_TextType = 0x2,
        };

        // all glyph / vertex offsets are into these pools.
        unsigned char* fVertices;
        GrGlyph** fGlyphs;
        Run* fRuns;
        GrMemoryPool* fPool;
        SkMaskFilter::BlurRec fBlurRec;
        StrokeInfo fStrokeInfo;
        SkTArray<BigGlyph> fBigGlyphs;
        Key fKey;
        SkMatrix fViewMatrix;
        SkColor fPaintColor;
        SkScalar fX;
        SkScalar fY;

        // We can reuse distance field text, but only if the new viewmatrix would not result in
        // a mip change.  Because there can be multiple runs in a blob, we track the overall
        // maximum minimum scale, and minimum maximum scale, we can support before we need to regen
        SkScalar fMaxMinScale;
        SkScalar fMinMaxScale;
        int fRunCount;
        uint8_t fTextType;

        BitmapTextBlob()
            : fMaxMinScale(-SK_ScalarMax)
            , fMinMaxScale(SK_ScalarMax)
            , fTextType(0) {}

        ~BitmapTextBlob() override {
            for (int i = 0; i < fRunCount; i++) {
                fRuns[i].~Run();
            }
        }

        static const Key& GetKey(const BitmapTextBlob& blob) {
            return blob.fKey;
        }

        static uint32_t Hash(const Key& key) {
            return SkChecksum::Murmur3(&key, sizeof(Key));
        }

        void operator delete(void* p) {
            BitmapTextBlob* blob = reinterpret_cast<BitmapTextBlob*>(p);
            blob->fPool->release(p);
        }
        void* operator new(size_t) {
            SkFAIL("All blobs are created by placement new.");
            return sk_malloc_throw(0);
        }

        void* operator new(size_t, void* p) { return p; }
        void operator delete(void* target, void* placement) {
            ::operator delete(target, placement);
        }

        bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceField_TextType); }
        bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
        void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
        void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
    };

    typedef BitmapTextBlob::Run Run;
    typedef Run::SubRunInfo PerSubRunInfo;

    inline bool canDrawAsDistanceFields(const SkPaint&, const SkMatrix& viewMatrix);
    BitmapTextBlob* setupDFBlob(int glyphCount, const SkPaint& origPaint,
                                const SkMatrix& viewMatrix, SkGlyphCache** cache,
                                SkPaint* dfPaint, SkScalar* textRatio);
    void bmpAppendGlyph(BitmapTextBlob*, int runIndex, const SkGlyph&, int left, int top,
                        GrColor color, GrFontScaler*, const SkIRect& clipRect);
    bool dfAppendGlyph(BitmapTextBlob*, int runIndex, const SkGlyph&, SkScalar sx, SkScalar sy,
                       GrColor color, GrFontScaler*, const SkIRect& clipRect, SkScalar textRatio,
                       const SkMatrix& viewMatrix);
    inline void appendGlyphPath(BitmapTextBlob*, GrGlyph*, GrFontScaler*, const SkGlyph&,
                                SkScalar x, SkScalar y);
    inline void appendGlyphCommon(BitmapTextBlob*, Run*, Run::SubRunInfo*,
                                  const SkRect& positions, GrColor color,
                                  size_t vertexStride, bool useVertexColor,
                                  GrGlyph*);

    inline void flushRunAsPaths(GrRenderTarget*,
                                const SkTextBlob::RunIterator&, const GrClip& clip,
                                const SkPaint&, SkDrawFilter*,
                                const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
                                SkScalar y);
    inline BitmapTextBatch* createBatch(BitmapTextBlob*, const PerSubRunInfo&,
                                        int glyphCount, int run, int subRun,
                                        GrColor, SkScalar transX, SkScalar transY,
                                        const SkPaint&);
    inline void flushRun(GrPipelineBuilder*, BitmapTextBlob*, int run, GrColor,
                         SkScalar transX, SkScalar transY, const SkPaint&);
    inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget*,
                               const GrClip& clip, const SkPaint& skPaint,
                               SkScalar transX, SkScalar transY, const SkIRect& clipBounds);

    // We have to flush SkTextBlobs differently from drawText / drawPosText
    void flush(const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*,
               const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&,
               const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y,
               SkScalar transX, SkScalar transY);
    void flush(BitmapTextBlob*, GrRenderTarget*, const SkPaint&,
               const GrPaint&, const GrClip&, const SkIRect& clipBounds);

    // A helper for drawing BitmapText in a run of distance fields
    inline void fallbackDrawPosText(BitmapTextBlob*, int runIndex,
                                    GrRenderTarget*, const GrClip&,
                                    const GrPaint&,
                                    const SkPaint&, const SkMatrix& viewMatrix,
                                    const SkTDArray<char>& fallbackTxt,
                                    const SkTDArray<SkScalar>& fallbackPos,
                                    int scalarsPerPosition,
                                    const SkPoint& offset,
                                    const SkIRect& clipRect);

    void internalDrawBMPText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
                             GrColor color, const SkMatrix& viewMatrix,
                             const char text[], size_t byteLength,
                             SkScalar x, SkScalar y, const SkIRect& clipRect);
    void internalDrawBMPPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
                                GrColor color, const SkMatrix& viewMatrix,
                                const char text[], size_t byteLength,
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset, const SkIRect& clipRect);

    void internalDrawDFText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
                            GrColor color, const SkMatrix& viewMatrix,
                            const char text[], size_t byteLength,
                            SkScalar x, SkScalar y, const SkIRect& clipRect,
                            SkScalar textRatio,
                            SkTDArray<char>* fallbackTxt,
                            SkTDArray<SkScalar>* fallbackPos,
                            SkPoint* offset, const SkPaint& origPaint);
    void internalDrawDFPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
                               GrColor color, const SkMatrix& viewMatrix,
                               const char text[], size_t byteLength,
                               const SkScalar pos[], int scalarsPerPosition,
                               const SkPoint& offset, const SkIRect& clipRect,
                               SkScalar textRatio,
                               SkTDArray<char>* fallbackTxt,
                               SkTDArray<SkScalar>* fallbackPos);

    // sets up the descriptor on the blob and returns a detached cache.  Client must attach
    inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd);
    inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma);
    static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY,
                                          const BitmapTextBlob&, const SkPaint&,
                                          const SkMaskFilter::BlurRec&,
                                          const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
    void regenerateTextBlob(BitmapTextBlob* bmp, const SkPaint& skPaint, GrColor,
                            const SkMatrix& viewMatrix,
                            const SkTextBlob* blob, SkScalar x, SkScalar y,
                            SkDrawFilter* drawFilter, const SkIRect& clipRect, GrRenderTarget*,
                            const GrClip&, const GrPaint&);
    inline static bool HasLCD(const SkTextBlob*);
    inline void initDistanceFieldPaint(BitmapTextBlob*, SkPaint*, SkScalar* textRatio,
                                       const SkMatrix&);

    // Test methods
    // TODO this is really ugly.  It'd be much nicer if positioning could be moved to batch
    inline BitmapTextBlob* createDrawTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
                                              const SkPaint&, const SkMatrix& viewMatrix,
                                              const char text[], size_t byteLength,
                                              SkScalar x, SkScalar y,
                                              const SkIRect& regionClipBounds);
    inline BitmapTextBlob* createDrawPosTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
                                                 const SkPaint&, const SkMatrix& viewMatrix,
                                                 const char text[], size_t byteLength,
                                                 const SkScalar pos[], int scalarsPerPosition,
                                                 const SkPoint& offset,
                                                 const SkIRect& regionClipBounds);

    // Distance field text needs this table to compute a value for use in the fragment shader.
    // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
    // refcnted and malloced
    struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> {
        DistanceAdjustTable() { this->buildDistanceAdjustTable(); }
        ~DistanceAdjustTable() { SkDELETE_ARRAY(fTable); }

        const SkScalar& operator[] (int i) const {
            return fTable[i];
        }

    private:
        void buildDistanceAdjustTable();

        SkScalar* fTable;
    };

    GrBatchTextStrike* fCurrStrike;
    GrTextBlobCache* fCache;
    SkAutoTUnref<DistanceAdjustTable> fDistanceAdjustTable;

    friend class GrTextBlobCache;
    friend class BitmapTextBatch;

#ifdef GR_TEST_UTILS
    BATCH_TEST_FRIEND(TextBlobBatch);
#endif

    typedef GrTextContext INHERITED;
};

#endif
