1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 9cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 10cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 12cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 13cb93a386Sopenharmony_ci#include "include/core/SkSize.h" 14cb93a386Sopenharmony_ci#include "include/core/SkString.h" 15cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 16cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 17cb93a386Sopenharmony_ci#include "modules/skottie/include/Skottie.h" 18cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGInvalidationController.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci#include <string> 21cb93a386Sopenharmony_ci#include <vector> 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci#include <emscripten.h> 24cb93a386Sopenharmony_ci#include <emscripten/bind.h> 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci#if SK_INCLUDE_MANAGED_SKOTTIE 27cb93a386Sopenharmony_ci#include "modules/skottie/utils/SkottieUtils.h" 28cb93a386Sopenharmony_ci#include "modules/skresources/include/SkResources.h" 29cb93a386Sopenharmony_ci#endif // SK_INCLUDE_MANAGED_SKOTTIE 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci#ifdef SK_GL 32cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 33cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 34cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 35cb93a386Sopenharmony_ci#include "include/gpu/gl/GrGLInterface.h" 36cb93a386Sopenharmony_ci#include "include/gpu/gl/GrGLTypes.h" 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci#include <GL/gl.h> 39cb93a386Sopenharmony_ci#include <emscripten/html5.h> 40cb93a386Sopenharmony_ci#endif 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ciusing namespace emscripten; 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci// Self-documenting types 45cb93a386Sopenharmony_ciusing JSArray = emscripten::val; 46cb93a386Sopenharmony_ciusing JSObject = emscripten::val; 47cb93a386Sopenharmony_ciusing JSString = emscripten::val; 48cb93a386Sopenharmony_ciusing SkPathOrNull = emscripten::val; 49cb93a386Sopenharmony_ciusing Uint8Array = emscripten::val; 50cb93a386Sopenharmony_ciusing Float32Array = emscripten::val; 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci#if SK_INCLUDE_MANAGED_SKOTTIE 53cb93a386Sopenharmony_cinamespace { 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ciclass SkottieAssetProvider : public skottie::ResourceProvider { 56cb93a386Sopenharmony_cipublic: 57cb93a386Sopenharmony_ci ~SkottieAssetProvider() override = default; 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci // Tried using a map, but that gave strange errors like 60cb93a386Sopenharmony_ci // https://emscripten.org/docs/porting/guidelines/function_pointer_issues.html 61cb93a386Sopenharmony_ci // Not entirely sure why, but perhaps the iterator in the map was 62cb93a386Sopenharmony_ci // confusing enscripten. 63cb93a386Sopenharmony_ci using AssetVec = std::vector<std::pair<SkString, sk_sp<SkData>>>; 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci static sk_sp<SkottieAssetProvider> Make(AssetVec assets) { 66cb93a386Sopenharmony_ci if (assets.empty()) { 67cb93a386Sopenharmony_ci return nullptr; 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci return sk_sp<SkottieAssetProvider>(new SkottieAssetProvider(std::move(assets))); 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci sk_sp<skottie::ImageAsset> loadImageAsset(const char[] /* path */, 74cb93a386Sopenharmony_ci const char name[], 75cb93a386Sopenharmony_ci const char[] /* id */) const override { 76cb93a386Sopenharmony_ci // For CK/Skottie we ignore paths & IDs, and identify images based solely on name. 77cb93a386Sopenharmony_ci if (auto data = this->findAsset(name)) { 78cb93a386Sopenharmony_ci return skresources::MultiFrameImageAsset::Make(std::move(data)); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci return nullptr; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci sk_sp<SkData> loadFont(const char name[], const char[] /* url */) const override { 85cb93a386Sopenharmony_ci // Same as images paths, we ignore font URLs. 86cb93a386Sopenharmony_ci return this->findAsset(name); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ciprivate: 90cb93a386Sopenharmony_ci explicit SkottieAssetProvider(AssetVec assets) : fAssets(std::move(assets)) {} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci sk_sp<SkData> findAsset(const char name[]) const { 93cb93a386Sopenharmony_ci for (const auto& asset : fAssets) { 94cb93a386Sopenharmony_ci if (asset.first.equals(name)) { 95cb93a386Sopenharmony_ci return asset.second; 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci SkDebugf("Could not find %s\n", name); 100cb93a386Sopenharmony_ci return nullptr; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci const AssetVec fAssets; 104cb93a386Sopenharmony_ci}; 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ciclass ManagedAnimation final : public SkRefCnt { 107cb93a386Sopenharmony_cipublic: 108cb93a386Sopenharmony_ci static sk_sp<ManagedAnimation> Make(const std::string& json, 109cb93a386Sopenharmony_ci sk_sp<skottie::ResourceProvider> rp) { 110cb93a386Sopenharmony_ci auto mgr = std::make_unique<skottie_utils::CustomPropertyManager>(); 111cb93a386Sopenharmony_ci auto animation = skottie::Animation::Builder() 112cb93a386Sopenharmony_ci .setMarkerObserver(mgr->getMarkerObserver()) 113cb93a386Sopenharmony_ci .setPropertyObserver(mgr->getPropertyObserver()) 114cb93a386Sopenharmony_ci .setResourceProvider(rp) 115cb93a386Sopenharmony_ci .make(json.c_str(), json.size()); 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci return animation 118cb93a386Sopenharmony_ci ? sk_sp<ManagedAnimation>(new ManagedAnimation(std::move(animation), std::move(mgr))) 119cb93a386Sopenharmony_ci : nullptr; 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci ~ManagedAnimation() override = default; 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci // skottie::Animation API 125cb93a386Sopenharmony_ci void render(SkCanvas* canvas) const { fAnimation->render(canvas, nullptr); } 126cb93a386Sopenharmony_ci void render(SkCanvas* canvas, const SkRect& dst) const { fAnimation->render(canvas, &dst); } 127cb93a386Sopenharmony_ci // Returns a damage rect. 128cb93a386Sopenharmony_ci SkRect seek(SkScalar t) { 129cb93a386Sopenharmony_ci sksg::InvalidationController ic; 130cb93a386Sopenharmony_ci fAnimation->seek(t, &ic); 131cb93a386Sopenharmony_ci return ic.bounds(); 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci // Returns a damage rect. 134cb93a386Sopenharmony_ci SkRect seekFrame(double t) { 135cb93a386Sopenharmony_ci sksg::InvalidationController ic; 136cb93a386Sopenharmony_ci fAnimation->seekFrame(t, &ic); 137cb93a386Sopenharmony_ci return ic.bounds(); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci double duration() const { return fAnimation->duration(); } 140cb93a386Sopenharmony_ci double fps() const { return fAnimation->fps(); } 141cb93a386Sopenharmony_ci const SkSize& size() const { return fAnimation->size(); } 142cb93a386Sopenharmony_ci std::string version() const { return std::string(fAnimation->version().c_str()); } 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci // CustomPropertyManager API 145cb93a386Sopenharmony_ci JSArray getColorProps() const { 146cb93a386Sopenharmony_ci JSArray props = emscripten::val::array(); 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci for (const auto& cp : fPropMgr->getColorProps()) { 149cb93a386Sopenharmony_ci JSObject prop = emscripten::val::object(); 150cb93a386Sopenharmony_ci prop.set("key", cp); 151cb93a386Sopenharmony_ci prop.set("value", fPropMgr->getColor(cp)); 152cb93a386Sopenharmony_ci props.call<void>("push", prop); 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci return props; 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci JSArray getOpacityProps() const { 159cb93a386Sopenharmony_ci JSArray props = emscripten::val::array(); 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci for (const auto& op : fPropMgr->getOpacityProps()) { 162cb93a386Sopenharmony_ci JSObject prop = emscripten::val::object(); 163cb93a386Sopenharmony_ci prop.set("key", op); 164cb93a386Sopenharmony_ci prop.set("value", fPropMgr->getOpacity(op)); 165cb93a386Sopenharmony_ci props.call<void>("push", prop); 166cb93a386Sopenharmony_ci } 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci return props; 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_ci bool setColor(const std::string& key, SkColor c) { 172cb93a386Sopenharmony_ci return fPropMgr->setColor(key, c); 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci bool setOpacity(const std::string& key, float o) { 176cb93a386Sopenharmony_ci return fPropMgr->setOpacity(key, o); 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci JSArray getMarkers() const { 180cb93a386Sopenharmony_ci JSArray markers = emscripten::val::array(); 181cb93a386Sopenharmony_ci for (const auto& m : fPropMgr->markers()) { 182cb93a386Sopenharmony_ci JSObject marker = emscripten::val::object(); 183cb93a386Sopenharmony_ci marker.set("name", m.name); 184cb93a386Sopenharmony_ci marker.set("t0" , m.t0); 185cb93a386Sopenharmony_ci marker.set("t1" , m.t1); 186cb93a386Sopenharmony_ci markers.call<void>("push", marker); 187cb93a386Sopenharmony_ci } 188cb93a386Sopenharmony_ci return markers; 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ciprivate: 192cb93a386Sopenharmony_ci ManagedAnimation(sk_sp<skottie::Animation> animation, 193cb93a386Sopenharmony_ci std::unique_ptr<skottie_utils::CustomPropertyManager> propMgr) 194cb93a386Sopenharmony_ci : fAnimation(std::move(animation)) 195cb93a386Sopenharmony_ci , fPropMgr(std::move(propMgr)) {} 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci sk_sp<skottie::Animation> fAnimation; 198cb93a386Sopenharmony_ci std::unique_ptr<skottie_utils::CustomPropertyManager> fPropMgr; 199cb93a386Sopenharmony_ci}; 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ci} // anonymous ns 202cb93a386Sopenharmony_ci#endif // SK_INCLUDE_MANAGED_SKOTTIE 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_cistruct SimpleImageInfo { 205cb93a386Sopenharmony_ci int width; 206cb93a386Sopenharmony_ci int height; 207cb93a386Sopenharmony_ci SkColorType colorType; 208cb93a386Sopenharmony_ci SkAlphaType alphaType; 209cb93a386Sopenharmony_ci // TODO color spaces? 210cb93a386Sopenharmony_ci}; 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ciSkImageInfo toSkImageInfo(const SimpleImageInfo& sii) { 213cb93a386Sopenharmony_ci return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType); 214cb93a386Sopenharmony_ci} 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ci#ifdef SK_GL 217cb93a386Sopenharmony_cisk_sp<GrDirectContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context) 218cb93a386Sopenharmony_ci{ 219cb93a386Sopenharmony_ci EMSCRIPTEN_RESULT r = emscripten_webgl_make_context_current(context); 220cb93a386Sopenharmony_ci if (r < 0) { 221cb93a386Sopenharmony_ci printf("failed to make webgl context current %d\n", r); 222cb93a386Sopenharmony_ci return nullptr; 223cb93a386Sopenharmony_ci } 224cb93a386Sopenharmony_ci // setup GrDirectContext 225cb93a386Sopenharmony_ci auto interface = GrGLMakeNativeInterface(); 226cb93a386Sopenharmony_ci return GrDirectContext::MakeGL(interface); 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_cisk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrDirectContext> grContext, int width, int height) { 230cb93a386Sopenharmony_ci glClearColor(0, 0, 0, 0); 231cb93a386Sopenharmony_ci glClearStencil(0); 232cb93a386Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci // Wrap the frame buffer object attached to the screen in a Skia render 236cb93a386Sopenharmony_ci // target so Skia can render to it 237cb93a386Sopenharmony_ci GrGLint buffer; 238cb93a386Sopenharmony_ci glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer); 239cb93a386Sopenharmony_ci GrGLFramebufferInfo info; 240cb93a386Sopenharmony_ci info.fFBOID = (GrGLuint) buffer; 241cb93a386Sopenharmony_ci SkColorType colorType; 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ci GrGLint stencil; 244cb93a386Sopenharmony_ci glGetIntegerv(GL_STENCIL_BITS, &stencil); 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ci info.fFormat = GL_RGBA8; 247cb93a386Sopenharmony_ci colorType = kRGBA_8888_SkColorType; 248cb93a386Sopenharmony_ci 249cb93a386Sopenharmony_ci GrBackendRenderTarget target(width, height, 0, stencil, info); 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ci sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(grContext.get(), target, 252cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, 253cb93a386Sopenharmony_ci colorType, nullptr, nullptr)); 254cb93a386Sopenharmony_ci return surface; 255cb93a386Sopenharmony_ci} 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_cisk_sp<SkSurface> MakeRenderTarget(sk_sp<GrDirectContext> grContext, int width, int height) { 258cb93a386Sopenharmony_ci SkImageInfo info = SkImageInfo::MakeN32(width, height, SkAlphaType::kPremul_SkAlphaType); 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ci sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(), 261cb93a386Sopenharmony_ci SkBudgeted::kYes, 262cb93a386Sopenharmony_ci info, 0, 263cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, 264cb93a386Sopenharmony_ci nullptr, true)); 265cb93a386Sopenharmony_ci return surface; 266cb93a386Sopenharmony_ci} 267cb93a386Sopenharmony_ci 268cb93a386Sopenharmony_cisk_sp<SkSurface> MakeRenderTarget(sk_sp<GrDirectContext> grContext, SimpleImageInfo sii) { 269cb93a386Sopenharmony_ci sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(grContext.get(), 270cb93a386Sopenharmony_ci SkBudgeted::kYes, 271cb93a386Sopenharmony_ci toSkImageInfo(sii), 0, 272cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, 273cb93a386Sopenharmony_ci nullptr, true)); 274cb93a386Sopenharmony_ci return surface; 275cb93a386Sopenharmony_ci} 276cb93a386Sopenharmony_ci#endif // SK_GL 277cb93a386Sopenharmony_ci 278cb93a386Sopenharmony_ci// Some signatures below have uintptr_t instead of a pointer to a primitive 279cb93a386Sopenharmony_ci// type (e.g. SkScalar). This is necessary because we can't use "bind" (EMSCRIPTEN_BINDINGS) 280cb93a386Sopenharmony_ci// and pointers to primitive types (Only bound types like SkPoint). We could if we used 281cb93a386Sopenharmony_ci// cwrap (see https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97) 282cb93a386Sopenharmony_ci// but that requires us to stick to C code and, AFAIK, doesn't allow us to return nice things like 283cb93a386Sopenharmony_ci// SkPath or SkCanvas. 284cb93a386Sopenharmony_ci// 285cb93a386Sopenharmony_ci// So, basically, if we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers 286cb93a386Sopenharmony_ci// in our function type signatures. (this gives an error message like "Cannot call foo due to unbound 287cb93a386Sopenharmony_ci// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and 288cb93a386Sopenharmony_ci// the compiler is happy. 289cb93a386Sopenharmony_ciEMSCRIPTEN_BINDINGS(Skottie) { 290cb93a386Sopenharmony_ci#ifdef SK_GL 291cb93a386Sopenharmony_ci function("currentContext", &emscripten_webgl_get_current_context); 292cb93a386Sopenharmony_ci function("setCurrentContext", &emscripten_webgl_make_context_current); 293cb93a386Sopenharmony_ci function("MakeGrContext", &MakeGrContext); 294cb93a386Sopenharmony_ci function("MakeOnScreenGLSurface", &MakeOnScreenGLSurface); 295cb93a386Sopenharmony_ci function("MakeRenderTarget", 296cb93a386Sopenharmony_ci select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int)>(&MakeRenderTarget)); 297cb93a386Sopenharmony_ci function("MakeRenderTarget", 298cb93a386Sopenharmony_ci select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, SimpleImageInfo)>(&MakeRenderTarget)); 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci constant("gpu", true); 301cb93a386Sopenharmony_ci 302cb93a386Sopenharmony_ci class_<GrDirectContext>("GrDirectContext") 303cb93a386Sopenharmony_ci .smart_ptr<sk_sp<GrDirectContext>>("sk_sp<GrDirectContext>"); 304cb93a386Sopenharmony_ci // .function("getResourceCacheLimitBytes", optional_override([](GrDirectContext& self)->size_t { 305cb93a386Sopenharmony_ci // int maxResources = 0;// ignored 306cb93a386Sopenharmony_ci // size_t currMax = 0; 307cb93a386Sopenharmony_ci // self.getResourceCacheLimits(&maxResources, &currMax); 308cb93a386Sopenharmony_ci // return currMax; 309cb93a386Sopenharmony_ci // })) 310cb93a386Sopenharmony_ci // .function("getResourceCacheUsageBytes", optional_override([](GrDirectContext& self)->size_t { 311cb93a386Sopenharmony_ci // int usedResources = 0;// ignored 312cb93a386Sopenharmony_ci // size_t currUsage = 0; 313cb93a386Sopenharmony_ci // self.getResourceCacheUsage(&usedResources, &currUsage); 314cb93a386Sopenharmony_ci // return currUsage; 315cb93a386Sopenharmony_ci // })) 316cb93a386Sopenharmony_ci // .function("releaseResourcesAndAbandonContext", &GrDirectContext::releaseResourcesAndAbandonContext) 317cb93a386Sopenharmony_ci // .function("setResourceCacheLimitBytes", optional_override([](GrDirectContext& self, size_t maxResourceBytes) { 318cb93a386Sopenharmony_ci // int maxResources = 0; 319cb93a386Sopenharmony_ci // size_t currMax = 0; // ignored 320cb93a386Sopenharmony_ci // self.getResourceCacheLimits(&maxResources, &currMax); 321cb93a386Sopenharmony_ci // self.setResourceCacheLimits(maxResources, maxResourceBytes); 322cb93a386Sopenharmony_ci // })); 323cb93a386Sopenharmony_ci#endif 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_ci // function("getDecodeCacheLimitBytes", &SkResourceCache::GetTotalByteLimit); 326cb93a386Sopenharmony_ci // function("setDecodeCacheLimitBytes", &SkResourceCache::SetTotalByteLimit); 327cb93a386Sopenharmony_ci // function("getDecodeCacheUsedBytes" , &SkResourceCache::GetTotalBytesUsed); 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci function("_getRasterDirectSurface", optional_override([](const SimpleImageInfo ii, 330cb93a386Sopenharmony_ci uintptr_t /* uint8_t* */ pPtr, 331cb93a386Sopenharmony_ci size_t rowBytes)->sk_sp<SkSurface> { 332cb93a386Sopenharmony_ci uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr); 333cb93a386Sopenharmony_ci SkImageInfo imageInfo = toSkImageInfo(ii); 334cb93a386Sopenharmony_ci return SkSurface::MakeRasterDirect(imageInfo, pixels, rowBytes, nullptr); 335cb93a386Sopenharmony_ci }), allow_raw_pointers()); 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci class_<SkCanvas>("SkCanvas") 338cb93a386Sopenharmony_ci .function("_clear", optional_override([](SkCanvas& self, uintptr_t /* float* */ cPtr) { 339cb93a386Sopenharmony_ci // See comment above for uintptr_t explanation 340cb93a386Sopenharmony_ci float* fourFloats = reinterpret_cast<float*>(cPtr); 341cb93a386Sopenharmony_ci SkColor4f color = { fourFloats[0], fourFloats[1], fourFloats[2], fourFloats[3]}; 342cb93a386Sopenharmony_ci // TODO(reed): SkCanvas.clear() should take SkColor4f, then we could just use it here. 343cb93a386Sopenharmony_ci SkPaint p; 344cb93a386Sopenharmony_ci p.setBlendMode(SkBlendMode::kSrc); 345cb93a386Sopenharmony_ci p.setColor4f(color); 346cb93a386Sopenharmony_ci self.drawPaint(p); 347cb93a386Sopenharmony_ci })); 348cb93a386Sopenharmony_ci 349cb93a386Sopenharmony_ci class_<SkSurface>("SkSurface") 350cb93a386Sopenharmony_ci .smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>") 351cb93a386Sopenharmony_ci .function("_flush", select_overload<void()>(&SkSurface::flush)) 352cb93a386Sopenharmony_ci .function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers()); 353cb93a386Sopenharmony_ci 354cb93a386Sopenharmony_ci class_<skottie::Animation>("Animation") 355cb93a386Sopenharmony_ci .smart_ptr<sk_sp<skottie::Animation>>("sk_sp<Animation>") 356cb93a386Sopenharmony_ci .function("version", optional_override([](skottie::Animation& self)->std::string { 357cb93a386Sopenharmony_ci return std::string(self.version().c_str()); 358cb93a386Sopenharmony_ci })) 359cb93a386Sopenharmony_ci .function("size" , &skottie::Animation::size) 360cb93a386Sopenharmony_ci .function("duration", &skottie::Animation::duration) 361cb93a386Sopenharmony_ci .function("fps" , &skottie::Animation::fps) 362cb93a386Sopenharmony_ci .function("seek", optional_override([](skottie::Animation& self, SkScalar t)->void { 363cb93a386Sopenharmony_ci self.seek(t); 364cb93a386Sopenharmony_ci })) 365cb93a386Sopenharmony_ci .function("seekFrame", optional_override([](skottie::Animation& self, double t)->void { 366cb93a386Sopenharmony_ci self.seekFrame(t); 367cb93a386Sopenharmony_ci })) 368cb93a386Sopenharmony_ci .function("render", optional_override([](skottie::Animation& self, SkCanvas* canvas)->void { 369cb93a386Sopenharmony_ci self.render(canvas, nullptr); 370cb93a386Sopenharmony_ci }), allow_raw_pointers()) 371cb93a386Sopenharmony_ci .function("render", optional_override([](skottie::Animation& self, SkCanvas* canvas, 372cb93a386Sopenharmony_ci const SkRect r)->void { 373cb93a386Sopenharmony_ci self.render(canvas, &r); 374cb93a386Sopenharmony_ci }), allow_raw_pointers()); 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_ci function("MakeAnimation", optional_override([](std::string json)->sk_sp<skottie::Animation> { 377cb93a386Sopenharmony_ci return skottie::Animation::Make(json.c_str(), json.length()); 378cb93a386Sopenharmony_ci })); 379cb93a386Sopenharmony_ci constant("skottie", true); 380cb93a386Sopenharmony_ci 381cb93a386Sopenharmony_ci#if SK_INCLUDE_MANAGED_SKOTTIE 382cb93a386Sopenharmony_ci class_<ManagedAnimation>("ManagedAnimation") 383cb93a386Sopenharmony_ci .smart_ptr<sk_sp<ManagedAnimation>>("sk_sp<ManagedAnimation>") 384cb93a386Sopenharmony_ci .function("version" , &ManagedAnimation::version) 385cb93a386Sopenharmony_ci .function("size" , &ManagedAnimation::size) 386cb93a386Sopenharmony_ci .function("duration" , &ManagedAnimation::duration) 387cb93a386Sopenharmony_ci .function("fps" , &ManagedAnimation::fps) 388cb93a386Sopenharmony_ci .function("seek" , &ManagedAnimation::seek) 389cb93a386Sopenharmony_ci .function("seekFrame" , &ManagedAnimation::seekFrame) 390cb93a386Sopenharmony_ci .function("render" , select_overload<void(SkCanvas*) const>(&ManagedAnimation::render), allow_raw_pointers()) 391cb93a386Sopenharmony_ci .function("render" , select_overload<void(SkCanvas*, const SkRect&) const> 392cb93a386Sopenharmony_ci (&ManagedAnimation::render), allow_raw_pointers()); 393cb93a386Sopenharmony_ci // .function("setColor" , optional_override([](ManagedAnimation& self, const std::string& key, SimpleColor4f c) { 394cb93a386Sopenharmony_ci // self.setColor(key, c.toSkColor()); 395cb93a386Sopenharmony_ci // })) 396cb93a386Sopenharmony_ci // .function("setOpacity", &ManagedAnimation::setOpacity) 397cb93a386Sopenharmony_ci // .function("getMarkers", &ManagedAnimation::getMarkers) 398cb93a386Sopenharmony_ci // .function("getColorProps" , &ManagedAnimation::getColorProps) 399cb93a386Sopenharmony_ci // .function("getOpacityProps", &ManagedAnimation::getOpacityProps); 400cb93a386Sopenharmony_ci 401cb93a386Sopenharmony_ci function("_MakeManagedAnimation", optional_override([](std::string json, 402cb93a386Sopenharmony_ci size_t assetCount, 403cb93a386Sopenharmony_ci uintptr_t /* char** */ nptr, 404cb93a386Sopenharmony_ci uintptr_t /* uint8_t** */ dptr, 405cb93a386Sopenharmony_ci uintptr_t /* size_t* */ sptr) 406cb93a386Sopenharmony_ci ->sk_sp<ManagedAnimation> { 407cb93a386Sopenharmony_ci // See the comment in canvaskit_bindings.cpp about the use of uintptr_t 408cb93a386Sopenharmony_ci const auto assetNames = reinterpret_cast<char** >(nptr); 409cb93a386Sopenharmony_ci const auto assetDatas = reinterpret_cast<uint8_t**>(dptr); 410cb93a386Sopenharmony_ci const auto assetSizes = reinterpret_cast<size_t* >(sptr); 411cb93a386Sopenharmony_ci 412cb93a386Sopenharmony_ci SkottieAssetProvider::AssetVec assets; 413cb93a386Sopenharmony_ci assets.reserve(assetCount); 414cb93a386Sopenharmony_ci 415cb93a386Sopenharmony_ci for (size_t i = 0; i < assetCount; i++) { 416cb93a386Sopenharmony_ci auto name = SkString(assetNames[i]); 417cb93a386Sopenharmony_ci auto bytes = SkData::MakeFromMalloc(assetDatas[i], assetSizes[i]); 418cb93a386Sopenharmony_ci assets.push_back(std::make_pair(std::move(name), std::move(bytes))); 419cb93a386Sopenharmony_ci } 420cb93a386Sopenharmony_ci 421cb93a386Sopenharmony_ci return ManagedAnimation::Make(json, 422cb93a386Sopenharmony_ci skresources::DataURIResourceProviderProxy::Make( 423cb93a386Sopenharmony_ci SkottieAssetProvider::Make(std::move(assets)))); 424cb93a386Sopenharmony_ci })); 425cb93a386Sopenharmony_ci constant("managed_skottie", true); 426cb93a386Sopenharmony_ci#endif // SK_INCLUDE_MANAGED_SKOTTIE 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_ci value_object<SimpleImageInfo>("SkImageInfo") 429cb93a386Sopenharmony_ci .field("width", &SimpleImageInfo::width) 430cb93a386Sopenharmony_ci .field("height", &SimpleImageInfo::height) 431cb93a386Sopenharmony_ci .field("colorType", &SimpleImageInfo::colorType) 432cb93a386Sopenharmony_ci .field("alphaType", &SimpleImageInfo::alphaType); 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ci value_object<SkRect>("SkRect") 435cb93a386Sopenharmony_ci .field("fLeft", &SkRect::fLeft) 436cb93a386Sopenharmony_ci .field("fTop", &SkRect::fTop) 437cb93a386Sopenharmony_ci .field("fRight", &SkRect::fRight) 438cb93a386Sopenharmony_ci .field("fBottom", &SkRect::fBottom); 439cb93a386Sopenharmony_ci 440cb93a386Sopenharmony_ci // {"w": Number, "h", Number} 441cb93a386Sopenharmony_ci value_object<SkSize>("SkSize") 442cb93a386Sopenharmony_ci .field("w", &SkSize::fWidth) 443cb93a386Sopenharmony_ci .field("h", &SkSize::fHeight); 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_ci enum_<SkAlphaType>("AlphaType") 446cb93a386Sopenharmony_ci .value("Opaque", SkAlphaType::kOpaque_SkAlphaType) 447cb93a386Sopenharmony_ci .value("Premul", SkAlphaType::kPremul_SkAlphaType) 448cb93a386Sopenharmony_ci .value("Unpremul", SkAlphaType::kUnpremul_SkAlphaType); 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci enum_<SkColorType>("ColorType") 451cb93a386Sopenharmony_ci .value("RGBA_8888", SkColorType::kRGBA_8888_SkColorType); 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_ci} 454