[skottie] Optimize color filter layerization
Use the deferred paint override mechanism, similar to opacity.
Change-Id: I78fa7f5d73ef333480ec72b0cb663819b1de2404
Reviewed-on: https://skia-review.googlesource.com/146527
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/sksg/include/SkSGRenderNode.h b/modules/sksg/include/SkSGRenderNode.h
index df69270..efa9934 100644
--- a/modules/sksg/include/SkSGRenderNode.h
+++ b/modules/sksg/include/SkSGRenderNode.h
@@ -9,6 +9,8 @@
#define SkSGRenderNode_DEFINED
#include "SkSGNode.h"
+
+#include "SkColorFilter.h"
#include "SkTLazy.h"
class SkCanvas;
@@ -36,7 +38,8 @@
// These are deferred until we can determine whether they can be applied to the individual
// draw paints, or whether they require content isolation (applied to a layer).
struct RenderContext {
- float fOpacity = 1;
+ sk_sp<SkColorFilter> fColorFilter;
+ float fOpacity = 1;
// Returns true if the paint was modified.
bool modulatePaint(SkPaint*) const;
@@ -62,8 +65,9 @@
operator const RenderContext* () const { return fCtx.get(); }
- // Add opacity to a render node sub-DAG.
+ // Add (cumulative) paint overrides to a render node sub-DAG.
ScopedRenderContext&& modulateOpacity(float opacity);
+ ScopedRenderContext&& modulateColorFilter(sk_sp<SkColorFilter>);
// Force content isolation for a node sub-DAG by applying the RenderContext
// overrides via a layer.
diff --git a/modules/sksg/src/SkSGColorFilter.cpp b/modules/sksg/src/SkSGColorFilter.cpp
index ab21117..3ad2287 100644
--- a/modules/sksg/src/SkSGColorFilter.cpp
+++ b/modules/sksg/src/SkSGColorFilter.cpp
@@ -7,7 +7,6 @@
#include "SkSGColorFilter.h"
-#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkSGColor.h"
@@ -20,15 +19,9 @@
if (this->bounds().isEmpty())
return;
- SkAutoCanvasRestore acr(canvas, false);
+ const auto local_ctx = ScopedRenderContext(canvas, ctx).modulateColorFilter(fColorFilter);
- if (fColorFilter) {
- SkPaint p;
- p.setColorFilter(fColorFilter);
- canvas->saveLayer(this->bounds(), &p);
- }
-
- this->INHERITED::onRender(canvas, ctx);
+ this->INHERITED::onRender(canvas, local_ctx);
}
ColorModeFilter::ColorModeFilter(sk_sp<RenderNode> child, sk_sp<Color> color, SkBlendMode mode)
diff --git a/modules/sksg/src/SkSGOpacityEffect.cpp b/modules/sksg/src/SkSGOpacityEffect.cpp
index bb2fadf..cc72c14 100644
--- a/modules/sksg/src/SkSGOpacityEffect.cpp
+++ b/modules/sksg/src/SkSGOpacityEffect.cpp
@@ -7,10 +7,6 @@
#include "SkSGOpacityEffect.h"
-#include "SkCanvas.h"
-
-#include <math.h>
-
namespace sksg {
OpacityEffect::OpacityEffect(sk_sp<RenderNode> child, float opacity)
diff --git a/modules/sksg/src/SkSGRenderNode.cpp b/modules/sksg/src/SkSGRenderNode.cpp
index 417cae9..bfaad0e 100644
--- a/modules/sksg/src/SkSGRenderNode.cpp
+++ b/modules/sksg/src/SkSGRenderNode.cpp
@@ -23,8 +23,10 @@
const auto initial_alpha = paint->getAlpha(),
alpha = SkToU8(sk_float_round2int(initial_alpha * fOpacity));
- if (alpha != initial_alpha) {
+ if (alpha != initial_alpha || fColorFilter) {
paint->setAlpha(alpha);
+ paint->setColorFilter(SkColorFilter::MakeComposeFilter(fColorFilter,
+ paint->refColorFilter()));
return true;
}
@@ -64,6 +66,15 @@
}
RenderNode::ScopedRenderContext&&
+RenderNode::ScopedRenderContext::modulateColorFilter(sk_sp<SkColorFilter> cf) {
+ if (cf) {
+ auto* ctx = this->writableContext();
+ ctx->fColorFilter = SkColorFilter::MakeComposeFilter(std::move(ctx->fColorFilter), cf);
+ }
+ return std::move(*this);
+}
+
+RenderNode::ScopedRenderContext&&
RenderNode::ScopedRenderContext::setIsolation(const SkRect& bounds, bool isolation) {
if (isolation && fCtx.get()) {
SkPaint layer_paint;