mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-19 06:21:45 +00:00
common: support static scene mode (internal)
This adds support for a static scene mode, allowing a scene to be treated as a static image. In this mode, partial rendering for the inner drawable components is skipped. This is especially useful for scenes designed to be fully updated as a whole, such as those used in fully dynamic Lottie contents. issue: https://github.com/thorvg/thorvg/issues/1747
This commit is contained in:
parent
fc712c9c36
commit
749bc850ec
3 changed files with 43 additions and 9 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgMath.h"
|
#include "tvgMath.h"
|
||||||
|
#include "tvgScene.h"
|
||||||
#include "tvgLottieModel.h"
|
#include "tvgLottieModel.h"
|
||||||
#include "tvgLottieBuilder.h"
|
#include "tvgLottieBuilder.h"
|
||||||
#include "tvgLottieExpressions.h"
|
#include "tvgLottieExpressions.h"
|
||||||
|
@ -1560,4 +1561,7 @@ void LottieBuilder::build(LottieComposition* comp)
|
||||||
auto clip = Shape::gen();
|
auto clip = Shape::gen();
|
||||||
clip->appendRect(0, 0, comp->w, comp->h);
|
clip->appendRect(0, 0, comp->w, comp->h);
|
||||||
comp->root->scene->clip(clip);
|
comp->root->scene->clip(clip);
|
||||||
}
|
|
||||||
|
//turn off partial rendering for children
|
||||||
|
SCENE(comp->root->scene)->size({comp->w, comp->h});
|
||||||
|
}
|
|
@ -149,6 +149,11 @@ namespace tvg
|
||||||
if (renderer) renderer->damage(bounds(renderer));
|
if (renderer) renderer->damage(bounds(renderer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void damage(const RenderRegion& vport)
|
||||||
|
{
|
||||||
|
if (renderer) renderer->damage(vport);
|
||||||
|
}
|
||||||
|
|
||||||
void mark(RenderUpdateFlag flag)
|
void mark(RenderUpdateFlag flag)
|
||||||
{
|
{
|
||||||
renderFlag |= flag;
|
renderFlag |= flag;
|
||||||
|
|
|
@ -66,8 +66,10 @@ struct SceneImpl : Scene
|
||||||
list<Paint*> paints; //children list
|
list<Paint*> paints; //children list
|
||||||
RenderRegion vport = {};
|
RenderRegion vport = {};
|
||||||
Array<RenderEffect*>* effects = nullptr;
|
Array<RenderEffect*>* 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;
|
bool vdirty = false;
|
||||||
|
uint8_t opacity; //for composition
|
||||||
|
|
||||||
SceneImpl() : impl(Paint::Impl(this))
|
SceneImpl() : impl(Paint::Impl(this))
|
||||||
{
|
{
|
||||||
|
@ -75,8 +77,14 @@ struct SceneImpl : Scene
|
||||||
|
|
||||||
~SceneImpl()
|
~SceneImpl()
|
||||||
{
|
{
|
||||||
resetEffects();
|
|
||||||
clearPaints();
|
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)
|
uint8_t needComposition(uint8_t opacity)
|
||||||
|
@ -117,22 +125,36 @@ struct SceneImpl : Scene
|
||||||
this->opacity = opacity;
|
this->opacity = opacity;
|
||||||
opacity = 255;
|
opacity = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//allow partial rendering?
|
||||||
|
auto recover = fixed ? renderer->partial(true) : false;
|
||||||
|
|
||||||
for (auto paint : paints) {
|
for (auto paint : paints) {
|
||||||
PAINT(paint)->update(renderer, transform, clips, opacity, flag, false);
|
PAINT(paint)->update(renderer, transform, clips, opacity, flag, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//recover the condition
|
||||||
|
renderer->partial(recover);
|
||||||
|
|
||||||
if (effects) {
|
if (effects) {
|
||||||
ARRAY_FOREACH(p, *effects) {
|
ARRAY_FOREACH(p, *effects) {
|
||||||
renderer->prepare(*p, transform);
|
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();
|
vport = renderer->viewport();
|
||||||
vdirty = true;
|
|
||||||
|
|
||||||
//bounds(renderer) here hinders parallelization.
|
if (fixed) {
|
||||||
if (effects) renderer->damage(vport);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -262,10 +284,13 @@ struct SceneImpl : Scene
|
||||||
while (itr != paints.end()) {
|
while (itr != paints.end()) {
|
||||||
auto paint = PAINT((*itr));
|
auto paint = PAINT((*itr));
|
||||||
//when the paint is destroyed damage will be triggered
|
//when the paint is destroyed damage will be triggered
|
||||||
if (paint->refCnt > 1) paint->damage();
|
if (paint->refCnt > 1 && !fixed) paint->damage();
|
||||||
paint->unref();
|
paint->unref();
|
||||||
paints.erase(itr++);
|
paints.erase(itr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!effects && fixed) impl.damage(vport);
|
||||||
|
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +343,7 @@ struct SceneImpl : Scene
|
||||||
}
|
}
|
||||||
delete(effects);
|
delete(effects);
|
||||||
effects = nullptr;
|
effects = nullptr;
|
||||||
impl.renderer->damage(vport);
|
impl.damage(vport);
|
||||||
}
|
}
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue