Added the framework for having canvas/recorder/picture record depth_set's.
authorvjiaoblack <vjiaoblack@google.com>
Wed, 13 Jul 2016 15:35:40 +0000 (08:35 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 13 Jul 2016 15:35:41 +0000 (08:35 -0700)
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2127233002

Committed: https://skia.googlesource.com/skia/+/6d3fb898d5f73a82e36f11c712a633c3921ed518
Review-Url: https://codereview.chromium.org/2127233002

15 files changed:
include/core/SkCanvas.h
include/private/SkRecords.h
src/core/SkCanvas.cpp
src/core/SkPictureFlat.h
src/core/SkPicturePlayback.cpp
src/core/SkPictureRecord.cpp
src/core/SkPictureRecord.h
src/core/SkRecordDraw.cpp
src/core/SkRecorder.cpp
src/core/SkRecorder.h
tests/CanvasTest.cpp
tools/debugger/SkDebugCanvas.cpp
tools/debugger/SkDebugCanvas.h
tools/debugger/SkDrawCommand.cpp
tools/debugger/SkDrawCommand.h

index 97aa3c7..fb3ae6d 100644 (file)
@@ -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
@@ -501,7 +508,8 @@ public:
         matrix, clipRegion() assumes its argument is already in device
         coordinates, and so no transformation is performed.
         @param deviceRgn    The region to apply to the current clip
-        @param op The region op to apply to the current clip
+        @param op The regio
+        n op to apply to the current clip
     */
     void clipRegion(const SkRegion& deviceRgn,
                     SkRegion::Op op = SkRegion::kIntersect_Op);
@@ -1260,6 +1268,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 +1337,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&);
index 9ec2d21..35adca2 100644 (file)
@@ -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) {}
index 3067772..2aa3f5e 100644 (file)
@@ -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) {
index 3546fb2..d814511 100644 (file)
@@ -52,6 +52,7 @@ enum DrawType {
     SAVE_LAYER_SAVEFLAGS_DEPRECATED,
     SCALE,
     SET_MATRIX,
+    TRANSLATE_Z,
     SKEW,
     TRANSLATE,
     NOOP,
index 6b89304..60c4fe8 100644 (file)
@@ -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);
     }
index 17ed1aa..3b70b56 100644 (file)
@@ -218,6 +218,15 @@ void SkPictureRecord::didSetMatrix(const SkMatrix& matrix) {
     this->INHERITED::didSetMatrix(matrix);
 }
 
+void SkPictureRecord::didTranslateZ(SkScalar z) {
+    this->validate(fWriter.bytesWritten(), 0);
+    // set Z
+    size_t size = sizeof(SkScalar);
+    size_t initialOffset = this->addDraw(TRANSLATE_Z, &size);
+
+    this->validate(initialOffset, size);
+}
+
 static bool regionOpExpands(SkRegion::Op op) {
     switch (op) {
         case SkRegion::kUnion_Op:
index bdb6609..276dd3e 100644 (file)
@@ -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;
index ec9aee9..03f8d53 100644 (file)
@@ -87,6 +87,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,
@@ -288,6 +290,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);
index 19cb663..c7869bb 100644 (file)
@@ -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);
index 3cf0be9..66a0067 100644 (file)
@@ -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;
index 82e065f..0886b53 100644 (file)
@@ -779,6 +779,27 @@ DEF_TEST(Canvas_ClipEmptyPath, reporter) {
     canvas.restore();
 }
 
+class SkTestCanvas : public SkCanvas {
+public:
+    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));
+    }
+};
+
 namespace {
 
 class MockFilterCanvas : public SkPaintFilterCanvas {
@@ -812,6 +833,11 @@ 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);
+
+    SkTestCanvas* tCanvas;
+
+    tCanvas = (SkTestCanvas*) new SkCanvas(100,100);
+    tCanvas->testUpdateDepth(reporter);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
index b80eeea..ae934a1 100644 (file)
@@ -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);
index e8d9113..4264f55 100644 (file)
@@ -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,
index ecd6a70..8f42cb7 100644 (file)
@@ -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);
+}
index dc639ec..a7e6c73 100644 (file)
@@ -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