From 6cfa73a29a26edf1d03bca224ad6860396308ffc Mon Sep 17 00:00:00 2001 From: mtklein Date: Wed, 13 Aug 2014 13:33:49 -0700 Subject: Start tracking the CTM while filling the BBH in SkRecordDraw. Depends on https://codereview.chromium.org/475473002/ BUG=skia: R=robertphillips@google.com, reed@google.com, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/468193003 --- include/core/SkCanvas.h | 11 ++++++----- src/core/SkCanvas.cpp | 11 ++++++----- src/core/SkRecordDraw.cpp | 8 ++++++++ src/core/SkRecorder.cpp | 7 ++++--- src/core/SkRecorder.h | 4 ++-- src/core/SkRecords.h | 8 ++++---- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 8afeae6d5f..3b8f17c53e 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1020,17 +1020,17 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint); - + /** Draw a cubic coons patch - + @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order starting at the top left corner. @param colors specifies the colors for the corners which will be bilerp across the patch, their order is clockwise starting at the top left corner. - @param texCoords specifies the texture coordinates that will be bilerp across the patch, + @param texCoords specifies the texture coordinates that will be bilerp across the patch, their order is the same as the colors. - @param xmode specifies how are the colors and the textures combined if both of them are + @param xmode specifies how are the colors and the textures combined if both of them are present. @param paint Specifies the shader/texture if present. */ @@ -1212,6 +1212,7 @@ protected: return kFullLayer_SaveLayerStrategy; } virtual void willRestore() {} + virtual void didRestore() {} virtual void didConcat(const SkMatrix&) {} virtual void didSetMatrix(const SkMatrix&) {} @@ -1230,7 +1231,7 @@ protected: virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint); - + virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint); diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 240dc9ccc5..7e2609b22d 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -895,6 +895,7 @@ void SkCanvas::restore() { if (fMCStack.count() > 1) { this->willRestore(); this->internalRestore(); + this->didRestore(); } } @@ -2260,7 +2261,7 @@ void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], if (NULL == cubics) { return; } - + // Since a patch is always within the convex hull of the control points, we discard it when its // bounding rectangle is completely outside the current clip. SkRect bounds; @@ -2268,7 +2269,7 @@ void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], if (this->quickReject(bounds)) { return; } - + this->onDrawPatch(cubics, colors, texCoords, xmode, paint); } @@ -2276,11 +2277,11 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) - + while (iter.next()) { iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); } - + LOOPER_END } @@ -2550,7 +2551,7 @@ SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatri } else if (NULL != matrix) { canvas->save(); } - + if (NULL != matrix) { canvas->concat(*matrix); } diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 688d0b695e..c9e029b8db 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -117,6 +117,7 @@ public: FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) { // Calculate bounds for all ops. This won't go quite in order, so we'll need // to store the bounds separately then feed them in to the BBH later in order. + fCTM.setIdentity(); for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) { record.visit(fCurrentOp, *this); } @@ -143,6 +144,7 @@ public: } template void operator()(const T& r) { + this->updateCTM(r); this->trackBounds(r); } @@ -152,6 +154,11 @@ private: SkIRect bounds; // Bounds of everything in the block. }; + template void updateCTM(const T&) { /* most ops don't change the CTM */ } + void updateCTM(const Restore& r) { fCTM = r.matrix; } + void updateCTM(const SetMatrix& r) { fCTM = r.matrix; } + void updateCTM(const Concat& r) { fCTM.preConcat(r.matrix); } + // The bounds of these ops must be calculated when we hit the Restore // from the bounds of the ops in the same Save block. void trackBounds(const Save&) { this->pushSaveBlock(); } @@ -219,6 +226,7 @@ private: SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); } // NoOps don't draw anywhere. SkAutoTMalloc fBounds; // One for each op in the record. + SkMatrix fCTM; unsigned fCurrentOp; SkTDArray fSaveStack; SkTDArray fControlIndices; diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 327a97acdb..53522c2110 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -229,9 +229,9 @@ SkCanvas::SaveLayerStrategy SkRecorder::willSaveLayer(const SkRect* bounds, return SkCanvas::kNoLayer_SaveLayerStrategy; } -void SkRecorder::willRestore() { - APPEND(Restore); - INHERITED(willRestore); +void SkRecorder::didRestore() { + APPEND(Restore, this->getTotalMatrix()); + INHERITED(didRestore); } void SkRecorder::onPushCull(const SkRect& rect) { @@ -248,6 +248,7 @@ void SkRecorder::didConcat(const SkMatrix& matrix) { } void SkRecorder::didSetMatrix(const SkMatrix& matrix) { + SkASSERT(matrix == this->getTotalMatrix()); APPEND(SetMatrix, matrix); INHERITED(didSetMatrix, matrix); } diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 2c7234ac86..97eeb9f454 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -64,7 +64,7 @@ public: void willSave() SK_OVERRIDE; SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE; - void willRestore() SK_OVERRIDE; + void didRestore() SK_OVERRIDE; void didConcat(const SkMatrix&) SK_OVERRIDE; void didSetMatrix(const SkMatrix&) SK_OVERRIDE; @@ -92,7 +92,7 @@ public: void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) SK_OVERRIDE; - + void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE; void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE; void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE; diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index 1efdf28b14..3d5b190893 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -197,7 +197,7 @@ private: RECORD0(NoOp); -RECORD0(Restore); +RECORD1(Restore, SkMatrix, matrix); RECORD0(Save); RECORD3(SaveLayer, Optional, bounds, Optional, paint, SkCanvas::SaveFlags, flags); @@ -291,10 +291,10 @@ struct DrawVertices { PODArray indices; int indexCount; }; - + struct DrawPatch { static const Type kType = DrawPatch_Type; - + DrawPatch(const SkPaint& paint, SkPoint cubics[12], SkColor colors[4], SkPoint texCoords[4], SkXfermode* xmode) : paint(paint) @@ -302,7 +302,7 @@ struct DrawPatch { , colors(colors) , texCoords(texCoords) , xmode(SkSafeRef(xmode)) { } - + SkPaint paint; PODArray cubics; PODArray colors; -- cgit v1.2.3