| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/debug/trace_event.h" |
| 6 #include "skia/ext/analysis_canvas.h" |
| 7 |
| 8 namespace { |
| 9 |
| 10 // FIXME: Arbitrary number. Requires tuning & experimentation. |
| 11 // Probably requires per-platform tuning; N10 average draw call takes |
| 12 // 25x as long as Z620. |
| 13 int gPictureCostThreshold = 100; |
| 14 |
| 15 } |
| 16 |
| 17 namespace skia { |
| 18 |
| 19 AnalysisDevice::AnalysisDevice(const SkBitmap& bm) : SkDevice(bm) { } |
| 20 |
| 21 AnalysisCanvas::AnalysisCanvas(SkDevice* device, SkRect clip) |
| 22 : SkCanvas(device) |
| 23 , estimatedCost_(0) |
| 24 , clip_(clip) { |
| 25 SkIRect ir; |
| 26 clip.roundOut(&ir); |
| 27 this->setClipRegion(SkRegion(ir)); |
| 28 } |
| 29 |
| 30 AnalysisCanvas::~AnalysisCanvas() { |
| 31 |
| 32 } |
| 33 |
| 34 |
| 35 int AnalysisCanvas::save(SkCanvas::SaveFlags) { |
| 36 ++estimatedCost_; |
| 37 } |
| 38 |
| 39 int AnalysisCanvas::saveLayer(const SkRect*, const SkPaint*, |
| 40 SkCanvas::SaveFlags) { |
| 41 ++estimatedCost_; |
| 42 } |
| 43 |
| 44 void AnalysisCanvas::restore() { |
| 45 ++estimatedCost_; |
| 46 } |
| 47 |
| 48 bool AnalysisCanvas::clipRect(const SkRect&, SkRegion::Op, bool) { |
| 49 ++estimatedCost_; |
| 50 } |
| 51 |
| 52 bool AnalysisCanvas::clipRRect(const SkRRect&, SkRegion::Op, bool) { |
| 53 ++estimatedCost_; |
| 54 } |
| 55 |
| 56 bool AnalysisCanvas::clipPath(const SkPath&, SkRegion::Op, bool) { |
| 57 ++estimatedCost_; |
| 58 } |
| 59 |
| 60 bool AnalysisCanvas::clipRegion(const SkRegion&, SkRegion::Op) { |
| 61 ++estimatedCost_; |
| 62 } |
| 63 |
| 64 void AnalysisCanvas::clear(SkColor) { |
| 65 ++estimatedCost_; |
| 66 } |
| 67 |
| 68 void AnalysisCanvas::drawPaint(const SkPaint&) { |
| 69 ++estimatedCost_; |
| 70 } |
| 71 |
| 72 void AnalysisCanvas::drawPoints(PointMode, size_t, const SkPoint [], |
| 73 const SkPaint&) { |
| 74 ++estimatedCost_; |
| 75 } |
| 76 |
| 77 void AnalysisCanvas::drawRect(const SkRect&, const SkPaint&) { |
| 78 // FIXME: if there's a pending image decode & resize, more expensive |
| 79 ++estimatedCost_; |
| 80 } |
| 81 |
| 82 void AnalysisCanvas::drawOval(const SkRect&, const SkPaint&) { |
| 83 ++estimatedCost_; |
| 84 } |
| 85 |
| 86 void AnalysisCanvas::drawRRect(const SkRRect&, const SkPaint&) { |
| 87 ++estimatedCost_; |
| 88 } |
| 89 |
| 90 void AnalysisCanvas::drawPath(const SkPath& path, const SkPaint& paint) { |
| 91 char tmpbuf [256]; |
| 92 sprintf(tmpbuf, "AnalysisCanvas::drawPath effect %s fill %s", paint.getPathEffec
t() ? "true" : "false", paint.getStyle() == SkPaint::kFill_Style ? "true" : "fal
se"); |
| 93 TRACE_EVENT0("skia", strdup(tmpbuf)); |
| 94 // if the path is filled, and there's a mask filter, more expensive |
| 95 // FIXME: this isn't correctly detecting yet; no paths are taking |
| 96 // the branch. See SkDraw::drawPath() for the code we're attempting |
| 97 // to reproduce. |
| 98 bool doFill = true; |
| 99 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) { |
| 100 TRACE_EVENT0("skia", "Checking fill path..."); |
| 101 SkPath tmpPath; |
| 102 doFill = paint.getFillPath(path, &tmpPath, &clip_); |
| 103 } |
| 104 if (doFill && paint.getMaskFilter()) { |
| 105 TRACE_EVENT0("skia", "Found filled masked path; ouch!"); |
| 106 estimatedCost_ += 100; |
| 107 } |
| 108 if (!paint.getMaskFilter()) { |
| 109 TRACE_EVENT0("skia", "No mask filter."); |
| 110 } |
| 111 ++estimatedCost_; |
| 112 |
| 113 } |
| 114 |
| 115 void AnalysisCanvas::drawBitmap(const SkBitmap&, SkScalar, SkScalar, |
| 116 const SkPaint&) { |
| 117 ++estimatedCost_; |
| 118 } |
| 119 |
| 120 void AnalysisCanvas::drawBitmapRectToRect(const SkBitmap&, const SkRect*, |
| 121 const SkRect&, const SkPaint*) { |
| 122 ++estimatedCost_; |
| 123 } |
| 124 |
| 125 void AnalysisCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&, |
| 126 const SkPaint*) { |
| 127 ++estimatedCost_; |
| 128 } |
| 129 |
| 130 void AnalysisCanvas::drawBitmapNine(const SkBitmap&, const SkIRect&, |
| 131 const SkRect&, const SkPaint*) { |
| 132 ++estimatedCost_; |
| 133 } |
| 134 |
| 135 void AnalysisCanvas::drawSprite(const SkBitmap&, int left, int top, |
| 136 const SkPaint*) { |
| 137 ++estimatedCost_; |
| 138 } |
| 139 |
| 140 void AnalysisCanvas::drawText(const void*, size_t, SkScalar, SkScalar, |
| 141 const SkPaint&) { |
| 142 ++estimatedCost_; |
| 143 } |
| 144 |
| 145 void AnalysisCanvas::drawPosText(const void*, size_t, const SkPoint [], |
| 146 const SkPaint&) { |
| 147 // FIXME: sometimes very expensive |
| 148 // NOT proportional to length: we see ~40B inputs taking 10-500 us |
| 149 // The difference seems to be cache misses; every miss adds 10-30 us, |
| 150 // and we might see 8 misses in 52B and spend >200us drawing a string |
| 151 // immediately after drawing a 48B string in 2us (!) with no misses. |
| 152 // https://code.google.com/p/skia/issues/detail?id=1102 |
| 153 ++estimatedCost_; |
| 154 } |
| 155 |
| 156 void AnalysisCanvas::drawPosTextH(const void*, size_t, const SkScalar [], |
| 157 SkScalar, const SkPaint&) { |
| 158 ++estimatedCost_; |
| 159 } |
| 160 |
| 161 void AnalysisCanvas::drawTextOnPath(const void*, size_t, const SkPath&, |
| 162 const SkMatrix*, const SkPaint&) { |
| 163 ++estimatedCost_; |
| 164 } |
| 165 |
| 166 void AnalysisCanvas::drawVertices(VertexMode, int, const SkPoint [], |
| 167 const SkPoint [], const SkColor [], |
| 168 SkXfermode*, |
| 169 const uint16_t [], int, const SkPaint&) { |
| 170 ++estimatedCost_; |
| 171 } |
| 172 |
| 173 void AnalysisCanvas::drawData(const void*, size_t) { |
| 174 ++estimatedCost_; |
| 175 } |
| 176 |
| 177 bool AnalysisCanvas::isCheap() const { |
| 178 return estimatedCost_ < gPictureCostThreshold; |
| 179 } |
| 180 |
| 181 int AnalysisCanvas::getEstimatedCost() const { |
| 182 return estimatedCost_; |
| 183 } |
| 184 |
| 185 |
| 186 void AnalysisCanvas::reset(SkRect clip) { |
| 187 estimatedCost_ = 0; |
| 188 clip_ = clip; |
| 189 SkIRect ir; |
| 190 clip.roundOut(&ir); |
| 191 this->setClipRegion(SkRegion(ir)); |
| 192 } |
| 193 |
| 194 |
| 195 |
| 196 } // namespace skia |
| 197 |
| 198 |
| OLD | NEW |