Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Side by Side Diff: skia/ext/analysis_canvas.cc

Issue 12316084: cc: Consolidate the analysis_canvas operations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« skia/ext/analysis_canvas.h ('K') | « skia/ext/analysis_canvas.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/debug/trace_event.h" 5 #include "base/debug/trace_event.h"
6 #include "skia/ext/analysis_canvas.h" 6 #include "skia/ext/analysis_canvas.h"
7 #include "third_party/skia/include/core/SkDevice.h" 7 #include "third_party/skia/include/core/SkDevice.h"
8 #include "third_party/skia/include/core/SkDraw.h" 8 #include "third_party/skia/include/core/SkDraw.h"
9 #include "third_party/skia/include/core/SkRRect.h" 9 #include "third_party/skia/include/core/SkRRect.h"
10 #include "third_party/skia/src/core/SkRasterClip.h"
10 #include "ui/gfx/rect_conversions.h" 11 #include "ui/gfx/rect_conversions.h"
11 12
12 namespace { 13 namespace {
13 14
14 // FIXME: Arbitrary number. Requires tuning & experimentation. 15 // FIXME: Arbitrary number. Requires tuning & experimentation.
15 // Probably requires per-platform tuning; N10 average draw call takes 16 // Probably requires per-platform tuning; N10 average draw call takes
16 // 25x as long as Z620. 17 // 25x as long as Z620.
17 const int gPictureCostThreshold = 1000; 18 const int gPictureCostThreshold = 1000;
18 19
20 static bool isSolidColorPaint(const SkPaint& paint) {
21 SkXfermode::Mode xferMode;
22
23 // NULL turns into kSrcOver mode.
Tom Hudson 2013/02/25 17:16:04 This comment is unclear, since NULL is nowhere in
24 SkXfermode::AsMode(paint.getXfermode(), &xferMode);
25
26 // Paint is solid color if the following holds:
27 // - Alpha is 1.0, style is fill, and there are no special effects
28 // - Xfer mode is either kSrc or kSrcOver (kSrcOver is equivalent
29 // to kSrc if source alpha is 1.0, which is already checked).
30 return (paint.getAlpha() == 255 &&
31 !paint.getShader() &&
32 !paint.getLooper() &&
33 !paint.getMaskFilter() &&
34 !paint.getColorFilter() &&
35 paint.getStyle() == SkPaint::kFill_Style &&
36 (xferMode == SkXfermode::kSrc_Mode ||
37 xferMode == SkXfermode::kSrcOver_Mode));
19 } 38 }
20 39
40 } // namespace
41
21 namespace skia { 42 namespace skia {
22 43
23 AnalysisDevice::AnalysisDevice(const SkBitmap& bm) 44 AnalysisDevice::AnalysisDevice(const SkBitmap& bm)
24 : INHERITED(bm) 45 : INHERITED(bm)
25 , estimatedCost_(0) { 46 , estimatedCost_(0)
47 , isForcedNotSolid_(false)
48 , isSolidColor_(false) {
26 49
27 } 50 }
28 51
29 AnalysisDevice::~AnalysisDevice() { 52 AnalysisDevice::~AnalysisDevice() {
30
31 } 53 }
32 54
33 int AnalysisDevice::getEstimatedCost() const { 55 int AnalysisDevice::getEstimatedCost() const {
34 return estimatedCost_; 56 return estimatedCost_;
35 } 57 }
36 58
59 bool AnalysisDevice::getColorIfSolid(SkColor* color) const {
60 if (isSolidColor_)
61 *color = color_;
62 return isSolidColor_;
63 }
64
65 bool AnalysisDevice::isTransparent() const {
66 //TODO(vmpstr) implement
67 return false;
68 }
69
70 void AnalysisDevice::setForceNotSolid(bool flag) {
71 isForcedNotSolid_ = flag;
72 if (isForcedNotSolid_)
73 isSolidColor_ = false;
74 }
75
37 void AnalysisDevice::clear(SkColor color) { 76 void AnalysisDevice::clear(SkColor color) {
38 ++estimatedCost_; 77 ++estimatedCost_;
78 if (!isForcedNotSolid_ && SkColorGetA(color) == 255) {
79 isSolidColor_ = true;
80 color_ = color;
81 }
82 else {
83 isSolidColor_ = false;
84 }
39 } 85 }
40 86
41 void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) { 87 void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) {
42 ++estimatedCost_; 88 ++estimatedCost_;
89 isSolidColor_ = false;
43 } 90 }
44 91
45 void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, 92 void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode,
46 size_t count, const SkPoint[], 93 size_t count, const SkPoint[],
47 const SkPaint& paint) { 94 const SkPaint& paint) {
48 ++estimatedCost_; 95 ++estimatedCost_;
96 isSolidColor_ = false;
49 } 97 }
50 98
51 void AnalysisDevice::drawRect(const SkDraw&, const SkRect& r, 99 void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect,
52 const SkPaint& paint) { 100 const SkPaint& paint) {
53 // FIXME: if there's a pending image decode & resize, more expensive 101 // FIXME: if there's a pending image decode & resize, more expensive
54 if (paint.getMaskFilter()) { 102 if (paint.getMaskFilter()) {
55 estimatedCost_ += 300; 103 estimatedCost_ += 300;
56 } 104 }
57 ++estimatedCost_; 105 ++estimatedCost_;
106
107 if (isForcedNotSolid_)
108 return;
109
110 SkRect clipRect = SkRect::Make(draw.fRC->getBounds());
111 SkRect bitmapRect = SkRect::MakeWH(width(), height());
112
113 // This bitmap is solid if and only if the following holds.
114 // Note that this might be overly conservative:
115 // - Paint is solid color
116 // - Clip rect is an actual rectangle.
117 // - The rect we're drawing contains the clip rect.
118 // That is, all of clip rect will be colored by the rect.
119 // - Clip rect contains the bitmap rect.
120 // That is, we're not clipping to a portion of this bitmap.
Tom Hudson 2013/02/25 17:16:04 You mention "bitmap", but when we're on the border
121 if (isSolidColorPaint(paint) &&
122 draw.fRC->isRect() &&
123 rect.contains(clipRect) &&
124 clipRect.contains(bitmapRect)) {
125 isSolidColor_ = true;
126 color_ = paint.getColor();
127 }
128 else {
129 isSolidColor_ = false;
130 }
58 } 131 }
59 132
60 void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval, 133 void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval,
61 const SkPaint& paint) { 134 const SkPaint& paint) {
62 ++estimatedCost_; 135 ++estimatedCost_;
136 isSolidColor_ = false;
63 } 137 }
64 138
65 void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path, 139 void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path,
66 const SkPaint& paint, 140 const SkPaint& paint,
67 const SkMatrix* prePathMatrix , 141 const SkMatrix* prePathMatrix ,
68 bool pathIsMutable ) { 142 bool pathIsMutable ) {
69 // On Z620, every antialiased path costs us about 300us. 143 // On Z620, every antialiased path costs us about 300us.
70 // We've only seen this in practice on filled paths, but 144 // We've only seen this in practice on filled paths, but
71 // we expect it to apply to all path stroking modes. 145 // we expect it to apply to all path stroking modes.
72 if (paint.getMaskFilter()) { 146 if (paint.getMaskFilter()) {
73 estimatedCost_ += 300; 147 estimatedCost_ += 300;
74 } 148 }
75 ++estimatedCost_; 149 ++estimatedCost_;
150 isSolidColor_ = false;
76 } 151 }
77 152
78 void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, 153 void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap,
79 const SkIRect* srcRectOrNull, 154 const SkIRect* srcRectOrNull,
80 const SkMatrix& matrix, const SkPaint& paint) 155 const SkMatrix& matrix, const SkPaint& paint)
81 { 156 {
82 ++estimatedCost_; 157 ++estimatedCost_;
158 isSolidColor_ = false;
83 } 159 }
84 160
85 void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, 161 void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
86 int x, int y, const SkPaint& paint) { 162 int x, int y, const SkPaint& paint) {
87 ++estimatedCost_; 163 ++estimatedCost_;
164 isSolidColor_ = false;
88 } 165 }
89 166
90 void AnalysisDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, 167 void AnalysisDevice::drawBitmapRect(const SkDraw&, const SkBitmap&,
91 const SkRect* srcOrNull, const SkRect& dst, 168 const SkRect* srcOrNull, const SkRect& dst,
92 const SkPaint& paint) { 169 const SkPaint& paint) {
93 ++estimatedCost_; 170 ++estimatedCost_;
171 isSolidColor_ = false;
94 } 172 }
95 173
96 174
97 void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len, 175 void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len,
98 SkScalar x, SkScalar y, const SkPaint& paint) 176 SkScalar x, SkScalar y, const SkPaint& paint)
99 { 177 {
100 ++estimatedCost_; 178 ++estimatedCost_;
179 isSolidColor_ = false;
101 } 180 }
102 181
103 void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t le n, 182 void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t le n,
104 const SkScalar pos[], SkScalar constY, 183 const SkScalar pos[], SkScalar constY,
105 int scalarsPerPos, const SkPaint& paint) { 184 int scalarsPerPos, const SkPaint& paint) {
106 // FIXME: On Z620, every glyph cache miss costs us about 10us. 185 // FIXME: On Z620, every glyph cache miss costs us about 10us.
107 // We don't have a good mechanism for predicting glyph cache misses. 186 // We don't have a good mechanism for predicting glyph cache misses.
108 ++estimatedCost_; 187 ++estimatedCost_;
188 isSolidColor_ = false;
109 } 189 }
110 190
111 void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, 191 void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len,
112 const SkPath& path, const SkMatrix* matrix, 192 const SkPath& path, const SkMatrix* matrix,
113 const SkPaint& paint) { 193 const SkPaint& paint) {
114 ++estimatedCost_; 194 ++estimatedCost_;
195 isSolidColor_ = false;
115 } 196 }
116 197
117 #ifdef SK_BUILD_FOR_ANDROID 198 #ifdef SK_BUILD_FOR_ANDROID
118 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, 199 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text,
119 size_t len, 200 size_t len,
120 const SkPoint pos[], const SkPaint& paint, 201 const SkPoint pos[], const SkPaint& paint,
121 const SkPath& path, const SkMatrix* matrix) 202 const SkPath& path, const SkMatrix* matrix)
122 { 203 {
123 ++estimatedCost_; 204 ++estimatedCost_;
205 isSolidColor_ = false;
124 } 206 }
125 #endif 207 #endif
126 208
127 void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, 209 void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
128 int vertexCount, 210 int vertexCount,
129 const SkPoint verts[], const SkPoint texs[], 211 const SkPoint verts[], const SkPoint texs[],
130 const SkColor colors[], SkXfermode* xmode, 212 const SkColor colors[], SkXfermode* xmode,
131 const uint16_t indices[], int indexCount, 213 const uint16_t indices[], int indexCount,
132 const SkPaint& paint) { 214 const SkPaint& paint) {
133 ++estimatedCost_; 215 ++estimatedCost_;
216 isSolidColor_ = false;
134 } 217 }
135 218
136 void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y, 219 void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y,
137 const SkPaint&) { 220 const SkPaint&) {
138 ++estimatedCost_; 221 ++estimatedCost_;
222 isSolidColor_ = false;
139 } 223 }
140 224
141 225
142 226
143 227
144 AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device) 228 AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device)
145 : INHERITED(device) { 229 : INHERITED(device)
146 230 , saveDepth_(0) {
147 } 231 }
148 232
149 AnalysisCanvas::~AnalysisCanvas() { 233 AnalysisCanvas::~AnalysisCanvas() {
150 } 234 }
151 235
152 236
153 bool AnalysisCanvas::isCheap() const { 237 bool AnalysisCanvas::isCheap() const {
154 return getEstimatedCost() < gPictureCostThreshold; 238 return getEstimatedCost() < gPictureCostThreshold;
155 } 239 }
156 240
241 bool AnalysisCanvas::getColorIfSolid(SkColor* color) const {
242 return (static_cast<AnalysisDevice*>(getDevice()))->getColorIfSolid(color);
243 }
244
245 bool AnalysisCanvas::isTransparent() const {
246 return (static_cast<AnalysisDevice*>(getDevice()))->isTransparent();
247 }
248
157 int AnalysisCanvas::getEstimatedCost() const { 249 int AnalysisCanvas::getEstimatedCost() const {
158 return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost(); 250 return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost();
159 } 251 }
160 252
161
162 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, 253 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op,
163 bool doAA) { 254 bool doAA) {
164 return INHERITED::clipRect(rect, op, doAA); 255 return INHERITED::clipRect(rect, op, doAA);
165 } 256 }
166 257
167 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, 258 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op,
168 bool doAA) { 259 bool doAA) {
169 return INHERITED::clipRect(path.getBounds(), op, doAA); 260 return INHERITED::clipRect(path.getBounds(), op, doAA);
170 } 261 }
171 262
172 bool AnalysisCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, 263 bool AnalysisCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op,
173 bool doAA) { 264 bool doAA) {
174 return INHERITED::clipRect(rrect.getBounds(), op, doAA); 265 return INHERITED::clipRect(rrect.getBounds(), op, doAA);
175 } 266 }
176 267
177 int AnalysisCanvas::saveLayer(const SkRect* bounds, const SkPaint*, 268 int AnalysisCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
178 SkCanvas::SaveFlags flags) { 269 SkCanvas::SaveFlags flags) {
270 if (paint && !isSolidColorPaint(*paint))
271 (static_cast<AnalysisDevice*>(getDevice()))->setForceNotSolid(true);
272 ++saveDepth_;
273
179 // Actually saving a layer here could cause a new bitmap to be created 274 // Actually saving a layer here could cause a new bitmap to be created
180 // and real rendering to occur. 275 // and real rendering to occur.
181 int count = SkCanvas::save(flags); 276 int count = INHERITED::save(flags);
182 if (bounds) { 277 if (bounds) {
183 INHERITED::clipRectBounds(bounds, flags, NULL); 278 INHERITED::clipRectBounds(bounds, flags, NULL);
184 } 279 }
185 return count; 280 return count;
186 } 281 }
187 282
283 void AnalysisCanvas::restore() {
284 INHERITED::restore();
285 if (--saveDepth_ == 0)
286 (static_cast<AnalysisDevice*>(getDevice()))->setForceNotSolid(false);
Tom Hudson 2013/02/25 17:16:04 This looks really conservative: if we ever save a
287 }
288
188 } // namespace skia 289 } // namespace skia
189 290
190 291
OLDNEW
« skia/ext/analysis_canvas.h ('K') | « skia/ext/analysis_canvas.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698