OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include <new> | 7 #include <new> |
8 #include "SkBBoxHierarchy.h" | 8 #include "SkBBoxHierarchy.h" |
9 #include "SkPicturePlayback.h" | 9 #include "SkPicturePlayback.h" |
10 #include "SkPictureRecord.h" | 10 #include "SkPictureRecord.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 if (paths != 0) | 131 if (paths != 0) |
132 SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths); | 132 SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths); |
133 if (pictures != 0) | 133 if (pictures != 0) |
134 SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures); | 134 SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures); |
135 if (regions != 0) | 135 if (regions != 0) |
136 SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions); | 136 SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions); |
137 SkDebugf("\n"); | 137 SkDebugf("\n"); |
138 #endif | 138 #endif |
139 } | 139 } |
140 | 140 |
141 static bool needs_deep_copy(const SkPaint& paint) { | |
142 /* | |
143 * These fields are known to be immutable, and so can be shallow-copied | |
144 * | |
145 * getTypeface() | |
146 * getAnnotation() | |
147 * paint.getColorFilter() | |
148 * getXfermode() | |
149 * getPathEffect() | |
150 * getMaskFilter() | |
151 */ | |
152 | |
153 return paint.getShader() || | |
154 #ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API | |
155 paint.getRasterizer() || | |
156 #endif | |
157 paint.getLooper() || // needs to hide its addLayer... | |
158 paint.getImageFilter(); | |
159 } | |
160 | |
161 SkPicturePlayback::SkPicturePlayback(const SkPicture* picture, const SkPicturePl
ayback& src, | 141 SkPicturePlayback::SkPicturePlayback(const SkPicture* picture, const SkPicturePl
ayback& src, |
162 SkPictCopyInfo* deepCopyInfo) | 142 SkPictCopyInfo* deepCopyInfo) |
163 : fPicture(picture) | 143 : fPicture(picture) |
164 , fInfo(src.fInfo) { | 144 , fInfo(src.fInfo) { |
165 this->init(); | 145 this->init(); |
166 | 146 |
167 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); | 147 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); |
168 | 148 |
169 fOpData = SkSafeRef(src.fOpData); | 149 fOpData = SkSafeRef(src.fOpData); |
170 | 150 |
171 fBoundingHierarchy = src.fBoundingHierarchy; | 151 fBoundingHierarchy = src.fBoundingHierarchy; |
172 fStateTree = src.fStateTree; | 152 fStateTree = src.fStateTree; |
173 | 153 |
174 SkSafeRef(fBoundingHierarchy); | 154 SkSafeRef(fBoundingHierarchy); |
175 SkSafeRef(fStateTree); | 155 SkSafeRef(fStateTree); |
176 | 156 |
177 if (deepCopyInfo) { | 157 if (deepCopyInfo) { |
| 158 SkASSERT(deepCopyInfo->initialized); |
| 159 |
178 int paintCount = SafeCount(src.fPaints); | 160 int paintCount = SafeCount(src.fPaints); |
179 | 161 |
180 if (src.fBitmaps) { | 162 if (src.fBitmaps) { |
181 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.
fBitmaps->count()); | 163 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.
fBitmaps->count()); |
182 } | 164 } |
183 | 165 |
184 if (!deepCopyInfo->initialized) { | |
185 /* The alternative to doing this is to have a clone method on the pa
int and have it make | |
186 * the deep copy of its internal structures as needed. The holdup to
doing that is at | |
187 * this point we would need to pass the SkBitmapHeap so that we don'
t unnecessarily | |
188 * flatten the pixels in a bitmap shader. | |
189 */ | |
190 deepCopyInfo->paintData.setCount(paintCount); | |
191 | |
192 /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. If th
ere already is one, | |
193 * use it. If this SkPicturePlayback was created from a stream, fBit
mapHeap will be | |
194 * NULL, so create a new one. | |
195 */ | |
196 if (fBitmapHeap.get() == NULL) { | |
197 // FIXME: Put this on the stack inside SkPicture::clone. Further
, is it possible to | |
198 // do the rest of this initialization in SkPicture::clone as wel
l? | |
199 SkBitmapHeap* heap = SkNEW(SkBitmapHeap); | |
200 deepCopyInfo->controller.setBitmapStorage(heap); | |
201 heap->unref(); | |
202 } else { | |
203 deepCopyInfo->controller.setBitmapStorage(fBitmapHeap); | |
204 } | |
205 | |
206 SkDEBUGCODE(int heapSize = SafeCount(fBitmapHeap.get());) | |
207 for (int i = 0; i < paintCount; i++) { | |
208 if (needs_deep_copy(src.fPaints->at(i))) { | |
209 deepCopyInfo->paintData[i] = | |
210 SkFlatData::Create<SkPaint::FlatteningTraits>(&deepCopyI
nfo->controller, | |
211 src.fPaints->at(i), 0)
; | |
212 | |
213 } else { | |
214 // this is our sentinel, which we use in the unflatten loop | |
215 deepCopyInfo->paintData[i] = NULL; | |
216 } | |
217 } | |
218 SkASSERT(SafeCount(fBitmapHeap.get()) == heapSize); | |
219 | |
220 // needed to create typeface playback | |
221 deepCopyInfo->controller.setupPlaybacks(); | |
222 deepCopyInfo->initialized = true; | |
223 } | |
224 | |
225 fPaints = SkTRefArray<SkPaint>::Create(paintCount); | 166 fPaints = SkTRefArray<SkPaint>::Create(paintCount); |
226 SkASSERT(deepCopyInfo->paintData.count() == paintCount); | 167 SkASSERT(deepCopyInfo->paintData.count() == paintCount); |
227 SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap(); | 168 SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap(); |
228 SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePla
yback(); | 169 SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePla
yback(); |
229 for (int i = 0; i < paintCount; i++) { | 170 for (int i = 0; i < paintCount; i++) { |
230 if (deepCopyInfo->paintData[i]) { | 171 if (deepCopyInfo->paintData[i]) { |
231 deepCopyInfo->paintData[i]->unflatten<SkPaint::FlatteningTraits>
( | 172 deepCopyInfo->paintData[i]->unflatten<SkPaint::FlatteningTraits>
( |
232 &fPaints->writableAt(i), bmHeap, tfPlayback); | 173 &fPaints->writableAt(i), bmHeap, tfPlayback); |
233 } else { | 174 } else { |
234 // needs_deep_copy was false, so just need to assign | 175 // needs_deep_copy was false, so just need to assign |
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 for (index = 0; index < fPictureCount; index++) | 1712 for (index = 0; index < fPictureCount; index++) |
1772 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), | 1713 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), |
1773 "picture%p, ", fPictureRefs[index]); | 1714 "picture%p, ", fPictureRefs[index]); |
1774 if (fPictureCount > 0) | 1715 if (fPictureCount > 0) |
1775 SkDebugf("%s0};\n", pBuffer); | 1716 SkDebugf("%s0};\n", pBuffer); |
1776 | 1717 |
1777 const_cast<SkPicturePlayback*>(this)->dumpStream(); | 1718 const_cast<SkPicturePlayback*>(this)->dumpStream(); |
1778 } | 1719 } |
1779 | 1720 |
1780 #endif | 1721 #endif |
OLD | NEW |