| Index: src/core/SkRecordOpts.cpp
|
| diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp
|
| index d51785bd54531630a244205c2084664612d32179..7899077a99dcf040018ce199c208336d3a12e184 100644
|
| --- a/src/core/SkRecordOpts.cpp
|
| +++ b/src/core/SkRecordOpts.cpp
|
| @@ -10,6 +10,7 @@
|
| #include "SkRecordPattern.h"
|
| #include "SkRecords.h"
|
| #include "SkTDArray.h"
|
| +#include "SkXfermode.h"
|
|
|
| using namespace SkRecords;
|
|
|
| @@ -171,6 +172,19 @@ void SkRecordNoopSaveRestores(SkRecord* record) {
|
| while (apply(&onlyDraws, record) || apply(&noDraws, record));
|
| }
|
|
|
| +static bool effectively_srcover(const SkPaint* paint) {
|
| + if (!paint) {
|
| + return true;
|
| + }
|
| + SkXfermode* mode = paint->getXfermode();
|
| + if (SkXfermode::IsMode(mode, SkXfermode::kSrcOver_Mode)) {
|
| + return true;
|
| + }
|
| + // src-mode with opaque and no effects (which might change opaqueness) is ok too.
|
| + return !paint->getShader() && !paint->getColorFilter() && !paint->getImageFilter() &&
|
| + 0xFF == paint->getAlpha() && SkXfermode::IsMode(mode, SkXfermode::kSrc_Mode);
|
| +}
|
| +
|
| // For some SaveLayer-[drawing command]-Restore patterns, merge the SaveLayer's alpha into the
|
| // draw, and no-op the SaveLayer and Restore.
|
| struct SaveLayerDrawRestoreNooper {
|
| @@ -184,12 +198,13 @@ struct SaveLayerDrawRestoreNooper {
|
|
|
| // A SaveLayer's bounds field is just a hint, so we should be free to ignore it.
|
| SkPaint* layerPaint = match->first<SaveLayer>()->paint;
|
| - if (nullptr == layerPaint) {
|
| + SkPaint* drawPaint = match->second<SkPaint>();
|
| +
|
| + if (nullptr == layerPaint && effectively_srcover(drawPaint)) {
|
| // There wasn't really any point to this SaveLayer at all.
|
| return KillSaveLayerAndRestore(record, begin);
|
| }
|
|
|
| - SkPaint* drawPaint = match->second<SkPaint>();
|
| if (drawPaint == nullptr) {
|
| // We can just give the draw the SaveLayer's paint.
|
| // TODO(mtklein): figure out how to do this clearly
|
|
|