180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkChunkAlloc.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGPipe.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPicture.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTDArray.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkCanvas;
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkMatrix;
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass PipeController : public SkGPipeController {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc = NULL);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ~PipeController();
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const void* getData() { return (const char*) fBlock + fBytesWritten; }
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeReader fReader;
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* fBlock;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t fBlockSize;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t fBytesWritten;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeReader::Status fStatus;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass TiledPipeController : public PipeController {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    TiledPipeController(const SkBitmap&, SkPicture::InstallPixelRefProc proc = NULL,
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        const SkMatrix* initialMatrix = NULL);
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ~TiledPipeController() {};
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual int numberOfReaders() const SK_OVERRIDE { return NumberOfTiles; }
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NumberOfTiles = 10
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeReader fReaders[NumberOfTiles - 1];
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap fBitmaps[NumberOfTiles];
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef PipeController INHERITED;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Borrowed (and modified) from SkDeferredCanvas.cpp::DeferredPipeController.
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Allows playing back from multiple threads, but does not do the threading itself.
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass ThreadSafePipeController : public SkGPipeController {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ThreadSafePipeController(int numberOfReaders);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual int numberOfReaders() const SK_OVERRIDE { return fNumberOfReaders; }
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Play the stored drawing commands to the specified canvas. If SkGPipeWriter::startRecording
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * used the flag SkGPipeWriter::kSimultaneousReaders_Flag, this can be called from different
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * threads simultaneously.
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void draw(SkCanvas*);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kMinBlockSize = 4096
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    struct PipeBlock {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        PipeBlock(void* block, size_t bytes) { fBlock = block, fBytes = bytes; }
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // Stream of draw commands written by the SkGPipeWriter. Allocated by fAllocator, which will
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // handle freeing it.
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* fBlock;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // Number of bytes that were written to fBlock.
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        size_t fBytes;
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void* fBlock;
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t fBytesWritten;
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkChunkAlloc fAllocator;
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDArray<PipeBlock> fBlockList;
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int fNumberOfReaders;
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
88