diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-16 14:06:02 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-16 14:06:02 +0000 |
commit | a584aed5f709ff9655fd3326e23cd6f602ac7ae4 (patch) | |
tree | ca28eca36769d5f69e3cadc6ccea90c3710482f4 | |
parent | 7b463acd46b8df866d3a27fbaf69b0090c842d1e (diff) |
perform quickReject in drawPoints (which is called by drawLine) just like we
already did in drawRect and drawPath
git-svn-id: http://skia.googlecode.com/svn/trunk@3968 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | bench/DashBench.cpp | 7 | ||||
-rw-r--r-- | include/core/SkPaint.h | 109 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 15 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 5 |
4 files changed, 86 insertions, 50 deletions
diff --git a/bench/DashBench.cpp b/bench/DashBench.cpp index 40fffe6dea..3f2cfa7856 100644 --- a/bench/DashBench.cpp +++ b/bench/DashBench.cpp @@ -34,7 +34,8 @@ protected: SkString fName; SkTDArray<SkScalar> fIntervals; int fWidth; - bool fDoClip; + SkPoint fPts[2]; + bool fDoClip; enum { N = SkBENCHLOOP(100) @@ -49,6 +50,9 @@ public: fWidth = width; fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip"); fDoClip = doClip; + + fPts[0].set(SkIntToScalar(10), SkIntToScalar(10)); + fPts[1].set(SkIntToScalar(600), SkIntToScalar(10)); } virtual void makePath(SkPath* path) { @@ -87,6 +91,7 @@ protected: virtual void handlePath(SkCanvas* canvas, const SkPath& path, const SkPaint& paint, int N) { for (int i = 0; i < N; ++i) { +// canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, paint); canvas->drawPath(path, paint); } } diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index c5f7c9c247..8fcfda26ba 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -434,52 +434,6 @@ public: */ bool getFillPath(const SkPath& src, SkPath* dst) const; - /** Returns true if the current paint settings allow for fast computation of - bounds (i.e. there is nothing complex like a patheffect that would make - the bounds computation expensive. - */ - bool canComputeFastBounds() const { - if (this->getLooper()) { - return this->getLooper()->canComputeFastBounds(*this); - } - return !this->getRasterizer(); - } - - /** Only call this if canComputeFastBounds() returned true. This takes a - raw rectangle (the raw bounds of a shape), and adjusts it for stylistic - effects in the paint (e.g. stroking). If needed, it uses the storage - rect parameter. It returns the adjusted bounds that can then be used - for quickReject tests. - - The returned rect will either be orig or storage, thus the caller - should not rely on storage being set to the result, but should always - use the retured value. It is legal for orig and storage to be the same - rect. - - e.g. - if (paint.canComputeFastBounds()) { - SkRect r, storage; - path.computeBounds(&r, SkPath::kFast_BoundsType); - const SkRect& fastR = paint.computeFastBounds(r, &storage); - if (canvas->quickReject(fastR, ...)) { - // don't draw the path - } - } - */ - const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const { - // ultra fast-case: filling with no effects that affect geometry - if (this->getStyle() == kFill_Style) { - uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper()); - effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter()); - effects |= reinterpret_cast<uintptr_t>(this->getPathEffect()); - if (!effects) { - return orig; - } - } - - return this->doComputeFastBounds(orig, storage); - } - /** Get the paint's shader object. <p /> The shader's reference count is not affected. @@ -914,7 +868,66 @@ private: void (*proc)(const SkDescriptor*, void*), void* context, bool ignoreGamma = false) const; - const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage) const; + /////////////////////////////////////////////////////////////////////////// + + /** Returns true if the current paint settings allow for fast computation of + bounds (i.e. there is nothing complex like a patheffect that would make + the bounds computation expensive. + */ + bool canComputeFastBounds() const { + if (this->getLooper()) { + return this->getLooper()->canComputeFastBounds(*this); + } + return !this->getRasterizer(); + } + + /** Only call this if canComputeFastBounds() returned true. This takes a + raw rectangle (the raw bounds of a shape), and adjusts it for stylistic + effects in the paint (e.g. stroking). If needed, it uses the storage + rect parameter. It returns the adjusted bounds that can then be used + for quickReject tests. + + The returned rect will either be orig or storage, thus the caller + should not rely on storage being set to the result, but should always + use the retured value. It is legal for orig and storage to be the same + rect. + + e.g. + if (paint.canComputeFastBounds()) { + SkRect r, storage; + path.computeBounds(&r, SkPath::kFast_BoundsType); + const SkRect& fastR = paint.computeFastBounds(r, &storage); + if (canvas->quickReject(fastR, ...)) { + // don't draw the path + } + } + */ + const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const { + SkPaint::Style style = this->getStyle(); + // ultra fast-case: filling with no effects that affect geometry + if (kFill_Style == style) { + uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper()); + effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter()); + effects |= reinterpret_cast<uintptr_t>(this->getPathEffect()); + if (!effects) { + return orig; + } + } + + return this->doComputeFastBounds(orig, storage, style); + } + + const SkRect& computeFastStrokeBounds(const SkRect& orig, + SkRect* storage) const { + return this->doComputeFastBounds(orig, storage, kFill_Style); + } + + // Take the style explicitly, so the caller can force us to be stroked + // without having to make a copy of the paint just to change that field. + const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage, + Style) const; + + /////////////////////////////////////////////////////////////////////////// enum { kCanonicalTextSizeForPaths = 64 @@ -922,6 +935,8 @@ private: friend class SkAutoGlyphCache; friend class SkCanvas; friend class SkDraw; + friend class SkDrawLooper; // computeFastBounds + friend class SkPictureRecord; // computeFastBounds friend class SkPDFDevice; friend class SkTextToPathIter; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 90de54a4e8..3687d1e984 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1452,6 +1452,21 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], return; } + if (paint.canComputeFastBounds()) { + SkRect r; + // special-case 2 points (common for drawing a single line) + if (2 == count) { + r.set(pts[0], pts[1]); + } else { + r.set(pts, count); + } + SkRect storage; + if (this->quickReject(paint.computeFastStrokeBounds(r, &storage), + paint2EdgeType(&paint))) { + return; + } + } + SkASSERT(pts != NULL); LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type) diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 66fa0df1be..1b74fa1e44 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -2045,7 +2045,8 @@ bool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const { } const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, - SkRect* storage) const { + SkRect* storage, + Style style) const { SkASSERT(storage); const SkRect* src = &origSrc; @@ -2062,7 +2063,7 @@ const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, src = &tmpSrc; } - if (this->getStyle() != SkPaint::kFill_Style) { + if (kFill_Style != style) { // since we're stroked, outset the rect by the radius (and join type) SkScalar radius = SkScalarHalf(this->getStrokeWidth()); if (0 == radius) { // hairline |