OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 The Android Open Source Project |
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 | 7 |
8 | 8 |
9 #include "SkPictureFlat.h" | 9 #include "SkPictureFlat.h" |
10 #include "SkPictureData.h" | 10 #include "SkPictureData.h" |
11 #include "SkPicturePlayback.h" | 11 #include "SkPicturePlayback.h" |
12 #include "SkPictureRecord.h" | 12 #include "SkPictureRecord.h" |
13 #include "SkPictureRecorder.h" | 13 #include "SkPictureRecorder.h" |
14 | 14 |
| 15 #include "SkAtomics.h" |
15 #include "SkBitmapDevice.h" | 16 #include "SkBitmapDevice.h" |
16 #include "SkCanvas.h" | 17 #include "SkCanvas.h" |
17 #include "SkChunkAlloc.h" | 18 #include "SkChunkAlloc.h" |
18 #include "SkMessageBus.h" | 19 #include "SkMessageBus.h" |
19 #include "SkPaintPriv.h" | 20 #include "SkPaintPriv.h" |
20 #include "SkPathEffect.h" | 21 #include "SkPathEffect.h" |
21 #include "SkPicture.h" | 22 #include "SkPicture.h" |
22 #include "SkRegion.h" | 23 #include "SkRegion.h" |
23 #include "SkShader.h" | 24 #include "SkShader.h" |
24 #include "SkStream.h" | 25 #include "SkStream.h" |
(...skipping 14 matching lines...) Expand all Loading... |
39 #include "SkRecordDraw.h" | 40 #include "SkRecordDraw.h" |
40 #include "SkRecordOpts.h" | 41 #include "SkRecordOpts.h" |
41 #include "SkRecorder.h" | 42 #include "SkRecorder.h" |
42 | 43 |
43 DECLARE_SKMESSAGEBUS_MESSAGE(SkPicture::DeletionMessage); | 44 DECLARE_SKMESSAGEBUS_MESSAGE(SkPicture::DeletionMessage); |
44 | 45 |
45 template <typename T> int SafeCount(const T* obj) { | 46 template <typename T> int SafeCount(const T* obj) { |
46 return obj ? obj->count() : 0; | 47 return obj ? obj->count() : 0; |
47 } | 48 } |
48 | 49 |
49 static int32_t gPictureGenerationID; | |
50 | |
51 // never returns a 0 | |
52 static int32_t next_picture_generation_id() { | |
53 // Loop in case our global wraps around. | |
54 int32_t genID; | |
55 do { | |
56 genID = sk_atomic_inc(&gPictureGenerationID) + 1; | |
57 } while (0 == genID); | |
58 return genID; | |
59 } | |
60 | |
61 /////////////////////////////////////////////////////////////////////////////// | 50 /////////////////////////////////////////////////////////////////////////////// |
62 | 51 |
63 namespace { | 52 namespace { |
64 | 53 |
65 // Some commands have a paint, some have an optional paint. Either way, get bac
k a pointer. | 54 // Some commands have a paint, some have an optional paint. Either way, get bac
k a pointer. |
66 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } | 55 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } |
67 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; } | 56 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; } |
68 | 57 |
69 /** SkRecords visitor to determine whether an instance may require an | 58 /** SkRecords visitor to determine whether an instance may require an |
70 "external" bitmap to rasterize. May return false positives. | 59 "external" bitmap to rasterize. May return false positives. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 int sampleCount) const { | 229 int sampleCount) const { |
241 // TODO: the heuristic used here needs to be refined | 230 // TODO: the heuristic used here needs to be refined |
242 static const int kNumSlowPathsTol = 6; | 231 static const int kNumSlowPathsTol = 6; |
243 | 232 |
244 int numSlowPathDashedPaths = fNumPaintWithPathEffectUses; | 233 int numSlowPathDashedPaths = fNumPaintWithPathEffectUses; |
245 if (0 == sampleCount) { | 234 if (0 == sampleCount) { |
246 // The fast dashing path only works when MSAA is disabled | 235 // The fast dashing path only works when MSAA is disabled |
247 numSlowPathDashedPaths -= fNumFastPathDashEffects; | 236 numSlowPathDashedPaths -= fNumFastPathDashEffects; |
248 } | 237 } |
249 | 238 |
250 int numSlowPaths = fNumAAConcavePaths - | 239 int numSlowPaths = fNumAAConcavePaths - |
251 fNumAAHairlineConcavePaths - | 240 fNumAAHairlineConcavePaths - |
252 fNumAADFEligibleConcavePaths; | 241 fNumAADFEligibleConcavePaths; |
253 | 242 |
254 bool ret = numSlowPathDashedPaths + numSlowPaths < kNumSlowPathsTol; | 243 bool ret = numSlowPathDashedPaths + numSlowPaths < kNumSlowPathsTol; |
255 | 244 |
256 if (!ret && reason) { | 245 if (!ret && reason) { |
257 *reason = "Too many slow paths (either concave or dashed)."; | 246 *reason = "Too many slow paths (either concave or dashed)."; |
258 } | 247 } |
259 return ret; | 248 return ret; |
260 } | 249 } |
261 | 250 |
262 /////////////////////////////////////////////////////////////////////////////// | 251 /////////////////////////////////////////////////////////////////////////////// |
263 | 252 |
264 int SkPicture::drawableCount() const { | 253 int SkPicture::drawableCount() const { |
265 return fDrawablePicts.get() ? fDrawablePicts->count() : 0; | 254 return fDrawablePicts.get() ? fDrawablePicts->count() : 0; |
266 } | 255 } |
267 | 256 |
268 SkPicture const* const* SkPicture::drawablePicts() const { | 257 SkPicture const* const* SkPicture::drawablePicts() const { |
269 return fDrawablePicts.get() ? fDrawablePicts->begin() : NULL; | 258 return fDrawablePicts.get() ? fDrawablePicts->begin() : NULL; |
270 } | 259 } |
271 | 260 |
272 SkPicture::~SkPicture() { | 261 SkPicture::~SkPicture() { |
273 SkPicture::DeletionMessage msg; | 262 // If the ID is still zero, no one has read it, so no need to send this mess
age. |
274 msg.fUniqueID = this->uniqueID(); | 263 uint32_t id = sk_atomic_load(&fUniqueID, sk_memory_order_relaxed); |
275 SkMessageBus<SkPicture::DeletionMessage>::Post(msg); | 264 if (id != 0) { |
| 265 SkPicture::DeletionMessage msg; |
| 266 msg.fUniqueID = id; |
| 267 SkMessageBus<SkPicture::DeletionMessage>::Post(msg); |
| 268 } |
276 } | 269 } |
277 | 270 |
278 void SkPicture::EXPERIMENTAL_addAccelData(const SkPicture::AccelData* data) cons
t { | 271 void SkPicture::EXPERIMENTAL_addAccelData(const SkPicture::AccelData* data) cons
t { |
279 fAccelData.reset(SkRef(data)); | 272 fAccelData.reset(SkRef(data)); |
280 } | 273 } |
281 | 274 |
282 const SkPicture::AccelData* SkPicture::EXPERIMENTAL_getAccelData( | 275 const SkPicture::AccelData* SkPicture::EXPERIMENTAL_getAccelData( |
283 SkPicture::AccelData::Key key) const { | 276 SkPicture::AccelData::Key key) const { |
284 if (fAccelData.get() && fAccelData->getKey() == key) { | 277 if (fAccelData.get() && fAccelData->getKey() == key) { |
285 return fAccelData.get(); | 278 return fAccelData.get(); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 return fAnalysis.suitableForGpuRasterization(reason, 0); | 474 return fAnalysis.suitableForGpuRasterization(reason, 0); |
482 } | 475 } |
483 #endif | 476 #endif |
484 | 477 |
485 bool SkPicture::hasText() const { return fAnalysis.fHasText; } | 478 bool SkPicture::hasText() const { return fAnalysis.fHasText; } |
486 bool SkPicture::willPlayBackBitmaps() const { return fAnalysis.fWillPlaybackBitm
aps; } | 479 bool SkPicture::willPlayBackBitmaps() const { return fAnalysis.fWillPlaybackBitm
aps; } |
487 int SkPicture::approximateOpCount() const { return fRecord->count(); } | 480 int SkPicture::approximateOpCount() const { return fRecord->count(); } |
488 | 481 |
489 SkPicture::SkPicture(const SkRect& cullRect, SkRecord* record, SnapshotArray* dr
awablePicts, | 482 SkPicture::SkPicture(const SkRect& cullRect, SkRecord* record, SnapshotArray* dr
awablePicts, |
490 SkBBoxHierarchy* bbh) | 483 SkBBoxHierarchy* bbh) |
491 : fUniqueID(next_picture_generation_id()) | 484 : fUniqueID(0) |
492 , fCullRect(cullRect) | 485 , fCullRect(cullRect) |
493 , fRecord(SkRef(record)) | 486 , fRecord(SkRef(record)) |
494 , fBBH(SkSafeRef(bbh)) | 487 , fBBH(SkSafeRef(bbh)) |
495 , fDrawablePicts(drawablePicts) // take ownership | 488 , fDrawablePicts(drawablePicts) // take ownership |
496 , fAnalysis(*fRecord) | 489 , fAnalysis(*fRecord) |
497 {} | 490 {} |
| 491 |
| 492 |
| 493 static uint32_t gNextID = 1; |
| 494 uint32_t SkPicture::uniqueID() const { |
| 495 uint32_t id = sk_atomic_load(&fUniqueID, sk_memory_order_relaxed); |
| 496 while (id == 0) { |
| 497 uint32_t next = sk_atomic_fetch_add(&gNextID, 1u); |
| 498 if (sk_atomic_compare_exchange(&fUniqueID, &id, next, |
| 499 sk_memory_order_relaxed, |
| 500 sk_memory_order_relaxed)) { |
| 501 id = next; |
| 502 } else { |
| 503 // sk_atomic_compare_exchange replaced id with the current value of
fUniqueID. |
| 504 } |
| 505 } |
| 506 return id; |
| 507 } |
OLD | NEW |