aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-08 16:42:59 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-08 22:36:01 +0000
commitc0034179a1c43e33d3f2d970450c5cf9a68e471c (patch)
tree9d6cb6d74867f18a03b7505338862caeb559d6e4 /experimental
parent185ffe916eb374ab3dfe3f42e265d26dacdd30ca (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.cpp34
-rw-r--r--experimental/sksg/SkSGNode.h5
-rw-r--r--experimental/sksg/effects/SkSGOpacityEffect.cpp42
-rw-r--r--experimental/sksg/effects/SkSGOpacityEffect.h42
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