diff options
author | vjiaoblack <vjiaoblack@google.com> | 2016-07-13 14:05:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-13 14:05:28 -0700 |
commit | e5de130788c8637d2f7df9ddb0241b78e04d5882 (patch) | |
tree | e837af1f0ce2a87a9b4be70172f74d9a5dea57a4 | |
parent | f382b48687176f15091c2defc0002f0a189f4167 (diff) |
Added the framework for having canvas/recorder/picture record depth_set's.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2127233002
Committed: https://skia.googlesource.com/skia/+/6d3fb898d5f73a82e36f11c712a633c3921ed518
Committed: https://skia.googlesource.com/skia/+/1185d90c785f743364cc9113d7007a59af07470c
Review-Url: https://codereview.chromium.org/2127233002
-rw-r--r-- | include/core/SkCanvas.h | 12 | ||||
-rw-r--r-- | include/private/SkRecords.h | 3 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 17 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 4 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 8 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 10 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 2 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 4 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 4 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 1 | ||||
-rw-r--r-- | tests/CanvasTest.cpp | 53 | ||||
-rw-r--r-- | tools/debugger/SkDebugCanvas.cpp | 5 | ||||
-rw-r--r-- | tools/debugger/SkDebugCanvas.h | 2 | ||||
-rw-r--r-- | tools/debugger/SkDrawCommand.cpp | 37 | ||||
-rw-r--r-- | tools/debugger/SkDrawCommand.h | 16 |
15 files changed, 173 insertions, 5 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 97aa3c7d8e..35a8d1c7b9 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -451,6 +451,13 @@ public: */ void resetMatrix(); + /** Add the specified translation to the current draw depth of the canvas. + @param z The distance to translate in Z. + Negative into screen, positive out of screen. + Without translation, the draw depth defaults to 0. + */ + void translateZ(SkScalar z); + /** * Modify the current clip with the specified rectangle. * @param rect The rect to combine with the current clip @@ -1260,6 +1267,10 @@ public: void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds); protected: + /** Returns the current (cumulative) draw depth of the canvas. + */ + SkScalar getZ() const; + /** After calling saveLayer(), there can be any number of devices that make up the top-most drawing area. LayerIter can be used to iterate through those devices. Note that the iterator is only valid until the next API @@ -1325,6 +1336,7 @@ protected: virtual void didRestore() {} virtual void didConcat(const SkMatrix&) {} virtual void didSetMatrix(const SkMatrix&) {} + virtual void didTranslateZ(SkScalar) {} virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value); virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h index 9ec2d2116c..35adca20e7 100644 --- a/include/private/SkRecords.h +++ b/include/private/SkRecords.h @@ -47,6 +47,7 @@ namespace SkRecords { M(Save) \ M(SaveLayer) \ M(SetMatrix) \ + M(TranslateZ) \ M(Concat) \ M(ClipPath) \ M(ClipRRect) \ @@ -218,6 +219,8 @@ RECORD(SetMatrix, 0, RECORD(Concat, 0, TypedMatrix matrix); +RECORD(TranslateZ, 0, SkScalar z); + struct RegionOpAndAA { RegionOpAndAA() {} RegionOpAndAA(SkRegion::Op op, bool aa) : op(op), aa(aa) {} diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index f893a62e75..0bd3851c06 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -294,17 +294,22 @@ public: SkMatrix fMatrix; int fDeferredSaveCount; + // This is the current cumulative depth (aggregate of all done translateZ calls) + SkScalar fCurDrawDepth; + MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { fFilter = nullptr; fLayer = nullptr; fTopLayer = nullptr; fMatrix.reset(); fDeferredSaveCount = 0; + fCurDrawDepth = 0; // don't bother initializing fNext inc_rec(); } - MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { + MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix), + fCurDrawDepth(prev.fCurDrawDepth) { fFilter = SkSafeRef(prev.fFilter); fLayer = nullptr; fTopLayer = prev.fTopLayer; @@ -1539,6 +1544,16 @@ void SkCanvas::resetMatrix() { this->setMatrix(SkMatrix::I()); } +void SkCanvas::translateZ(SkScalar z) { + this->checkForDeferredSave(); + this->fMCRec->fCurDrawDepth += z; + this->didTranslateZ(z); +} + +SkScalar SkCanvas::getZ() const { + return this->fMCRec->fCurDrawDepth; +} + ////////////////////////////////////////////////////////////////////////////// void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index 3546fb2e0a..125d4e95e8 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -81,7 +81,9 @@ enum DrawType { DRAW_DRAWABLE_MATRIX, DRAW_TEXT_RSXFORM, - LAST_DRAWTYPE_ENUM = DRAW_DRAWABLE_MATRIX, + TRANSLATE_Z, + + LAST_DRAWTYPE_ENUM = TRANSLATE_Z }; // In the 'match' method, this constant will match any flavor of DRAW_BITMAP* diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 6b8930436f..60c4fe898d 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -129,8 +129,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, reader->skip(size - 4); } break; case CLIP_PATH: { - const SkPath& path = fPictureData->getPath(reader); - uint32_t packed = reader->readInt(); + const SkPath& path = fPictureData->getPath(reader); + uint32_t packed = reader->readInt(); SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); bool doAA = ClipParams_unpackDoAA(packed); size_t offsetToRestore = reader->readInt(); @@ -616,6 +616,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, SkScalar dy = reader->readScalar(); canvas->translate(dx, dy); } break; + case TRANSLATE_Z: { + SkScalar dz = reader->readScalar(); + canvas->translateZ(dz); + } default: SkASSERTF(false, "Unknown draw type: %d", op); } diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 17ed1aa20b..f2a0fd857c 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -218,6 +218,16 @@ void SkPictureRecord::didSetMatrix(const SkMatrix& matrix) { this->INHERITED::didSetMatrix(matrix); } +void SkPictureRecord::didTranslateZ(SkScalar z) { + this->validate(fWriter.bytesWritten(), 0); + // op + scalar + size_t size = 1 * kUInt32Size + 1 * sizeof(SkScalar); + size_t initialOffset = this->addDraw(TRANSLATE_Z, &size); + this->addScalar(z); + this->validate(initialOffset, size); + this->INHERITED::didTranslateZ(z); +} + static bool regionOpExpands(SkRegion::Op op) { switch (op) { case SkRegion::kUnion_Op: diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index bdb6609bd9..276dd3e29b 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -159,6 +159,8 @@ protected: void didConcat(const SkMatrix&) override; void didSetMatrix(const SkMatrix&) override; + void didTranslateZ(SkScalar) override; + void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; void onDrawText(const void* text, size_t, SkScalar x, SkScalar y, const SkPaint&) override; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index eb027296f1..02d07d5005 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -86,6 +86,8 @@ DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa)); DRAW(ClipRect, clipRect(r.rect, r.opAA.op, r.opAA.aa)); DRAW(ClipRegion, clipRegion(r.region, r.op)); +DRAW(TranslateZ, SkCanvas::translateZ(r.z)); + DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint)); DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.paint)); DRAW(DrawBitmapRect, @@ -287,6 +289,8 @@ private: void trackBounds(const ClipPath&) { this->pushControl(); } void trackBounds(const ClipRegion&) { this->pushControl(); } + void trackBounds(const TranslateZ&) { this->pushControl(); } + // For all other ops, we can calculate and store the bounds directly now. template <typename T> void trackBounds(const T& op) { fBounds[fCurrentOp] = this->bounds(op); diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 19cb663eaf..c7869bb6a4 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -369,6 +369,10 @@ void SkRecorder::didSetMatrix(const SkMatrix& matrix) { APPEND(SetMatrix, matrix); } +void SkRecorder::didTranslateZ(SkScalar z) { + APPEND(TranslateZ, z); +} + void SkRecorder::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { INHERITED(onClipRect, rect, op, edgeStyle); SkRecords::RegionOpAndAA opAA(op, kSoft_ClipEdgeStyle == edgeStyle); diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 3cf0be97c3..66a006712e 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -60,6 +60,7 @@ public: void didConcat(const SkMatrix&) override; void didSetMatrix(const SkMatrix&) override; + void didTranslateZ(SkScalar) override; void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; void onDrawDrawable(SkDrawable*, const SkMatrix*) override; diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp index 82e065f5ac..1e5f9e18bc 100644 --- a/tests/CanvasTest.cpp +++ b/tests/CanvasTest.cpp @@ -779,6 +779,45 @@ DEF_TEST(Canvas_ClipEmptyPath, reporter) { canvas.restore(); } +#define SHADOW_TEST_CANVAS_CONST 10 + +class SkShadowTestCanvas : public SkPaintFilterCanvas { +public: + + SkShadowTestCanvas(int x, int y, skiatest::Reporter* reporter) + : INHERITED(x,y) + , fReporter(reporter) {} + + bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const { + REPORTER_ASSERT(this->fReporter, this->getZ() == SHADOW_TEST_CANVAS_CONST); + + return true; + } + + void testUpdateDepth(skiatest::Reporter *reporter) { + // set some depths (with picture enabled), then check them as they get set + + REPORTER_ASSERT(reporter, this->getZ() == 0); + this->translateZ(-10); + REPORTER_ASSERT(reporter, this->getZ() == -10); + + this->save(); + this->translateZ(20); + REPORTER_ASSERT(reporter, this->getZ() == 10); + + this->restore(); + REPORTER_ASSERT(reporter, this->getZ() == -10); + + this->translateZ(13.14f); + REPORTER_ASSERT(reporter, SkScalarNearlyEqual(this->getZ(), 3.14f)); + } + +private: + skiatest::Reporter* fReporter; + + typedef SkPaintFilterCanvas INHERITED; +}; + namespace { class MockFilterCanvas : public SkPaintFilterCanvas { @@ -812,6 +851,20 @@ DEF_TEST(PaintFilterCanvas_ConsistentState, reporter) { REPORTER_ASSERT(reporter, canvas.getTotalMatrix() == filterCanvas.getTotalMatrix()); REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2)); REPORTER_ASSERT(reporter, clip1 == clip2); + + SkShadowTestCanvas* tCanvas = new SkShadowTestCanvas(100,100, reporter); + tCanvas->testUpdateDepth(reporter); + delete(tCanvas); + + SkPictureRecorder recorder; + SkShadowTestCanvas *tSCanvas = new SkShadowTestCanvas(100, 100, reporter); + SkCanvas *tPCanvas = recorder.beginRecording(SkRect::MakeIWH(100, 100)); + + tPCanvas->translateZ(SHADOW_TEST_CANVAS_CONST); + sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture(); + tSCanvas->drawPicture(pic); + + delete(tSCanvas); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp index b80eeea0b1..ae934a16e7 100644 --- a/tools/debugger/SkDebugCanvas.cpp +++ b/tools/debugger/SkDebugCanvas.cpp @@ -690,6 +690,11 @@ void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) { this->INHERITED::didSetMatrix(matrix); } +void SkDebugCanvas::didTranslateZ(SkScalar z) { + this->addDrawCommand(new SkTranslateZCommand(z)); + this->INHERITED::didTranslateZ(z); +} + void SkDebugCanvas::toggleCommand(int index, bool toggle) { SkASSERT(index < fCommandVector.count()); fCommandVector[index]->setVisible(toggle); diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h index e8d9113438..4264f55200 100644 --- a/tools/debugger/SkDebugCanvas.h +++ b/tools/debugger/SkDebugCanvas.h @@ -194,6 +194,8 @@ protected: void didConcat(const SkMatrix&) override; void didSetMatrix(const SkMatrix&) override; + void didTranslateZ(SkScalar) override; + void onDrawAnnotation(const SkRect&, const char[], SkData*) override; void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index ecd6a7003f..8f42cb70ec 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -28,6 +28,7 @@ #define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command" #define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible" #define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix" +#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation" #define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords" #define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds" #define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint" @@ -211,6 +212,7 @@ const char* SkDrawCommand::GetCommandString(OpType type) { case kSave_OpType: return "Save"; case kSaveLayer_OpType: return "SaveLayer"; case kSetMatrix_OpType: return "SetMatrix"; + case kTranslateZ_OpType: return "TranslateZ"; default: SkDebugf("OpType error 0x%08x\n", type); SkASSERT(0); @@ -268,6 +270,8 @@ SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& url INSTALL_FACTORY(Save); INSTALL_FACTORY(SaveLayer); INSTALL_FACTORY(SetMatrix); + + INSTALL_FACTORY(TranslateZ); } SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString()); FROM_JSON* factory = factories.find(name); @@ -470,6 +474,11 @@ Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) { return result; } +Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) { + Json::Value result(z); + return result; +} + Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) { Json::Value result(Json::objectValue); switch (path.getFillType()) { @@ -1482,6 +1491,11 @@ static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) { result->set9(values); } +static void extract_json_scalar(Json::Value& scalar, SkScalar* result) { + SkScalar value = scalar.asFloat(); + *result = value; +} + static void extract_json_path(Json::Value& path, SkPath* result) { const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString(); if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) { @@ -3295,3 +3309,26 @@ SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command, extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix); return new SkSetMatrixCommand(matrix); } + +SkTranslateZCommand::SkTranslateZCommand(SkScalar z) + : INHERITED(kTranslateZ_OpType) { + fZTranslate = z; + fInfo.push(SkObjectParser::ScalarToString(fZTranslate, "drawDepthTranslation")); +} + +void SkTranslateZCommand::execute(SkCanvas* canvas) const { + canvas->translateZ(fZTranslate); +} + +Json::Value SkTranslateZCommand::toJSON(UrlDataManager& urlDataManager) const { + Json::Value result = INHERITED::toJSON(urlDataManager); + result[SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS] = MakeJsonScalar(fZTranslate); + return result; +} + +SkTranslateZCommand* SkTranslateZCommand::fromJSON(Json::Value& command, + UrlDataManager& urlDataManager) { + SkScalar z; + extract_json_scalar(command[SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS], &z); + return new SkTranslateZCommand(z); +} diff --git a/tools/debugger/SkDrawCommand.h b/tools/debugger/SkDrawCommand.h index dc639ec3a3..a7e6c73802 100644 --- a/tools/debugger/SkDrawCommand.h +++ b/tools/debugger/SkDrawCommand.h @@ -56,8 +56,9 @@ public: kSave_OpType, kSaveLayer_OpType, kSetMatrix_OpType, + kTranslateZ_OpType, - kLast_OpType = kSetMatrix_OpType + kLast_OpType = kTranslateZ_OpType }; static const int kOpTypeCount = kLast_OpType + 1; @@ -125,6 +126,7 @@ public: static Json::Value MakeJsonRect(const SkRect& rect); static Json::Value MakeJsonIRect(const SkIRect&); static Json::Value MakeJsonMatrix(const SkMatrix&); + static Json::Value MakeJsonScalar(SkScalar); static Json::Value MakeJsonPath(const SkPath& path); static Json::Value MakeJsonRegion(const SkRegion& region); static Json::Value MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager); @@ -731,4 +733,16 @@ private: typedef SkDrawCommand INHERITED; }; +class SkTranslateZCommand : public SkDrawCommand { +public: + SkTranslateZCommand(SkScalar); + void execute(SkCanvas* canvas) const override; + Json::Value toJSON(UrlDataManager& urlDataManager) const override; + static SkTranslateZCommand* fromJSON(Json::Value& command, UrlDataManager& urlDataManager); + +private: + SkScalar fZTranslate; + + typedef SkDrawCommand INHERITED; +}; #endif |