diff options
author | Florin Malita <fmalita@chromium.org> | 2018-01-08 16:42:59 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-01-08 22:36:01 +0000 |
commit | c0034179a1c43e33d3f2d970450c5cf9a68e471c (patch) | |
tree | 9d6cb6d74867f18a03b7505338862caeb559d6e4 /experimental | |
parent | 185ffe916eb374ab3dfe3f42e265d26dacdd30ca (diff) |
[skotty] Initial opacity support
TBR=
Change-Id: I62581d3a7a83af5ccf373f0f4edf66a2d7f06f07
Reviewed-on: https://skia-review.googlesource.com/92223
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental')
-rw-r--r-- | experimental/skotty/Skotty.cpp | 34 | ||||
-rw-r--r-- | experimental/sksg/SkSGNode.h | 5 | ||||
-rw-r--r-- | experimental/sksg/effects/SkSGOpacityEffect.cpp | 42 | ||||
-rw-r--r-- | experimental/sksg/effects/SkSGOpacityEffect.h | 42 |
4 files changed, 120 insertions, 3 deletions
diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp index 077640b695..5c3016c6c9 100644 --- a/experimental/skotty/Skotty.cpp +++ b/experimental/skotty/Skotty.cpp @@ -24,6 +24,7 @@ #include "SkSGImage.h" #include "SkSGInvalidationController.h" #include "SkSGMerge.h" +#include "SkSGOpacityEffect.h" #include "SkSGPath.h" #include "SkSGRect.h" #include "SkSGTransform.h" @@ -140,6 +141,31 @@ sk_sp<sksg::Matrix> AttachMatrix(const Json::Value& t, AttachContext* ctx, return matrix; } +sk_sp<sksg::RenderNode> AttachOpacity(const Json::Value& jtransform, AttachContext* ctx, + sk_sp<sksg::RenderNode> childNode) { + if (!jtransform.isObject() || !childNode) + return childNode; + + // This is more peeky than other attachers, because we want to avoid redundant opacity + // nodes for the extremely common case of static opaciy == 100. + const auto& opacity = jtransform["o"]; + if (opacity.isObject() && + !ParseBool(opacity["a"], true) && + ParseScalar(opacity["k"], -1) == 100) { + // Ignoring static full opacity. + return childNode; + } + + auto opacityNode = sksg::OpacityEffect::Make(childNode); + AttachProperty<ScalarValue, SkScalar>(opacity, ctx, opacityNode, + [](const sk_sp<sksg::OpacityEffect>& node, const SkScalar& o) { + // BM opacity is [0..100] + node->setOpacity(o * 0.01f); + }); + + return opacityNode; +} + sk_sp<sksg::RenderNode> AttachShape(const Json::Value&, AttachContext* ctx); sk_sp<sksg::RenderNode> AttachComposition(const Json::Value&, AttachContext* ctx); @@ -512,6 +538,7 @@ sk_sp<sksg::RenderNode> AttachShape(const Json::Value& shapeArray, AttachContext xformed_group = sksg::Transform::Make(std::move(xformed_group), std::move(matrix)); } + xformed_group = AttachOpacity(s, ctx, std::move(xformed_group)); } break; } } @@ -694,10 +721,11 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer, auto layer = gLayerAttachers[type](jlayer, layerCtx->fCtx); auto layerMatrix = layerCtx->AttachLayerMatrix(jlayer); + auto transformed = layerMatrix + ? sksg::Transform::Make(std::move(layer), std::move(layerMatrix)) + : layer; - return layerMatrix - ? sksg::Transform::Make(std::move(layer), std::move(layerMatrix)) - : layer; + return AttachOpacity(jlayer["ks"], layerCtx->fCtx, std::move(transformed)); } sk_sp<sksg::RenderNode> AttachComposition(const Json::Value& comp, AttachContext* ctx) { diff --git a/experimental/sksg/SkSGNode.h b/experimental/sksg/SkSGNode.h index 4e1e7b0d2a..1ed2a782d2 100644 --- a/experimental/sksg/SkSGNode.h +++ b/experimental/sksg/SkSGNode.h @@ -44,6 +44,11 @@ protected: explicit Node(uint32_t invalTraits); ~Node() override; + const SkRect& bounds() const { + SkASSERT(!this->hasInval()); + return fBounds; + } + // Tag this node for invalidation and optional damage. void invalidate(bool damage = true); bool hasInval() const { return fFlags & kInvalidated_Flag; } diff --git a/experimental/sksg/effects/SkSGOpacityEffect.cpp b/experimental/sksg/effects/SkSGOpacityEffect.cpp new file mode 100644 index 0000000000..b1ff10d217 --- /dev/null +++ b/experimental/sksg/effects/SkSGOpacityEffect.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkSGOpacityEffect.h" + +#include "SkCanvas.h" + +#include <math.h> + +namespace sksg { + +OpacityEffect::OpacityEffect(sk_sp<RenderNode> child, float opacity) + : INHERITED(std::move(child)) + , fOpacity(opacity) {} + +void OpacityEffect::onRender(SkCanvas* canvas) const { + // opacity <= 0 disables rendering + if (fOpacity <= 0) + return; + + // TODO: we could avoid savelayer if there is no more than one drawing primitive + // in the sub-DAG. + SkAutoCanvasRestore acr(canvas, false); + if (fOpacity < 1) { + canvas->saveLayerAlpha(&this->bounds(), roundf(fOpacity * 255)); + } + + this->INHERITED::onRender(canvas); +} + +SkRect OpacityEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) { + SkASSERT(this->hasInval()); + + // opacity <= 0 disables rendering AND revalidation for the sub-DAG + return fOpacity > 0 ? this->INHERITED::onRevalidate(ic, ctm) : SkRect::MakeEmpty(); +} + +} // namespace sksg diff --git a/experimental/sksg/effects/SkSGOpacityEffect.h b/experimental/sksg/effects/SkSGOpacityEffect.h new file mode 100644 index 0000000000..d906775b44 --- /dev/null +++ b/experimental/sksg/effects/SkSGOpacityEffect.h @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGOpacityEffect_DEFINED +#define SkSGOpacityEffect_DEFINED + +#include "SkSGEffectNode.h" + +namespace sksg { + +/** + * Concrete Effect node, applying opacity to its descendants. + * + */ +class OpacityEffect final : public EffectNode { +public: + static sk_sp<OpacityEffect> Make(sk_sp<RenderNode> child, float opacity = 1) { + return child ? sk_sp<OpacityEffect>(new OpacityEffect(std::move(child), opacity)) : nullptr; + } + + SG_ATTRIBUTE(Opacity, float, fOpacity) + +protected: + OpacityEffect(sk_sp<RenderNode>, float); + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + float fOpacity; + + typedef EffectNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGOpacityEffect_DEFINED |