| Index: src/core/SkPicture.cpp
|
| ===================================================================
|
| --- src/core/SkPicture.cpp (revision 14435)
|
| +++ src/core/SkPicture.cpp (working copy)
|
| @@ -217,6 +217,26 @@
|
| return clonedPicture;
|
| }
|
|
|
| +static bool needs_deep_copy(const SkPaint& paint) {
|
| + /*
|
| + * These fields are known to be immutable, and so can be shallow-copied
|
| + *
|
| + * getTypeface()
|
| + * getAnnotation()
|
| + * paint.getColorFilter()
|
| + * getXfermode()
|
| + * getPathEffect()
|
| + * getMaskFilter()
|
| + */
|
| +
|
| + return paint.getShader() ||
|
| +#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API
|
| + paint.getRasterizer() ||
|
| +#endif
|
| + paint.getLooper() || // needs to hide its addLayer...
|
| + paint.getImageFilter();
|
| +}
|
| +
|
| void SkPicture::clone(SkPicture* pictures, int count) const {
|
| SkPictCopyInfo copyInfo;
|
| SkPictInfo info;
|
| @@ -237,6 +257,48 @@
|
| it (since it is destructive, and we don't want to change src).
|
| */
|
| if (fPlayback) {
|
| + if (!copyInfo.initialized) {
|
| + int paintCount = SafeCount(fPlayback->fPaints);
|
| +
|
| + /* The alternative to doing this is to have a clone method on the paint and have it
|
| + * make the deep copy of its internal structures as needed. The holdup to doing
|
| + * that is at this point we would need to pass the SkBitmapHeap so that we don't
|
| + * unnecessarily flatten the pixels in a bitmap shader.
|
| + */
|
| + copyInfo.paintData.setCount(paintCount);
|
| +
|
| + /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. If there already is
|
| + * one, use it. If this SkPicturePlayback was created from a stream, fBitmapHeap
|
| + * will be NULL, so create a new one.
|
| + */
|
| + if (fPlayback->fBitmapHeap.get() == NULL) {
|
| + // FIXME: Put this on the stack inside SkPicture::clone.
|
| + SkBitmapHeap* heap = SkNEW(SkBitmapHeap);
|
| + copyInfo.controller.setBitmapStorage(heap);
|
| + heap->unref();
|
| + } else {
|
| + copyInfo.controller.setBitmapStorage(fPlayback->fBitmapHeap);
|
| + }
|
| +
|
| + SkDEBUGCODE(int heapSize = SafeCount(fPlayback->fBitmapHeap.get());)
|
| + for (int i = 0; i < paintCount; i++) {
|
| + if (needs_deep_copy(fPlayback->fPaints->at(i))) {
|
| + copyInfo.paintData[i] =
|
| + SkFlatData::Create<SkPaint::FlatteningTraits>(©Info.controller,
|
| + fPlayback->fPaints->at(i), 0);
|
| +
|
| + } else {
|
| + // this is our sentinel, which we use in the unflatten loop
|
| + copyInfo.paintData[i] = NULL;
|
| + }
|
| + }
|
| + SkASSERT(SafeCount(fPlayback->fBitmapHeap.get()) == heapSize);
|
| +
|
| + // needed to create typeface playback
|
| + copyInfo.controller.setupPlaybacks();
|
| + copyInfo.initialized = true;
|
| + }
|
| +
|
| clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback, ©Info));
|
| SkASSERT(NULL == fRecord);
|
| clone->fUniqueID = this->uniqueID(); // need to call method to ensure != 0
|
|
|