aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2016-08-19 09:05:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-19 09:05:27 -0700
commitcbdf007bc2eb85056a1a5c75c088202becba2d16 (patch)
treee5ad582ba81b2c6b113195f64ab584c8376567a1 /src/core
parent68d952cf4061dc455d6a6040ce1e4625e4f2ab29 (diff)
Fast path translate() in SkCanvas and SkLiteDL.
This adds didTranslate() so that SkLiteDL (and other canvas recorders) can record the translate rather than the full concat. It also adds a case to SkMatrix::preTranslate() to fast path translate x translate -> translate (i.e. +=). BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2255283002 Committed: https://skia.googlesource.com/skia/+/5fa47f4fd13b3158de4599414c86d17649c2dd1c Misc bots failing in pictureimagefilter replay modes. https://luci-milo.appspot.com/swarming/task/30b8e53f3a1f4f10/steps/dm/0/stdout Problem is FMA vs. not. CQ_INCLUDE_TRYBOTS=master.client.skia: Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Fast-Trybot Review-Url: https://codereview.chromium.org/2255283002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkCanvas.cpp11
-rw-r--r--src/core/SkLiteDL.cpp15
-rw-r--r--src/core/SkLiteDL.h1
-rw-r--r--src/core/SkLiteRecorder.cpp5
-rw-r--r--src/core/SkLiteRecorder.h1
-rw-r--r--src/core/SkMatrix.cpp9
-rw-r--r--src/core/SkRecordDraw.cpp7
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
9 files changed, 42 insertions, 12 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index e5ad3b80ef..e039c60e0a 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1444,9 +1444,14 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
/////////////////////////////////////////////////////////////////////////////
void SkCanvas::translate(SkScalar dx, SkScalar dy) {
- SkMatrix m;
- m.setTranslate(dx, dy);
- this->concat(m);
+ this->checkForDeferredSave();
+ fDeviceCMDirty = true;
+ fMCRec->fMatrix.preTranslate(dx,dy);
+
+ // Translate shouldn't affect the is-scale-translateness of the matrix.
+ SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
+
+ this->didTranslate(dx,dy);
}
void SkCanvas::scale(SkScalar sx, SkScalar sy) {
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index c634d4825a..c3bf976a88 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -52,7 +52,7 @@ static void make_threadsafe(SkPath* path, SkMatrix* matrix) {
namespace {
#define TYPES(M) \
M(Save) M(Restore) M(SaveLayer) \
- M(Concat) M(SetMatrix) M(TranslateZ) \
+ M(Concat) M(SetMatrix) M(Translate) M(TranslateZ) \
M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \
M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawOval) M(DrawRRect) M(DrawDRRect) \
M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) M(DrawShadowedPicture) \
@@ -115,6 +115,14 @@ namespace {
}
void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
};
+ struct Translate final : Op {
+ static const auto kType = Type::Translate;
+ Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
+ SkScalar dx,dy;
+ void draw(SkCanvas* c, const SkMatrix&) {
+ c->translate(dx, dy);
+ }
+ };
struct TranslateZ final : Op {
static const auto kType = Type::TranslateZ;
TranslateZ(SkScalar dz) : dz(dz) {}
@@ -539,8 +547,9 @@ void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint,
this->push<SaveLayer>(0, bounds, paint, backdrop, flags);
}
-void SkLiteDL:: concat(const SkMatrix& matrix) { this->push <Concat>(0, matrix); }
-void SkLiteDL::setMatrix(const SkMatrix& matrix) { this->push<SetMatrix>(0, matrix); }
+void SkLiteDL:: concat(const SkMatrix& matrix) { this->push <Concat>(0, matrix); }
+void SkLiteDL::setMatrix(const SkMatrix& matrix) { this->push<SetMatrix>(0, matrix); }
+void SkLiteDL::translate(SkScalar dx, SkScalar dy) { this->push<Translate>(0, dx, dy); }
void SkLiteDL::translateZ(SkScalar dz) { this->push<TranslateZ>(0, dz); }
void SkLiteDL::clipPath(const SkPath& path, SkRegion::Op op, bool aa) {
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index 38a08129ac..e80548cecd 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -29,6 +29,7 @@ public:
void concat (const SkMatrix&);
void setMatrix (const SkMatrix&);
+ void translate(SkScalar, SkScalar);
void translateZ(SkScalar);
void clipPath (const SkPath&, SkRegion::Op, bool aa);
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index b61dd8f582..049ccd1afe 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -29,8 +29,9 @@ SkCanvas::SaveLayerStrategy SkLiteRecorder::getSaveLayerStrategy(const SaveLayer
}
void SkLiteRecorder::willRestore() { fDL->restore(); }
-void SkLiteRecorder::didConcat (const SkMatrix& matrix) { fDL-> concat(matrix); }
-void SkLiteRecorder::didSetMatrix(const SkMatrix& matrix) { fDL->setMatrix(matrix); }
+void SkLiteRecorder::didConcat (const SkMatrix& matrix) { fDL-> concat(matrix); }
+void SkLiteRecorder::didSetMatrix(const SkMatrix& matrix) { fDL->setMatrix(matrix); }
+void SkLiteRecorder::didTranslate(SkScalar dx, SkScalar dy) { fDL->translate(dx, dy); }
void SkLiteRecorder::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle style) {
fDL->clipRect(rect, op, style==kSoft_ClipEdgeStyle);
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index a924378846..6ca03cd46c 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -25,6 +25,7 @@ public:
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
+ void didTranslate(SkScalar, SkScalar) override;
void onClipRect (const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
void onClipRRect (const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index 0fd802087f..fb0c69d7c7 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -290,7 +290,12 @@ void SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
return;
}
- if (this->hasPerspective()) {
+ if (fTypeMask <= kTranslate_Mask) {
+ fMat[kMTransX] += dx;
+ fMat[kMTransY] += dy;
+ this->setTypeMask((fMat[kMTransX] != 0 || fMat[kMTransY] != 0) ? kTranslate_Mask
+ : kIdentity_Mask);
+ } else if (this->hasPerspective()) {
SkMatrix m;
m.setTranslate(dx, dy);
this->preConcat(m);
@@ -1100,7 +1105,7 @@ void SkMatrix::mapVectors(SkPoint dst[], const SkPoint src[], int count) const {
void SkMatrix::mapRectScaleTranslate(SkRect* dst, const SkRect& src) const {
SkASSERT(dst);
SkASSERT(this->isScaleTranslate());
-
+
SkScalar sx = fMat[kMScaleX];
SkScalar sy = fMat[kMScaleY];
SkScalar tx = fMat[kMTransX];
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index dcfc0fbf90..4d27fb6968 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -83,6 +83,7 @@ DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
r.saveLayerFlags)));
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
DRAW(Concat, concat(r.matrix));
+DRAW(Translate, translate(r.dx, r.dy));
DRAW(ClipPath, clipPath(r.path, r.opAA.op, r.opAA.aa));
DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa));
@@ -241,11 +242,12 @@ private:
SkMatrix ctm;
};
- // Only Restore, SetMatrix, and Concat change the CTM.
+ // Only Restore, SetMatrix, Concat, and Translate change the CTM.
template <typename T> void updateCTM(const T&) {}
void updateCTM(const Restore& op) { fCTM = op.matrix; }
void updateCTM(const SetMatrix& op) { fCTM = op.matrix; }
void updateCTM(const Concat& op) { fCTM.preConcat(op.matrix); }
+ void updateCTM(const Translate& op) { fCTM.preTranslate(op.dx, op.dy); }
// Most ops don't change the clip.
template <typename T> void updateClipBounds(const T&) {}
@@ -299,12 +301,13 @@ private:
void trackBounds(const SetMatrix&) { this->pushControl(); }
void trackBounds(const Concat&) { this->pushControl(); }
+ void trackBounds(const Translate&) { this->pushControl(); }
+ void trackBounds(const TranslateZ&) { this->pushControl(); }
void trackBounds(const ClipRect&) { this->pushControl(); }
void trackBounds(const ClipRRect&) { this->pushControl(); }
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) {
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index b961c7d1e7..92bb6aee5d 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -380,6 +380,10 @@ void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
APPEND(SetMatrix, matrix);
}
+void SkRecorder::didTranslate(SkScalar dx, SkScalar dy) {
+ APPEND(Translate, dx, dy);
+}
+
void SkRecorder::didTranslateZ(SkScalar z) {
#ifdef SK_EXPERIMENTAL_SHADOWING
APPEND(TranslateZ, z);
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index ba171a17ee..d039e20e29 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 didTranslate(SkScalar, SkScalar) override;
#ifdef SK_EXPERIMENTAL_SHADOWING
void didTranslateZ(SkScalar) override;