mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
loader/lottie: revised the key-frame searching
Replace the linear search algorithm with binary-search. The performance enhancement may not yield significant benefits in normal cases. However, it becomes crucial if the animation comprises an extensive number of frames...
This commit is contained in:
parent
345b867c38
commit
4127f4ce7a
1 changed files with 87 additions and 48 deletions
|
@ -183,12 +183,19 @@ struct LottieProperty
|
|||
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
|
||||
if (frameNo >= frames->last().no) return frames->last().value;
|
||||
|
||||
for (auto frame = frames->data + 1; frame < frames->end(); ++frame) {
|
||||
if (frameNo > frame->no) continue;
|
||||
uint32_t low = 1;
|
||||
uint32_t high = frames->count - 1;
|
||||
|
||||
while (low <= high) {
|
||||
auto mid = low + (high - low) / 2;
|
||||
auto frame = frames->data + mid;
|
||||
if (frameNo == frame->no) return frame->value;
|
||||
return (frame - 1)->interpolate(frame, frameNo);
|
||||
else if (frameNo > frame->no) low = mid + 1;
|
||||
else high = mid - 1;
|
||||
}
|
||||
return value;
|
||||
|
||||
auto frame = frames->data + low;
|
||||
return (frame - 1)->interpolate(frame, frameNo);
|
||||
}
|
||||
|
||||
float angle(int32_t frameNo) { return 0; }
|
||||
|
@ -258,14 +265,25 @@ struct LottiePathSet
|
|||
return true;
|
||||
}
|
||||
|
||||
for (auto frame = frames->data + 1; frame < frames->end(); ++frame) {
|
||||
if (frameNo > frame->no) continue;
|
||||
uint32_t low = 1;
|
||||
uint32_t high = frames->count - 1;
|
||||
|
||||
while (low <= high) {
|
||||
auto mid = low + (high - low) / 2;
|
||||
auto frame = frames->data + mid;
|
||||
if (frameNo == frame->no) {
|
||||
copy(frame->value, cmds);
|
||||
copy(frame->value, pts);
|
||||
return true;
|
||||
} else if (frameNo > frame->no) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
//interpolate
|
||||
auto frame = frames->data + low;
|
||||
auto pframe = frame - 1;
|
||||
copy(pframe->value, cmds);
|
||||
|
||||
|
@ -280,8 +298,6 @@ struct LottiePathSet
|
|||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void prepare() {}
|
||||
};
|
||||
|
@ -340,14 +356,24 @@ struct LottieColorStop
|
|||
return;
|
||||
}
|
||||
|
||||
for (auto frame = frames->data + 1; frame < frames->end(); ++frame) {
|
||||
if (frameNo > frame->no) continue;
|
||||
uint32_t low = 1;
|
||||
uint32_t high = frames->count - 1;
|
||||
|
||||
while (low <= high) {
|
||||
auto mid = low + (high - low) / 2;
|
||||
auto frame = frames->data + mid;
|
||||
if (frameNo == frame->no) {
|
||||
fill->colorStops(frame->value.data, count);
|
||||
return;
|
||||
} else if (frameNo > frame->no) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
//interpolate
|
||||
auto frame = frames->data + low;
|
||||
auto pframe = frame - 1;
|
||||
auto t = float(frameNo - pframe->no) / float(frame->no - pframe->no);
|
||||
if (pframe->interpolator) t = pframe->interpolator->progress(t);
|
||||
|
@ -365,9 +391,8 @@ struct LottieColorStop
|
|||
result.push({offset, r, g, b, 255});
|
||||
}
|
||||
fill->colorStops(result.data, count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void prepare() {}
|
||||
};
|
||||
|
||||
|
@ -409,12 +434,19 @@ struct LottiePosition
|
|||
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
|
||||
if (frameNo >= frames->last().no) return frames->last().value;
|
||||
|
||||
for (auto frame = frames->data + 1; frame < frames->end(); ++frame) {
|
||||
if (frameNo > frame->no) continue;
|
||||
uint32_t low = 1;
|
||||
uint32_t high = frames->count - 1;
|
||||
|
||||
while (low <= high) {
|
||||
auto mid = low + (high - low) / 2;
|
||||
auto frame = frames->data + mid;
|
||||
if (frameNo == frame->no) return frame->value;
|
||||
return (frame - 1)->interpolate(frame, frameNo);
|
||||
else if (frameNo > frame->no) low = mid + 1;
|
||||
else high = mid - 1;
|
||||
}
|
||||
return value;
|
||||
|
||||
auto frame = frames->data + low;
|
||||
return (frame - 1)->interpolate(frame, frameNo);
|
||||
}
|
||||
|
||||
float angle(int32_t frameNo)
|
||||
|
@ -423,11 +455,18 @@ struct LottiePosition
|
|||
if (frames->count == 1 || frameNo <= frames->first().no) return 0;
|
||||
if (frameNo >= frames->last().no) return 0;
|
||||
|
||||
for (auto frame = frames->data + 1; frame < frames->end(); ++frame) {
|
||||
if (frameNo > frame->no) continue;
|
||||
return (frame - 1)->angle(frame, frameNo);
|
||||
uint32_t low = 1;
|
||||
uint32_t high = frames->count - 1;
|
||||
|
||||
while (low <= high) {
|
||||
auto mid = low + (high - low) / 2;
|
||||
auto frame = frames->data + mid;
|
||||
if (frameNo > frame->no) low = mid + 1;
|
||||
else high = mid - 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
auto frame = frames->data + low;
|
||||
return (frame - 1)->angle(frame, frameNo);
|
||||
}
|
||||
|
||||
void prepare()
|
||||
|
|
Loading…
Add table
Reference in a new issue