author | Rik Cabanier <cabanier@adobe.com> |
Mon, 31 Mar 2014 08:55:00 +0200 (2014-03-31) | |
changeset 176487 | 9204362c5122a603be768c4df295cecc75fbfeee |
parent 176486 | 05a2d06d232fb63503b964d3f678ab74f8903c9d |
child 176488 | aa6cc6b2ef8f6e12d4443f0c98ca5e170fa224e2 |
push id | 26524 |
push user | ryanvm@gmail.com |
push date | Tue, 01 Apr 2014 20:44:18 +0000 (2014-04-01) |
treeherder | mozilla-central@0ff6afce0133 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bas |
bugs | 988088 |
milestone | 31.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
content/canvas/src/CanvasRenderingContext2D.cpp | file | annotate | diff | comparison | revisions | |
content/canvas/src/CanvasRenderingContext2D.h | file | annotate | diff | comparison | revisions |
--- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -4400,34 +4400,42 @@ CanvasPath::Constructor(const GlobalObje nsRefPtr<CanvasPath> path = new CanvasPath(aGlobal.GetAsSupports(), tempPath->CopyToBuilder()); return path.forget(); } void CanvasPath::ClosePath() { + EnsurePathBuilder(); + mPathBuilder->Close(); } void CanvasPath::MoveTo(double x, double y) { + EnsurePathBuilder(); + mPathBuilder->MoveTo(Point(ToFloat(x), ToFloat(y))); } void CanvasPath::LineTo(double x, double y) { + EnsurePathBuilder(); + mPathBuilder->LineTo(Point(ToFloat(x), ToFloat(y))); } void CanvasPath::QuadraticCurveTo(double cpx, double cpy, double x, double y) { + EnsurePathBuilder(); + mPathBuilder->QuadraticBezierTo(gfx::Point(ToFloat(cpx), ToFloat(cpy)), gfx::Point(ToFloat(x), ToFloat(y))); } void CanvasPath::BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y) @@ -4522,48 +4530,75 @@ CanvasPath::Arc(double x, double y, doub } ArcToBezier(this, Point(x, y), Size(radius, radius), startAngle, endAngle, anticlockwise); } void CanvasPath::LineTo(const gfx::Point& aPoint) { + EnsurePathBuilder(); + mPathBuilder->LineTo(aPoint); } void CanvasPath::BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2, const gfx::Point& aCP3) { + EnsurePathBuilder(); + mPathBuilder->BezierTo(aCP1, aCP2, aCP3); } RefPtr<gfx::Path> CanvasPath::GetPath(const CanvasWindingRule& winding, const mozilla::RefPtr<mozilla::gfx::DrawTarget>& mTarget) const { FillRule fillRule = FillRule::FILL_WINDING; if (winding == CanvasWindingRule::Evenodd) { fillRule = FillRule::FILL_EVEN_ODD; } - RefPtr<Path> mTempPath = mPathBuilder->Finish(); - if (!mTempPath) - return mTempPath; + if (mPath && + (mPath->GetBackendType() == mTarget->GetType()) && + (mPath->GetFillRule() == fillRule)) { + return mPath; + } + + if (!mPath) { + // if there is no path, there must be a pathbuilder + MOZ_ASSERT(mPathBuilder); + mPath = mPathBuilder->Finish(); + if (!mPath) + return mPath; + + mPathBuilder = nullptr; + } // retarget our backend if we're used with a different backend - if (mTempPath->GetBackendType() != mTarget->GetType()) { - mPathBuilder = mTarget->CreatePathBuilder(fillRule); - mTempPath->StreamToSink(mPathBuilder); - mTempPath = mPathBuilder->Finish(); - } else if (mTempPath->GetFillRule() != fillRule) { - mPathBuilder = mTempPath->CopyToBuilder(fillRule); - mTempPath = mPathBuilder->Finish(); - } - - mPathBuilder = mTempPath->CopyToBuilder(); - - return mTempPath; + if (mPath->GetBackendType() != mTarget->GetType()) { + RefPtr<PathBuilder> tmpPathBuilder = mTarget->CreatePathBuilder(fillRule); + mPath->StreamToSink(tmpPathBuilder); + mPath = tmpPathBuilder->Finish(); + } else if (mPath->GetFillRule() != fillRule) { + RefPtr<PathBuilder> tmpPathBuilder = mPath->CopyToBuilder(fillRule); + mPath = tmpPathBuilder->Finish(); + } + + return mPath; +} + +void +CanvasPath::EnsurePathBuilder() const +{ + if (mPathBuilder) { + return; + } + + // if there is not pathbuilder, there must be a path + MOZ_ASSERT(mPath); + mPathBuilder = mPath->CopyToBuilder(); + mPath = nullptr; } } }
--- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -91,17 +91,20 @@ public: CanvasPath(nsCOMPtr<nsISupports> aParent, RefPtr<gfx::PathBuilder> mPathBuilder); virtual ~CanvasPath() {} private: nsCOMPtr<nsISupports> mParent; static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); } + mutable RefPtr<gfx::Path> mPath; mutable RefPtr<gfx::PathBuilder> mPathBuilder; + + void EnsurePathBuilder() const; }; struct CanvasBidiProcessor; class CanvasRenderingContext2DUserData; /** ** CanvasRenderingContext2D **/