Chromium Code Reviews| Index: skia/ext/analysis_canvas.cc |
| diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc |
| index 12ed69ec262c6b4493cb84b054e31e0fb2bba366..5b40a923f5a6f58ec55ac0ad455d1d947780881d 100644 |
| --- a/skia/ext/analysis_canvas.cc |
| +++ b/skia/ext/analysis_canvas.cc |
| @@ -4,195 +4,180 @@ |
| #include "base/debug/trace_event.h" |
| #include "skia/ext/analysis_canvas.h" |
| +#include "third_party/skia/include/core/SkDevice.h" |
| +#include "third_party/skia/include/core/SkDraw.h" |
| +#include "third_party/skia/include/core/SkRRect.h" |
| +#include "ui/gfx/rect_conversions.h" |
| namespace { |
| // FIXME: Arbitrary number. Requires tuning & experimentation. |
| // Probably requires per-platform tuning; N10 average draw call takes |
| // 25x as long as Z620. |
| -int gPictureCostThreshold = 100; |
| +int gPictureCostThreshold = 1000; |
| } |
| namespace skia { |
| -AnalysisDevice::AnalysisDevice(const SkBitmap& bm) : SkDevice(bm) { } |
| +AnalysisDevice::AnalysisDevice(const SkBitmap& bm) |
| + : SkDevice(bm) |
| + , estimatedCost_(0) { |
| -AnalysisCanvas::AnalysisCanvas(SkDevice* device, SkRect clip) |
| - : SkCanvas(device) |
| - , estimatedCost_(0) |
| - , clip_(clip) { |
| - SkIRect ir; |
| - clip.roundOut(&ir); |
| - this->setClipRegion(SkRegion(ir)); |
| } |
| - |
| -AnalysisCanvas::~AnalysisCanvas() { |
| - |
| -} |
| - |
| -int AnalysisCanvas::save(SkCanvas::SaveFlags) { |
| - ++estimatedCost_; |
| -} |
| - |
| -int AnalysisCanvas::saveLayer(const SkRect*, const SkPaint*, |
| - SkCanvas::SaveFlags) { |
| - ++estimatedCost_; |
| -} |
| +AnalysisDevice::~AnalysisDevice() { |
| -void AnalysisCanvas::restore() { |
| - ++estimatedCost_; |
| } |
| -bool AnalysisCanvas::clipRect(const SkRect&, SkRegion::Op, bool) { |
| - ++estimatedCost_; |
| +int AnalysisDevice::getEstimatedCost() const { |
| + return estimatedCost_; |
| } |
| -bool AnalysisCanvas::clipRRect(const SkRRect&, SkRegion::Op, bool) { |
| - ++estimatedCost_; |
| +void AnalysisDevice::clear(SkColor color) { |
| + ++estimatedCost_; |
| } |
| -bool AnalysisCanvas::clipPath(const SkPath&, SkRegion::Op, bool) { |
| +void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -bool AnalysisCanvas::clipRegion(const SkRegion&, SkRegion::Op) { |
| +void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, |
| + size_t count, const SkPoint[], |
| + const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::clear(SkColor) { |
| +void AnalysisDevice::drawRect(const SkDraw&, const SkRect& r, |
| + const SkPaint& paint) { |
| + // FIXME: if there's a pending image decode & resize, more expensive |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawPaint(const SkPaint&) { |
| +void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval, |
| + const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawPoints(PointMode, size_t, const SkPoint [], |
| - const SkPaint&) { |
| +void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path, |
| + const SkPaint& paint, |
| + const SkMatrix* prePathMatrix , |
| + bool pathIsMutable ) { |
| + // On Z620, every antialiased path costs us about 300us. |
| + // We've only seen this in practice on filled paths, but |
| + // we expect it to apply to all path stroking modes. |
| + if (paint.getMaskFilter()) { |
| + estimatedCost_ += 300; |
| + } |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawRect(const SkRect&, const SkPaint&) { |
| -// FIXME: if there's a pending image decode & resize, more expensive |
| +void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
| + const SkIRect* srcRectOrNull, |
| + const SkMatrix& matrix, const SkPaint& paint) |
| + { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawOval(const SkRect&, const SkPaint&) { |
| +void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, |
| + int x, int y, const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawRRect(const SkRRect&, const SkPaint&) { |
| +void AnalysisDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, |
| + const SkRect* srcOrNull, const SkRect& dst, |
| + const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawPath(const SkPath& path, const SkPaint& paint) { |
| -char tmpbuf [256]; |
| -sprintf(tmpbuf, "AnalysisCanvas::drawPath effect %s fill %s", paint.getPathEffect() ? "true" : "false", paint.getStyle() == SkPaint::kFill_Style ? "true" : "false"); |
| -TRACE_EVENT0("skia", strdup(tmpbuf)); |
| - // if the path is filled, and there's a mask filter, more expensive |
| - // FIXME: this isn't correctly detecting yet; no paths are taking |
| - // the branch. See SkDraw::drawPath() for the code we're attempting |
| - // to reproduce. |
| - bool doFill = true; |
| - if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) { |
| -TRACE_EVENT0("skia", "Checking fill path..."); |
| - SkPath tmpPath; |
| - doFill = paint.getFillPath(path, &tmpPath, &clip_); |
| - } |
| - if (doFill && paint.getMaskFilter()) { |
| -TRACE_EVENT0("skia", "Found filled masked path; ouch!"); |
| - estimatedCost_ += 100; |
| - } |
| - if (!paint.getMaskFilter()) { |
| -TRACE_EVENT0("skia", "No mask filter."); |
| - } |
| - ++estimatedCost_; |
| - |
| -} |
| -void AnalysisCanvas::drawBitmap(const SkBitmap&, SkScalar, SkScalar, |
| - const SkPaint&) { |
| +void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len, |
| + SkScalar x, SkScalar y, const SkPaint& paint) |
| + { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawBitmapRectToRect(const SkBitmap&, const SkRect*, |
| - const SkRect&, const SkPaint*) { |
| +void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t len, |
| + const SkScalar pos[], SkScalar constY, |
| + int scalarsPerPos, const SkPaint& paint) { |
| + // FIXME: On Z620, every glyph cache miss costs us about 10us. |
| + // We don't have a good mechanism for predicting glyph cache misses. |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&, |
| - const SkPaint*) { |
| +void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, |
| + const SkPath& path, const SkMatrix* matrix, |
| + const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawBitmapNine(const SkBitmap&, const SkIRect&, |
| - const SkRect&, const SkPaint*) { |
| +#ifdef SK_BUILD_FOR_ANDROID |
| +void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, |
| + size_t len, |
| + const SkPoint pos[], const SkPaint& paint, |
| + const SkPath& path, const SkMatrix* matrix) |
| + { |
| ++estimatedCost_; |
| } |
| +#endif |
| -void AnalysisCanvas::drawSprite(const SkBitmap&, int left, int top, |
| - const SkPaint*) { |
| +void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, |
| + int vertexCount, |
| + const SkPoint verts[], const SkPoint texs[], |
| + const SkColor colors[], SkXfermode* xmode, |
| + const uint16_t indices[], int indexCount, |
| + const SkPaint& paint) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawText(const void*, size_t, SkScalar, SkScalar, |
| - const SkPaint&) { |
| +void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y, |
| + const SkPaint&) { |
| ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawPosText(const void*, size_t, const SkPoint [], |
| - const SkPaint&) { |
| -// FIXME: sometimes very expensive |
| -// NOT proportional to length: we see ~40B inputs taking 10-500 us |
| -// The difference seems to be cache misses; every miss adds 10-30 us, |
| -// and we might see 8 misses in 52B and spend >200us drawing a string |
| -// immediately after drawing a 48B string in 2us (!) with no misses. |
| -// https://code.google.com/p/skia/issues/detail?id=1102 |
| - ++estimatedCost_; |
| -} |
| -void AnalysisCanvas::drawPosTextH(const void*, size_t, const SkScalar [], |
| - SkScalar, const SkPaint&) { |
| - ++estimatedCost_; |
| -} |
| +AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device) |
| + : SkCanvas(device) { |
| -void AnalysisCanvas::drawTextOnPath(const void*, size_t, const SkPath&, |
| - const SkMatrix*, const SkPaint&) { |
| - ++estimatedCost_; |
| } |
| -void AnalysisCanvas::drawVertices(VertexMode, int, const SkPoint [], |
| - const SkPoint [], const SkColor [], |
| - SkXfermode*, |
| - const uint16_t [], int, const SkPaint&) { |
| - ++estimatedCost_; |
| -} |
| +AnalysisCanvas::~AnalysisCanvas() { |
| -void AnalysisCanvas::drawData(const void*, size_t) { |
| - ++estimatedCost_; |
| } |
| bool AnalysisCanvas::isCheap() const { |
| - return estimatedCost_ < gPictureCostThreshold; |
| + return getEstimatedCost() < gPictureCostThreshold; |
| } |
| int AnalysisCanvas::getEstimatedCost() const { |
| - return estimatedCost_; |
| + return ((AnalysisDevice*)getDevice())->getEstimatedCost(); |
| } |
| +bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, |
| + bool doAA) { |
| + return SkCanvas::clipRect(rect, op, doAA); |
|
Justin Novosad
2013/02/06 14:08:03
Should use a typedef to refer to parent class.
Tom Hudson
2013/02/06 17:36:00
I'd avoided it as an unChromey Skiaism, but
Done.
|
| +} |
| -void AnalysisCanvas::reset(SkRect clip) { |
| - estimatedCost_ = 0; |
| - clip_ = clip; |
| - SkIRect ir; |
| - clip.roundOut(&ir); |
| - this->setClipRegion(SkRegion(ir)); |
| +bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, |
| + bool doAA) { |
| + return SkCanvas::clipPath(path, op, doAA); |
|
Justin Novosad
2013/02/06 14:08:03
To prevent complex clip rasterization in SkRasterC
Tom Hudson
2013/02/06 17:36:00
Done.
(I assume we aren't worrying about inverse f
|
| } |
| +bool AnalysisCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, |
| + bool doAA) { |
| + return SkCanvas::clipRect(rrect.getBounds(), op, doAA); |
| +} |
| +int AnalysisCanvas::saveLayer(const SkRect* bounds, const SkPaint*, |
| + SkCanvas::SaveFlags flags) { |
| + int count = SkCanvas::save(flags); |
| + if (bounds) { |
| + SkCanvas::clipRectBounds(bounds, flags, NULL); |
| + } |
| + return count; |
| +} |
| + |
| } // namespace skia |