Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Unified Diff: src/core/SkPictureRecord.h

Issue 139093003: Collapse matrix & clip stack in PictureRecord (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: update to ToT Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gyp/tests.gyp ('k') | src/core/SkPictureRecord.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPictureRecord.h
===================================================================
--- src/core/SkPictureRecord.h (revision 13263)
+++ src/core/SkPictureRecord.h (working copy)
@@ -16,6 +16,291 @@
#include "SkTemplates.h"
#include "SkWriter32.h"
+#define COLLAPSE_MATRIX_CLIP_STATE 1
+
+#ifdef COLLAPSE_MATRIX_CLIP_STATE
+#include "SkTypes.h"
+
+class MatrixClipState {
+public:
+ class MatrixInfo {
+ public:
+ SkMatrix fMatrix;
+ // TODO: add an internal dictionary and an ID here
+ };
+
+ class ClipInfo : public SkNoncopyable {
+ public:
+ ClipInfo() {}
+
+ bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA, const SkMatrix& matrix) {
+ ClipOp* newClip = fClips.append();
+ newClip->fClipType = kRect_ClipType;
+ newClip->fGeom.fRRect.setRect(rect); // store the clipRect in the RRect
+ newClip->fOp = op;
+ newClip->fDoAA = doAA;
+ newClip->fMatrix = matrix;
+ newClip->fOffset = kInvalidJumpOffset;
+ return false;
+ }
+
+ bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA, const SkMatrix& matrix) {
+ ClipOp* newClip = fClips.append();
+ newClip->fClipType = kRRect_ClipType;
+ newClip->fGeom.fRRect = rrect;
+ newClip->fOp = op;
+ newClip->fDoAA = doAA;
+ newClip->fMatrix = matrix;
+ newClip->fOffset = kInvalidJumpOffset;
+ return false;
+ }
+
+ bool clipPath(SkPictureRecord* picRecord,
+ const SkPath& path,
+ SkRegion::Op op,
+ bool doAA,
+ const SkMatrix& matrix);
+ bool clipRegion(SkPictureRecord* picRecord,
+ const SkRegion& region,
+ SkRegion::Op op,
+ const SkMatrix& matrix);
+ void writeClip(SkMatrix* curMat, SkPictureRecord* picRecord,
+ bool* overrideFirstOp);
+ void fillInSkips(SkWriter32* writer, int32_t restoreOffset);
+
+ private:
+ enum ClipType {
+ kRect_ClipType,
+ kRRect_ClipType,
+ kPath_ClipType,
+ kRegion_ClipType
+ };
+
+ static const int kInvalidJumpOffset = -1;
+
+ struct ClipOp {
+ ClipType fClipType;
+
+ union {
+ SkRRect fRRect; // also stores clipRect
+ int fPathID;
+ // TODO: add internal dictionary of regions
+ // Arrg - need to free this in dtor!!!
+ const SkRegion* fRegion;
+ } fGeom;
+
+ bool fDoAA;
+ SkRegion::Op fOp;
+
+ // This used to be and int (when matrices were in a dictionary)
+ // now it is a full matrix.
+ // The CTM in effect when this clip call was issued
+ SkMatrix fMatrix;
+
+ // The offset of this clipOp's "jump-to-offset" variable in the skp.
+ // -1 means the offset hasn't been written.
+ int32_t fOffset;
+ };
+
+ SkTDArray<ClipOp> fClips;
+
+ typedef SkNoncopyable INHERITED;
+ };
+
+ MatrixClipState(MatrixClipState *prev, int flags) {
+ if (NULL == prev) {
+ fLayerID = 0;
+
+ fMatrixInfoStorage.fMatrix.reset();
+ fMatrixInfo = &fMatrixInfoStorage;
+ fClipInfo = &fClipInfoStorage;
+
+ fIsCurrent = true;
+ }
+ else {
+ fLayerID = prev->fLayerID;
+
+ if (flags & SkCanvas::kMatrix_SaveFlag) {
+ fMatrixInfoStorage = *prev->fMatrixInfo;
+ fMatrixInfo = &fMatrixInfoStorage;
+ } else {
+ fMatrixInfo = prev->fMatrixInfo;
+ }
+
+ if (flags & SkCanvas::kClip_SaveFlag) {
+ // We don't copy the ClipOps of the previous clip states
+ fClipInfo = &fClipInfoStorage;
+ } else {
+ fClipInfo = prev->fClipInfo;
+ }
+
+ fIsCurrent = prev->fIsCurrent;
+ }
+
+ fWroteSave = false;
+ fIsSaveLayer = false;
+ }
+
+ MatrixInfo* fMatrixInfo;
+ MatrixInfo fMatrixInfoStorage;
+
+ ClipInfo* fClipInfo;
+ ClipInfo fClipInfoStorage;
+
+ int fLayerID;
+ // Does this MC state represent a saveLayer call?
+ bool fIsSaveLayer;
+ // Is this the current MC state in the picture command stream?
+ bool fIsCurrent;
+ // Is there an unbalanced 'save' for this MC state already in the command stream?
+ bool fWroteSave;
+};
+
+
+class MatrixClipStateMgr {
+public:
+ enum CallType {
+ kMatrix_CallType,
+ kClip_CallType,
+ kOther_CallType
+ };
+
+ MatrixClipStateMgr();
+
+ void init(SkPictureRecord* picRecord) {
+ fPicRecord = picRecord;
+ }
+
+ // TODO: need to override canvas' getSaveCount
+ int getSaveCount() const { return fMatrixClipStack.count(); }
+
+ int save(SkCanvas::SaveFlags flags) {
+ MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back();
+ new (newTop) MatrixClipState(fCurMCState, flags); // balanced in restore()
+ fCurMCState = newTop;
+ return fMatrixClipStack.count();
+ }
+
+ int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SkCanvas::SaveFlags flags) {
+ int result = this->save(flags);
+ ++fCurMCState->fLayerID;
+ fCurMCState->fIsSaveLayer = true;
+ return result;
+ }
+
+ bool isDrawingToLayer() const {
+ return fCurMCState->fLayerID > 0;
+ }
+
+ void restore();
+
+ bool translate(SkScalar dx, SkScalar dy) {
+ this->call(kMatrix_CallType);
+ bool result = fCurMCState->fMatrixInfo->fMatrix.preTranslate(dx, dy);
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ return result;
+ }
+
+ bool scale(SkScalar sx, SkScalar sy) {
+ this->call(kMatrix_CallType);
+ bool result = fCurMCState->fMatrixInfo->fMatrix.preScale(sx, sy);
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ return result;
+ }
+
+ bool rotate(SkScalar degrees) {
+ this->call(kMatrix_CallType);
+ bool result = fCurMCState->fMatrixInfo->fMatrix.preRotate(degrees);
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ return result;
+ }
+
+ bool skew(SkScalar sx, SkScalar sy) {
+ this->call(kMatrix_CallType);
+ bool result = fCurMCState->fMatrixInfo->fMatrix.preSkew(sx, sy);
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ return result;
+ }
+
+ bool concat(const SkMatrix& matrix) {
+ this->call(kMatrix_CallType);
+ bool result = fCurMCState->fMatrixInfo->fMatrix.preConcat(matrix);
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ return result;
+ }
+
+ void setMatrix(const SkMatrix& matrix) {
+ this->call(kMatrix_CallType);
+ fCurMCState->fMatrixInfo->fMatrix = matrix;
+// fCurMCState->fMatrixInfo->fID = -1;
+ fCurMCState->fIsCurrent = false;
+ }
+
+ bool clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
+ this->call(MatrixClipStateMgr::kClip_CallType);
+
+ fCurMCState->fIsCurrent = false;
+ return fCurMCState->fClipInfo->clipRect(rect, op, doAA,
+ fCurMCState->fMatrixInfo->fMatrix);
+ }
+
+ bool clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ this->call(MatrixClipStateMgr::kClip_CallType);
+
+ fCurMCState->fIsCurrent = false;
+ return fCurMCState->fClipInfo->clipRRect(rrect, op, doAA,
+ fCurMCState->fMatrixInfo->fMatrix);
+ }
+
+ bool clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
+ this->call(MatrixClipStateMgr::kClip_CallType);
+
+ fCurMCState->fIsCurrent = false;
+ bool result = fCurMCState->fClipInfo->clipPath(fPicRecord, path, op, doAA,
+ fCurMCState->fMatrixInfo->fMatrix);
+ return result;
+ }
+
+ bool clipRegion(const SkRegion& region, SkRegion::Op op) {
+ this->call(MatrixClipStateMgr::kClip_CallType);
+
+ fCurMCState->fIsCurrent = false;
+ bool result = fCurMCState->fClipInfo->clipRegion(fPicRecord, region, op,
+ fCurMCState->fMatrixInfo->fMatrix);
+ return result;
+ }
+
+ void call(CallType callType);
+
+ void fillInSkips(SkWriter32* writer, int32_t restoreOffset) {
+ fCurMCState->fClipInfo->fillInSkips(writer, restoreOffset);
+ }
+
+ void finish1() {
+#if 0
+ if (fCurMCState->fWroteSave) {
+ fCurMCState->fWroteSave = false;
+ fPicRecord->restoreImpl();
+ }
+#endif
+ }
+
+protected:
+ SkPictureRecord* fPicRecord;
+
+ uint32_t fMatrixClipStackStorage[43]; // sized to fit 2 clip states
+ SkDeque fMatrixClipStack;
+ MatrixClipState* fCurMCState;
+};
+#endif
+
+
class SkPictureStateTree;
class SkBBoxHierarchy;
@@ -108,15 +393,16 @@
private:
void handleOptimization(int opt);
- void recordRestoreOffsetPlaceholder(SkRegion::Op);
- void fillRestoreOffsetPlaceholdersForCurrentStackLevel(
- uint32_t restoreOffset);
+ int recordRestoreOffsetPlaceholder(SkRegion::Op);
+ void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset);
+#ifndef COLLAPSE_MATRIX_CLIP_STATE
SkTDArray<int32_t> fRestoreOffsetStack;
int fFirstSavedLayerIndex;
enum {
kNoSavedLayerIndex = -1
};
+#endif
/*
* Write the 'drawType' operation and chunk size to the skp. 'size'
@@ -161,10 +447,12 @@
}
void addBitmap(const SkBitmap& bitmap);
+ int addMatrixToHeap(const SkMatrix& matrix);
void addMatrix(const SkMatrix& matrix);
const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); }
const SkFlatData* addPaintPtr(const SkPaint* paint);
void addFlatPaint(const SkFlatData* flatPaint);
+ int addPathToHeap(const SkPath& path);
void addPath(const SkPath& path);
void addPicture(SkPicture& picture);
void addPoint(const SkPoint& point);
@@ -174,6 +462,7 @@
void addIRect(const SkIRect& rect);
void addIRectPtr(const SkIRect* rect);
void addRRect(const SkRRect&);
+ int addRegionToHeap(const SkRegion& region);
void addRegion(const SkRegion& region);
void addText(const void* text, size_t byteLength);
@@ -237,6 +526,15 @@
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint, const SkFlatData* flatPaintData);
+ void concatImpl(const SkMatrix& matrix);
+ void setMatrixImpl(const SkMatrix& matrix);
+ int clipRectImpl(const SkRect& rect, SkRegion::Op op, bool doAA);
+ int clipRRectImpl(const SkRRect& rrect, SkRegion::Op op, bool doAA);
+ int clipPathImpl(int pathID, SkRegion::Op op, bool doAA);
+ int clipRegionImpl(const SkRegion& region, SkRegion::Op op);
+ void saveImpl(SaveFlags flags);
+ void restoreImpl();
+
// These are set to NULL in our constructor, but may be changed by
// subclasses, in which case they will be SkSafeUnref'd in our destructor.
SkBBoxHierarchy* fBoundingHierarchy;
@@ -246,6 +544,11 @@
SkBitmapHeap* fBitmapHeap;
private:
+#ifdef COLLAPSE_MATRIX_CLIP_STATE
+ friend class MatrixClipState; // for access to *Impl methods
+ friend class MatrixClipStateMgr; // for access to *Impl methods
+#endif
+
SkChunkFlatController fFlattenableHeap;
SkPaintDictionary fPaints;
@@ -262,6 +565,10 @@
friend class SkPicturePlayback;
friend class SkPictureTester; // for unit testing
+#ifdef COLLAPSE_MATRIX_CLIP_STATE
+ MatrixClipStateMgr fMCMgr;
+#endif
+
typedef SkCanvas INHERITED;
};
« no previous file with comments | « gyp/tests.gyp ('k') | src/core/SkPictureRecord.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698