Chromium Code Reviews| 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 |