common: improve thread safety for partial rendering
Some checks are pending
Android / build_x86_64 (push) Waiting to run
Android / build_aarch64 (push) Waiting to run
iOS / build_x86_64 (push) Waiting to run
iOS / build_arm64 (push) Waiting to run
macOS / build (push) Waiting to run
macOS / compact_test (push) Waiting to run
macOS / unit_test (push) Waiting to run
Ubuntu / build (push) Waiting to run
Ubuntu / compact_test (push) Waiting to run
Ubuntu / unit_test (push) Waiting to run
Windows / build (push) Waiting to run
Windows / compact_test (push) Waiting to run
Windows / unit_test (push) Waiting to run

- clear resources on the main thread to safely remove resources associated with dirty regions.
- skip redundant condition checks for unsafe disabled add calls.
This commit is contained in:
Hermet Park 2025-07-03 22:53:24 +09:00 committed by Hermet Park
parent 380d2c3f3f
commit f3fb04c63c
5 changed files with 13 additions and 10 deletions

View file

@ -1542,15 +1542,12 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
if (equal(frameNo, tween.frameNo)) offTween(); if (equal(frameNo, tween.frameNo)) offTween();
} }
//update children layers
auto root = comp->root;
root->scene->remove();
if (exps && comp->expressions) exps->update(comp->timeAtFrame(frameNo)); if (exps && comp->expressions) exps->update(comp->timeAtFrame(frameNo));
ARRAY_REVERSE_FOREACH(child, root->children) { //update children layers
ARRAY_REVERSE_FOREACH(child, comp->root->children) {
auto layer = static_cast<LottieLayer*>(*child); auto layer = static_cast<LottieLayer*>(*child);
if (!layer->matteSrc) updateLayer(comp, root->scene, layer, frameNo); if (!layer->matteSrc) updateLayer(comp, comp->root->scene, layer, frameNo);
} }
return true; return true;

View file

@ -347,6 +347,8 @@ bool LottieLoader::frame(float no)
builder->offTween(); builder->offTween();
if (comp) comp->clear(); //clear synchronously
TaskScheduler::request(this); TaskScheduler::request(this);
return true; return true;
@ -452,6 +454,8 @@ bool LottieLoader::tween(float from, float to, float progress)
builder->onTween(shorten(to), progress); builder->onTween(shorten(to), progress);
if (comp) comp->clear(); //clear synchronously
TaskScheduler::request(this); TaskScheduler::request(this);
return true; return true;

View file

@ -1089,6 +1089,11 @@ struct LottieComposition
{ {
~LottieComposition(); ~LottieComposition();
void clear()
{
if (root && root->scene) root->scene->remove();
}
float duration() const float duration() const
{ {
return frameCnt() / frameRate; // in second return frameCnt() / frameRate; // in second

View file

@ -384,7 +384,7 @@ bool SwRenderer::postRender()
void SwRenderer::damage(RenderData rd, const RenderRegion& region) void SwRenderer::damage(RenderData rd, const RenderRegion& region)
{ {
SwTask* task = static_cast<SwTask*>(rd); SwTask* task = static_cast<SwTask*>(rd);
if (task && task->opacity == 0) return; if (dirtyRegion.deactivated() || (task && task->opacity == 0)) return;
dirtyRegion.add(region); dirtyRegion.add(region);
} }

View file

@ -160,8 +160,6 @@ void RenderDirtyRegion::init(uint32_t w, uint32_t h)
bool RenderDirtyRegion::add(const RenderRegion& bbox) bool RenderDirtyRegion::add(const RenderRegion& bbox)
{ {
if (disabled) return false;
for (int idx = 0; idx < PARTITIONING; ++idx) { for (int idx = 0; idx < PARTITIONING; ++idx) {
auto& partition = partitions[idx]; auto& partition = partitions[idx];
if (bbox.max.y <= partition.region.min.y) break; if (bbox.max.y <= partition.region.min.y) break;
@ -176,7 +174,6 @@ bool RenderDirtyRegion::add(const RenderRegion& bbox)
bool RenderDirtyRegion::add(const RenderRegion& prv, const RenderRegion& cur) bool RenderDirtyRegion::add(const RenderRegion& prv, const RenderRegion& cur)
{ {
if (disabled) return false;
if (prv == cur) return add(prv); if (prv == cur) return add(prv);
for (int idx = 0; idx < PARTITIONING; ++idx) { for (int idx = 0; idx < PARTITIONING; ++idx) {