diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 13530042..ef43223c 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -23,6 +23,7 @@ #include #include "tvgCommon.h" #include "tvgMath.h" +#include "tvgScene.h" #include "tvgLottieModel.h" #include "tvgLottieBuilder.h" #include "tvgLottieExpressions.h" @@ -1560,4 +1561,7 @@ void LottieBuilder::build(LottieComposition* comp) auto clip = Shape::gen(); clip->appendRect(0, 0, comp->w, comp->h); comp->root->scene->clip(clip); -} + + //turn off partial rendering for children + SCENE(comp->root->scene)->size({comp->w, comp->h}); +} \ No newline at end of file diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index 9cbeb7ea..094304c5 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -149,6 +149,11 @@ namespace tvg if (renderer) renderer->damage(bounds(renderer)); } + void damage(const RenderRegion& vport) + { + if (renderer) renderer->damage(vport); + } + void mark(RenderUpdateFlag flag) { renderFlag |= flag; diff --git a/src/renderer/tvgScene.h b/src/renderer/tvgScene.h index 68e7056a..d2ec39b6 100644 --- a/src/renderer/tvgScene.h +++ b/src/renderer/tvgScene.h @@ -66,8 +66,10 @@ struct SceneImpl : Scene list paints; //children list RenderRegion vport = {}; Array* effects = nullptr; - uint8_t opacity; //for composition + Point fsize; //fixed scene size + bool fixed = false; //true: fixed scene size, false: dynamic size bool vdirty = false; + uint8_t opacity; //for composition SceneImpl() : impl(Paint::Impl(this)) { @@ -75,8 +77,14 @@ struct SceneImpl : Scene ~SceneImpl() { - resetEffects(); clearPaints(); + resetEffects(); + } + + void size(const Point& size) + { + this->fsize = size; + fixed = (size.x > 0 && size.y > 0) ? true : false; } uint8_t needComposition(uint8_t opacity) @@ -117,22 +125,36 @@ struct SceneImpl : Scene this->opacity = opacity; opacity = 255; } + + //allow partial rendering? + auto recover = fixed ? renderer->partial(true) : false; + for (auto paint : paints) { PAINT(paint)->update(renderer, transform, clips, opacity, flag, false); } + //recover the condition + renderer->partial(recover); + if (effects) { ARRAY_FOREACH(p, *effects) { renderer->prepare(*p, transform); } } - //this viewport update is more performant than in bounds()? + //this viewport update is more performant than in bounds(). No idea. vport = renderer->viewport(); - vdirty = true; - //bounds(renderer) here hinders parallelization. - if (effects) renderer->damage(vport); + if (fixed) { + auto pt = fsize * transform; + vport.intersect({int32_t(round(transform.e13)), int32_t(round(transform.e23))}, {int32_t(round(pt.x)), int32_t(round(pt.y))}); + } else { + vdirty = true; + } + + //bounds(renderer) here hinders parallelization + //TODO: we can bring the precise effects region here + if (fixed || effects) impl.damage(vport); return true; } @@ -262,10 +284,13 @@ struct SceneImpl : Scene while (itr != paints.end()) { auto paint = PAINT((*itr)); //when the paint is destroyed damage will be triggered - if (paint->refCnt > 1) paint->damage(); + if (paint->refCnt > 1 && !fixed) paint->damage(); paint->unref(); paints.erase(itr++); } + + if (!effects && fixed) impl.damage(vport); + return Result::Success; } @@ -318,7 +343,7 @@ struct SceneImpl : Scene } delete(effects); effects = nullptr; - impl.renderer->damage(vport); + impl.damage(vport); } return Result::Success; }