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

#ifndef SkRecord_DEFINED
#define SkRecord_DEFINED

#include "SkRecords.h"
#include "SkTLogic.h"
#include "SkTemplates.h"
#include "SkVarAlloc.h"

// SkRecord (REC-ord) represents a sequence of SkCanvas calls, saved for future use.
// These future uses may include: replay, optimization, serialization, or combinations of those.
//
// Though an enterprising user may find calling alloc(), append(), visit(), and mutate() enough to
// work with SkRecord, you probably want to look at SkRecorder which presents an SkCanvas interface
// for creating an SkRecord, and SkRecordDraw which plays an SkRecord back into another SkCanvas.
//
// SkRecord often looks like it's compatible with any type T, but really it's compatible with any
// type T which has a static const SkRecords::Type kType.  That is to say, SkRecord is compatible
// only with SkRecords::* structs defined in SkRecords.h.  Your compiler will helpfully yell if you
// get this wrong.

class SkRecord : public SkNVRefCnt<SkRecord> {
    enum {
        kFirstReserveCount = 64 / sizeof(void*),
    };
public:
    SkRecord() : fCount(0), fReserved(0), fAlloc(8/*start block sizes at 256 bytes*/) {}
    ~SkRecord();

    // Returns the number of canvas commands in this SkRecord.
    unsigned count() const { return fCount; }

    // Visit the i-th canvas command with a functor matching this interface:
    //   template <typename T>
    //   R operator()(const T& record) { ... }
    // This operator() must be defined for at least all SkRecords::*.
    template <typename R, typename F>
    R visit(unsigned i, F& f) const {
        SkASSERT(i < this->count());
        return fRecords[i].visit<R>(fTypes[i], f);
    }

    // Mutate the i-th canvas command with a functor matching this interface:
    //   template <typename T>
    //   R operator()(T* record) { ... }
    // This operator() must be defined for at least all SkRecords::*.
    template <typename R, typename F>
    R mutate(unsigned i, F& f) {
        SkASSERT(i < this->count());
        return fRecords[i].mutate<R>(fTypes[i], f);
    }
    // TODO: It'd be nice to infer R from F for visit and mutate if we ever get std::result_of.

    // Allocate contiguous space for count Ts, to be freed when the SkRecord is destroyed.
    // Here T can be any class, not just those from SkRecords.  Throws on failure.
    template <typename T>
    T* alloc(size_t count = 1) {
        // Bump up to the next pointer width if needed, so all allocations start pointer-aligned.
        return (T*)fAlloc.alloc(sizeof(T) * count, SK_MALLOC_THROW);
    }

    // Add a new command of type T to the end of this SkRecord.
    // You are expected to placement new an object of type T onto this pointer.
    template <typename T>
    T* append() {
        if (fCount == fReserved) {
            this->grow();
        }
        fTypes[fCount] = T::kType;
        return fRecords[fCount++].set(this->allocCommand<T>());
    }

    // Replace the i-th command with a new command of type T.
    // You are expected to placement new an object of type T onto this pointer.
    // References to the original command are invalidated.
    template <typename T>
    T* replace(unsigned i) {
        SkASSERT(i < this->count());

        Destroyer destroyer;
        this->mutate<void>(i, destroyer);

        fTypes[i] = T::kType;
        return fRecords[i].set(this->allocCommand<T>());
    }

    // Replace the i-th command with a new command of type T.
    // You are expected to placement new an object of type T onto this pointer.
    // You must show proof that you've already adopted the existing command.
    template <typename T, typename Existing>
    T* replace(unsigned i, const SkRecords::Adopted<Existing>& proofOfAdoption) {
        SkASSERT(i < this->count());

        SkASSERT(Existing::kType == fTypes[i]);
        SkASSERT(proofOfAdoption == fRecords[i].ptr<Existing>());

        fTypes[i] = T::kType;
        return fRecords[i].set(this->allocCommand<T>());
    }

