blob: 166a3bfbd350b326925e27380d6573b13a2af393 [file] [log] [blame]
/*
* 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<ReplacementInfo> 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