Remove ResourceProvider and ImageAsset sample impls from skottie
All tools are updated to use the new copies in skresources Change-Id: If3cfc3104d72535ea4c49f70f1fa68dcf78af987 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/256657 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
704d5408db
commit
4449f1f3fa
@ -7,181 +7,8 @@
|
||||
|
||||
#include "modules/skottie/utils/SkottieUtils.h"
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkImage.h"
|
||||
#include "include/utils/SkAnimCodecPlayer.h"
|
||||
#include "include/utils/SkBase64.h"
|
||||
#include "src/core/SkMakeUnique.h"
|
||||
#include "src/core/SkOSFile.h"
|
||||
#include "src/utils/SkOSPath.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace skottie_utils {
|
||||
|
||||
sk_sp<MultiFrameImageAsset> MultiFrameImageAsset::Make(sk_sp<SkData> data, bool predecode) {
|
||||
if (auto codec = SkCodec::MakeFromData(std::move(data))) {
|
||||
return sk_sp<MultiFrameImageAsset>(
|
||||
new MultiFrameImageAsset(skstd::make_unique<SkAnimCodecPlayer>(std::move(codec)),
|
||||
predecode));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MultiFrameImageAsset::MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer> player,
|
||||
bool predecode)
|
||||
: fPlayer(std::move(player))
|
||||
, fPreDecode(predecode) {
|
||||
SkASSERT(fPlayer);
|
||||
}
|
||||
|
||||
bool MultiFrameImageAsset::isMultiFrame() {
|
||||
return fPlayer->duration() > 0;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> MultiFrameImageAsset::getFrame(float t) {
|
||||
auto decode = [](sk_sp<SkImage> image) {
|
||||
SkASSERT(image->isLazyGenerated());
|
||||
|
||||
static constexpr size_t kMaxArea = 2048 * 2048;
|
||||
const auto image_area = SkToSizeT(image->width() * image->height());
|
||||
|
||||
if (image_area > kMaxArea) {
|
||||
// When the image is too large, decode and scale down to a reasonable size.
|
||||
const auto scale = std::sqrt(static_cast<float>(kMaxArea) / image_area);
|
||||
const auto info = SkImageInfo::MakeN32Premul(scale * image->width(),
|
||||
scale * image->height());
|
||||
SkBitmap bm;
|
||||
if (bm.tryAllocPixels(info, info.minRowBytes()) &&
|
||||
image->scalePixels(bm.pixmap(),
|
||||
SkFilterQuality::kMedium_SkFilterQuality,
|
||||
SkImage::kDisallow_CachingHint)) {
|
||||
image = SkImage::MakeFromBitmap(bm);
|
||||
}
|
||||
} else {
|
||||
// When the image size is OK, just force-decode.
|
||||
image = image->makeRasterImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
};
|
||||
|
||||
fPlayer->seek(static_cast<uint32_t>(t * 1000));
|
||||
auto frame = fPlayer->getFrame();
|
||||
|
||||
if (fPreDecode && frame && frame->isLazyGenerated()) {
|
||||
frame = decode(std::move(frame));
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
sk_sp<FileResourceProvider> FileResourceProvider::Make(SkString base_dir, bool predecode) {
|
||||
return sk_isdir(base_dir.c_str())
|
||||
? sk_sp<FileResourceProvider>(new FileResourceProvider(std::move(base_dir), predecode))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
FileResourceProvider::FileResourceProvider(SkString base_dir, bool predecode)
|
||||
: fDir(std::move(base_dir))
|
||||
, fPredecode(predecode) {}
|
||||
|
||||
sk_sp<SkData> FileResourceProvider::load(const char resource_path[],
|
||||
const char resource_name[]) const {
|
||||
const auto full_dir = SkOSPath::Join(fDir.c_str() , resource_path),
|
||||
full_path = SkOSPath::Join(full_dir.c_str(), resource_name);
|
||||
return SkData::MakeFromFileName(full_path.c_str());
|
||||
}
|
||||
|
||||
sk_sp<skottie::ImageAsset> FileResourceProvider::loadImageAsset(const char resource_path[],
|
||||
const char resource_name[],
|
||||
const char[]) const {
|
||||
return MultiFrameImageAsset::Make(this->load(resource_path, resource_name), fPredecode);
|
||||
}
|
||||
|
||||
ResourceProviderProxyBase::ResourceProviderProxyBase(sk_sp<ResourceProvider> rp)
|
||||
: fProxy(std::move(rp)) {}
|
||||
|
||||
sk_sp<SkData> ResourceProviderProxyBase::load(const char resource_path[],
|
||||
const char resource_name[]) const {
|
||||
return fProxy ? fProxy->load(resource_path, resource_name)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
sk_sp<skottie::ImageAsset> ResourceProviderProxyBase::loadImageAsset(const char rpath[],
|
||||
const char rname[],
|
||||
const char rid[]) const {
|
||||
return fProxy ? fProxy->loadImageAsset(rpath, rname, rid)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkData> ResourceProviderProxyBase::loadFont(const char name[], const char url[]) const {
|
||||
return fProxy ? fProxy->loadFont(name, url)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
CachingResourceProvider::CachingResourceProvider(sk_sp<ResourceProvider> rp)
|
||||
: INHERITED(std::move(rp)) {}
|
||||
|
||||
sk_sp<skottie::ImageAsset> CachingResourceProvider::loadImageAsset(const char resource_path[],
|
||||
const char resource_name[],
|
||||
const char resource_id[]) const {
|
||||
SkAutoMutexExclusive amx(fMutex);
|
||||
|
||||
const SkString key(resource_id);
|
||||
if (const auto* asset = fImageCache.find(key)) {
|
||||
return *asset;
|
||||
}
|
||||
|
||||
auto asset = this->INHERITED::loadImageAsset(resource_path, resource_name, resource_id);
|
||||
fImageCache.set(key, asset);
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
sk_sp<DataURIResourceProviderProxy> DataURIResourceProviderProxy::Make(sk_sp<ResourceProvider> rp,
|
||||
bool predecode) {
|
||||
return sk_sp<DataURIResourceProviderProxy>(
|
||||
new DataURIResourceProviderProxy(std::move(rp), predecode));
|
||||
}
|
||||
|
||||
DataURIResourceProviderProxy::DataURIResourceProviderProxy(sk_sp<ResourceProvider> rp,
|
||||
bool predecode)
|
||||
: INHERITED(std::move(rp))
|
||||
, fPredecode(predecode) {}
|
||||
|
||||
sk_sp<skottie::ImageAsset> DataURIResourceProviderProxy::loadImageAsset(const char rpath[],
|
||||
const char rname[],
|
||||
const char rid[]) const {
|
||||
// We only handle B64 encoded image dataURIs: data:image/<type>;base64,<data>
|
||||
// (https://en.wikipedia.org/wiki/Data_URI_scheme)
|
||||
static constexpr char kDataURIImagePrefix[] = "data:image/",
|
||||
kDataURIEncodingStr[] = ";base64,";
|
||||
|
||||
if (!strncmp(rname, kDataURIImagePrefix, SK_ARRAY_COUNT(kDataURIImagePrefix) - 1)) {
|
||||
const char* encoding_start = strstr(rname + SK_ARRAY_COUNT(kDataURIImagePrefix) - 1,
|
||||
kDataURIEncodingStr);
|
||||
if (encoding_start) {
|
||||
const char* data_start = encoding_start + SK_ARRAY_COUNT(kDataURIEncodingStr) - 1;
|
||||
|
||||
// TODO: SkBase64::decode ergonomics are... interesting.
|
||||
SkBase64 b64;
|
||||
if (SkBase64::kNoError == b64.decode(data_start, strlen(data_start))) {
|
||||
return MultiFrameImageAsset::Make(SkData::MakeWithProc(b64.getData(),
|
||||
b64.getDataSize(),
|
||||
[](const void* ptr, void*) {
|
||||
delete[] static_cast<const char*>(ptr);
|
||||
}, /*ctx=*/nullptr),
|
||||
fPredecode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this->INHERITED::loadImageAsset(rpath, rname, rid);
|
||||
}
|
||||
|
||||
class CustomPropertyManager::PropertyInterceptor final : public skottie::PropertyObserver {
|
||||
public:
|
||||
explicit PropertyInterceptor(CustomPropertyManager* mgr) : fMgr(mgr) {}
|
||||
|
@ -8,10 +8,6 @@
|
||||
#ifndef SkottieUtils_DEFINED
|
||||
#define SkottieUtils_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkString.h"
|
||||
#include "include/private/SkMutex.h"
|
||||
#include "include/private/SkTHash.h"
|
||||
#include "modules/skottie/include/Skottie.h"
|
||||
#include "modules/skottie/include/SkottieProperty.h"
|
||||
|
||||
@ -20,102 +16,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class SkAnimCodecPlayer;
|
||||
class SkData;
|
||||
class SkImage;
|
||||
|
||||
namespace skottie_utils {
|
||||
|
||||
class MultiFrameImageAsset final : public skottie::ImageAsset {
|
||||
public:
|
||||
/**
|
||||
* By default, images are decoded on-the-fly, at rasterization time.
|
||||
* Large images may cause jank as decoding is expensive (and can thrash internal caches).
|
||||
*
|
||||
* Pass |predecode| true to force-decode all images upfront, at the cost of potentially more RAM
|
||||
* and slower animation build times.
|
||||
*/
|
||||
static sk_sp<MultiFrameImageAsset> Make(sk_sp<SkData>, bool predecode = false);
|
||||
|
||||
bool isMultiFrame() override;
|
||||
|
||||
sk_sp<SkImage> getFrame(float t) override;
|
||||
|
||||
private:
|
||||
explicit MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer>, bool predecode);
|
||||
|
||||
std::unique_ptr<SkAnimCodecPlayer> fPlayer;
|
||||
bool fPreDecode;
|
||||
|
||||
using INHERITED = skottie::ImageAsset;
|
||||
};
|
||||
|
||||
class FileResourceProvider final : public skottie::ResourceProvider {
|
||||
public:
|
||||
static sk_sp<FileResourceProvider> Make(SkString base_dir, bool predecode = false);
|
||||
|
||||
sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override;
|
||||
|
||||
sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char[],
|
||||
const char[]) const override;
|
||||
|
||||
private:
|
||||
FileResourceProvider(SkString, bool);
|
||||
|
||||
const SkString fDir;
|
||||
const bool fPredecode;
|
||||
|
||||
using INHERITED = skottie::ResourceProvider;
|
||||
};
|
||||
|
||||
class ResourceProviderProxyBase : public skottie::ResourceProvider {
|
||||
protected:
|
||||
explicit ResourceProviderProxyBase(sk_sp<ResourceProvider>);
|
||||
|
||||
sk_sp<SkData> load(const char[], const char[]) const override;
|
||||
sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char[],
|
||||
const char[]) const override;
|
||||
sk_sp<SkData> loadFont(const char[], const char[]) const override;
|
||||
|
||||
private:
|
||||
const sk_sp<ResourceProvider> fProxy;
|
||||
};
|
||||
|
||||
class CachingResourceProvider final : public ResourceProviderProxyBase {
|
||||
public:
|
||||
static sk_sp<CachingResourceProvider> Make(sk_sp<ResourceProvider> rp) {
|
||||
return rp ? sk_sp<CachingResourceProvider>(new CachingResourceProvider(std::move(rp)))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit CachingResourceProvider(sk_sp<ResourceProvider>);
|
||||
|
||||
sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char[],
|
||||
const char[]) const override;
|
||||
|
||||
mutable SkMutex fMutex;
|
||||
mutable SkTHashMap<SkString, sk_sp<skottie::ImageAsset>> fImageCache;
|
||||
|
||||
using INHERITED = ResourceProviderProxyBase;
|
||||
};
|
||||
|
||||
class DataURIResourceProviderProxy final : public ResourceProviderProxyBase {
|
||||
public:
|
||||
static sk_sp<DataURIResourceProviderProxy> Make(sk_sp<ResourceProvider> rp,
|
||||
bool predecode = false);
|
||||
|
||||
private:
|
||||
DataURIResourceProviderProxy(sk_sp<ResourceProvider>, bool);
|
||||
|
||||
sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char[],
|
||||
const char[]) const override;
|
||||
|
||||
const bool fPredecode;
|
||||
|
||||
using INHERITED = ResourceProviderProxyBase;
|
||||
};
|
||||
|
||||
/**
|
||||
* CustomPropertyManager implements a property management scheme where color/opacity/transform
|
||||
* attributes are grouped and manipulated by name (one-to-many mapping).
|
||||
|
Loading…
Reference in New Issue
Block a user