/* * 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(); void* requestBlock(size_t minRequest, size_t* actual) override; void notifyWritten(size_t bytes) 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() {}; void notifyWritten(size_t bytes) override; int numberOfReaders() const 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); void* requestBlock(size_t minRequest, size_t* actual) override; void notifyWritten(size_t bytes) override; int numberOfReaders() const 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; };