Create SkLayerRasterizer w/o destroying Builder.
Add a new method to SkLayerRasterizer::Builder that creates a new
SkLayerRasterizer without destroying the Builder. Necessary to
continue to support Android's API.
Also fix a bug where creating a Builder and never calling
detachRasterizer results in not calling the destructor for any SkPaints
in the Builder.
Add tests.
BUG=b/13729784
R=reed@google.com, dominikg@chromium.org
Author: scroggo@google.com
Review URL: https://codereview.chromium.org/233673002
git-svn-id: http://skia.googlecode.com/svn/trunk@14139 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkLayerRasterizer.cpp b/src/effects/SkLayerRasterizer.cpp
index e35c5e8..7143a3b 100644
--- a/src/effects/SkLayerRasterizer.cpp
+++ b/src/effects/SkLayerRasterizer.cpp
@@ -34,15 +34,20 @@
{
}
-SkLayerRasterizer::~SkLayerRasterizer() {
- SkASSERT(fLayers);
- SkDeque::F2BIter iter(*fLayers);
+// Helper function to call destructors on SkPaints held by layers and delete layers.
+static void clean_up_layers(SkDeque* layers) {
+ SkDeque::F2BIter iter(*layers);
SkLayerRasterizer_Rec* rec;
while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL)
rec->fPaint.~SkPaint();
- SkDELETE(fLayers);
+ SkDELETE(layers);
+}
+
+SkLayerRasterizer::~SkLayerRasterizer() {
+ SkASSERT(fLayers);
+ clean_up_layers(const_cast<SkDeque*>(fLayers));
}
#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
@@ -194,7 +199,9 @@
SkLayerRasterizer::Builder::~Builder()
{
- SkDELETE(fLayers);
+ if (fLayers != NULL) {
+ clean_up_layers(fLayers);
+ }
}
void SkLayerRasterizer::Builder::addLayer(const SkPaint& paint, SkScalar dx,
@@ -211,3 +218,20 @@
fLayers = NULL;
return rasterizer;
}
+
+SkLayerRasterizer* SkLayerRasterizer::Builder::snapshotRasterizer() const {
+ SkDeque* layers = SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec), fLayers->count()));
+ SkDeque::F2BIter iter(*fLayers);
+ const SkLayerRasterizer_Rec* recOrig;
+ SkDEBUGCODE(int count = 0;)
+ while ((recOrig = static_cast<SkLayerRasterizer_Rec*>(iter.next())) != NULL) {
+ SkDEBUGCODE(count++);
+ SkLayerRasterizer_Rec* recCopy = static_cast<SkLayerRasterizer_Rec*>(layers->push_back());
+ SkNEW_PLACEMENT_ARGS(&recCopy->fPaint, SkPaint, (recOrig->fPaint));
+ recCopy->fOffset = recOrig->fOffset;
+ }
+ SkASSERT(fLayers->count() == count);
+ SkASSERT(layers->count() == count);
+ SkLayerRasterizer* rasterizer = SkNEW_ARGS(SkLayerRasterizer, (layers));
+ return rasterizer;
+}