[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>
This commit is contained in:
parent
185ffe916e
commit
c0034179a1
1
BUILD.gn
1
BUILD.gn
@ -1384,6 +1384,7 @@ if (skia_enable_tools) {
|
||||
"experimental/sksg/SkSGNode.cpp",
|
||||
"experimental/sksg/SkSGPaintNode.cpp",
|
||||
"experimental/sksg/SkSGRenderNode.cpp",
|
||||
"experimental/sksg/effects/SkSGOpacityEffect.cpp",
|
||||
"experimental/sksg/effects/SkSGTransform.cpp",
|
||||
"experimental/sksg/geometry/SkSGMerge.cpp",
|
||||
"experimental/sksg/geometry/SkSGPath.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) {
|
||||
|
@ -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; }
|
||||
|
42
experimental/sksg/effects/SkSGOpacityEffect.cpp
Normal file
42
experimental/sksg/effects/SkSGOpacityEffect.cpp
Normal file
@ -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
|
42
experimental/sksg/effects/SkSGOpacityEffect.h
Normal file
42
experimental/sksg/effects/SkSGOpacityEffect.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user