[skotty,sksg] Initial matte layer support

TBR=
Change-Id: I5b689f5d7b0d147fa200cf5bffe476077085cb19
Reviewed-on: https://skia-review.googlesource.com/93300
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-01-10 13:36:22 -05:00 committed by Skia Commit-Bot
parent 68c3fac8ce
commit 5f9102f291
5 changed files with 110 additions and 0 deletions

View File

@ -1384,6 +1384,7 @@ if (skia_enable_tools) {
"experimental/sksg/SkSGNode.cpp",
"experimental/sksg/SkSGPaintNode.cpp",
"experimental/sksg/SkSGRenderNode.cpp",
"experimental/sksg/effects/SkSGMaskEffect.cpp",
"experimental/sksg/effects/SkSGOpacityEffect.cpp",
"experimental/sksg/effects/SkSGTransform.cpp",
"experimental/sksg/geometry/SkSGMerge.cpp",

View File

@ -24,6 +24,7 @@
#include "SkSGGroup.h"
#include "SkSGImage.h"
#include "SkSGInvalidationController.h"
#include "SkSGMaskEffect.h"
#include "SkSGMerge.h"
#include "SkSGOpacityEffect.h"
#include "SkSGPath.h"
@ -689,6 +690,7 @@ struct AttachLayerContext {
AttachContext* fCtx;
std::unordered_map<const Json::Value*, sk_sp<sksg::Matrix>> fLayerMatrixCache;
std::unordered_map<int, const Json::Value*> fLayerIndexCache;
sk_sp<sksg::RenderNode> fCurrentMatte;
const Json::Value* findLayer(int index) {
SkASSERT(fLayerList.isArray());
@ -795,6 +797,17 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
layerCtx->fCtx->fAnimators.push_back(skstd::make_unique<Activator>(layerControl, in, out));
if (ParseBool(jlayer["td"], false)) {
// This layer is a matte. We apply it as a mask to the next layer.
layerCtx->fCurrentMatte = std::move(layerControl);
return nullptr;
}
if (layerCtx->fCurrentMatte) {
// There is a pending matte. Apply and reset.
return sksg::MaskEffect::Make(std::move(layerControl), std::move(layerCtx->fCurrentMatte));
}
return layerControl;
}

View File

@ -71,6 +71,7 @@ private:
friend class Draw;
friend class EffectNode;
friend class Group;
friend class MaskEffect;
friend class Matrix;
friend class Merge;
friend class Stroke;

View File

@ -0,0 +1,51 @@
/*
* 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 "SkSGMaskEffect.h"
#include "SkCanvas.h"
namespace sksg {
MaskEffect::MaskEffect(sk_sp<RenderNode> child, sk_sp<RenderNode> mask)
: INHERITED(std::move(child))
, fMaskNode(std::move(mask)) {
fMaskNode->addInvalReceiver(this);
}
MaskEffect::~MaskEffect() {
fMaskNode->removeInvalReceiver(this);
}
void MaskEffect::onRender(SkCanvas* canvas) const {
if (this->bounds().isEmpty())
return;
SkAutoCanvasRestore acr(canvas, false);
canvas->saveLayer(this->bounds(), nullptr);
fMaskNode->render(canvas);
SkPaint p;
p.setBlendMode(SkBlendMode::kSrcIn);
canvas->saveLayer(this->bounds(), &p);
this->INHERITED::onRender(canvas);
}
SkRect MaskEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
SkASSERT(this->hasInval());
const auto maskBounds = fMaskNode->revalidate(ic, ctm);
auto childBounds = this->INHERITED::onRevalidate(ic, ctm);
return childBounds.intersect(maskBounds) ? childBounds : SkRect::MakeEmpty();
}
} // namespace sksg

View File

@ -0,0 +1,44 @@
/*
* 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 SkSGMaskEffect_DEFINED
#define SkSGMaskEffect_DEFINED
#include "SkSGEffectNode.h"
namespace sksg {
/**
* Concrete Effect node, applying a mask to its descendants.
*
*/
class MaskEffect final : public EffectNode {
public:
static sk_sp<MaskEffect> Make(sk_sp<RenderNode> child, sk_sp<RenderNode> mask) {
return (child && mask)
? sk_sp<MaskEffect>(new MaskEffect(std::move(child), std::move(mask)))
: nullptr;
}
~MaskEffect() override;
protected:
MaskEffect(sk_sp<RenderNode>, sk_sp<RenderNode> mask);
void onRender(SkCanvas*) const override;
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
private:
sk_sp<RenderNode> fMaskNode;
typedef EffectNode INHERITED;
};
} // namespace sksg
#endif // SkSGMaskEffect_DEFINED