OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012, Google Inc. All rights reserved. | 2 * Copyright (c) 2012, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 23 matching lines...) Expand all Loading... | |
34 | 34 |
35 #include "platform/graphics/GraphicsContext.h" | 35 #include "platform/graphics/GraphicsContext.h" |
36 | 36 |
37 #include "SkColorFilter.h" | 37 #include "SkColorFilter.h" |
38 #include "SkShader.h" | 38 #include "SkShader.h" |
39 | 39 |
40 namespace blink { | 40 namespace blink { |
41 | 41 |
42 OpaqueRegionSkia::OpaqueRegionSkia() | 42 OpaqueRegionSkia::OpaqueRegionSkia() |
43 : m_opaqueRect(SkRect::MakeEmpty()) | 43 : m_opaqueRect(SkRect::MakeEmpty()) |
44 , m_treatOverwriteAsOpaque(false) | |
44 { | 45 { |
45 } | 46 } |
46 | 47 |
47 void OpaqueRegionSkia::reset() | 48 void OpaqueRegionSkia::reset() |
48 { | 49 { |
49 ASSERT(m_canvasLayerStack.isEmpty()); | 50 ASSERT(m_canvasLayerStack.isEmpty()); |
50 m_opaqueRect = SkRect::MakeEmpty(); | 51 m_opaqueRect = SkRect::MakeEmpty(); |
51 } | 52 } |
52 | 53 |
53 IntRect OpaqueRegionSkia::asRect() const | 54 IntRect OpaqueRegionSkia::asRect() const |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 case SkXfermode::kSrcIn_Mode: // source * dest | 90 case SkXfermode::kSrcIn_Mode: // source * dest |
90 case SkXfermode::kDstIn_Mode: // dest * source | 91 case SkXfermode::kDstIn_Mode: // dest * source |
91 case SkXfermode::kSrcOut_Mode: // source * (1-dest) | 92 case SkXfermode::kSrcOut_Mode: // source * (1-dest) |
92 case SkXfermode::kDstOut_Mode: // dest * (1-source) | 93 case SkXfermode::kDstOut_Mode: // dest * (1-source) |
93 case SkXfermode::kSrcATop_Mode: // dest | 94 case SkXfermode::kSrcATop_Mode: // dest |
94 case SkXfermode::kXor_Mode: // source + dest - 2*(source*dest) | 95 case SkXfermode::kXor_Mode: // source + dest - 2*(source*dest) |
95 return false; | 96 return false; |
96 } | 97 } |
97 } | 98 } |
98 | 99 |
100 static inline bool xfermodeIsOverwrite(const SkPaint& paint) | |
101 { | |
102 SkXfermode* xfermode = paint.getXfermode(); | |
103 if (!xfermode) | |
104 return false; // default to kSrcOver_Mode | |
105 SkXfermode::Mode mode; | |
106 if (!xfermode->asMode(&mode)) | |
107 return false; | |
108 switch (mode) { | |
109 case SkXfermode::kSrc_Mode: | |
110 case SkXfermode::kClear_Mode: | |
111 return true; | |
112 default: | |
113 return false; | |
114 } | |
115 } | |
116 | |
99 // Returns true if the xfermode will keep the dst opaque, assuming the dst is al ready opaque. | 117 // Returns true if the xfermode will keep the dst opaque, assuming the dst is al ready opaque. |
100 static inline bool xfermodePreservesOpaque(const SkPaint& paint, bool srcIsOpaqu e) | 118 static inline bool xfermodePreservesOpaque(const SkPaint& paint, bool srcIsOpaqu e) |
101 { | 119 { |
102 SkXfermode* xfermode = paint.getXfermode(); | 120 SkXfermode* xfermode = paint.getXfermode(); |
103 if (!xfermode) | 121 if (!xfermode) |
104 return true; // default to kSrcOver_Mode | 122 return true; // default to kSrcOver_Mode |
105 SkXfermode::Mode mode; | 123 SkXfermode::Mode mode; |
106 if (!xfermode->asMode(&mode)) | 124 if (!xfermode->asMode(&mode)) |
107 return false; | 125 return false; |
108 | 126 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 if (!canvasTransform.mapRect(&targetRect)) | 313 if (!canvasTransform.mapRect(&targetRect)) |
296 fillsBounds = false; | 314 fillsBounds = false; |
297 | 315 |
298 // Apply the current clip. | 316 // Apply the current clip. |
299 SkRect deviceClipRect; | 317 SkRect deviceClipRect; |
300 if (!getDeviceClipAsRect(context, deviceClipRect)) | 318 if (!getDeviceClipAsRect(context, deviceClipRect)) |
301 fillsBounds = false; | 319 fillsBounds = false; |
302 else if (!targetRect.intersect(deviceClipRect)) | 320 else if (!targetRect.intersect(deviceClipRect)) |
303 return; | 321 return; |
304 | 322 |
323 if (m_treatOverwriteAsOpaque && fillsBounds && xfermodeIsOverwrite(paint)) { | |
324 markRectAsOpaque(targetRect); | |
325 return; | |
326 } | |
327 | |
305 bool drawsOpaque = paintIsOpaque(paint, drawType, sourceBitmap); | 328 bool drawsOpaque = paintIsOpaque(paint, drawType, sourceBitmap); |
306 bool xfersOpaque = xfermodeIsOpaque(paint, drawsOpaque); | 329 bool xfersOpaque = xfermodeIsOpaque(paint, drawsOpaque); |
307 bool preservesOpaque = xfermodePreservesOpaque(paint, drawsOpaque); | |
308 | 330 |
309 if (fillsBounds && xfersOpaque) | 331 if (fillsBounds && xfersOpaque) { |
310 markRectAsOpaque(targetRect); | 332 markRectAsOpaque(targetRect); |
311 else if (!preservesOpaque) | 333 } else if (!m_treatOverwriteAsOpaque) { |
312 markRectAsNonOpaque(targetRect); | 334 bool preservesOpaque = xfermodePreservesOpaque(paint, drawsOpaque); |
335 if (!preservesOpaque) | |
Stephen White
2014/07/25 19:29:06
Nit: unless I'm missing something, this could all
| |
336 markRectAsNonOpaque(targetRect); | |
337 } | |
313 } | 338 } |
314 | 339 |
315 void OpaqueRegionSkia::didDrawUnbounded(const GraphicsContext* context, const Sk Paint& paint, DrawType drawType) | 340 void OpaqueRegionSkia::didDrawUnbounded(const GraphicsContext* context, const Sk Paint& paint, DrawType drawType) |
316 { | 341 { |
317 ASSERT(!context->paintingDisabled()); | 342 ASSERT(!context->paintingDisabled()); |
318 bool drawsOpaque = paintIsOpaque(paint, drawType, 0); | 343 bool drawsOpaque = paintIsOpaque(paint, drawType, 0); |
319 bool preservesOpaque = xfermodePreservesOpaque(paint, drawsOpaque); | 344 bool preservesOpaque = xfermodePreservesOpaque(paint, drawsOpaque); |
320 | 345 |
321 if (preservesOpaque) | 346 if (preservesOpaque) |
322 return; | 347 return; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 opaqueRect.setEmpty(); | 464 opaqueRect.setEmpty(); |
440 } | 465 } |
441 | 466 |
442 SkRect& OpaqueRegionSkia::currentTrackingOpaqueRect() | 467 SkRect& OpaqueRegionSkia::currentTrackingOpaqueRect() |
443 { | 468 { |
444 // If we are drawing into a canvas layer, then track the opaque rect in that layer. | 469 // If we are drawing into a canvas layer, then track the opaque rect in that layer. |
445 return m_canvasLayerStack.isEmpty() ? m_opaqueRect : m_canvasLayerStack.last ().opaqueRect; | 470 return m_canvasLayerStack.isEmpty() ? m_opaqueRect : m_canvasLayerStack.last ().opaqueRect; |
446 } | 471 } |
447 | 472 |
448 } // namespace blink | 473 } // namespace blink |
OLD | NEW |