aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkCanvas.h12
-rw-r--r--include/private/SkRecords.h3
-rw-r--r--src/core/SkCanvas.cpp17
-rw-r--r--src/core/SkPictureFlat.h1
-rw-r--r--src/core/SkPictureRecord.cpp9
-rw-r--r--src/core/SkPictureRecord.h2
-rw-r--r--src/core/SkRecordDraw.cpp4
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
-rw-r--r--tests/CanvasTest.cpp26
-rw-r--r--tools/debugger/SkDebugCanvas.cpp5
-rw-r--r--tools/debugger/SkDebugCanvas.h2
-rw-r--r--tools/debugger/SkDrawCommand.cpp37
-rw-r--r--tools/debugger/SkDrawCommand.h16
14 files changed, 137 insertions, 2 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 26458696bc..337ce72767 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -444,6 +444,13 @@ public:
*/
void resetMatrix();
+ /** Set the current draw depth of the canvas.
+ @param z The SkScalar depth; it's tracked in the save/restore stack.
+ Negative into screen, positive out of screen.
+ 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
@@ -1253,6 +1260,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
@@ -1318,6 +1329,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 0ce97fff20..20e745758e 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;
@@ -1533,6 +1538,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..d8145110b8 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -52,6 +52,7 @@ enum DrawType {
SAVE_LAYER_SAVEFLAGS_DEPRECATED,
SCALE,
SET_MATRIX,
+ TRANSLATE_Z,
SKEW,
TRANSLATE,
NOOP,
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 17ed1aa20b..3b70b56774 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -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:
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 ec9aee9562..03f8d53d5e 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -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);
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..0886b53652 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -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);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
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