michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #include "SkBitmap.h" michael@0: #include "SkChunkAlloc.h" michael@0: #include "SkGPipe.h" michael@0: #include "SkPicture.h" michael@0: #include "SkTDArray.h" michael@0: michael@0: class SkCanvas; michael@0: class SkMatrix; michael@0: michael@0: class PipeController : public SkGPipeController { michael@0: public: michael@0: PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc = NULL); michael@0: virtual ~PipeController(); michael@0: virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE; michael@0: virtual void notifyWritten(size_t bytes) SK_OVERRIDE; michael@0: protected: michael@0: const void* getData() { return (const char*) fBlock + fBytesWritten; } michael@0: SkGPipeReader fReader; michael@0: private: michael@0: void* fBlock; michael@0: size_t fBlockSize; michael@0: size_t fBytesWritten; michael@0: SkGPipeReader::Status fStatus; michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: class TiledPipeController : public PipeController { michael@0: public: michael@0: TiledPipeController(const SkBitmap&, SkPicture::InstallPixelRefProc proc = NULL, michael@0: const SkMatrix* initialMatrix = NULL); michael@0: virtual ~TiledPipeController() {}; michael@0: virtual void notifyWritten(size_t bytes) SK_OVERRIDE; michael@0: virtual int numberOfReaders() const SK_OVERRIDE { return NumberOfTiles; } michael@0: private: michael@0: enum { michael@0: NumberOfTiles = 10 michael@0: }; michael@0: SkGPipeReader fReaders[NumberOfTiles - 1]; michael@0: SkBitmap fBitmaps[NumberOfTiles]; michael@0: typedef PipeController INHERITED; michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * Borrowed (and modified) from SkDeferredCanvas.cpp::DeferredPipeController. michael@0: * Allows playing back from multiple threads, but does not do the threading itself. michael@0: */ michael@0: class ThreadSafePipeController : public SkGPipeController { michael@0: public: michael@0: ThreadSafePipeController(int numberOfReaders); michael@0: virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE; michael@0: virtual void notifyWritten(size_t bytes) SK_OVERRIDE; michael@0: virtual int numberOfReaders() const SK_OVERRIDE { return fNumberOfReaders; } michael@0: michael@0: /** michael@0: * Play the stored drawing commands to the specified canvas. If SkGPipeWriter::startRecording michael@0: * used the flag SkGPipeWriter::kSimultaneousReaders_Flag, this can be called from different michael@0: * threads simultaneously. michael@0: */ michael@0: void draw(SkCanvas*); michael@0: private: michael@0: enum { michael@0: kMinBlockSize = 4096 michael@0: }; michael@0: struct PipeBlock { michael@0: PipeBlock(void* block, size_t bytes) { fBlock = block, fBytes = bytes; } michael@0: // Stream of draw commands written by the SkGPipeWriter. Allocated by fAllocator, which will michael@0: // handle freeing it. michael@0: void* fBlock; michael@0: // Number of bytes that were written to fBlock. michael@0: size_t fBytes; michael@0: }; michael@0: void* fBlock; michael@0: size_t fBytesWritten; michael@0: SkChunkAlloc fAllocator; michael@0: SkTDArray fBlockList; michael@0: int fNumberOfReaders; michael@0: };