|
24 | 24 | #include "SkSGTransform.h"
|
25 | 25 | #include "SkSGTrimEffect.h"
|
26 | 26 |
|
| 27 | +#include <iterator> |
| 28 | + |
27 | 29 | namespace skottie {
|
28 | 30 | namespace internal {
|
29 | 31 |
|
@@ -452,9 +454,7 @@ sk_sp<sksg::RenderNode> AttachShape(const skjson::ArrayValue* jshape, AttachShap
|
452 | 454 |
|
453 | 455 | SkDEBUGCODE(const auto initialGeometryEffects = ctx->fGeometryEffectStack->size();)
|
454 | 456 |
|
455 |
| - sk_sp<sksg::Group> shape_group = sksg::Group::Make(); |
456 |
| - sk_sp<sksg::RenderNode> shape_wrapper = shape_group; |
457 |
| - sk_sp<sksg::Matrix> shape_matrix; |
| 457 | + const skjson::ObjectValue* jtransform = nullptr; |
458 | 458 |
|
459 | 459 | struct ShapeRec {
|
460 | 460 | const skjson::ObjectValue& fJson;
|
@@ -482,11 +482,8 @@ sk_sp<sksg::RenderNode> AttachShape(const skjson::ArrayValue* jshape, AttachShap
|
482 | 482 |
|
483 | 483 | switch (info->fShapeType) {
|
484 | 484 | case ShapeType::kTransform:
|
485 |
| - if ((shape_matrix = ctx->fBuilder->attachMatrix(*shape, ctx->fScope, nullptr))) { |
486 |
| - shape_wrapper = sksg::Transform::Make(std::move(shape_wrapper), shape_matrix); |
487 |
| - } |
488 |
| - shape_wrapper = ctx->fBuilder->attachOpacity(*shape, ctx->fScope, |
489 |
| - std::move(shape_wrapper)); |
| 485 | + // Just track the transform property for now -- we'll deal with it later. |
| 486 | + jtransform = shape; |
490 | 487 | break;
|
491 | 488 | case ShapeType::kGeometryEffect:
|
492 | 489 | SkASSERT(info->fAttacherIndex < SK_ARRAY_COUNT(gGeometryEffectAttachers));
|
@@ -575,20 +572,50 @@ sk_sp<sksg::RenderNode> AttachShape(const skjson::ArrayValue* jshape, AttachShap
|
575 | 572 | // By now we should have popped all local geometry effects.
|
576 | 573 | SkASSERT(ctx->fGeometryEffectStack->size() == initialGeometryEffects);
|
577 | 574 |
|
| 575 | + sk_sp<sksg::RenderNode> shape_wrapper; |
| 576 | + if (draws.size() == 1) { |
| 577 | + // For a single draw, we don't need a group. |
| 578 | + shape_wrapper = std::move(draws.front()); |
| 579 | + } else if (!draws.empty()) { |
| 580 | + // We need a group to dispatch multiple draws. |
| 581 | + auto group = sksg::Group::Make(); |
| 582 | + |
| 583 | + // Emit local draws reversed (bottom->top, per spec). |
| 584 | + for (auto it = draws.rbegin(); it != draws.rend(); ++it) { |
| 585 | + group->addChild(std::move(*it)); |
| 586 | + } |
| 587 | + group->shrink_to_fit(); |
| 588 | + |
| 589 | + shape_wrapper = std::move(group); |
| 590 | + } |
| 591 | + |
| 592 | + sk_sp<sksg::Matrix> shape_matrix; |
| 593 | + if (jtransform) { |
| 594 | + // This is tricky due to the interaction with ctx->fCommittedAnimators: we want any |
| 595 | + // animators related to tranform/opacity to be committed => they must be inserted in front |
| 596 | + // of the dangling/uncommitted ones. |
| 597 | + AnimatorScope local_scope; |
| 598 | + |
| 599 | + if ((shape_matrix = ctx->fBuilder->attachMatrix(*jtransform, &local_scope, nullptr))) { |
| 600 | + shape_wrapper = sksg::Transform::Make(std::move(shape_wrapper), shape_matrix); |
| 601 | + } |
| 602 | + shape_wrapper = ctx->fBuilder->attachOpacity(*jtransform, &local_scope, |
| 603 | + std::move(shape_wrapper)); |
| 604 | + |
| 605 | + ctx->fScope->insert(ctx->fScope->begin() + ctx->fCommittedAnimators, |
| 606 | + std::make_move_iterator(local_scope.begin()), |
| 607 | + std::make_move_iterator(local_scope.end())); |
| 608 | + ctx->fCommittedAnimators += local_scope.size(); |
| 609 | + } |
| 610 | + |
578 | 611 | // Push transformed local geometries to parent list, for subsequent paints.
|
579 | 612 | for (const auto& geo : geos) {
|
580 | 613 | ctx->fGeometryStack->push_back(shape_matrix
|
581 | 614 | ? sksg::GeometryTransform::Make(std::move(geo), shape_matrix)
|
582 | 615 | : std::move(geo));
|
583 | 616 | }
|
584 | 617 |
|
585 |
| - // Emit local draws reversed (bottom->top, per spec). |
586 |
| - for (auto it = draws.rbegin(); it != draws.rend(); ++it) { |
587 |
| - shape_group->addChild(std::move(*it)); |
588 |
| - } |
589 |
| - shape_group->shrink_to_fit(); |
590 |
| - |
591 |
| - return draws.empty() ? nullptr : shape_wrapper; |
| 618 | + return shape_wrapper; |
592 | 619 | }
|
593 | 620 |
|
594 | 621 | } // namespace
|
|
0 commit comments