OLD | NEW |
---|---|
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 "base/logging.h" | 6 #include "base/logging.h" |
7 #include "skia/ext/analysis_canvas.h" | 7 #include "skia/ext/analysis_canvas.h" |
8 #include "third_party/skia/include/core/SkDevice.h" | 8 #include "third_party/skia/include/core/SkDevice.h" |
9 #include "third_party/skia/include/core/SkDraw.h" | 9 #include "third_party/skia/include/core/SkDraw.h" |
10 #include "third_party/skia/include/core/SkRRect.h" | 10 #include "third_party/skia/include/core/SkRRect.h" |
11 #include "third_party/skia/include/core/SkShader.h" | 11 #include "third_party/skia/include/core/SkShader.h" |
12 #include "third_party/skia/src/core/SkRasterClip.h" | 12 #include "third_party/skia/src/core/SkRasterClip.h" |
13 #include "ui/gfx/rect_conversions.h" | 13 #include "ui/gfx/rect_conversions.h" |
14 #include "ui/gfx/skia_util.h" | |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 const int kNoLayer = -1; | 18 const int kNoLayer = -1; |
18 | 19 |
19 bool IsSolidColorPaint(const SkPaint& paint) { | 20 bool IsSolidColorPaint(const SkPaint& paint) { |
20 SkXfermode::Mode xfermode; | 21 SkXfermode::Mode xfermode; |
21 | 22 |
22 // getXfermode can return a NULL, but that is handled | 23 // getXfermode can return a NULL, but that is handled |
23 // gracefully by AsMode (NULL turns into kSrcOver mode). | 24 // gracefully by AsMode (NULL turns into kSrcOver mode). |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 return draw.fRC->isRect() && | 64 return draw.fRC->isRect() && |
64 device_rect.contains(clip_rect) && | 65 device_rect.contains(clip_rect) && |
65 clip_rect.contains(canvas_rect) && | 66 clip_rect.contains(canvas_rect) && |
66 draw_bitmap_rect.contains(canvas_rect); | 67 draw_bitmap_rect.contains(canvas_rect); |
67 } | 68 } |
68 | 69 |
69 } // namespace | 70 } // namespace |
70 | 71 |
71 namespace skia { | 72 namespace skia { |
72 | 73 |
73 AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap) | 74 AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap, gfx::Rect analysis_rect) |
74 : INHERITED(bitmap), | 75 : INHERITED(bitmap), |
76 analysis_rect_(analysis_rect), | |
75 is_forced_not_solid_(false), | 77 is_forced_not_solid_(false), |
76 is_forced_not_transparent_(false), | 78 is_forced_not_transparent_(false), |
77 is_solid_color_(true), | 79 is_solid_color_(true), |
78 is_transparent_(true), | 80 is_transparent_(true), |
79 has_text_(false) {} | 81 has_text_(false) {} |
80 | 82 |
81 AnalysisDevice::~AnalysisDevice() {} | 83 AnalysisDevice::~AnalysisDevice() {} |
82 | 84 |
83 bool AnalysisDevice::GetColorIfSolid(SkColor* color) const { | 85 bool AnalysisDevice::GetColorIfSolid(SkColor* color) const { |
84 if (is_transparent_) { | 86 if (is_transparent_) { |
(...skipping 29 matching lines...) Expand all Loading... | |
114 | 116 |
115 if (!is_forced_not_solid_ && SkColorGetA(color) == 255) { | 117 if (!is_forced_not_solid_ && SkColorGetA(color) == 255) { |
116 is_solid_color_ = true; | 118 is_solid_color_ = true; |
117 color_ = color; | 119 color_ = color; |
118 } else { | 120 } else { |
119 is_solid_color_ = false; | 121 is_solid_color_ = false; |
120 } | 122 } |
121 } | 123 } |
122 | 124 |
123 void AnalysisDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { | 125 void AnalysisDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { |
126 INHERITED::drawPaint(draw, paint); | |
vangelis
2013/11/07 01:35:03
Do we see this method getting called for common we
enne (OOO)
2013/11/07 22:13:50
No. This is not called from Blink.
| |
124 is_solid_color_ = false; | 127 is_solid_color_ = false; |
125 is_transparent_ = false; | 128 is_transparent_ = false; |
126 } | 129 } |
127 | 130 |
128 void AnalysisDevice::drawPoints(const SkDraw& draw, | 131 void AnalysisDevice::drawPoints(const SkDraw& draw, |
129 SkCanvas::PointMode mode, | 132 SkCanvas::PointMode mode, |
130 size_t count, | 133 size_t count, |
131 const SkPoint points[], | 134 const SkPoint points[], |
132 const SkPaint& paint) { | 135 const SkPaint& paint) { |
136 INHERITED::drawPoints(draw, mode, count, points, paint); | |
133 is_solid_color_ = false; | 137 is_solid_color_ = false; |
134 is_transparent_ = false; | 138 is_transparent_ = false; |
135 } | 139 } |
136 | 140 |
137 void AnalysisDevice::drawRect(const SkDraw& draw, | 141 void AnalysisDevice::drawRect(const SkDraw& draw, |
138 const SkRect& rect, | 142 const SkRect& rect, |
139 const SkPaint& paint) { | 143 const SkPaint& paint) { |
140 bool does_cover_canvas = | 144 INHERITED::drawRect(draw, rect, paint); |
141 IsFullQuad(draw, SkRect::MakeWH(width(), height()), rect); | 145 AnalyzeDrawRect(draw, rect, paint); |
142 | |
143 SkXfermode::Mode xfermode; | |
144 SkXfermode::AsMode(paint.getXfermode(), &xfermode); | |
145 | |
146 // This canvas will become transparent if the following holds: | |
147 // - The quad is a full tile quad | |
148 // - We're not in "forced not transparent" mode | |
149 // - Transfer mode is clear (0 color, 0 alpha) | |
150 // | |
151 // If the paint alpha is not 0, or if the transfrer mode is | |
152 // not src, then this canvas will not be transparent. | |
153 // | |
154 // In all other cases, we keep the current transparent value | |
155 if (does_cover_canvas && | |
156 !is_forced_not_transparent_ && | |
157 xfermode == SkXfermode::kClear_Mode) { | |
158 is_transparent_ = true; | |
159 has_text_ = false; | |
160 } else if (paint.getAlpha() != 0 || xfermode != SkXfermode::kSrc_Mode) { | |
161 is_transparent_ = false; | |
162 } | |
163 | |
164 // This bitmap is solid if and only if the following holds. | |
165 // Note that this might be overly conservative: | |
166 // - We're not in "forced not solid" mode | |
167 // - Paint is solid color | |
168 // - The quad is a full tile quad | |
169 if (!is_forced_not_solid_ && IsSolidColorPaint(paint) && does_cover_canvas) { | |
170 is_solid_color_ = true; | |
171 color_ = paint.getColor(); | |
172 has_text_ = false; | |
173 } else { | |
174 is_solid_color_ = false; | |
175 } | |
176 } | 146 } |
177 | 147 |
178 void AnalysisDevice::drawOval(const SkDraw& draw, | 148 void AnalysisDevice::drawOval(const SkDraw& draw, |
179 const SkRect& oval, | 149 const SkRect& oval, |
180 const SkPaint& paint) { | 150 const SkPaint& paint) { |
151 INHERITED::drawOval(draw, oval, paint); | |
181 is_solid_color_ = false; | 152 is_solid_color_ = false; |
182 is_transparent_ = false; | 153 is_transparent_ = false; |
183 } | 154 } |
184 | 155 |
185 void AnalysisDevice::drawPath(const SkDraw& draw, | 156 void AnalysisDevice::drawPath(const SkDraw& draw, |
186 const SkPath& path, | 157 const SkPath& path, |
187 const SkPaint& paint, | 158 const SkPaint& paint, |
188 const SkMatrix* pre_path_matrix, | 159 const SkMatrix* pre_path_matrix, |
189 bool path_is_mutable) { | 160 bool path_is_mutable) { |
161 INHERITED::drawPath(draw, path, paint, pre_path_matrix, path_is_mutable); | |
190 is_solid_color_ = false; | 162 is_solid_color_ = false; |
191 is_transparent_ = false; | 163 is_transparent_ = false; |
192 } | 164 } |
193 | 165 |
194 void AnalysisDevice::drawBitmap(const SkDraw& draw, | 166 void AnalysisDevice::drawBitmap(const SkDraw& draw, |
195 const SkBitmap& bitmap, | 167 const SkBitmap& bitmap, |
196 const SkMatrix& matrix, | 168 const SkMatrix& matrix, |
197 const SkPaint& paint) { | 169 const SkPaint& paint) { |
170 INHERITED::drawBitmap(draw, bitmap, matrix, paint); | |
198 is_solid_color_ = false; | 171 is_solid_color_ = false; |
199 is_transparent_ = false; | 172 is_transparent_ = false; |
200 } | 173 } |
201 | 174 |
202 void AnalysisDevice::drawSprite(const SkDraw& draw, | 175 void AnalysisDevice::drawSprite(const SkDraw& draw, |
203 const SkBitmap& bitmap, | 176 const SkBitmap& bitmap, |
204 int x, | 177 int x, |
205 int y, | 178 int y, |
206 const SkPaint& paint) { | 179 const SkPaint& paint) { |
180 INHERITED::drawSprite(draw, bitmap, x, y, paint); | |
207 is_solid_color_ = false; | 181 is_solid_color_ = false; |
208 is_transparent_ = false; | 182 is_transparent_ = false; |
209 } | 183 } |
210 | 184 |
211 void AnalysisDevice::drawBitmapRect(const SkDraw& draw, | 185 void AnalysisDevice::drawBitmapRect(const SkDraw& draw, |
212 const SkBitmap& bitmap, | 186 const SkBitmap& bitmap, |
213 const SkRect* src_or_null, | 187 const SkRect* src_or_null, |
214 const SkRect& dst, | 188 const SkRect& rect, |
215 const SkPaint& paint, | 189 const SkPaint& paint, |
216 SkCanvas::DrawBitmapRectFlags flags) { | 190 SkCanvas::DrawBitmapRectFlags flags) { |
217 // Call drawRect to determine transparency, | 191 INHERITED::drawBitmapRect(draw, bitmap, src_or_null, rect, paint, flags); |
192 | |
193 // Call AnalyzeDrawRect to determine transparency, | |
218 // but reset solid color to false. | 194 // but reset solid color to false. |
219 drawRect(draw, dst, paint); | 195 AnalyzeDrawRect(draw, rect, paint); |
220 is_solid_color_ = false; | 196 is_solid_color_ = false; |
221 } | 197 } |
222 | 198 |
223 void AnalysisDevice::drawText(const SkDraw& draw, | 199 void AnalysisDevice::drawText(const SkDraw& draw, |
224 const void* text, | 200 const void* text, |
225 size_t len, | 201 size_t len, |
226 SkScalar x, | 202 SkScalar x, |
227 SkScalar y, | 203 SkScalar y, |
228 const SkPaint& paint) { | 204 const SkPaint& paint) { |
205 INHERITED::drawText(draw, text, len, x, y, paint); | |
229 is_solid_color_ = false; | 206 is_solid_color_ = false; |
230 is_transparent_ = false; | 207 is_transparent_ = false; |
231 has_text_ = true; | 208 has_text_ = true; |
232 } | 209 } |
233 | 210 |
234 void AnalysisDevice::drawPosText(const SkDraw& draw, | 211 void AnalysisDevice::drawPosText(const SkDraw& draw, |
235 const void* text, | 212 const void* text, |
236 size_t len, | 213 size_t len, |
237 const SkScalar pos[], | 214 const SkScalar pos[], |
238 SkScalar const_y, | 215 SkScalar const_y, |
239 int scalars_per_pos, | 216 int scalars_per_pos, |
240 const SkPaint& paint) { | 217 const SkPaint& paint) { |
218 INHERITED::drawPosText(draw, text, len, pos, const_y, scalars_per_pos, paint); | |
241 is_solid_color_ = false; | 219 is_solid_color_ = false; |
242 is_transparent_ = false; | 220 is_transparent_ = false; |
243 has_text_ = true; | 221 has_text_ = true; |
244 } | 222 } |
245 | 223 |
246 void AnalysisDevice::drawTextOnPath(const SkDraw& draw, | 224 void AnalysisDevice::drawTextOnPath(const SkDraw& draw, |
247 const void* text, | 225 const void* text, |
248 size_t len, | 226 size_t len, |
249 const SkPath& path, | 227 const SkPath& path, |
250 const SkMatrix* matrix, | 228 const SkMatrix* matrix, |
251 const SkPaint& paint) { | 229 const SkPaint& paint) { |
230 INHERITED::drawTextOnPath(draw, text, len, path, matrix, paint); | |
252 is_solid_color_ = false; | 231 is_solid_color_ = false; |
253 is_transparent_ = false; | 232 is_transparent_ = false; |
254 has_text_ = true; | 233 has_text_ = true; |
255 } | 234 } |
256 | 235 |
257 #ifdef SK_BUILD_FOR_ANDROID | 236 #ifdef SK_BUILD_FOR_ANDROID |
258 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, | 237 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, |
259 const void* text, | 238 const void* text, |
260 size_t len, | 239 size_t len, |
261 const SkPoint pos[], | 240 const SkPoint pos[], |
262 const SkPaint& paint, | 241 const SkPaint& paint, |
263 const SkPath& path, | 242 const SkPath& path, |
264 const SkMatrix* matrix) { | 243 const SkMatrix* matrix) { |
244 INHERITED::drawPosTextOnPath(draw, text, len, pos, paint, path, matrix); | |
265 is_solid_color_ = false; | 245 is_solid_color_ = false; |
266 is_transparent_ = false; | 246 is_transparent_ = false; |
267 has_text_ = true; | 247 has_text_ = true; |
268 } | 248 } |
269 #endif | 249 #endif |
270 | 250 |
271 void AnalysisDevice::drawVertices(const SkDraw& draw, | 251 void AnalysisDevice::drawVertices(const SkDraw& draw, |
272 SkCanvas::VertexMode, | 252 SkCanvas::VertexMode mode, |
273 int vertex_count, | 253 int vertex_count, |
274 const SkPoint verts[], | 254 const SkPoint verts[], |
275 const SkPoint texs[], | 255 const SkPoint texs[], |
276 const SkColor colors[], | 256 const SkColor colors[], |
277 SkXfermode* xmode, | 257 SkXfermode* xmode, |
278 const uint16_t indices[], | 258 const uint16_t indices[], |
279 int index_count, | 259 int index_count, |
280 const SkPaint& paint) { | 260 const SkPaint& paint) { |
261 INHERITED::drawVertices(draw, | |
262 mode, | |
263 vertex_count, | |
264 verts, | |
265 texs, | |
266 colors, | |
267 xmode, | |
268 indices, | |
269 index_count, | |
270 paint); | |
281 is_solid_color_ = false; | 271 is_solid_color_ = false; |
282 is_transparent_ = false; | 272 is_transparent_ = false; |
283 } | 273 } |
284 | 274 |
285 void AnalysisDevice::drawDevice(const SkDraw& draw, | 275 void AnalysisDevice::drawDevice(const SkDraw& draw, |
286 SkBaseDevice* device, | 276 SkBaseDevice* device, |
287 int x, | 277 int x, |
288 int y, | 278 int y, |
289 const SkPaint& paint) { | 279 const SkPaint& paint) { |
280 INHERITED::drawDevice(draw, device, x, y, paint); | |
290 is_solid_color_ = false; | 281 is_solid_color_ = false; |
291 is_transparent_ = false; | 282 is_transparent_ = false; |
292 } | 283 } |
293 | 284 |
294 AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device) | 285 AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device) |
295 : INHERITED(device), | 286 : INHERITED(device), |
296 saved_stack_size_(0), | 287 saved_stack_size_(0), |
297 force_not_solid_stack_level_(kNoLayer), | 288 force_not_solid_stack_level_(kNoLayer), |
298 force_not_transparent_stack_level_(kNoLayer) {} | 289 force_not_transparent_stack_level_(kNoLayer) {} |
299 | 290 |
300 AnalysisCanvas::~AnalysisCanvas() {} | 291 AnalysisCanvas::~AnalysisCanvas() {} |
301 | 292 |
302 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { | 293 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { |
303 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); | 294 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); |
304 } | 295 } |
305 | 296 |
306 bool AnalysisCanvas::HasText() const { | 297 bool AnalysisCanvas::HasText() const { |
307 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); | 298 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); |
308 } | 299 } |
309 | 300 |
310 bool AnalysisCanvas::abortDrawing() { | |
311 // Early out as soon as we have detected that the tile has text. | |
312 return HasText(); | |
313 } | |
314 | |
315 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { | 301 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { |
316 return INHERITED::clipRect(rect, op, do_aa); | 302 return INHERITED::clipRect(rect, op, do_aa); |
317 } | 303 } |
318 | 304 |
319 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { | 305 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { |
320 // clipPaths can make our calls to IsFullQuad invalid (ie have false | 306 // clipPaths can make our calls to IsFullQuad invalid (ie have false |
321 // positives). As a precaution, force the setting to be non-solid | 307 // positives). As a precaution, force the setting to be non-solid |
322 // and non-transparent until we pop this | 308 // and non-transparent until we pop this |
323 if (force_not_solid_stack_level_ == kNoLayer) { | 309 if (force_not_solid_stack_level_ == kNoLayer) { |
324 force_not_solid_stack_level_ = saved_stack_size_; | 310 force_not_solid_stack_level_ = saved_stack_size_; |
325 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); | 311 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); |
326 } | 312 } |
327 if (force_not_transparent_stack_level_ == kNoLayer) { | 313 if (force_not_transparent_stack_level_ == kNoLayer) { |
328 force_not_transparent_stack_level_ = saved_stack_size_; | 314 force_not_transparent_stack_level_ = saved_stack_size_; |
329 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); | 315 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); |
330 } | 316 } |
331 | 317 |
332 return INHERITED::clipRect(path.getBounds(), op, do_aa); | 318 return INHERITED::clipPath(path, op, do_aa); |
333 } | 319 } |
334 | 320 |
335 bool AnalysisCanvas::clipRRect(const SkRRect& rrect, | 321 bool AnalysisCanvas::clipRRect(const SkRRect& rrect, |
336 SkRegion::Op op, | 322 SkRegion::Op op, |
337 bool do_aa) { | 323 bool do_aa) { |
338 // clipRRect can make our calls to IsFullQuad invalid (ie have false | 324 // clipRRect can make our calls to IsFullQuad invalid (ie have false |
339 // positives). As a precaution, force the setting to be non-solid | 325 // positives). As a precaution, force the setting to be non-solid |
340 // and non-transparent until we pop this | 326 // and non-transparent until we pop this |
341 if (force_not_solid_stack_level_ == kNoLayer) { | 327 if (force_not_solid_stack_level_ == kNoLayer) { |
342 force_not_solid_stack_level_ = saved_stack_size_; | 328 force_not_solid_stack_level_ = saved_stack_size_; |
343 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); | 329 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); |
344 } | 330 } |
345 if (force_not_transparent_stack_level_ == kNoLayer) { | 331 if (force_not_transparent_stack_level_ == kNoLayer) { |
346 force_not_transparent_stack_level_ = saved_stack_size_; | 332 force_not_transparent_stack_level_ = saved_stack_size_; |
347 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); | 333 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); |
348 } | 334 } |
349 | 335 |
350 return INHERITED::clipRect(rrect.getBounds(), op, do_aa); | 336 return INHERITED::clipRRect(rrect, op, do_aa); |
351 } | 337 } |
352 | 338 |
353 int AnalysisCanvas::save(SkCanvas::SaveFlags flags) { | 339 int AnalysisCanvas::save(SkCanvas::SaveFlags flags) { |
354 ++saved_stack_size_; | 340 ++saved_stack_size_; |
355 return INHERITED::save(flags); | 341 return INHERITED::save(flags); |
356 } | 342 } |
357 | 343 |
358 int AnalysisCanvas::saveLayer(const SkRect* bounds, | 344 int AnalysisCanvas::saveLayer(const SkRect* bounds, |
359 const SkPaint* paint, | 345 const SkPaint* paint, |
360 SkCanvas::SaveFlags flags) { | 346 SkCanvas::SaveFlags flags) { |
361 ++saved_stack_size_; | 347 ++saved_stack_size_; |
362 | 348 |
363 // If after we draw to the saved layer, we have to blend with the current | 349 // If after we draw to the saved layer, we have to blend with the current |
364 // layer, then we can conservatively say that the canvas will not be of | 350 // layer, then we can conservatively say that the canvas will not be of |
365 // solid color. | 351 // solid color. |
352 gfx::Rect analysis_rect = | |
353 static_cast<AnalysisDevice*>(getDevice())->AnalysisRect(); | |
366 if ((paint && !IsSolidColorPaint(*paint)) || | 354 if ((paint && !IsSolidColorPaint(*paint)) || |
367 (bounds && !bounds->contains(SkRect::MakeWH(getDevice()->width(), | 355 (bounds && !bounds->contains(RectToSkRect(analysis_rect)))) { |
368 getDevice()->height())))) { | |
369 if (force_not_solid_stack_level_ == kNoLayer) { | 356 if (force_not_solid_stack_level_ == kNoLayer) { |
370 force_not_solid_stack_level_ = saved_stack_size_; | 357 force_not_solid_stack_level_ = saved_stack_size_; |
371 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); | 358 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); |
372 } | 359 } |
373 } | 360 } |
374 | 361 |
375 // If after we draw to the save layer, we have to blend with the current | 362 // If after we draw to the save layer, we have to blend with the current |
376 // layer using any part of the current layer's alpha, then we can | 363 // layer using any part of the current layer's alpha, then we can |
377 // conservatively say that the canvas will not be transparent. | 364 // conservatively say that the canvas will not be transparent. |
378 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; | 365 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; |
379 if (paint) | 366 if (paint) |
380 SkXfermode::AsMode(paint->getXfermode(), &xfermode); | 367 SkXfermode::AsMode(paint->getXfermode(), &xfermode); |
381 if (xfermode != SkXfermode::kSrc_Mode) { | 368 if (xfermode != SkXfermode::kSrc_Mode) { |
382 if (force_not_transparent_stack_level_ == kNoLayer) { | 369 if (force_not_transparent_stack_level_ == kNoLayer) { |
383 force_not_transparent_stack_level_ = saved_stack_size_; | 370 force_not_transparent_stack_level_ = saved_stack_size_; |
384 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); | 371 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent(true); |
385 } | 372 } |
386 } | 373 } |
387 | 374 |
388 // Actually saving a layer here could cause a new bitmap to be created | 375 return INHERITED::saveLayer(bounds, paint, flags); |
389 // and real rendering to occur. | |
390 int count = INHERITED::save(flags); | |
391 if (bounds) { | |
392 INHERITED::clipRectBounds(bounds, flags, NULL); | |
393 } | |
394 return count; | |
395 } | 376 } |
396 | 377 |
397 void AnalysisCanvas::restore() { | 378 void AnalysisCanvas::restore() { |
398 INHERITED::restore(); | 379 INHERITED::restore(); |
399 | 380 |
400 DCHECK(saved_stack_size_); | 381 DCHECK(saved_stack_size_); |
401 if (saved_stack_size_) { | 382 if (saved_stack_size_) { |
402 --saved_stack_size_; | 383 --saved_stack_size_; |
403 if (saved_stack_size_ < force_not_solid_stack_level_) { | 384 if (saved_stack_size_ < force_not_solid_stack_level_) { |
404 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(false); | 385 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(false); |
405 force_not_solid_stack_level_ = kNoLayer; | 386 force_not_solid_stack_level_ = kNoLayer; |
406 } | 387 } |
407 if (saved_stack_size_ < force_not_transparent_stack_level_) { | 388 if (saved_stack_size_ < force_not_transparent_stack_level_) { |
408 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( | 389 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( |
409 false); | 390 false); |
410 force_not_transparent_stack_level_ = kNoLayer; | 391 force_not_transparent_stack_level_ = kNoLayer; |
411 } | 392 } |
412 } | 393 } |
413 } | 394 } |
414 | 395 |
396 void AnalysisDevice::AnalyzeDrawRect(const SkDraw& draw, | |
397 const SkRect& rect, | |
398 const SkPaint& paint) { | |
399 bool does_cover_canvas = | |
400 IsFullQuad(draw, RectToSkRect(analysis_rect_), rect); | |
401 | |
402 SkXfermode::Mode xfermode; | |
403 SkXfermode::AsMode(paint.getXfermode(), &xfermode); | |
404 | |
405 // This canvas will become transparent if the following holds: | |
406 // - The quad is a full tile quad | |
407 // - We're not in "forced not transparent" mode | |
408 // - Transfer mode is clear (0 color, 0 alpha) | |
Stephen White
2013/11/07 18:14:22
Nit: also not new to this patch, but is it possibl
enne (OOO)
2013/11/07 22:36:10
Such a helper function from the Skia side would be
| |
409 // | |
410 // If the paint alpha is not 0, or if the transfrer mode is | |
411 // not src, then this canvas will not be transparent. | |
412 // | |
413 // In all other cases, we keep the current transparent value | |
414 if (does_cover_canvas && | |
415 !is_forced_not_transparent_ && | |
416 xfermode == SkXfermode::kClear_Mode) { | |
417 is_transparent_ = true; | |
418 has_text_ = false; | |
419 } else if (paint.getAlpha() != 0 || xfermode != SkXfermode::kSrc_Mode) { | |
420 is_transparent_ = false; | |
421 } | |
422 | |
423 // This bitmap is solid if and only if the following holds. | |
424 // Note that this might be overly conservative: | |
425 // - We're not in "forced not solid" mode | |
426 // - Paint is solid color | |
427 // - The quad is a full tile quad | |
428 if (!is_forced_not_solid_ && IsSolidColorPaint(paint) && does_cover_canvas) { | |
429 is_solid_color_ = true; | |
430 color_ = paint.getColor(); | |
431 has_text_ = false; | |
432 } else { | |
433 is_solid_color_ = false; | |
434 } | |
435 } | |
436 | |
415 } // namespace skia | 437 } // namespace skia |
416 | |
417 | |
OLD | NEW |