diff options
author | Florin Malita <fmalita@chromium.org> | 2018-05-25 12:43:51 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-25 17:11:52 +0000 |
commit | 3b526b05d652ad6c310d9c636187b20b51c7648c (patch) | |
tree | 6c6fa99f2e80db81e9c3f593fe5883aabdaa442b /modules/sksg/include | |
parent | 59da548b0c4d4239e0ec1855d3f7f77a2bff4b93 (diff) |
"Modularize" SkSG
* relocate all SkSG-related files under modules/sksg/
* fix various tidbits to make non-sksg builds possible
* drop obsolete SampleSGInval.cpp
Change-Id: I54e6c5bb1a09f45030fa8d607b3eb3f7cba78957
Reviewed-on: https://skia-review.googlesource.com/130025
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'modules/sksg/include')
24 files changed, 1391 insertions, 0 deletions
diff --git a/modules/sksg/include/SkSGClipEffect.h b/modules/sksg/include/SkSGClipEffect.h new file mode 100644 index 0000000000..674edb2b5c --- /dev/null +++ b/modules/sksg/include/SkSGClipEffect.h @@ -0,0 +1,50 @@ +/* + * 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 SkSGClipEffect_DEFINED +#define SkSGClipEffect_DEFINED + +#include "SkSGEffectNode.h" + +namespace sksg { + +class GeometryNode; + +/** + * Concrete Effect node, applying a clip to its descendants. + * + */ +class ClipEffect final : public EffectNode { +public: + static sk_sp<ClipEffect> Make(sk_sp<RenderNode> child, sk_sp<GeometryNode> clip, + bool aa = false) { + return (child && clip) + ? sk_sp<ClipEffect>(new ClipEffect(std::move(child), std::move(clip), aa)) + : nullptr; + } + + ~ClipEffect() override; + +protected: + ClipEffect(sk_sp<RenderNode>, sk_sp<GeometryNode>, bool aa); + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + const sk_sp<GeometryNode> fClipNode; + const bool fAntiAlias; + + bool fNoop = false; + + typedef EffectNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGClipEffect_DEFINED diff --git a/modules/sksg/include/SkSGColor.h b/modules/sksg/include/SkSGColor.h new file mode 100644 index 0000000000..a19921cfd3 --- /dev/null +++ b/modules/sksg/include/SkSGColor.h @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGColor_DEFINED +#define SkSGColor_DEFINED + +#include "SkSGPaintNode.h" + +#include "SkColor.h" + +namespace sksg { + +/** + * Concrete Paint node, wrapping an SkColor. + */ +class Color : public PaintNode { +public: + static sk_sp<Color> Make(SkColor c) { return sk_sp<Color>(new Color(c)); } + + SG_ATTRIBUTE(Color, SkColor, fColor) + +protected: + void onApplyToPaint(SkPaint*) const override; + +private: + explicit Color(SkColor); + + SkColor fColor; +}; + +} // namespace sksg + +#endif // SkSGColor_DEFINED diff --git a/modules/sksg/include/SkSGDraw.h b/modules/sksg/include/SkSGDraw.h new file mode 100644 index 0000000000..20ead3d5f6 --- /dev/null +++ b/modules/sksg/include/SkSGDraw.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGDraw_DEFINED +#define SkSGDraw_DEFINED + +#include "SkSGRenderNode.h" + +namespace sksg { + +class GeometryNode; +class PaintNode; + +/** + * Concrete rendering node. + * + * Wraps and draws a [geometry, paint] tuple. + * + * Think Skia SkCanvas::drawFoo(foo, paint) calls. + */ +class Draw : public RenderNode { +public: + static sk_sp<Draw> Make(sk_sp<GeometryNode> geo, sk_sp<PaintNode> paint) { + return (geo && paint) ? sk_sp<Draw>(new Draw(std::move(geo), std::move(paint))) : nullptr; + } + +protected: + Draw(sk_sp<GeometryNode>, sk_sp<PaintNode> paint); + ~Draw() override; + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + sk_sp<GeometryNode> fGeometry; + sk_sp<PaintNode> fPaint; + + typedef RenderNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGDraw_DEFINED diff --git a/modules/sksg/include/SkSGEffectNode.h b/modules/sksg/include/SkSGEffectNode.h new file mode 100644 index 0000000000..ab0968e96c --- /dev/null +++ b/modules/sksg/include/SkSGEffectNode.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGEffectNode_DEFINED +#define SkSGEffectNode_DEFINED + +#include "SkSGRenderNode.h" + +namespace sksg { + +/** + * Base class for nodes which apply some transformation when rendering + * their descendants. + * + * This includes transforms, clipping, filters, etc. + */ +class EffectNode : public RenderNode { +protected: + explicit EffectNode(sk_sp<RenderNode>); + ~EffectNode() override; + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + sk_sp<RenderNode> fChild; + + typedef RenderNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGEffectNode_DEFINED diff --git a/modules/sksg/include/SkSGGeometryNode.h b/modules/sksg/include/SkSGGeometryNode.h new file mode 100644 index 0000000000..7ce3aa9b79 --- /dev/null +++ b/modules/sksg/include/SkSGGeometryNode.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGGeometryNode_DEFINED +#define SkSGGeometryNode_DEFINED + +#include "SkSGNode.h" + +class SkCanvas; +class SkPaint; +class SkPath; + +namespace sksg { + +/** + * Base class for nodes which provide 'geometry' (as opposed to paint) + * for drawing. + * + * Think SkRect, SkPath, etc. + */ +class GeometryNode : public Node { +public: + void clip(SkCanvas*, bool antiAlias) const; + void draw(SkCanvas*, const SkPaint&) const; + + SkPath asPath() const; + +protected: + GeometryNode(); + + virtual void onClip(SkCanvas*, bool antiAlias) const = 0; + + virtual void onDraw(SkCanvas*, const SkPaint&) const = 0; + + virtual SkPath onAsPath() const = 0; + +private: + friend class Draw; // wants to know the cached bounds. + + typedef Node INHERITED; +}; + +} // namespace sksg + +#endif // SkSGGeometryNode_DEFINED diff --git a/modules/sksg/include/SkSGGeometryTransform.h b/modules/sksg/include/SkSGGeometryTransform.h new file mode 100644 index 0000000000..fe7e026031 --- /dev/null +++ b/modules/sksg/include/SkSGGeometryTransform.h @@ -0,0 +1,58 @@ +/* + * 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 SkSGGeometryTransform_DEFINED +#define SkSGGeometryTransform_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPath.h" +#include "SkSGTransform.h" + +class SkMatrix; + +namespace sksg { + +/** + * Concrete Effect node, binding a Matrix to a GeometryNode. + */ +class GeometryTransform final : public GeometryNode { +public: + static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, sk_sp<Matrix> matrix) { + return child && matrix + ? sk_sp<GeometryTransform>(new GeometryTransform(std::move(child), std::move(matrix))) + : nullptr; + } + + static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, const SkMatrix& m) { + return Make(std::move(child), Matrix::Make(m)); + } + + ~GeometryTransform() override; + + const sk_sp<Matrix>& getMatrix() const { return fMatrix; } + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + GeometryTransform(sk_sp<GeometryNode>, sk_sp<Matrix>); + + const sk_sp<GeometryNode> fChild; + const sk_sp<Matrix> fMatrix; + SkPath fTransformed; + + using INHERITED = GeometryNode; +}; + +} + +#endif // SkSGGeometryTransform_DEFINED diff --git a/modules/sksg/include/SkSGGradient.h b/modules/sksg/include/SkSGGradient.h new file mode 100644 index 0000000000..d69cb1495c --- /dev/null +++ b/modules/sksg/include/SkSGGradient.h @@ -0,0 +1,105 @@ +/* + * 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 SkSGGradient_DEFINED +#define SkSGGradient_DEFINED + +#include "SkSGPaintNode.h" + +#include "SkColor.h" +#include "SkPoint.h" +#include "SkScalar.h" +#include "SkShader.h" + +#include <vector> + +namespace sksg { + +/** + * Gradient base class. + */ +class Gradient : public PaintNode { +public: + struct ColorStop { + SkScalar fPosition; + SkColor fColor; + + bool operator==(const ColorStop& other) const { + return fPosition == other.fPosition && fColor == other.fColor; + } + }; + + SG_ATTRIBUTE(ColorStops, std::vector<ColorStop>, fColorStops) + SG_ATTRIBUTE(TileMode , SkShader::TileMode , fTileMode ) + +protected: + void onApplyToPaint(SkPaint*) const final; + + virtual sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors, + const std::vector<SkScalar>& positions) const = 0; + +protected: + Gradient() = default; + +private: + std::vector<ColorStop> fColorStops; + SkShader::TileMode fTileMode = SkShader::kClamp_TileMode; + + using INHERITED = PaintNode; +}; + +class LinearGradient final : public Gradient { +public: + static sk_sp<LinearGradient> Make() { + return sk_sp<LinearGradient>(new LinearGradient()); + } + + SG_ATTRIBUTE(StartPoint, SkPoint, fStartPoint) + SG_ATTRIBUTE(EndPoint , SkPoint, fEndPoint ) + +protected: + sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors, + const std::vector<SkScalar>& positions) const override; + +private: + LinearGradient() = default; + + SkPoint fStartPoint = SkPoint::Make(0, 0), + fEndPoint = SkPoint::Make(0, 0); + + using INHERITED = Gradient; +}; + +class RadialGradient final : public Gradient { +public: + static sk_sp<RadialGradient> Make() { + return sk_sp<RadialGradient>(new RadialGradient()); + } + + SG_ATTRIBUTE(StartCenter, SkPoint , fStartCenter) + SG_ATTRIBUTE(EndCenter , SkPoint , fEndCenter ) + SG_ATTRIBUTE(StartRadius, SkScalar, fStartRadius) + SG_ATTRIBUTE(EndRadius , SkScalar, fEndRadius ) + +protected: + sk_sp<SkShader> onMakeShader(const std::vector<SkColor>& colors, + const std::vector<SkScalar>& positions) const override; + +private: + RadialGradient() = default; + + SkPoint fStartCenter = SkPoint::Make(0, 0), + fEndCenter = SkPoint::Make(0, 0); + SkScalar fStartRadius = 0, + fEndRadius = 0; + + using INHERITED = Gradient; +}; + +} // namespace sksg + +#endif // SkSGGradient_DEFINED diff --git a/modules/sksg/include/SkSGGroup.h b/modules/sksg/include/SkSGGroup.h new file mode 100644 index 0000000000..482f10db8c --- /dev/null +++ b/modules/sksg/include/SkSGGroup.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGGroup_DEFINED +#define SkSGGroup_DEFINED + +#include "SkSGRenderNode.h" + +#include "SkTArray.h" + +namespace sksg { + +/** + * Concrete node, grouping together multiple descendants. + */ +class Group : public RenderNode { +public: + static sk_sp<Group> Make() { + return sk_sp<Group>(new Group()); + } + + void addChild(sk_sp<RenderNode>); + void removeChild(const sk_sp<RenderNode>&); + + size_t size() const { return SkTo<size_t>(fChildren.count()); } + bool empty() const { return fChildren.empty(); } + +protected: + Group(); + ~Group() override; + + void onRender(SkCanvas*) const override; + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + SkTArray<sk_sp<RenderNode>, true> fChildren; + + typedef RenderNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGGroup_DEFINED diff --git a/modules/sksg/include/SkSGImage.h b/modules/sksg/include/SkSGImage.h new file mode 100644 index 0000000000..7d17a50aaa --- /dev/null +++ b/modules/sksg/include/SkSGImage.h @@ -0,0 +1,49 @@ +/* + * 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 SkSGImage_DEFINED +#define SkSGImage_DEFINED + +#include "SkSGRenderNode.h" + +#include "SkFilterQuality.h" + +class SkImage; + +namespace sksg { + +/** + * Concrete rendering node, wrapping an SkImage. + * + */ +class Image final : public RenderNode { +public: + static sk_sp<Image> Make(sk_sp<SkImage> image) { + return image ? sk_sp<Image>(new Image(std::move(image))) : nullptr; + } + + SG_ATTRIBUTE(Quality , SkFilterQuality, fQuality ) + SG_ATTRIBUTE(AntiAlias, bool , fAntiAlias) + +protected: + explicit Image(sk_sp<SkImage>); + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + const sk_sp<SkImage> fImage; + SkFilterQuality fQuality = kLow_SkFilterQuality; + bool fAntiAlias = true; + + typedef RenderNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGImage_DEFINED diff --git a/modules/sksg/include/SkSGInvalidationController.h b/modules/sksg/include/SkSGInvalidationController.h new file mode 100644 index 0000000000..df3857c1fe --- /dev/null +++ b/modules/sksg/include/SkSGInvalidationController.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGInvalidationController_DEFINED +#define SkSGInvalidationController_DEFINED + +#include "SkMatrix.h" +#include "SkTDArray.h" +#include "SkTypes.h" + +struct SkRect; + +namespace sksg { + +/** + * Receiver for invalidation events. + * + * Tracks dirty regions for repaint. + */ +class InvalidationController : public SkNoncopyable { +public: + InvalidationController(); + + void inval(const SkRect&, const SkMatrix& ctm = SkMatrix::I()); + + const SkRect& bounds() const { return fBounds; } + const SkRect* begin() const { return fRects.begin(); } + const SkRect* end() const { return fRects.end(); } + +private: + SkTDArray<SkRect> fRects; + SkRect fBounds; + + typedef SkNoncopyable INHERITED; +}; + +} // namespace sksg + +#endif // SkSGInvalidationController_DEFINED diff --git a/modules/sksg/include/SkSGMaskEffect.h b/modules/sksg/include/SkSGMaskEffect.h new file mode 100644 index 0000000000..c4fd0120e5 --- /dev/null +++ b/modules/sksg/include/SkSGMaskEffect.h @@ -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. + */ + +#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: + enum class Mode { + kNormal, + kInvert + }; + + static sk_sp<MaskEffect> Make(sk_sp<RenderNode> child, sk_sp<RenderNode> mask, + Mode mode = Mode::kNormal) { + return (child && mask) + ? sk_sp<MaskEffect>(new MaskEffect(std::move(child), std::move(mask), mode)) + : nullptr; + } + + ~MaskEffect() override; + +protected: + MaskEffect(sk_sp<RenderNode>, sk_sp<RenderNode> mask, Mode); + + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + const sk_sp<RenderNode> fMaskNode; + const Mode fMaskMode; + + typedef EffectNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGMaskEffect_DEFINED diff --git a/modules/sksg/include/SkSGMerge.h b/modules/sksg/include/SkSGMerge.h new file mode 100644 index 0000000000..54924d6475 --- /dev/null +++ b/modules/sksg/include/SkSGMerge.h @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGMerge_DEFINED +#define SkSGMerge_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPath.h" + +#include <vector> + +class SkCanvas; +class SkPaint; + +namespace sksg { + +/** + * Concrete Geometry node, combining other geometries based on Mode. + */ +class Merge final : public GeometryNode { +public: + enum class Mode { + // Append path mode. + kMerge, + + // SkPathOp ops. + kUnion, + kIntersect, + kDifference, + kReverseDifference, + kXOR, + }; + + static sk_sp<Merge> Make(std::vector<sk_sp<GeometryNode>>&& geos, Mode mode) { + return sk_sp<Merge>(new Merge(std::move(geos), mode)); + } + + ~Merge() override; + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + Merge(std::vector<sk_sp<GeometryNode>>&& geos, Mode); + + std::vector<sk_sp<GeometryNode>> fGeos; + SkPath fMerged; + Mode fMode; + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGMerge_DEFINED diff --git a/modules/sksg/include/SkSGNode.h b/modules/sksg/include/SkSGNode.h new file mode 100644 index 0000000000..17619de485 --- /dev/null +++ b/modules/sksg/include/SkSGNode.h @@ -0,0 +1,107 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGNode_DEFINED +#define SkSGNode_DEFINED + +#include "SkRect.h" +#include "SkRefCnt.h" +#include "SkTDArray.h" + +class SkCanvas; +class SkMatrix; + +namespace sksg { + +class InvalidationController; + +/** + * Base class for all scene graph nodes. + * + * Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping), + * and invalidation. + * + * Note: egress edges are only implemented/supported in container subclasses + * (e.g. Group, Effect, Draw). + */ +class Node : public SkRefCnt { +public: + // Traverse the DAG and revalidate any dependant/invalidated nodes. + // Returns the bounding box for the DAG fragment. + const SkRect& revalidate(InvalidationController*, const SkMatrix&); + +protected: + enum InvalTraits { + // Nodes with this trait never generate direct damage -- instead, + // the damage bubbles up to ancestors. + kBubbleDamage_Trait = 1 << 0, + }; + + 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; } + + // Dispatched on revalidation. Subclasses are expected to recompute/cache their properties + // and return their bounding box in local coordinates. + virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0; + + // Register/unregister |this| to receive invalidation events from a descendant. + void observeInval(const sk_sp<Node>&); + void unobserveInval(const sk_sp<Node>&); + +private: + enum Flags { + kInvalidated_Flag = 1 << 0, // the node or its descendants require revalidation + kDamage_Flag = 1 << 1, // the node contributes damage during revalidation + kObserverArray_Flag = 1 << 2, // the node has more than one inval observer + kInTraversal_Flag = 1 << 3, // the node is part of a traversal (cycle detection) + }; + + template <typename Func> + void forEachInvalObserver(Func&&) const; + + class ScopedFlag; + + union { + Node* fInvalObserver; + SkTDArray<Node*>* fInvalObserverArray; + }; + SkRect fBounds; + const uint32_t fInvalTraits : 16; + uint32_t fFlags : 16; + + typedef SkRefCnt INHERITED; +}; + +// Helper for defining attribute getters/setters in subclasses. +#define SG_ATTRIBUTE(attr_name, attr_type, attr_container) \ + const attr_type& get##attr_name() const { return attr_container; } \ + void set##attr_name(const attr_type& v) { \ + if (attr_container == v) return; \ + attr_container = v; \ + this->invalidate(); \ + } + +#define SG_MAPPED_ATTRIBUTE(attr_name, attr_type, attr_container) \ + attr_type get##attr_name() const { return attr_container.get##attr_name(); } \ + void set##attr_name(const attr_type& v) { \ + if (attr_container.get##attr_name() == v) return; \ + attr_container.set##attr_name(v); \ + this->invalidate(); \ + } + +} // namespace sksg + +#endif // SkSGNode_DEFINED diff --git a/modules/sksg/include/SkSGOpacityEffect.h b/modules/sksg/include/SkSGOpacityEffect.h new file mode 100644 index 0000000000..d906775b44 --- /dev/null +++ b/modules/sksg/include/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 diff --git a/modules/sksg/include/SkSGPaintNode.h b/modules/sksg/include/SkSGPaintNode.h new file mode 100644 index 0000000000..5c9563b3a6 --- /dev/null +++ b/modules/sksg/include/SkSGPaintNode.h @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGPaintNode_DEFINED +#define SkSGPaintNode_DEFINED + +#include "SkSGNode.h" + +#include "SkPaint.h" + +namespace sksg { + +/** + * Base class for nodes which provide a 'paint' (as opposed to geometry) for + * drawing (e.g. colors, gradients, patterns). + * + * Roughly equivalent to Skia's SkPaint. + */ +class PaintNode : public Node { +public: + const SkPaint& makePaint(); + + SG_ATTRIBUTE(AntiAlias , bool , fAntiAlias ) + SG_ATTRIBUTE(Opacity , SkScalar , fOpacity ) + SG_ATTRIBUTE(BlendMode , SkBlendMode , fBlendMode ) + SG_ATTRIBUTE(StrokeWidth, SkScalar , fStrokeWidth) + SG_ATTRIBUTE(StrokeMiter, SkScalar , fStrokeMiter) + SG_ATTRIBUTE(Style , SkPaint::Style, fStyle ) + SG_ATTRIBUTE(StrokeJoin , SkPaint::Join , fStrokeJoin ) + SG_ATTRIBUTE(StrokeCap , SkPaint::Cap , fStrokeCap ) + +protected: + PaintNode(); + + virtual void onApplyToPaint(SkPaint*) const = 0; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) final; + +private: + SkPaint fPaint; + + SkScalar fOpacity = 1, + fStrokeWidth = 1, + fStrokeMiter = 4; + bool fAntiAlias = false; + SkBlendMode fBlendMode = SkBlendMode::kSrcOver; + SkPaint::Style fStyle = SkPaint::kFill_Style; + SkPaint::Join fStrokeJoin = SkPaint::kMiter_Join; + SkPaint::Cap fStrokeCap = SkPaint::kButt_Cap; + + typedef Node INHERITED; +}; + +} // namespace sksg + +#endif // SkSGGeometryNode_DEFINED diff --git a/modules/sksg/include/SkSGPath.h b/modules/sksg/include/SkSGPath.h new file mode 100644 index 0000000000..1a8718868d --- /dev/null +++ b/modules/sksg/include/SkSGPath.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGPath_DEFINED +#define SkSGPath_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPath.h" + +class SkCanvas; +class SkPaint; + +namespace sksg { + +/** + * Concrete Geometry node, wrapping an SkPath. + */ +class Path : public GeometryNode { +public: + static sk_sp<Path> Make() { return sk_sp<Path>(new Path(SkPath())); } + static sk_sp<Path> Make(const SkPath& r) { return sk_sp<Path>(new Path(r)); } + + SG_ATTRIBUTE(Path, SkPath, fPath) + SG_MAPPED_ATTRIBUTE(FillType, SkPath::FillType, fPath) + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit Path(const SkPath&); + + SkPath fPath; + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGPath_DEFINED diff --git a/modules/sksg/include/SkSGPlane.h b/modules/sksg/include/SkSGPlane.h new file mode 100644 index 0000000000..c0a26375b2 --- /dev/null +++ b/modules/sksg/include/SkSGPlane.h @@ -0,0 +1,40 @@ +/* + * 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 SkSGPlane_DEFINED +#define SkSGPlane_DEFINED + +#include "SkSGGeometryNode.h" + +class SkCanvas; +class SkPaint; + +namespace sksg { + +/** + * Concrete Geometry node, representing the whole canvas. + */ +class Plane final : public GeometryNode { +public: + static sk_sp<Plane> Make() { return sk_sp<Plane>(new Plane()); } + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + Plane(); + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGPlane_DEFINED diff --git a/modules/sksg/include/SkSGRect.h b/modules/sksg/include/SkSGRect.h new file mode 100644 index 0000000000..f5fcb962c6 --- /dev/null +++ b/modules/sksg/include/SkSGRect.h @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGRect_DEFINED +#define SkSGRect_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkRect.h" +#include "SkRRect.h" + +class SkCanvas; +class SkPaint; + +namespace sksg { + +/** + * Concrete Geometry node, wrapping an SkRect. + */ +class Rect final : public GeometryNode { +public: + static sk_sp<Rect> Make() { return sk_sp<Rect>(new Rect(SkRect::MakeEmpty())); } + static sk_sp<Rect> Make(const SkRect& r) { return sk_sp<Rect>(new Rect(r)); } + + SG_ATTRIBUTE(L, SkScalar, fRect.fLeft ) + SG_ATTRIBUTE(T, SkScalar, fRect.fTop ) + SG_ATTRIBUTE(R, SkScalar, fRect.fRight ) + SG_ATTRIBUTE(B, SkScalar, fRect.fBottom) + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit Rect(const SkRect&); + + SkRect fRect; + + using INHERITED = GeometryNode; +}; + +/** + * Concrete Geometry node, wrapping an SkRRect. + */ +class RRect final : public GeometryNode { +public: + static sk_sp<RRect> Make() { return sk_sp<RRect>(new RRect(SkRRect())); } + static sk_sp<RRect> Make(const SkRRect& rr) { return sk_sp<RRect>(new RRect(rr)); } + + SG_ATTRIBUTE(RRect, SkRRect, fRRect) + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit RRect(const SkRRect&); + + SkRRect fRRect; + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGRect_DEFINED diff --git a/modules/sksg/include/SkSGRenderNode.h b/modules/sksg/include/SkSGRenderNode.h new file mode 100644 index 0000000000..4ca1aec616 --- /dev/null +++ b/modules/sksg/include/SkSGRenderNode.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGRenderNode_DEFINED +#define SkSGRenderNode_DEFINED + +#include "SkSGNode.h" + +class SkCanvas; + +namespace sksg { + +/** + * Base class for nodes which can render to a canvas. + */ +class RenderNode : public Node { +public: + // Render the node and its descendants to the canvas. + void render(SkCanvas*) const; + +protected: + RenderNode(); + + virtual void onRender(SkCanvas*) const = 0; + +private: + typedef Node INHERITED; +}; + +} // namespace sksg + +#endif // SkSGRenderNode_DEFINED diff --git a/modules/sksg/include/SkSGRoundEffect.h b/modules/sksg/include/SkSGRoundEffect.h new file mode 100644 index 0000000000..67124ca072 --- /dev/null +++ b/modules/sksg/include/SkSGRoundEffect.h @@ -0,0 +1,50 @@ +/* + * 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 SkSGRoundEffect_DEFINED +#define SkSGRoundEffect_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPath.h" + +namespace sksg { + +/** + * Concrete Geometry node, applying a rounded-corner effect to its child. + */ +class RoundEffect final : public GeometryNode { +public: + static sk_sp<RoundEffect> Make(sk_sp<GeometryNode> child) { + return child ? sk_sp<RoundEffect>(new RoundEffect(std::move(child))) : nullptr; + } + + ~RoundEffect() override; + + SG_ATTRIBUTE(Radius, SkScalar, fRadius) + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit RoundEffect(sk_sp<GeometryNode>); + + const sk_sp<GeometryNode> fChild; + + SkPath fRoundedPath; + SkScalar fRadius = 0; + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGRoundEffect_DEFINED diff --git a/modules/sksg/include/SkSGScene.h b/modules/sksg/include/SkSGScene.h new file mode 100644 index 0000000000..2081c1d747 --- /dev/null +++ b/modules/sksg/include/SkSGScene.h @@ -0,0 +1,85 @@ +/* + * 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 SkSGScene_DEFINED +#define SkSGScene_DEFINED + +#include "SkRefCnt.h" +#include "SkTypes.h" + +#include <memory> +#include <vector> + +class SkCanvas; + +namespace sksg { + +class RenderNode; + +/** + * Base class for animators. + * + */ +class Animator : public SkNoncopyable { +public: + virtual ~Animator(); + + void tick(float t); + +protected: + Animator(); + + virtual void onTick(float t) = 0; + +private: + using INHERITED = SkNoncopyable; +}; + +using AnimatorList = std::vector<std::unique_ptr<Animator>>; + +class GroupAnimator : public Animator { +protected: + explicit GroupAnimator(AnimatorList&&); + + void onTick(float t) override; + +private: + const AnimatorList fAnimators; + + using INHERITED = Animator; +}; + +/** + * Holds a scene root and a list of animators. + * + * Provides high-level mehods for driving rendering and animations. + * + */ +class Scene final : SkNoncopyable { +public: + static std::unique_ptr<Scene> Make(sk_sp<RenderNode> root, AnimatorList&& animators); + ~Scene(); + + void render(SkCanvas*) const; + void animate(float t); + + void setShowInval(bool show) { fShowInval = show; } + +private: + Scene(sk_sp<RenderNode> root, AnimatorList&& animators); + + const sk_sp<RenderNode> fRoot; + const AnimatorList fAnimators; + + bool fShowInval = false; + + using INHERITED = SkNoncopyable; +}; + +} // namespace sksg + +#endif // SkSGScene_DEFINED diff --git a/modules/sksg/include/SkSGText.h b/modules/sksg/include/SkSGText.h new file mode 100644 index 0000000000..eb43337a10 --- /dev/null +++ b/modules/sksg/include/SkSGText.h @@ -0,0 +1,69 @@ +/* + * 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 SkSGText_DEFINED +#define SkSGText_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPaintDefaults.h" +#include "SkPoint.h" +#include "SkString.h" + +class SkCanvas; +class SkPaint; +class SkTextBlob; +class SkTypeface; + +namespace sksg { + +/** + * Concrete Geometry node, wrapping a (shaped) SkTextBlob. + */ +class Text final : public GeometryNode { +public: + static sk_sp<Text> Make(sk_sp<SkTypeface> tf, const SkString& text); + ~Text() override; + + SG_ATTRIBUTE(Text , SkString , fText ) + SG_ATTRIBUTE(Flags , uint32_t , fFlags ) + SG_ATTRIBUTE(Position, SkPoint , fPosition) + SG_ATTRIBUTE(Size , SkScalar , fSize ) + SG_ATTRIBUTE(ScaleX , SkScalar , fScaleX ) + SG_ATTRIBUTE(SkewX , SkScalar , fSkewX ) + SG_ATTRIBUTE(Align , SkPaint::Align, fAlign ) + + // TODO: add shaping functionality. + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit Text(sk_sp<SkTypeface>, const SkString&); + + const sk_sp<SkTypeface> fTypeface; + SkString fText; + uint32_t fFlags = SkPaintDefaults_Flags; + SkPoint fPosition = SkPoint::Make(0, 0); + SkScalar fSize = SkPaintDefaults_TextSize; + SkScalar fScaleX = 1; + SkScalar fSkewX = 0; + SkPaint::Align fAlign = SkPaint::kLeft_Align; + SkPaint::Hinting fHinting = SkPaintDefaults_Hinting; + + sk_sp<SkTextBlob> fBlob; // cached text blob + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGText_DEFINED diff --git a/modules/sksg/include/SkSGTransform.h b/modules/sksg/include/SkSGTransform.h new file mode 100644 index 0000000000..6b7fbc010b --- /dev/null +++ b/modules/sksg/include/SkSGTransform.h @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGTransform_DEFINED +#define SkSGTransform_DEFINED + +#include "SkSGEffectNode.h" + +#include "SkMatrix.h" + +namespace sksg { + +/** + * Concrete node, wrapping an SkMatrix, with an optional parent Matrix (to allow chaining): + * + * M' = parent x M + */ +class Matrix : public Node { +public: + static sk_sp<Matrix> Make(const SkMatrix& m, sk_sp<Matrix> parent = nullptr) { + return sk_sp<Matrix>(new Matrix(m, std::move(parent))); + } + + ~Matrix() override; + + SG_ATTRIBUTE(Matrix, SkMatrix, fLocalMatrix) + + const SkMatrix& getTotalMatrix() const { return fTotalMatrix; } + +protected: + Matrix(const SkMatrix&, sk_sp<Matrix>); + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + sk_sp<Matrix> fParent; + SkMatrix fLocalMatrix, + fTotalMatrix; // cached during revalidation + + typedef Node INHERITED; +}; + +/** + * Concrete Effect node, binding a Matrix to a RenderNode. + */ +class Transform final : public EffectNode { +public: + static sk_sp<Transform> Make(sk_sp<RenderNode> child, sk_sp<Matrix> matrix) { + return child && matrix + ? sk_sp<Transform>(new Transform(std::move(child), std::move(matrix))) + : nullptr; + } + + static sk_sp<Transform> Make(sk_sp<RenderNode> child, const SkMatrix& m) { + return Make(std::move(child), Matrix::Make(m)); + } + + ~Transform() override; + + const sk_sp<Matrix>& getMatrix() const { return fMatrix; } + +protected: + void onRender(SkCanvas*) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + +private: + Transform(sk_sp<RenderNode>, sk_sp<Matrix>); + + const sk_sp<Matrix> fMatrix; + + typedef EffectNode INHERITED; +}; + +} // namespace sksg + +#endif // SkSGTransform_DEFINED diff --git a/modules/sksg/include/SkSGTrimEffect.h b/modules/sksg/include/SkSGTrimEffect.h new file mode 100644 index 0000000000..18f15921e7 --- /dev/null +++ b/modules/sksg/include/SkSGTrimEffect.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSGTrimEffect_DEFINED +#define SkSGTrimEffect_DEFINED + +#include "SkSGGeometryNode.h" + +#include "SkPath.h" +#include "SkTrimPathEffect.h" + +class SkCanvas; +class SkPaint; + +namespace sksg { + +/** + * Concrete Geometry node, applying a trim effect to its child. + */ +class TrimEffect final : public GeometryNode { +public: + static sk_sp<TrimEffect> Make(sk_sp<GeometryNode> child) { + return child ? sk_sp<TrimEffect>(new TrimEffect(std::move(child))) : nullptr; + } + + ~TrimEffect() override; + + SG_ATTRIBUTE(Start , SkScalar , fStart ) + SG_ATTRIBUTE(Stop , SkScalar , fStop ) + SG_ATTRIBUTE(Mode , SkTrimPathEffect::Mode, fMode ) + +protected: + void onClip(SkCanvas*, bool antiAlias) const override; + void onDraw(SkCanvas*, const SkPaint&) const override; + + SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; + SkPath onAsPath() const override; + +private: + explicit TrimEffect(sk_sp<GeometryNode>); + + const sk_sp<GeometryNode> fChild; + + SkPath fTrimmedPath; + SkScalar fStart = 0, + fStop = 1; + SkTrimPathEffect::Mode fMode = SkTrimPathEffect::Mode::kNormal; + + using INHERITED = GeometryNode; +}; + +} // namespace sksg + +#endif // SkSGTrimEffect_DEFINED |