[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:
parent
68c3fac8ce
commit
5f9102f291
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/SkSGMaskEffect.cpp",
|
||||
"experimental/sksg/effects/SkSGOpacityEffect.cpp",
|
||||
"experimental/sksg/effects/SkSGTransform.cpp",
|
||||
"experimental/sksg/geometry/SkSGMerge.cpp",
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
51
experimental/sksg/effects/SkSGMaskEffect.cpp
Normal file
51
experimental/sksg/effects/SkSGMaskEffect.cpp
Normal 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
|
44
experimental/sksg/effects/SkSGMaskEffect.h
Normal file
44
experimental/sksg/effects/SkSGMaskEffect.h
Normal 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
|
Loading…
Reference in New Issue
Block a user