| Index: src/core/SkPictureRecord.cpp
|
| ===================================================================
|
| --- src/core/SkPictureRecord.cpp (revision 13263)
|
| +++ src/core/SkPictureRecord.cpp (working copy)
|
| @@ -13,6 +13,137 @@
|
| #include "SkDevice.h"
|
| #include "SkPictureStateTree.h"
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| +bool MatrixClipState::ClipInfo::clipPath(SkPictureRecord* picRecord,
|
| + const SkPath& path,
|
| + SkRegion::Op op,
|
| + bool doAA,
|
| + const SkMatrix& matrix) {
|
| + int pathID = picRecord->addPathToHeap(path);
|
| +
|
| + ClipOp* newClip = fClips.append();
|
| + newClip->fClipType = kPath_ClipType;
|
| + newClip->fGeom.fPathID = pathID;
|
| + newClip->fOp = op;
|
| + newClip->fDoAA = doAA;
|
| + newClip->fMatrix = matrix;
|
| + newClip->fOffset = kInvalidJumpOffset;
|
| + return false;
|
| +}
|
| +
|
| +bool MatrixClipState::ClipInfo::clipRegion(SkPictureRecord* picRecord, const SkRegion& region,
|
| + SkRegion::Op op, const SkMatrix& matrix) {
|
| + ClipOp* newClip = fClips.append();
|
| + newClip->fClipType = kRegion_ClipType;
|
| + newClip->fGeom.fRegion = SkNEW(SkRegion(region));
|
| + newClip->fOp = op;
|
| + newClip->fDoAA = true; // not necessary but sanity preserving
|
| + newClip->fMatrix = matrix;
|
| + newClip->fOffset = kInvalidJumpOffset;
|
| + return false;
|
| +}
|
| +
|
| +void MatrixClipState::ClipInfo::writeClip(SkMatrix* curMat, SkPictureRecord* picRecord,
|
| + bool* overrideFirstOp) {
|
| +
|
| + for (int i = 0; i < fClips.count(); ++i) {
|
| + ClipOp& curClip = fClips[i];
|
| +
|
| + SkRegion::Op op = curClip.fOp;
|
| + if (*overrideFirstOp) {
|
| + op = SkRegion::kReplace_Op;
|
| + *overrideFirstOp = false;
|
| + }
|
| +
|
| + if (*curMat != curClip.fMatrix) {
|
| + picRecord->setMatrixImpl(curClip.fMatrix);
|
| + *curMat = curClip.fMatrix;
|
| + }
|
| +
|
| + switch (curClip.fClipType) {
|
| + case kRect_ClipType:
|
| + curClip.fOffset = picRecord->clipRectImpl(curClip.fGeom.fRRect.rect(),
|
| + op, curClip.fDoAA);
|
| + break;
|
| + case kRRect_ClipType:
|
| + curClip.fOffset = picRecord->clipRRectImpl(curClip.fGeom.fRRect, op,
|
| + curClip.fDoAA);
|
| + break;
|
| + case kPath_ClipType:
|
| + curClip.fOffset = picRecord->clipPathImpl(curClip.fGeom.fPathID, op,
|
| + curClip.fDoAA);
|
| + break;
|
| + case kRegion_ClipType:
|
| + curClip.fOffset = picRecord->clipRegionImpl(*curClip.fGeom.fRegion, op);
|
| + break;
|
| + default:
|
| + SkASSERT(0);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void MatrixClipState::ClipInfo::fillInSkips(SkWriter32* writer, int32_t restoreOffset) {
|
| + for (int i = 0; i < fClips.count(); ++i) {
|
| + const ClipOp& curClip = fClips[i];
|
| +
|
| + SkASSERT(-1 != curClip.fOffset);
|
| + uint32_t* peek = writer->peek32(curClip.fOffset);
|
| + SkASSERT(-1 == *peek);
|
| + *peek = restoreOffset;
|
| + }
|
| +}
|
| +
|
| +MatrixClipStateMgr::MatrixClipStateMgr()
|
| + : fPicRecord(NULL)
|
| + , fMatrixClipStack(sizeof(MatrixClipState),
|
| + fMatrixClipStackStorage,
|
| + sizeof(fMatrixClipStackStorage)) {
|
| + fCurMCState = (MatrixClipState*)fMatrixClipStack.push_back();
|
| + new (fCurMCState) MatrixClipState(NULL, 0); // balanced in restore()
|
| +}
|
| +
|
| +void MatrixClipStateMgr::restore() {
|
| + if (fCurMCState->fIsSaveLayer) {
|
| + fPicRecord->restoreImpl();
|
| + }
|
| +
|
| + fCurMCState->~MatrixClipState(); // balanced in save()
|
| + fMatrixClipStack.pop_back();
|
| + fCurMCState = (MatrixClipState*)fMatrixClipStack.back();
|
| +}
|
| +
|
| +void MatrixClipStateMgr::call(CallType callType) {
|
| + if (fCurMCState->fIsCurrent || kOther_CallType != callType) {
|
| + return;
|
| + }
|
| +
|
| + if (fCurMCState->fWroteSave) {
|
| + fCurMCState->fWroteSave = false;
|
| + fPicRecord->restoreImpl();
|
| + }
|
| +
|
| + // write out save
|
| + fPicRecord->saveImpl(SkCanvas::kMatrixClip_SaveFlag);
|
| +
|
| + // write out matrix
|
| + fPicRecord->setMatrixImpl(fCurMCState->fMatrixInfo->fMatrix);
|
| +
|
| + // write out clips
|
| + SkDeque::F2BIter iter(fMatrixClipStack);
|
| + bool firstClip = true;
|
| +
|
| + SkMatrix curMat = fCurMCState->fMatrixInfo->fMatrix;
|
| + for (const MatrixClipState* state = (const MatrixClipState*) iter.next();
|
| + state != NULL;
|
| + state = (const MatrixClipState*) iter.next()) {
|
| + state->fClipInfo->writeClip(&curMat, fPicRecord, &firstClip);
|
| + }
|
| +
|
| + fCurMCState->fWroteSave = true;
|
| + fCurMCState->fIsCurrent = true;
|
| +}
|
| +#endif
|
| +
|
| #define HEAP_BLOCK_SIZE 4096
|
|
|
| enum {
|
| @@ -27,13 +158,13 @@
|
| static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size;
|
| static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect);
|
|
|
| -SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) :
|
| - INHERITED(device),
|
| - fBoundingHierarchy(NULL),
|
| - fStateTree(NULL),
|
| - fFlattenableHeap(HEAP_BLOCK_SIZE),
|
| - fPaints(&fFlattenableHeap),
|
| - fRecordFlags(flags) {
|
| +SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device)
|
| + : INHERITED(device)
|
| + , fBoundingHierarchy(NULL)
|
| + , fStateTree(NULL)
|
| + , fFlattenableHeap(HEAP_BLOCK_SIZE)
|
| + , fPaints(&fFlattenableHeap)
|
| + , fRecordFlags(flags) {
|
| #ifdef SK_DEBUG_SIZE
|
| fPointBytes = fRectBytes = fTextBytes = 0;
|
| fPointWrites = fRectWrites = fTextWrites = 0;
|
| @@ -42,9 +173,15 @@
|
| fBitmapHeap = SkNEW(SkBitmapHeap);
|
| fFlattenableHeap.setBitmapStorage(fBitmapHeap);
|
| fPathHeap = NULL; // lazy allocate
|
| +#ifndef COLLAPSE_MATRIX_CLIP_STATE
|
| fFirstSavedLayerIndex = kNoSavedLayerIndex;
|
| +#endif
|
|
|
| fInitialSaveCount = kNoInitialSave;
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.init(this);
|
| +#endif
|
| }
|
|
|
| SkPictureRecord::~SkPictureRecord() {
|
| @@ -138,24 +275,40 @@
|
| }
|
|
|
| int SkPictureRecord::save(SaveFlags flags) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + // TODO: need to skip saving "save" to op stream & replace restore stack
|
| + fMCMgr.save(flags);
|
| +#else
|
| // record the offset to us, making it non-positive to distinguish a save
|
| // from a clip entry.
|
| fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten());
|
| + this->saveImpl(flags);
|
| +#endif
|
| + return this->INHERITED::save(flags);
|
| +}
|
|
|
| +void SkPictureRecord::saveImpl(SaveFlags flags) {
|
| // op + flags
|
| uint32_t size = kSaveSize;
|
| size_t initialOffset = this->addDraw(SAVE, &size);
|
| addInt(flags);
|
|
|
| this->validate(initialOffset, size);
|
| - return this->INHERITED::save(flags);
|
| }
|
|
|
| int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint,
|
| SaveFlags flags) {
|
| +
|
| + int count;
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + // TODO: need to replace restore stack mechanism
|
| + count = fMCMgr.saveLayer(bounds, paint, flags);
|
| +#else
|
| // record the offset to us, making it non-positive to distinguish a save
|
| // from a clip entry.
|
| fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten());
|
| +#endif
|
|
|
| // op + bool for 'bounds'
|
| uint32_t size = 2 * kUInt32Size;
|
| @@ -173,9 +326,11 @@
|
| addPaintPtr(paint);
|
| addInt(flags);
|
|
|
| +#ifndef COLLAPSE_MATRIX_CLIP_STATE
|
| if (kNoSavedLayerIndex == fFirstSavedLayerIndex) {
|
| fFirstSavedLayerIndex = fRestoreOffsetStack.count();
|
| }
|
| +#endif
|
|
|
| this->validate(initialOffset, size);
|
| /* Don't actually call saveLayer, because that will try to allocate an
|
| @@ -184,13 +339,17 @@
|
| clip starts out the size of the picture, which is often much larger
|
| than the size of the actual device we'll use during playback).
|
| */
|
| - int count = this->INHERITED::save(flags);
|
| + count = this->INHERITED::save(flags);
|
| this->clipRectBounds(bounds, flags, NULL);
|
| return count;
|
| }
|
|
|
| bool SkPictureRecord::isDrawingToLayer() const {
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + return fMCMgr.isDrawingToLayer();
|
| +#else
|
| return fFirstSavedLayerIndex != kNoSavedLayerIndex;
|
| +#endif
|
| }
|
|
|
| /*
|
| @@ -321,7 +480,6 @@
|
| return false;
|
| }
|
|
|
| -
|
| return merge_savelayer_paint_into_drawbitmp(writer, paintDict,
|
| result[0], result[1]);
|
| }
|
| @@ -574,6 +732,14 @@
|
| SkASSERT(fRestoreOffsetStack.count() > 1);
|
| #endif
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + if (fMCMgr.getSaveCount() == 1) {
|
| + return;
|
| + }
|
| +
|
| + // TODO: don't write the restore to the op stream for normal saves
|
| + fMCMgr.restore();
|
| +#else
|
| // check for underflow
|
| if (fRestoreOffsetStack.count() == 0) {
|
| return;
|
| @@ -585,6 +751,7 @@
|
|
|
| uint32_t initialOffset, size;
|
| size_t opt = 0;
|
| + // TODO: need to bring optimization back to life in new world
|
| if (!(fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag)) {
|
| for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) {
|
| if (0 != (gPictureRecordOpts[opt].fFlags & kSkipIfBBoxHierarchy_Flag)
|
| @@ -605,74 +772,122 @@
|
| if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) ||
|
| SK_ARRAY_COUNT(gPictureRecordOpts) == opt) {
|
| // No optimization fired so add the RESTORE
|
| - fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten());
|
| - size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code
|
| - initialOffset = this->addDraw(RESTORE, &size);
|
| + this->restoreImpl();
|
| }
|
|
|
| fRestoreOffsetStack.pop();
|
| +#endif
|
|
|
| - this->validate(initialOffset, size);
|
| return this->INHERITED::restore();
|
| }
|
|
|
| +void SkPictureRecord::restoreImpl() {
|
| + uint32_t initialOffset, size;
|
| + this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten());
|
| + size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code
|
| + initialOffset = this->addDraw(RESTORE, &size);
|
| + this->validate(initialOffset, size);
|
| +}
|
| +
|
| bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) {
|
| +
|
| + if (0 == dx && 0 == dy) {
|
| + return true;
|
| + }
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.translate(dx, dy);
|
| +#else
|
| // op + dx + dy
|
| uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
|
| size_t initialOffset = this->addDraw(TRANSLATE, &size);
|
| addScalar(dx);
|
| addScalar(dy);
|
| this->validate(initialOffset, size);
|
| +#endif
|
| return this->INHERITED::translate(dx, dy);
|
| }
|
|
|
| bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.scale(sx, sy);
|
| +#else
|
| // op + sx + sy
|
| uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
|
| size_t initialOffset = this->addDraw(SCALE, &size);
|
| addScalar(sx);
|
| addScalar(sy);
|
| this->validate(initialOffset, size);
|
| +#endif
|
| return this->INHERITED::scale(sx, sy);
|
| }
|
|
|
| bool SkPictureRecord::rotate(SkScalar degrees) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.rotate(degrees);
|
| +#else
|
| // op + degrees
|
| uint32_t size = 1 * kUInt32Size + sizeof(SkScalar);
|
| size_t initialOffset = this->addDraw(ROTATE, &size);
|
| addScalar(degrees);
|
| this->validate(initialOffset, size);
|
| +#endif
|
| return this->INHERITED::rotate(degrees);
|
| }
|
|
|
| bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.skew(sx, sy);
|
| +#else
|
| // op + sx + sy
|
| uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
|
| size_t initialOffset = this->addDraw(SKEW, &size);
|
| addScalar(sx);
|
| addScalar(sy);
|
| this->validate(initialOffset, size);
|
| +#endif
|
| return this->INHERITED::skew(sx, sy);
|
| }
|
|
|
| bool SkPictureRecord::concat(const SkMatrix& matrix) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.concat(matrix);
|
| +#else
|
| + this->concatImpl(matrix);
|
| +#endif
|
| + return this->INHERITED::concat(matrix);
|
| +}
|
| +
|
| +void SkPictureRecord::concatImpl(const SkMatrix& matrix) {
|
| this->validate(fWriter.bytesWritten(), 0);
|
| // op + matrix
|
| uint32_t size = kUInt32Size + matrix.writeToMemory(NULL);
|
| size_t initialOffset = this->addDraw(CONCAT, &size);
|
| - addMatrix(matrix);
|
| + this->addMatrix(matrix);
|
| this->validate(initialOffset, size);
|
| - return this->INHERITED::concat(matrix);
|
| }
|
|
|
| void SkPictureRecord::setMatrix(const SkMatrix& matrix) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.setMatrix(matrix);
|
| +#else
|
| + this->setMatrixImpl(matrix);
|
| +#endif
|
| + this->INHERITED::setMatrix(matrix);
|
| +}
|
| +
|
| +void SkPictureRecord::setMatrixImpl(const SkMatrix& matrix) {
|
| this->validate(fWriter.bytesWritten(), 0);
|
| // op + matrix
|
| uint32_t size = kUInt32Size + matrix.writeToMemory(NULL);
|
| size_t initialOffset = this->addDraw(SET_MATRIX, &size);
|
| - addMatrix(matrix);
|
| + this->addMatrix(matrix);
|
| this->validate(initialOffset, size);
|
| - this->INHERITED::setMatrix(matrix);
|
| }
|
|
|
| static bool regionOpExpands(SkRegion::Op op) {
|
| @@ -691,7 +906,12 @@
|
| }
|
| }
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
|
| + fMCMgr.fillInSkips(&fWriter, restoreOffset);
|
| +}
|
| +#else
|
| +void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
|
| int32_t offset = fRestoreOffsetStack.top();
|
| while (offset > 0) {
|
| uint32_t* peek = fWriter.peek32(offset);
|
| @@ -706,6 +926,7 @@
|
| SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp);
|
| #endif
|
| }
|
| +#endif
|
|
|
| void SkPictureRecord::beginRecording() {
|
| // we have to call this *after* our constructor, to ensure that it gets
|
| @@ -717,11 +938,21 @@
|
| void SkPictureRecord::endRecording() {
|
| SkASSERT(kNoInitialSave != fInitialSaveCount);
|
| this->restoreToCount(fInitialSaveCount);
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.finish1();
|
| +#endif
|
| }
|
|
|
| -void SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| +int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {
|
| + size_t offset = fWriter.bytesWritten();
|
| + this->addInt(0);
|
| + return offset;
|
| +}
|
| +#else
|
| +int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) {
|
| if (fRestoreOffsetStack.isEmpty()) {
|
| - return;
|
| + return -1;
|
| }
|
|
|
| // The RestoreOffset field is initially filled with a placeholder
|
| @@ -744,25 +975,43 @@
|
| }
|
|
|
| size_t offset = fWriter.bytesWritten();
|
| - addInt(prevOffset);
|
| + this->addInt(prevOffset);
|
| fRestoreOffsetStack.top() = offset;
|
| + return offset;
|
| }
|
| +#endif
|
|
|
| bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.clipRect(rect, op, doAA);
|
| +#else
|
| + this->clipRectImpl(rect, op, doAA);
|
| +#endif
|
| + return this->INHERITED::clipRect(rect, op, doAA);
|
| +}
|
| +
|
| +int SkPictureRecord::clipRectImpl(const SkRect& rect, SkRegion::Op op, bool doAA) {
|
| +
|
| // id + rect + clip params
|
| uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size;
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + size += kUInt32Size;
|
| +#else
|
| // recordRestoreOffsetPlaceholder doesn't always write an offset
|
| if (!fRestoreOffsetStack.isEmpty()) {
|
| // + restore offset
|
| size += kUInt32Size;
|
| }
|
| +#endif
|
| +
|
| size_t initialOffset = this->addDraw(CLIP_RECT, &size);
|
| - addRect(rect);
|
| - addInt(ClipParams_pack(op, doAA));
|
| - recordRestoreOffsetPlaceholder(op);
|
| + this->addRect(rect);
|
| + this->addInt(ClipParams_pack(op, doAA));
|
| + int offset = this->recordRestoreOffsetPlaceholder(op);
|
|
|
| this->validate(initialOffset, size);
|
| - return this->INHERITED::clipRect(rect, op, doAA);
|
| + return offset;
|
| }
|
|
|
| bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
|
| @@ -770,25 +1019,38 @@
|
| return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA);
|
| }
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.clipRRect(rrect, op, doAA);
|
| +#else
|
| + this->clipRRectImpl(rrect, op, doAA);
|
| +#endif
|
| + if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
|
| + return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
|
| + } else {
|
| + return this->INHERITED::clipRRect(rrect, op, doAA);
|
| + }
|
| +}
|
| +
|
| +int SkPictureRecord::clipRRectImpl(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
|
| +
|
| // op + rrect + clip params
|
| uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size;
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + size += kUInt32Size;
|
| +#else
|
| // recordRestoreOffsetPlaceholder doesn't always write an offset
|
| if (!fRestoreOffsetStack.isEmpty()) {
|
| // + restore offset
|
| size += kUInt32Size;
|
| }
|
| +#endif
|
| size_t initialOffset = this->addDraw(CLIP_RRECT, &size);
|
| addRRect(rrect);
|
| addInt(ClipParams_pack(op, doAA));
|
| - recordRestoreOffsetPlaceholder(op);
|
| + int offset = recordRestoreOffsetPlaceholder(op);
|
|
|
| this->validate(initialOffset, size);
|
| -
|
| - if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
|
| - return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false);
|
| - } else {
|
| - return this->INHERITED::clipRRect(rrect, op, doAA);
|
| - }
|
| + return offset;
|
| }
|
|
|
| bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
|
| @@ -798,46 +1060,81 @@
|
| return this->clipRect(r, op, doAA);
|
| }
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.clipPath(path, op, doAA);
|
| +#else
|
| + int pathID = this->addPathToHeap(path);
|
| + this->clipPathImpl(pathID, op, doAA);
|
| +#endif
|
| +
|
| + if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
|
| + return this->updateClipConservativelyUsingBounds(path.getBounds(), op,
|
| + path.isInverseFillType());
|
| + } else {
|
| + return this->INHERITED::clipPath(path, op, doAA);
|
| + }
|
| +}
|
| +
|
| +int SkPictureRecord::clipPathImpl(int pathID, SkRegion::Op op, bool doAA) {
|
| +
|
| // op + path index + clip params
|
| uint32_t size = 3 * kUInt32Size;
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + size += kUInt32Size;
|
| +#else
|
| // recordRestoreOffsetPlaceholder doesn't always write an offset
|
| if (!fRestoreOffsetStack.isEmpty()) {
|
| // + restore offset
|
| size += kUInt32Size;
|
| }
|
| +#endif
|
| size_t initialOffset = this->addDraw(CLIP_PATH, &size);
|
| - addPath(path);
|
| + this->addInt(pathID);
|
| addInt(ClipParams_pack(op, doAA));
|
| - recordRestoreOffsetPlaceholder(op);
|
| + int offset = recordRestoreOffsetPlaceholder(op);
|
|
|
| this->validate(initialOffset, size);
|
| + return offset;
|
| +}
|
|
|
| - if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
|
| - return this->updateClipConservativelyUsingBounds(path.getBounds(), op,
|
| - path.isInverseFillType());
|
| - } else {
|
| - return this->INHERITED::clipPath(path, op, doAA);
|
| - }
|
| +bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.clipRegion(region, op);
|
| +#else
|
| + this->clipRegionImpl(region, op);
|
| +#endif
|
| + return this->INHERITED::clipRegion(region, op);
|
| }
|
|
|
| -bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
|
| +int SkPictureRecord::clipRegionImpl(const SkRegion& region, SkRegion::Op op) {
|
| // op + clip params + region
|
| uint32_t size = 2 * kUInt32Size + region.writeToMemory(NULL);
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + // + restore offset
|
| + size += kUInt32Size;
|
| +#else
|
| // recordRestoreOffsetPlaceholder doesn't always write an offset
|
| if (!fRestoreOffsetStack.isEmpty()) {
|
| // + restore offset
|
| size += kUInt32Size;
|
| }
|
| +#endif
|
| size_t initialOffset = this->addDraw(CLIP_REGION, &size);
|
| - addRegion(region);
|
| - addInt(ClipParams_pack(op, false));
|
| - recordRestoreOffsetPlaceholder(op);
|
| + this->addRegion(region);
|
| + this->addInt(ClipParams_pack(op, false));
|
| + int offset = recordRestoreOffsetPlaceholder(op);
|
|
|
| this->validate(initialOffset, size);
|
| - return this->INHERITED::clipRegion(region, op);
|
| + return offset;
|
| }
|
|
|
| void SkPictureRecord::clear(SkColor color) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + color
|
| uint32_t size = 2 * kUInt32Size;
|
| size_t initialOffset = this->addDraw(DRAW_CLEAR, &size);
|
| @@ -846,6 +1143,11 @@
|
| }
|
|
|
| void SkPictureRecord::drawPaint(const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index
|
| uint32_t size = 2 * kUInt32Size;
|
| size_t initialOffset = this->addDraw(DRAW_PAINT, &size);
|
| @@ -856,6 +1158,11 @@
|
|
|
| void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
| const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + mode + count + point data
|
| uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint);
|
| size_t initialOffset = this->addDraw(DRAW_POINTS, &size);
|
| @@ -868,6 +1175,11 @@
|
| }
|
|
|
| void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + rect
|
| uint32_t size = 2 * kUInt32Size + sizeof(oval);
|
| size_t initialOffset = this->addDraw(DRAW_OVAL, &size);
|
| @@ -878,6 +1190,11 @@
|
| }
|
|
|
| void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + rect
|
| uint32_t size = 2 * kUInt32Size + sizeof(rect);
|
| size_t initialOffset = this->addDraw(DRAW_RECT, &size);
|
| @@ -888,6 +1205,11 @@
|
| }
|
|
|
| void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| if (rrect.isRect()) {
|
| this->SkPictureRecord::drawRect(rrect.getBounds(), paint);
|
| } else if (rrect.isOval()) {
|
| @@ -905,17 +1227,27 @@
|
| }
|
|
|
| void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + path index
|
| uint32_t size = 3 * kUInt32Size;
|
| size_t initialOffset = this->addDraw(DRAW_PATH, &size);
|
| SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.bytesWritten());
|
| - addPaint(paint);
|
| - addPath(path);
|
| + this->addPaint(paint);
|
| + this->addPath(path);
|
| this->validate(initialOffset, size);
|
| }
|
|
|
| void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
|
| const SkPaint* paint = NULL) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + bitmap index + left + top
|
| uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
|
| size_t initialOffset = this->addDraw(DRAW_BITMAP, &size);
|
| @@ -930,6 +1262,11 @@
|
| void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
|
| const SkRect& dst, const SkPaint* paint,
|
| DrawBitmapRectFlags flags) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // id + paint index + bitmap index + bool for 'src' + flags
|
| uint32_t size = 5 * kUInt32Size;
|
| if (NULL != src) {
|
| @@ -949,18 +1286,28 @@
|
|
|
| void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix,
|
| const SkPaint* paint) {
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // id + paint index + bitmap index + matrix
|
| uint32_t size = 3 * kUInt32Size + matrix.writeToMemory(NULL);
|
| +
|
| size_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size);
|
| SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.bytesWritten());
|
| - addPaintPtr(paint);
|
| - addBitmap(bitmap);
|
| - addMatrix(matrix);
|
| + this->addPaintPtr(paint);
|
| + this->addBitmap(bitmap);
|
| + this->addMatrix(matrix);
|
| this->validate(initialOffset, size);
|
| }
|
|
|
| void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
| const SkRect& dst, const SkPaint* paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + bitmap id + center + dst rect
|
| uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst);
|
| size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size);
|
| @@ -974,6 +1321,11 @@
|
|
|
| void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
|
| const SkPaint* paint = NULL) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + bitmap index + left + top
|
| uint32_t size = 5 * kUInt32Size;
|
| size_t initialOffset = this->addDraw(DRAW_SPRITE, &size);
|
| @@ -1006,6 +1358,11 @@
|
|
|
| void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
|
| SkScalar y, const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
|
|
|
| // op + paint index + length + 'length' worth of chars + x + y
|
| @@ -1030,6 +1387,11 @@
|
|
|
| void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
|
| const SkPoint pos[], const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| size_t points = paint.countText(text, byteLength);
|
| if (0 == points)
|
| return;
|
| @@ -1116,8 +1478,12 @@
|
| const SkScalar xpos[], SkScalar constY,
|
| const SkPaint& paint) {
|
|
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| const SkFlatData* flatPaintData = this->getFlatPaintData(paint);
|
| - drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData);
|
| + this->drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData);
|
| }
|
|
|
| void SkPictureRecord::drawPosTextHImpl(const void* text, size_t byteLength,
|
| @@ -1162,19 +1528,30 @@
|
| void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
|
| const SkPath& path, const SkMatrix* matrix,
|
| const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + paint index + length + 'length' worth of data + path index + matrix
|
| const SkMatrix& m = matrix ? *matrix : SkMatrix::I();
|
| uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + m.writeToMemory(NULL);
|
| +
|
| size_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size);
|
| SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.bytesWritten());
|
| - addPaint(paint);
|
| - addText(text, byteLength);
|
| - addPath(path);
|
| - addMatrix(m);
|
| + this->addPaint(paint);
|
| + this->addText(text, byteLength);
|
| + this->addPath(path);
|
| + this->addMatrix(m);
|
| this->validate(initialOffset, size);
|
| }
|
|
|
| void SkPictureRecord::drawPicture(SkPicture& picture) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + picture index
|
| uint32_t size = 2 * kUInt32Size;
|
| size_t initialOffset = this->addDraw(DRAW_PICTURE, &size);
|
| @@ -1187,6 +1564,11 @@
|
| const SkColor colors[], SkXfermode* xfer,
|
| const uint16_t indices[], int indexCount,
|
| const SkPaint& paint) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| uint32_t flags = 0;
|
| if (texs) {
|
| flags |= DRAW_VERTICES_HAS_TEXS;
|
| @@ -1246,6 +1628,11 @@
|
| }
|
|
|
| void SkPictureRecord::drawData(const void* data, size_t length) {
|
| +
|
| +#ifdef COLLAPSE_MATRIX_CLIP_STATE
|
| + fMCMgr.call(MatrixClipStateMgr::kOther_CallType);
|
| +#endif
|
| +
|
| // op + length + 'length' worth of data
|
| uint32_t size = 2 * kUInt32Size + SkAlign4(length);
|
| size_t initialOffset = this->addDraw(DRAW_DATA, &size);
|
| @@ -1311,13 +1698,17 @@
|
| this->addInt(index);
|
| }
|
|
|
| -void SkPictureRecord::addPath(const SkPath& path) {
|
| +int SkPictureRecord::addPathToHeap(const SkPath& path) {
|
| if (NULL == fPathHeap) {
|
| fPathHeap = SkNEW(SkPathHeap);
|
| }
|
| - addInt(fPathHeap->append(path));
|
| + return fPathHeap->append(path);
|
| }
|
|
|
| +void SkPictureRecord::addPath(const SkPath& path) {
|
| + this->addInt(this->addPathToHeap(path));
|
| +}
|
| +
|
| void SkPictureRecord::addPicture(SkPicture& picture) {
|
| int index = fPictureRefs.find(&picture);
|
| if (index < 0) { // not found
|
|
|