| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #ifndef SkPictureFlat_DEFINED | 8 #ifndef SkPictureFlat_DEFINED |
| 9 #define SkPictureFlat_DEFINED | 9 #define SkPictureFlat_DEFINED |
| 10 | 10 |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 | 385 |
| 386 /** | 386 /** |
| 387 * Clears the dictionary of all entries. However, it does NOT free the | 387 * Clears the dictionary of all entries. However, it does NOT free the |
| 388 * memory that was allocated for each entry (that's owned by controller). | 388 * memory that was allocated for each entry (that's owned by controller). |
| 389 */ | 389 */ |
| 390 void reset() { | 390 void reset() { |
| 391 fIndexedData.rewind(); | 391 fIndexedData.rewind(); |
| 392 // TODO(mtklein): There's no reason to have the index start from 1. Cle
an this up. | 392 // TODO(mtklein): There's no reason to have the index start from 1. Cle
an this up. |
| 393 // index 0 is always empty since it is used as a signal that find failed | 393 // index 0 is always empty since it is used as a signal that find failed |
| 394 fIndexedData.push(NULL); | 394 fIndexedData.push(NULL); |
| 395 fNextIndex = 1; | |
| 396 } | 395 } |
| 397 | 396 |
| 398 ~SkFlatDictionary() { | 397 ~SkFlatDictionary() { |
| 399 sk_free(fScratch); | 398 sk_free(fScratch); |
| 400 } | 399 } |
| 401 | 400 |
| 402 int count() const { | 401 int count() const { |
| 403 SkASSERT(fIndexedData.count() == fNextIndex); | 402 SkASSERT(fHash.count() == fIndexedData.count() - 1); |
| 404 SkASSERT(fHash.count() == fNextIndex - 1); | 403 return fHash.count(); |
| 405 return fNextIndex - 1; | |
| 406 } | 404 } |
| 407 | 405 |
| 408 // For testing only. Index is zero-based. | 406 // For testing only. Index is zero-based. |
| 409 const SkFlatData* operator[](int index) { | 407 const SkFlatData* operator[](int index) { |
| 410 return fIndexedData[index+1]; | 408 return fIndexedData[index+1]; |
| 411 } | 409 } |
| 412 | 410 |
| 413 /** | 411 /** |
| 414 * Given an element of type T return its 1-based index in the dictionary. If | 412 * Given an element of type T return its 1-based index in the dictionary. If |
| 415 * the element wasn't previously in the dictionary it is automatically | 413 * the element wasn't previously in the dictionary it is automatically |
| (...skipping 27 matching lines...) Expand all Loading... |
| 443 return flat; | 441 return flat; |
| 444 } | 442 } |
| 445 | 443 |
| 446 // If we don't have the thing to replace, we're done. | 444 // If we don't have the thing to replace, we're done. |
| 447 const SkFlatData* found = fHash.find(*toReplace); | 445 const SkFlatData* found = fHash.find(*toReplace); |
| 448 if (found == NULL) { | 446 if (found == NULL) { |
| 449 *replaced = false; | 447 *replaced = false; |
| 450 return flat; | 448 return flat; |
| 451 } | 449 } |
| 452 | 450 |
| 453 // findAndReturnMutableFlat gave us index (fNextIndex-1), but we'll use
the old one. | 451 // findAndReturnMutableFlat put flat at the back. Swap it into found->i
ndex() instead. |
| 454 fIndexedData.remove(flat->index()); | 452 SkASSERT(flat->index() == this->count()); |
| 455 fNextIndex--; | |
| 456 flat->setIndex(found->index()); | 453 flat->setIndex(found->index()); |
| 457 fIndexedData[flat->index()] = flat; | 454 fIndexedData.removeShuffle(found->index()); |
| 455 SkASSERT(flat == fIndexedData[found->index()]); |
| 458 | 456 |
| 459 // findAndReturnMutableFlat already called fHash.add(), so we just clean
up the old entry. | 457 // findAndReturnMutableFlat already called fHash.add(), so we just clean
up the old entry. |
| 460 fHash.remove(*found); | 458 fHash.remove(*found); |
| 461 fController->unalloc((void*)found); | 459 fController->unalloc((void*)found); |
| 462 SkASSERT(this->count() == oldCount); | 460 SkASSERT(this->count() == oldCount); |
| 463 | 461 |
| 464 *replaced = true; | 462 *replaced = true; |
| 465 return flat; | 463 return flat; |
| 466 } | 464 } |
| 467 | 465 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 fWriteBuffer.setBitmapHeap(fController->getBitmapHeap()); | 529 fWriteBuffer.setBitmapHeap(fController->getBitmapHeap()); |
| 532 fWriteBuffer.setTypefaceRecorder(fController->getTypefaceSet()); | 530 fWriteBuffer.setTypefaceRecorder(fController->getTypefaceSet()); |
| 533 fWriteBuffer.setNamedFactoryRecorder(fController->getNamedFactorySet()); | 531 fWriteBuffer.setNamedFactoryRecorder(fController->getNamedFactorySet()); |
| 534 fWriteBuffer.setFlags(fController->getWriteBufferFlags()); | 532 fWriteBuffer.setFlags(fController->getWriteBufferFlags()); |
| 535 fReady = true; | 533 fReady = true; |
| 536 } | 534 } |
| 537 | 535 |
| 538 // As findAndReturnFlat, but returns a mutable pointer for internal use. | 536 // As findAndReturnFlat, but returns a mutable pointer for internal use. |
| 539 SkFlatData* findAndReturnMutableFlat(const T& element) { | 537 SkFlatData* findAndReturnMutableFlat(const T& element) { |
| 540 // Only valid until the next call to resetScratch(). | 538 // Only valid until the next call to resetScratch(). |
| 541 const SkFlatData& scratch = this->resetScratch(element, fNextIndex); | 539 const SkFlatData& scratch = this->resetScratch(element, this->count()+1)
; |
| 542 | 540 |
| 543 SkFlatData* candidate = fHash.find(scratch); | 541 SkFlatData* candidate = fHash.find(scratch); |
| 544 if (candidate != NULL) return candidate; | 542 if (candidate != NULL) return candidate; |
| 545 | 543 |
| 546 SkFlatData* detached = this->detachScratch(); | 544 SkFlatData* detached = this->detachScratch(); |
| 547 fHash.add(detached); | 545 fHash.add(detached); |
| 548 *fIndexedData.insert(fNextIndex) = detached; | 546 *fIndexedData.append() = detached; |
| 549 fNextIndex++; | 547 SkASSERT(fIndexedData.top()->index() == this->count()); |
| 550 return detached; | 548 return detached; |
| 551 } | 549 } |
| 552 | 550 |
| 553 // This reference is valid only until the next call to resetScratch() or det
achScratch(). | 551 // This reference is valid only until the next call to resetScratch() or det
achScratch(). |
| 554 const SkFlatData& resetScratch(const T& element, int index) { | 552 const SkFlatData& resetScratch(const T& element, int index) { |
| 555 this->lazyInit(); | 553 this->lazyInit(); |
| 556 | 554 |
| 557 // Flatten element into fWriteBuffer (using fScratch as storage). | 555 // Flatten element into fWriteBuffer (using fScratch as storage). |
| 558 fWriteBuffer.reset(fScratch->data(), fScratchSize); | 556 fWriteBuffer.reset(fScratch->data(), fScratchSize); |
| 559 Traits::flatten(fWriteBuffer, element); | 557 Traits::flatten(fWriteBuffer, element); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 fController->getTypefacePlayback()); | 598 fController->getTypefacePlayback()); |
| 601 } | 599 } |
| 602 | 600 |
| 603 // All SkFlatData* stored in fIndexedData and fHash are owned by the control
ler. | 601 // All SkFlatData* stored in fIndexedData and fHash are owned by the control
ler. |
| 604 SkAutoTUnref<SkFlatController> fController; | 602 SkAutoTUnref<SkFlatController> fController; |
| 605 size_t fScratchSize; // How many bytes fScratch has allocated for data itse
lf. | 603 size_t fScratchSize; // How many bytes fScratch has allocated for data itse
lf. |
| 606 SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_fre
e. | 604 SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_fre
e. |
| 607 SkOrderedWriteBuffer fWriteBuffer; | 605 SkOrderedWriteBuffer fWriteBuffer; |
| 608 bool fReady; | 606 bool fReady; |
| 609 | 607 |
| 610 // We map between SkFlatData and a 1-based integer index. | |
| 611 int fNextIndex; | |
| 612 | |
| 613 // For index -> SkFlatData. fIndexedData[0] is always NULL. | 608 // For index -> SkFlatData. fIndexedData[0] is always NULL. |
| 614 SkTDArray<const SkFlatData*> fIndexedData; | 609 SkTDArray<const SkFlatData*> fIndexedData; |
| 615 | 610 |
| 616 // For SkFlatData -> cached SkFlatData, which has index(). | 611 // For SkFlatData -> cached SkFlatData, which has index(). |
| 617 SkTDynamicHash<SkFlatData, SkFlatData, | 612 SkTDynamicHash<SkFlatData, SkFlatData, |
| 618 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH
ash; | 613 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH
ash; |
| 619 }; | 614 }; |
| 620 | 615 |
| 621 /////////////////////////////////////////////////////////////////////////////// | 616 /////////////////////////////////////////////////////////////////////////////// |
| 622 // Some common dictionaries are defined here for both reference and convenience | 617 // Some common dictionaries are defined here for both reference and convenience |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 } | 679 } |
| 685 | 680 |
| 686 private: | 681 private: |
| 687 SkChunkAlloc fHeap; | 682 SkChunkAlloc fHeap; |
| 688 SkAutoTUnref<SkRefCntSet> fTypefaceSet; | 683 SkAutoTUnref<SkRefCntSet> fTypefaceSet; |
| 689 void* fLastAllocated; | 684 void* fLastAllocated; |
| 690 mutable SkTypefacePlayback fTypefacePlayback; | 685 mutable SkTypefacePlayback fTypefacePlayback; |
| 691 }; | 686 }; |
| 692 | 687 |
| 693 #endif | 688 #endif |
| OLD | NEW |