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

#include "SkBitmap.h"
#include "SkChunkAlloc.h"
#include "SkGPipe.h"
#include "SkPicture.h"
#include "SkTDArray.h"

class SkCanvas;
class SkMatrix;

class PipeController : public SkGPipeController {
public:
    PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc = NULL);
    virtual ~PipeController();
    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
protected:
    const void* getData() { return (const char*) fBlock + fBytesWritten; }
    SkGPipeReader fReader;
private:
    void* fBlock;
    size_t fBlockSize;
    size_t fBytesWritten;
    SkGPipeReader::Status fStatus;
};

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

class TiledPipeController : public PipeController {
public:
    TiledPipeController(const SkBitmap&, SkPicture::InstallPixelRefProc proc = NULL,
                        const SkMatrix* initialMatrix = NULL);
    virtual ~TiledPipeController() {};
    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
    virtual int numberOfReaders() const SK_OVERRIDE { return NumberOfTiles; }
private:
    enum {
        NumberOfTiles = 10
    };
    SkGPipeReader fReaders[NumberOfTiles - 1];
    SkBitmap fBitmaps[NumberOfTiles];
    typedef PipeController INHERITED;
};

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

/**
 * Borrowed (and modified) from SkDeferredCanvas.cpp::DeferredPipeController.
 * Allows playing back from multiple threads, but does not do the threading itself.
 */
class ThreadSafePipeController : public SkGPipeController {
public:
    ThreadSafePipeController(int numberOfReaders);
    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
    virtual int numberOfReaders() const SK_OVERRIDE { return fNumberOfReaders; }

    /**
     * Play the stored drawing commands to the specified canvas. If SkGPipeWriter::startRecording
     * used the flag SkGPipeWriter::kSimultaneousReaders_Flag, this can be called from different
     * threads simultaneously.
     */
    void draw(SkCanvas*);
private:
    enum {
        kMinBlockSize = 4096
    };
    struct PipeBlock {
        PipeBlock(void* block, size_t bytes) { fBlock = block, fBytes = bytes; }
        // Stream of draw commands written by the SkGPipeWriter. Allocated by fAllocator, which will
        // handle freeing it.
        void* fBlock;
        // Number of bytes that were written to fBlock.
        size_t fBytes;
    };
    void* fBlock;
    size_t fBytesWritten;
    SkChunkAlloc fAllocator;
    SkTDArray<PipeBlock> fBlockList;
    int fNumberOfReaders;
};