    // Does not return the bytes in any pointers embedded in the Records; callers
    // need to iterate with a visitor to measure those they care for.
    size_t bytesUsed() const;

private:
    // Implementation notes!
    //
    // Logically an SkRecord is structured as an array of pointers into a big chunk of memory where
    // records representing each canvas draw call are stored:
    //
    // fRecords:  [*][*][*]...
    //             |  |  |
    //             |  |  |
    //             |  |  +---------------------------------------+
    //             |  +-----------------+                        |
    //             |                    |                        |
    //             v                    v                        v
    //   fAlloc:  [SkRecords::DrawRect][SkRecords::DrawPosTextH][SkRecords::DrawRect]...
    //
    // In the scheme above, the pointers in fRecords are void*: they have no type.  The type is not
    // stored in fAlloc either; we just write raw data there.  But we need that type information.
    // Here are some options:
    //   1) use inheritance, virtuals, and vtables to make the fRecords pointers smarter
    //   2) store the type data manually in fAlloc at the start of each record
    //   3) store the type data manually somewhere with fRecords
    //
    // This code uses approach 3).  The implementation feels very similar to 1), but it's
    // devirtualized instead of using the language's polymorphism mechanisms.  This lets us work
    // with the types themselves (as SkRecords::Type), a sort of limited free RTTI; it lets us pay
    // only 1 byte to store the type instead of a full pointer (4-8 bytes); and it leads to better
    // decoupling between the SkRecords::* record types and the operations performed on them in
    // visit() or mutate().  The recorded canvas calls don't have to have any idea about the
    // operations performed on them.
    //
    // We store the types in a parallel fTypes array, mainly so that they can be tightly packed as
    // single bytes.  This has the side effect of allowing very fast analysis passes over an
    // SkRecord looking for just patterns of draw commands (or using this as a quick reject
    // mechanism) though there's admittedly not a very good API exposed publically for this.
    //
    // The cost to append a T into this structure is 1 + sizeof(void*) + sizeof(T).

    // A mutator that can be used with replace to destroy canvas commands.
    struct Destroyer {
        template <typename T>
        void operator()(T* record) { record->~T(); }
    };

    // Logically the same as SkRecords::Type, but packed into 8 bits.
    struct Type8 {
    public:
        // This intentionally converts implicitly back and forth.
        Type8(SkRecords::Type type) : fType(type) { SkASSERT(*this == type); }
        operator SkRecords::Type () { return (SkRecords::Type)fType; }

    private:
        uint8_t fType;
    };

    // No point in allocating any more than one of an empty struct.
    // We could just return NULL but it's sort of confusing to return NULL on success.
    template <typename T>
    SK_WHEN(SkTIsEmpty<T>, T*) allocCommand() {
        static T singleton = {};
        return &singleton;
    }

    template <typename T>
    SK_WHEN(!SkTIsEmpty<T>, T*) allocCommand() { return this->alloc<T>(); }

    // Called when we've run out of room to record new commands.
    void grow();

    // An untyped pointer to some bytes in fAlloc.  This is the interface for polymorphic dispatch:
    // visit() and mutate() work with the parallel fTypes array to do the work of a vtable.
    struct Record {
    public:
        // Point this record to its data in fAlloc.  Returns ptr for convenience.
        template <typename T>
        T* set(T* ptr) {
            fPtr = ptr;
            return ptr;
        }

        // Get the data in fAlloc, assuming it's of type T.
        template <typename T>
        T* ptr() const { return (T*)fPtr; }

        // Visit this record with functor F (see public API above) assuming the record we're
        // pointing to has this type.
        template <typename R, typename F>
        R visit(Type8 type, F& f) const {
        #define CASE(T) case SkRecords::T##_Type: return f(*this->ptr<SkRecords::T>());
            switch(type) { SK_RECORD_TYPES(CASE) }
        #undef CASE
            SkDEBUGFAIL("Unreachable");
            return R();
        }

        // Mutate this record with functor F (see public API above) assuming the record we're
        // pointing to has this type.
        template <typename R, typename F>
        R mutate(Type8 type, F& f) {
        #define CASE(T) case SkRecords::T##_Type: return f(this->ptr<SkRecords::T>());
            switch(type) { SK_RECORD_TYPES(CASE) }
        #undef CASE
            SkDEBUGFAIL("Unreachable");
            return R();
        }

    private:
        void* fPtr;
    };

    // fAlloc needs to be a data structure which can append variable length data in contiguous
    // chunks, returning a stable handle to that data for later retrieval.
    //
    // fRecords and fTypes need to be data structures that can append fixed length data, and need to
    // support efficient random access and forward iteration.  (They don't need to be contiguous.)

    // fCount and fReserved measure both fRecords and fTypes, which always grow in lock step.
    unsigned fCount;
    unsigned fReserved;
    SkAutoTMalloc<Record> fRecords;
    SkAutoTMalloc<Type8> fTypes;
    SkVarAlloc fAlloc;
    // Strangely the order of these fields matters.  If the unsigneds don't go first we're 56 bytes.
    // tomhudson and mtklein have no idea why.
};
SK_COMPILE_ASSERT(sizeof(SkRecord) <= 56, SkRecordSize);

#endif//SkRecord_DEFINED
