aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-08 12:51:12 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-08 18:11:31 +0000
commit493280782430b76251145cfb7d78d6d33b65c1d1 (patch)
tree14973ee0898f4b193664a34e16c551a846509bbd /experimental
parent7b7d9b374d62c4be5d439a3a1dd761b9ef4b3052 (diff)
[skotty,sksg] Initial image support
TBR= Change-Id: Ib3c918b1d746e4f190ae05708681f2d5519afdb2 Reviewed-on: https://skia-review.googlesource.com/91980 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental')
-rw-r--r--experimental/skotty/Skotty.cpp79
-rw-r--r--experimental/skotty/Skotty.h15
-rw-r--r--experimental/sksg/SkSGImage.cpp29
-rw-r--r--experimental/sksg/SkSGImage.h49
4 files changed, 162 insertions, 10 deletions
diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp
index b331547316..077640b695 100644
--- a/experimental/skotty/Skotty.cpp
+++ b/experimental/skotty/Skotty.cpp
@@ -12,14 +12,17 @@
#include "SkottyPriv.h"
#include "SkottyProperties.h"
#include "SkData.h"
+#include "SkImage.h"
#include "SkMakeUnique.h"
+#include "SkOSPath.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPoint.h"
#include "SkSGColor.h"
#include "SkSGDraw.h"
-#include "SkSGInvalidationController.h"
#include "SkSGGroup.h"
+#include "SkSGImage.h"
+#include "SkSGInvalidationController.h"
#include "SkSGMerge.h"
#include "SkSGPath.h"
#include "SkSGRect.h"
@@ -42,6 +45,7 @@ namespace {
using AssetMap = SkTHashMap<SkString, const Json::Value*>;
struct AttachContext {
+ const ResourceProvider& fResources;
const AssetMap& fAssets;
SkTArray<std::unique_ptr<AnimatorBase>>& fAnimators;
};
@@ -550,11 +554,43 @@ sk_sp<sksg::RenderNode> AttachSolidLayer(const Json::Value& layer, AttachContext
return nullptr;
}
-sk_sp<sksg::RenderNode> AttachImageLayer(const Json::Value& layer, AttachContext*) {
+sk_sp<sksg::RenderNode> AttachImageAsset(const Json::Value& jimage, AttachContext* ctx) {
+ SkASSERT(jimage.isObject());
+
+ const auto name = ParseString(jimage["p"], ""),
+ path = ParseString(jimage["u"], "");
+ if (name.isEmpty())
+ return nullptr;
+
+ // TODO: plumb resource paths explicitly to ResourceProvider?
+ const auto resName = path.isEmpty() ? name : SkOSPath::Join(path.c_str(), name.c_str());
+ const auto resStream = ctx->fResources.openStream(resName.c_str());
+ if (!resStream || !resStream->hasLength()) {
+ LOG("!! Could not load image resource: %s\n", resName.c_str());
+ return nullptr;
+ }
+
+ // TODO: non-intrisic image sizing
+ return sksg::Image::Make(
+ SkImage::MakeFromEncoded(SkData::MakeFromStream(resStream.get(), resStream->getLength())));
+}
+
+sk_sp<sksg::RenderNode> AttachImageLayer(const Json::Value& layer, AttachContext* ctx) {
SkASSERT(layer.isObject());
- LOG("?? Image layer stub\n");
- return nullptr;
+ auto refId = ParseString(layer["refId"], "");
+ if (refId.isEmpty()) {
+ LOG("!! Image layer missing refId\n");
+ return nullptr;
+ }
+
+ const auto* jimage = ctx->fAssets.find(refId);
+ if (!jimage) {
+ LOG("!! Image asset not found: '%s'\n", refId.c_str());
+ return nullptr;
+ }
+
+ return AttachImageAsset(**jimage, ctx);
}
sk_sp<sksg::RenderNode> AttachNullLayer(const Json::Value& layer, AttachContext*) {
@@ -699,7 +735,7 @@ sk_sp<sksg::RenderNode> AttachComposition(const Json::Value& comp, AttachContext
} // namespace
-std::unique_ptr<Animation> Animation::Make(SkStream* stream) {
+std::unique_ptr<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res) {
if (!stream->hasLength()) {
// TODO: handle explicit buffering?
LOG("!! cannot parse streaming content\n");
@@ -733,10 +769,37 @@ std::unique_ptr<Animation> Animation::Make(SkStream* stream) {
return nullptr;
}
- return std::unique_ptr<Animation>(new Animation(std::move(version), size, fps, json));
+ return std::unique_ptr<Animation>(new Animation(res, std::move(version), size, fps, json));
+}
+
+std::unique_ptr<Animation> Animation::MakeFromFile(const char path[], const ResourceProvider* res) {
+ class DirectoryResourceProvider final : public ResourceProvider {
+ public:
+ explicit DirectoryResourceProvider(SkString dir) : fDir(std::move(dir)) {}
+
+ std::unique_ptr<SkStream> openStream(const char resource[]) const override {
+ const auto resPath = SkOSPath::Join(fDir.c_str(), resource);
+ return SkStream::MakeFromFile(resPath.c_str());
+ }
+
+ private:
+ const SkString fDir;
+ };
+
+ const auto jsonStream = SkStream::MakeFromFile(path);
+ if (!jsonStream)
+ return nullptr;
+
+ std::unique_ptr<ResourceProvider> defaultProvider;
+ if (!res) {
+ defaultProvider = skstd::make_unique<DirectoryResourceProvider>(SkOSPath::Dirname(path));
+ }
+
+ return Make(jsonStream.get(), res ? *res : *defaultProvider);
}
-Animation::Animation(SkString version, const SkSize& size, SkScalar fps, const Json::Value& json)
+Animation::Animation(const ResourceProvider& resources,
+ SkString version, const SkSize& size, SkScalar fps, const Json::Value& json)
: fVersion(std::move(version))
, fSize(size)
, fFrameRate(fps)
@@ -752,7 +815,7 @@ Animation::Animation(SkString version, const SkSize& size, SkScalar fps, const J
assets.set(ParseString(asset["id"], ""), &asset);
}
- AttachContext ctx = { assets, fAnimators };
+ AttachContext ctx = { resources, assets, fAnimators };
fDom = AttachComposition(json, &ctx);
LOG("** Attached %d animators\n", fAnimators.count());
diff --git a/experimental/skotty/Skotty.h b/experimental/skotty/Skotty.h
index d02dc8d3ab..ebd103d60c 100644
--- a/experimental/skotty/Skotty.h
+++ b/experimental/skotty/Skotty.h
@@ -29,9 +29,18 @@ namespace skotty {
class AnimatorBase;
+class ResourceProvider : public SkNoncopyable {
+public:
+ virtual ~ResourceProvider() = default;
+
+ virtual std::unique_ptr<SkStream> openStream(const char resource[]) const = 0;
+};
+
class Animation : public SkNoncopyable {
public:
- static std::unique_ptr<Animation> Make(SkStream*);
+ static std::unique_ptr<Animation> Make(SkStream*, const ResourceProvider&);
+ static std::unique_ptr<Animation> MakeFromFile(const char path[],
+ const ResourceProvider* = nullptr);
~Animation();
@@ -48,7 +57,9 @@ public:
void setShowInval(bool show) { fShowInval = show; }
private:
- Animation(SkString ver, const SkSize& size, SkScalar fps, const Json::Value&);
+ Animation(const ResourceProvider&,
+ SkString ver, const SkSize& size, SkScalar fps,
+ const Json::Value&);
SkString fVersion;
SkSize fSize;
diff --git a/experimental/sksg/SkSGImage.cpp b/experimental/sksg/SkSGImage.cpp
new file mode 100644
index 0000000000..a0c3a759dc
--- /dev/null
+++ b/experimental/sksg/SkSGImage.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 "SkSGImage.h"
+
+#include "SkCanvas.h"
+#include "SkImage.h"
+
+namespace sksg {
+
+Image::Image(sk_sp<SkImage> image) : fImage(std::move(image)) {}
+
+void Image::onRender(SkCanvas* canvas) const {
+ SkPaint paint;
+ paint.setAntiAlias(fAntiAlias);
+ paint.setFilterQuality(fQuality);
+
+ canvas->drawImage(fImage, 0, 0);
+}
+
+SkRect Image::onRevalidate(InvalidationController*, const SkMatrix& ctm) {
+ return SkRect::Make(fImage->bounds());
+}
+
+} // namespace sksg
diff --git a/experimental/sksg/SkSGImage.h b/experimental/sksg/SkSGImage.h
new file mode 100644
index 0000000000..7d17a50aaa
--- /dev/null
+++ b/experimental/sksg/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