lottie: optimize the rendering by preventing partial rendering branches.

this optimization is to figure out if this group is a simple path drawing.
In that case, the rendering context can be sharable with the parent's.
This commit is contained in:
Hermet Park 2024-03-28 12:03:29 +09:00
parent f0527a2304
commit 40647d5882
2 changed files with 32 additions and 5 deletions

View file

@ -142,13 +142,20 @@ void LottieGroup::prepare(LottieObject::Type type)
size_t fillCnt = 0;
for (auto c = children.end() - 1; c >= children.begin(); --c) {
if (reqFragment) break;
if (!mergeable && reqFragment) break;
auto child = static_cast<LottieObject*>(*c);
/* Figure out if this group is a simple path drawing.
In that case, the rendering context can be sharable with the parent's. */
if (mergeable && !child->mergeable()) mergeable = false;
if (reqFragment) continue;
/* Figure out if the rendering context should be fragmented.
Multiple stroking or grouping with a stroking would occur this.
This fragment resolves the overlapped stroke outlines. */
if (reqFragment) continue;
if (child->type == LottieObject::Group) {
if (child->type == LottieObject::Group && !static_cast<LottieGroup*>(child)->mergeable) {
if (strokeCnt > 0 || fillCnt > 0) reqFragment = true;
} else if (child->type == LottieObject::SolidStroke || child->type == LottieObject::GradientStroke) {
if (strokeCnt > 0) reqFragment = true;

View file

@ -124,6 +124,8 @@ struct LottieObject
TVGERR("LOTTIE", "Unsupported slot type");
}
virtual bool mergeable() { return false; }
char* name = nullptr;
Type type;
bool hidden = false; //remove?
@ -195,17 +197,23 @@ struct LottieText : LottieObject
struct LottieTrimpath : LottieObject
{
enum Type : uint8_t { Individual = 1, Simultaneous = 2 };
enum Type : uint8_t { Simultaneous = 1, Individual = 2 };
void prepare()
{
LottieObject::type = LottieObject::Trimpath;
}
bool mergeable() override
{
if (!start.frames && start.value == 0.0f && !end.frames && end.value == 100.0f && !offset.frames && offset.value == 0.0f) return true;
return false;
}
void segment(float frameNo, float& start, float& end);
LottieFloat start = 0.0f;
LottieFloat end = 0.0f;
LottieFloat end = 100.0f;
LottieFloat offset = 0.0f;
Type type = Simultaneous;
};
@ -215,6 +223,11 @@ struct LottieShape : LottieObject
{
virtual ~LottieShape() {}
uint8_t direction = 0; //0: clockwise, 2: counter-clockwise, 3: xor(?)
bool mergeable() override
{
return true;
}
};
@ -309,6 +322,12 @@ struct LottieTransform : LottieObject
LottieObject::type = LottieObject::Transform;
}
bool mergeable() override
{
if (!opacity.frames && opacity.value == 255) return true;
return false;
}
LottiePosition position = Point{0.0f, 0.0f};
LottieFloat rotation = 0.0f; //z rotation
LottiePoint scale = Point{100.0f, 100.0f};
@ -559,6 +578,7 @@ struct LottieGroup : LottieObject
bool reqFragment = false; //requirment to fragment the render context
bool buildDone = false; //completed in building the composition.
bool mergeable = true; //if this group is consisted of simple (transformed) shapes.
};