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
This commit is contained in:
reed@google.com 2012-05-16 14:06:02 +00:00
parent 7b463acd46
commit a584aed5f7
4 changed files with 86 additions and 50 deletions

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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