[sksg] Switch containers from SkT(D)Array to std::vector
Skia's containers grow too aggressively, stick to STL containers for
reduced head overhead.
Also introduce Group::shrink_to_fit() to be used when clients know they
are done adding children to a group.
TBR=
Bug: skia:8340
Change-Id: I842db2e80c7cfb65a462e4859af6e63496863a5c
Reviewed-on: https://skia-review.googlesource.com/151161
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/skottie/src/SkottieLayer.cpp b/modules/skottie/src/SkottieLayer.cpp
index 7b09ddc..a79a47f 100644
--- a/modules/skottie/src/SkottieLayer.cpp
+++ b/modules/skottie/src/SkottieLayer.cpp
@@ -157,6 +157,7 @@
std::move(rec.mask_paint)));
}
+ mask_group->shrink_to_fit();
return sksg::MaskEffect::Make(std::move(childNode), std::move(mask_group));
}
@@ -519,6 +520,7 @@
for (int i = layers.count() - 1; i >= 0; --i) {
comp_group->addChild(std::move(layers[i]));
}
+ comp_group->shrink_to_fit();
return std::move(comp_group);
}
diff --git a/modules/skottie/src/SkottieShapeLayer.cpp b/modules/skottie/src/SkottieShapeLayer.cpp
index 54f7675..0da8b15 100644
--- a/modules/skottie/src/SkottieShapeLayer.cpp
+++ b/modules/skottie/src/SkottieShapeLayer.cpp
@@ -586,6 +586,7 @@
for (auto it = draws.rbegin(); it != draws.rend(); ++it) {
shape_group->addChild(std::move(*it));
}
+ shape_group->shrink_to_fit();
return draws.empty() ? nullptr : shape_wrapper;
}
diff --git a/modules/sksg/include/SkSGGroup.h b/modules/sksg/include/SkSGGroup.h
index 3b8de32..04506dc 100644
--- a/modules/sksg/include/SkSGGroup.h
+++ b/modules/sksg/include/SkSGGroup.h
@@ -9,8 +9,8 @@
#define SkSGGroup_DEFINED
#include "SkSGRenderNode.h"
-#include "SkTArray.h"
-#include "SkTo.h"
+
+#include <vector>
namespace sksg {
@@ -26,9 +26,11 @@
void addChild(sk_sp<RenderNode>);
void removeChild(const sk_sp<RenderNode>&);
- size_t size() const { return SkTo<size_t>(fChildren.count()); }
+ size_t size() const { return fChildren.size(); }
bool empty() const { return fChildren.empty(); }
+ void shrink_to_fit();
+
protected:
Group();
~Group() override;
@@ -37,7 +39,7 @@
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
private:
- SkTArray<sk_sp<RenderNode>, true> fChildren;
+ std::vector<sk_sp<RenderNode>> fChildren;
typedef RenderNode INHERITED;
};
diff --git a/modules/sksg/include/SkSGNode.h b/modules/sksg/include/SkSGNode.h
index 17619de..63b8d1e 100644
--- a/modules/sksg/include/SkSGNode.h
+++ b/modules/sksg/include/SkSGNode.h
@@ -10,7 +10,8 @@
#include "SkRect.h"
#include "SkRefCnt.h"
-#include "SkTDArray.h"
+
+#include <vector>
class SkCanvas;
class SkMatrix;
@@ -75,12 +76,12 @@
class ScopedFlag;
union {
- Node* fInvalObserver;
- SkTDArray<Node*>* fInvalObserverArray;
+ Node* fInvalObserver;
+ std::vector<Node*>* fInvalObserverArray;
};
- SkRect fBounds;
- const uint32_t fInvalTraits : 16;
- uint32_t fFlags : 16;
+ SkRect fBounds;
+ const uint32_t fInvalTraits : 16;
+ uint32_t fFlags : 16;
typedef SkRefCnt INHERITED;
};
diff --git a/modules/sksg/src/SkSGGroup.cpp b/modules/sksg/src/SkSGGroup.cpp
index 9911292..2c0a9d7 100644
--- a/modules/sksg/src/SkSGGroup.cpp
+++ b/modules/sksg/src/SkSGGroup.cpp
@@ -7,6 +7,8 @@
#include "SkSGGroup.h"
+#include <algorithm>
+
namespace sksg {
Group::Group() {}
@@ -32,24 +34,22 @@
}
void Group::removeChild(const sk_sp<RenderNode>& node) {
- int origCount = fChildren.count();
- for (int i = 0; i < origCount; ++i) {
- if (fChildren[i] == node) {
- fChildren.removeShuffle(i);
- this->unobserveInval(node);
- break;
- }
- }
- SkASSERT(fChildren.count() == origCount - 1);
+ SkDEBUGCODE(const auto origSize = fChildren.size());
+ fChildren.erase(std::remove(fChildren.begin(), fChildren.end(), node), fChildren.end());
+ SkASSERT(fChildren.size() == origSize - 1);
this->invalidate();
}
+void Group::shrink_to_fit() {
+ fChildren.shrink_to_fit();
+}
+
void Group::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
// TODO: this heuristic works at the moment, but:
// a) it is fragile because it relies on all leaf render nodes being atomic draws
// b) could be improved by e.g. detecting all leaf render draws are non-overlapping
- const auto isolate = fChildren.count() > 1;
+ const auto isolate = fChildren.size() > 1;
const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(), isolate);
for (const auto& child : fChildren) {
diff --git a/modules/sksg/src/SkSGNode.cpp b/modules/sksg/src/SkSGNode.cpp
index 0cb578e..59ce87b 100644
--- a/modules/sksg/src/SkSGNode.cpp
+++ b/modules/sksg/src/SkSGNode.cpp
@@ -9,6 +9,8 @@
#include "SkSGNode.h"
#include "SkSGInvalidationController.h"
+#include <algorithm>
+
namespace sksg {
class Node::ScopedFlag {
@@ -46,7 +48,7 @@
Node::~Node() {
if (fFlags & kObserverArray_Flag) {
- SkASSERT(fInvalObserverArray->isEmpty());
+ SkASSERT(fInvalObserverArray->empty());
delete fInvalObserverArray;
} else {
SkASSERT(!fInvalObserver);
@@ -61,8 +63,8 @@
return;
}
- auto observers = new SkTDArray<Node*>();
- observers->setReserve(2);
+ auto observers = new std::vector<Node*>();
+ observers->reserve(2);
observers->push_back(node->fInvalObserver);
node->fInvalObserverArray = observers;
@@ -70,7 +72,8 @@
}
// No duplicate observers.
- SkASSERT(node->fInvalObserverArray->find(this) < 0);
+ SkASSERT(std::find(node->fInvalObserverArray->begin(),
+ node->fInvalObserverArray->end(), this) == node->fInvalObserverArray->end());
node->fInvalObserverArray->push_back(this);
}
@@ -83,9 +86,11 @@
return;
}
- const auto idx = node->fInvalObserverArray->find(this);
- SkASSERT(idx >= 0);
- node->fInvalObserverArray->remove(idx);
+ SkDEBUGCODE(const auto origSize = node->fInvalObserverArray->size());
+ node->fInvalObserverArray->erase(std::remove(node->fInvalObserverArray->begin(),
+ node->fInvalObserverArray->end(), this),
+ node->fInvalObserverArray->end());
+ SkASSERT(node->fInvalObserverArray->size() == origSize - 1);
}
template <typename Func>