/* * 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 SkPictureReplacementPlayback_DEFINED #define SkPictureReplacementPlayback_DEFINED #include "SkPicturePlayback.h" // This playback class replaces complete "saveLayer ... restore" runs with a // single drawBitmap call. class SkPictureReplacementPlayback : public SkPicturePlayback { public: // PlaybackReplacements collects op ranges that can be replaced with // a single drawBitmap call (using a precomputed bitmap). class PlaybackReplacements { public: // All the operations between fStart and fStop (inclusive) will be replaced with // a single drawBitmap call using fPos, fBM and fPaint. // fPaint will be NULL if the picture's paint wasn't copyable struct ReplacementInfo { size_t fStart; size_t fStop; SkIPoint fPos; SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD const SkPaint* fPaint; // Note: this object doesn't own the paint SkIRect fSrcRect; }; ~PlaybackReplacements() { this->freeAll(); } // Add a new replacement range. The replacement ranges should be // sorted in increasing order and non-overlapping (esp. no nested // saveLayers). ReplacementInfo* push(); // look up a replacement range by its start offset ReplacementInfo* lookupByStart(size_t start); private: SkTDArray fReplacements; void freeAll(); #ifdef SK_DEBUG void validate() const; #endif }; // This class doesn't take ownership of either 'replacements' or 'activeOpsList' // The caller must guarantee they exist across any calls to 'draw'. // 'activeOpsList' can be NULL but in that case BBH acceleration will not // be used ('replacements' can be NULL too but that defeats the purpose // of using this class). SkPictureReplacementPlayback(const SkPicture* picture, PlaybackReplacements* replacements, const SkPicture::OperationList* activeOpsList) : INHERITED(picture) , fReplacements(replacements) , fActiveOpsList(activeOpsList) { } virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*) SK_OVERRIDE; private: PlaybackReplacements* fReplacements; const SkPicture::OperationList* fActiveOpsList; // This method checks if the current op pointed at by 'iter' and 'reader' // is within a replacement range. If so, it issues the drawBitmap call, // updates 'iter' and 'reader' to be after the restore operation, and // returns true. If the operation is not in a replacement range (and thus // needs to be drawn normally) false is returned. bool replaceOps(SkPictureStateTree::Iterator* iter, SkReader32* reader, SkCanvas* canvas, const SkMatrix& initialMatrix); typedef SkPicturePlayback INHERITED; }; #endif