/*
 * 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 GrBatchAtlas_DEFINED
#define GrBatchAtlas_DEFINED

#include "GrTexture.h"
#include "SkPoint.h"
#include "SkTDArray.h"
#include "SkTInternalLList.h"

class BatchPlot;
class GrBatchTarget;
class GrRectanizer;

typedef SkTInternalLList<BatchPlot> GrBatchPlotList;

class GrBatchAtlas {
public:
    typedef uint64_t BatchToken;
    // An AtlasID is an opaque handle which callers can use to determine if the atlas contains
    // a specific piece of data
    typedef uint32_t AtlasID;
    static const uint32_t kInvalidAtlasID = 0;
    static const uint64_t kInvalidAtlasGeneration = 0;

    // A function pointer for use as a callback during eviction.  Whenever GrBatchAtlas evicts a
    // specific AtlasID, it will call all of the registered listeners so they can optionally process
    // the eviction
    typedef void (*EvictionFunc)(GrBatchAtlas::AtlasID, void*);

    GrBatchAtlas(GrTexture*, int numPlotsX, int numPlotsY);
    ~GrBatchAtlas();

    // Adds a width x height subimage to the atlas. Upon success it returns
    // the containing GrPlot and absolute location in the backing texture.
    // NULL is returned if the subimage cannot fit in the atlas.
    // If provided, the image data will be written to the CPU-side backing bitmap.
    bool addToAtlas(AtlasID*, GrBatchTarget*, int width, int height, const void* image,
                    SkIPoint16* loc);

    GrTexture* getTexture() const { return fTexture; }

    uint64_t atlasGeneration() const { return fAtlasGeneration; }
    bool hasID(AtlasID id);
    void setLastRefToken(AtlasID id, BatchToken batchToken);
    void registerEvictionCallback(EvictionFunc func, void* userData) {
        EvictionData* data = fEvictionCallbacks.append();
        data->fFunc = func;
        data->fData = userData;
    }

private:
    int getIndexFromID(AtlasID id) {
        return id & 0xffff;
    }

    int getGenerationFromID(AtlasID id) {
        return (id >> 16) & 0xffff;
    }

    inline void updatePlot(GrBatchTarget*, AtlasID*, BatchPlot*);

    inline void makeMRU(BatchPlot* plot);

    inline void processEviction(AtlasID);

    GrTexture* fTexture;
    int fNumPlotsX;
    int fNumPlotsY;
    int fPlotWidth;
    int fPlotHeight;
    size_t fBPP;
    uint64_t fAtlasGeneration;

    struct EvictionData {
        EvictionFunc fFunc;
        void* fData;
    };

    SkTDArray<EvictionData> fEvictionCallbacks;
    // allocated array of GrBatchPlots
    SkAutoTUnref<BatchPlot>* fPlotArray;
    // LRU list of GrPlots (MRU at head - LRU at tail)
    GrBatchPlotList fPlotList;
};

#endif
