[skottie] Ref-counted ResourceProvider

Update the ResourceProvider interface to inherit from SkRefCnt, to
clarify sharing/ownership semantics in the Skottie Builder API.  Now it
follows the same pattern as SkFontMgr.

Change-Id: I7ff8ad39023d9ecfe609e0180b5aabf776672d48
Reviewed-on: https://skia-review.googlesource.com/148991
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2018-08-23 14:49:05 -04:00 committed by Skia Commit-Bot
parent afcef4bb4f
commit 906cdf3fcd
4 changed files with 27 additions and 28 deletions

View File

@ -26,7 +26,7 @@ namespace sksg { class Scene; }
namespace skottie {
class SK_API ResourceProvider {
class SK_API ResourceProvider : public SkRefCnt {
public:
ResourceProvider() = default;
virtual ~ResourceProvider() = default;
@ -57,10 +57,9 @@ public:
const Stats& getStats() const { return fStats; }
/**
* Specify a loader for external resources (images, etc.). Ownership stays with the caller
* (the ResrouceProvider must be valid for this builder's lifespan).
* Specify a loader for external resources (images, etc.).
*/
Builder& setResourceProvider(const ResourceProvider*);
Builder& setResourceProvider(sk_sp<ResourceProvider>);
/**
* Specify a font manager for loading animation fonts.
@ -75,7 +74,7 @@ public:
sk_sp<Animation> makeFromFile(const char path[]);
private:
const ResourceProvider* fResourceProvider = nullptr;
sk_sp<ResourceProvider> fResourceProvider;
sk_sp<SkFontMgr> fFontMgr;
Stats fStats;
};

View File

@ -129,9 +129,10 @@ sk_sp<sksg::Color> AttachColor(const skjson::ObjectValue& jcolor, AnimatorScope*
return color_node;
}
AnimationBuilder::AnimationBuilder(const ResourceProvider& rp, sk_sp<SkFontMgr> fontmgr,
Animation::Builder::Stats* stats, float duration, float framerate)
: fResourceProvider(rp)
AnimationBuilder::AnimationBuilder(sk_sp<ResourceProvider> rp, sk_sp<SkFontMgr> fontmgr,
Animation::Builder::Stats* stats,
float duration, float framerate)
: fResourceProvider(std::move(rp))
, fFontMgr(std::move(fontmgr))
, fStats(stats)
, fDuration(duration)
@ -163,8 +164,8 @@ void AnimationBuilder::parseAssets(const skjson::ArrayValue* jassets) {
} // namespace internal
Animation::Builder& Animation::Builder::setResourceProvider(const ResourceProvider* rp) {
fResourceProvider = rp;
Animation::Builder& Animation::Builder::setResourceProvider(sk_sp<ResourceProvider> rp) {
fResourceProvider = std::move(rp);
return *this;
}
@ -194,10 +195,10 @@ sk_sp<Animation> Animation::Builder::make(const char* data, size_t data_len) {
class NullResourceProvider final : public ResourceProvider {
sk_sp<SkData> load(const char[], const char[]) const override { return nullptr; }
};
const NullResourceProvider nullProvider;
auto resolvedProvider = fResourceProvider ? fResourceProvider : &nullProvider;
auto resolvedFontMgr = fFontMgr ? fFontMgr : SkFontMgr::RefDefault();
auto resolvedProvider = fResourceProvider
? fResourceProvider : sk_make_sp<NullResourceProvider>();
auto resolvedFontMgr = fFontMgr
? fFontMgr : SkFontMgr::RefDefault();
memset(&fStats, 0, sizeof(struct Stats));
@ -233,8 +234,8 @@ sk_sp<Animation> Animation::Builder::make(const char* data, size_t data_len) {
SkASSERT(resolvedProvider);
SkASSERT(resolvedFontMgr);
internal::AnimationBuilder builder(*resolvedProvider, std::move(resolvedFontMgr), &fStats,
duration, fps);
internal::AnimationBuilder builder(std::move(resolvedProvider), std::move(resolvedFontMgr),
&fStats, duration, fps);
auto scene = builder.parse(json);
const auto t2 = SkTime::GetMSecs();
@ -268,17 +269,16 @@ sk_sp<Animation> Animation::Builder::makeFromFile(const char path[]) {
if (!data)
return nullptr;
const auto* origProvider = fResourceProvider;
std::unique_ptr<ResourceProvider> localProvider;
if (!fResourceProvider) {
localProvider = skstd::make_unique<DirectoryResourceProvider>(SkOSPath::Dirname(path));
fResourceProvider = localProvider.get();
const auto useLocalProvider = !fResourceProvider;
if (useLocalProvider) {
fResourceProvider = sk_make_sp<DirectoryResourceProvider>(SkOSPath::Dirname(path));
}
auto animation = this->make(static_cast<const char*>(data->data()), data->size());
// Don't leak localProvider references.
fResourceProvider = origProvider;
if (useLocalProvider) {
fResourceProvider.reset();
}
return animation;
}

View File

@ -206,14 +206,14 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachNestedAnimation(const char* name
const float fTimeScale;
};
const auto data = fResourceProvider.load("", name);
const auto data = fResourceProvider->load("", name);
if (!data) {
LOG("!! Could not load: %s\n", name);
return nullptr;
}
auto animation = Animation::Builder()
.setResourceProvider(&fResourceProvider)
.setResourceProvider(fResourceProvider)
.setFontManager(fFontMgr)
.make(static_cast<const char*>(data->data()), data->size());
if (!animation) {
@ -294,7 +294,7 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachImageAsset(const skjson::ObjectV
return *attached_image;
}
const auto data = fResourceProvider.load(path_cstr, name_cstr);
const auto data = fResourceProvider->load(path_cstr, name_cstr);
if (!data) {
LOG("!! Could not load image resource: %s/%s\n", path_cstr, name_cstr);
return nullptr;

View File

@ -44,7 +44,7 @@ using AnimatorScope = sksg::AnimatorList;
class AnimationBuilder final : public SkNoncopyable {
public:
AnimationBuilder(const ResourceProvider&, sk_sp<SkFontMgr>, Animation::Builder::Stats*,
AnimationBuilder(sk_sp<ResourceProvider>, sk_sp<SkFontMgr>, Animation::Builder::Stats*,
float duration, float framerate);
std::unique_ptr<sksg::Scene> parse(const skjson::ObjectValue&);
@ -75,7 +75,7 @@ private:
sk_sp<sksg::RenderNode> attachSolidLayer (const skjson::ObjectValue&, AnimatorScope*);
sk_sp<sksg::RenderNode> attachTextLayer (const skjson::ObjectValue&, AnimatorScope*);
const ResourceProvider& fResourceProvider;
sk_sp<ResourceProvider> fResourceProvider;
sk_sp<SkFontMgr> fFontMgr;
Animation::Builder::Stats* fStats;
const float fDuration,