Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: src/core/SkPictureFlat.h

Issue 131483005: Allocate SkPictureFlat::fScratch lazily. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 template <typename T, typename Traits, int kScratchSizeGuess> friend class S kFlatDictionary; 369 template <typename T, typename Traits, int kScratchSizeGuess> friend class S kFlatDictionary;
370 }; 370 };
371 371
372 template <typename T, typename Traits, int kScratchSizeGuess=0> 372 template <typename T, typename Traits, int kScratchSizeGuess=0>
373 class SkFlatDictionary { 373 class SkFlatDictionary {
374 static const size_t kWriteBufferGrowthBytes = 1024; 374 static const size_t kWriteBufferGrowthBytes = 1024;
375 375
376 public: 376 public:
377 explicit SkFlatDictionary(SkFlatController* controller) 377 explicit SkFlatDictionary(SkFlatController* controller)
378 : fController(SkRef(controller)) 378 : fController(SkRef(controller))
379 , fScratchSize(kScratchSizeGuess) 379 , fScratchSize(kScratchSizeGuess)
mtklein 2014/01/09 14:38:58 For consistency, let's make this fScratchSize(0) t
tomhudson 2014/01/09 14:49:32 Done.
380 , fScratch(AllocScratch(fScratchSize)) 380 , fScratch(NULL)
381 , fWriteBuffer(kWriteBufferGrowthBytes) 381 , fWriteBuffer(kWriteBufferGrowthBytes)
382 , fWriteBufferReady(false) { 382 , fBuffersReady(false) {
mtklein 2014/01/09 14:38:58 Suggestion: fReady and lazyInit() ?
tomhudson 2014/01/09 14:49:32 Done.
383 this->reset(); 383 this->reset();
384 } 384 }
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.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 SkASSERT(SkIsAlign4(flatDataSize)); 508 SkASSERT(SkIsAlign4(flatDataSize));
509 return sizeof(SkFlatData) + flatDataSize; 509 return sizeof(SkFlatData) + flatDataSize;
510 } 510 }
511 511
512 // Allocate a new scratch SkFlatData. Must be sk_freed. 512 // Allocate a new scratch SkFlatData. Must be sk_freed.
513 static SkFlatData* AllocScratch(size_t scratchSize) { 513 static SkFlatData* AllocScratch(size_t scratchSize) {
514 return (SkFlatData*) sk_malloc_throw(SizeWithPadding(scratchSize)); 514 return (SkFlatData*) sk_malloc_throw(SizeWithPadding(scratchSize));
515 } 515 }
516 516
517 // We have to delay fWriteBuffer's initialization until its first use; fCont roller might not 517 // We have to delay fWriteBuffer's initialization until its first use; fCont roller might not
518 // be fully set up by the time we get it in the constructor. 518 // be fully set up by the time we get it in the constructor. We also delay f Scratch to
mtklein 2014/01/09 14:38:58 delay -> delay allocating?
tomhudson 2014/01/09 14:49:32 Done.
519 void lazyWriteBufferInit() { 519 // avoid unnecessary heap allocations, since we're paying the price of the c onditional
520 if (fWriteBufferReady) { 520 // anyway.
521 void lazyBufferInit() {
522 if (fBuffersReady) {
521 return; 523 return;
522 } 524 }
525
526 fScratch = AllocScratch(fScratchSize);
527
523 // Without a bitmap heap, we'll flatten bitmaps into paints. That's nev er what you want. 528 // Without a bitmap heap, we'll flatten bitmaps into paints. That's nev er what you want.
524 SkASSERT(fController->getBitmapHeap() != NULL); 529 SkASSERT(fController->getBitmapHeap() != NULL);
525 fWriteBuffer.setBitmapHeap(fController->getBitmapHeap()); 530 fWriteBuffer.setBitmapHeap(fController->getBitmapHeap());
526 fWriteBuffer.setTypefaceRecorder(fController->getTypefaceSet()); 531 fWriteBuffer.setTypefaceRecorder(fController->getTypefaceSet());
527 fWriteBuffer.setNamedFactoryRecorder(fController->getNamedFactorySet()); 532 fWriteBuffer.setNamedFactoryRecorder(fController->getNamedFactorySet());
528 fWriteBuffer.setFlags(fController->getWriteBufferFlags()); 533 fWriteBuffer.setFlags(fController->getWriteBufferFlags());
529 fWriteBufferReady = true; 534 fBuffersReady = true;
530 } 535 }
531 536
532 // As findAndReturnFlat, but returns a mutable pointer for internal use. 537 // As findAndReturnFlat, but returns a mutable pointer for internal use.
533 SkFlatData* findAndReturnMutableFlat(const T& element) { 538 SkFlatData* findAndReturnMutableFlat(const T& element) {
534 // Only valid until the next call to resetScratch(). 539 // Only valid until the next call to resetScratch().
535 const SkFlatData& scratch = this->resetScratch(element, fNextIndex); 540 const SkFlatData& scratch = this->resetScratch(element, fNextIndex);
536 541
537 SkFlatData* candidate = fHash.find(scratch); 542 SkFlatData* candidate = fHash.find(scratch);
538 if (candidate != NULL) return candidate; 543 if (candidate != NULL) return candidate;
539 544
540 SkFlatData* detached = this->detachScratch(); 545 SkFlatData* detached = this->detachScratch();
541 fHash.add(detached); 546 fHash.add(detached);
542 *fIndexedData.insert(fNextIndex) = detached; 547 *fIndexedData.insert(fNextIndex) = detached;
543 fNextIndex++; 548 fNextIndex++;
544 return detached; 549 return detached;
545 } 550 }
546 551
547 // This reference is valid only until the next call to resetScratch() or det achScratch(). 552 // This reference is valid only until the next call to resetScratch() or det achScratch().
548 const SkFlatData& resetScratch(const T& element, int index) { 553 const SkFlatData& resetScratch(const T& element, int index) {
549 this->lazyWriteBufferInit(); 554 this->lazyBufferInit();
550 555
551 // Flatten element into fWriteBuffer (using fScratch as storage). 556 // Flatten element into fWriteBuffer (using fScratch as storage).
552 fWriteBuffer.reset(fScratch->data(), fScratchSize); 557 fWriteBuffer.reset(fScratch->data(), fScratchSize);
553 Traits::flatten(fWriteBuffer, element); 558 Traits::flatten(fWriteBuffer, element);
554 const size_t bytesWritten = fWriteBuffer.bytesWritten(); 559 const size_t bytesWritten = fWriteBuffer.bytesWritten();
555 560
556 // If all the flattened bytes fit into fScratch, we can skip a call to w riteToMemory. 561 // If all the flattened bytes fit into fScratch, we can skip a call to w riteToMemory.
557 if (!fWriteBuffer.wroteOnlyToStorage()) { 562 if (!fWriteBuffer.wroteOnlyToStorage()) {
558 SkASSERT(bytesWritten > fScratchSize); 563 SkASSERT(bytesWritten > fScratchSize);
559 // It didn't all fit. Copy into a larger replacement SkFlatData. 564 // It didn't all fit. Copy into a larger replacement SkFlatData.
(...skipping 10 matching lines...) Expand all
570 // The data is in fScratch now but we need to stamp its header. 575 // The data is in fScratch now but we need to stamp its header.
571 fScratch->stampHeader(index, bytesWritten); 576 fScratch->stampHeader(index, bytesWritten);
572 return *fScratch; 577 return *fScratch;
573 } 578 }
574 579
575 // This result is owned by fController and lives as long as it does (unless unalloc'd). 580 // This result is owned by fController and lives as long as it does (unless unalloc'd).
576 SkFlatData* detachScratch() { 581 SkFlatData* detachScratch() {
577 // Allocate a new SkFlatData exactly big enough to hold our current scra tch. 582 // Allocate a new SkFlatData exactly big enough to hold our current scra tch.
578 // We use the controller for this allocation to extend the allocation's lifetime and allow 583 // We use the controller for this allocation to extend the allocation's lifetime and allow
579 // the controller to do whatever memory management it wants. 584 // the controller to do whatever memory management it wants.
585 SkASSERT(fScratch);
mtklein 2014/01/09 14:38:58 Suggestion: SkASSERT(fScratch != NULL); as a free
tomhudson 2014/01/09 14:49:32 Done.
580 const size_t paddedSize = SizeWithPadding(fScratch->flatSize()); 586 const size_t paddedSize = SizeWithPadding(fScratch->flatSize());
581 SkFlatData* detached = (SkFlatData*)fController->allocThrow(paddedSize); 587 SkFlatData* detached = (SkFlatData*)fController->allocThrow(paddedSize);
582 588
583 // Copy scratch into the new SkFlatData. 589 // Copy scratch into the new SkFlatData.
584 memcpy(detached, fScratch, paddedSize); 590 memcpy(detached, fScratch, paddedSize);
585 591
586 // We can now reuse fScratch, and detached will live until fController d ies. 592 // We can now reuse fScratch, and detached will live until fController d ies.
587 return detached; 593 return detached;
588 } 594 }
589 595
590 void unflatten(T* dst, const SkFlatData* element) const { 596 void unflatten(T* dst, const SkFlatData* element) const {
591 element->unflatten<Traits>(dst, 597 element->unflatten<Traits>(dst,
592 fController->getBitmapHeap(), 598 fController->getBitmapHeap(),
593 fController->getTypefacePlayback()); 599 fController->getTypefacePlayback());
594 } 600 }
595 601
596 // All SkFlatData* stored in fIndexedData and fHash are owned by the control ler. 602 // All SkFlatData* stored in fIndexedData and fHash are owned by the control ler.
597 SkAutoTUnref<SkFlatController> fController; 603 SkAutoTUnref<SkFlatController> fController;
598 size_t fScratchSize; // How many bytes fScratch has allocated for data itse lf. 604 size_t fScratchSize; // How many bytes fScratch has allocated for data itse lf.
599 SkFlatData* fScratch; // Owned, must be freed with sk_free. 605 SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_fre e.
600 SkOrderedWriteBuffer fWriteBuffer; 606 SkOrderedWriteBuffer fWriteBuffer;
601 bool fWriteBufferReady; 607 bool fBuffersReady;
602 608
603 // We map between SkFlatData and a 1-based integer index. 609 // We map between SkFlatData and a 1-based integer index.
604 int fNextIndex; 610 int fNextIndex;
605 611
606 // For index -> SkFlatData. fIndexedData[0] is always NULL. 612 // For index -> SkFlatData. fIndexedData[0] is always NULL.
607 SkTDArray<const SkFlatData*> fIndexedData; 613 SkTDArray<const SkFlatData*> fIndexedData;
608 614
609 // For SkFlatData -> cached SkFlatData, which has index(). 615 // For SkFlatData -> cached SkFlatData, which has index().
610 SkTDynamicHash<SkFlatData, SkFlatData, 616 SkTDynamicHash<SkFlatData, SkFlatData,
611 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH ash; 617 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH ash;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 } 683 }
678 684
679 private: 685 private:
680 SkChunkAlloc fHeap; 686 SkChunkAlloc fHeap;
681 SkAutoTUnref<SkRefCntSet> fTypefaceSet; 687 SkAutoTUnref<SkRefCntSet> fTypefaceSet;
682 void* fLastAllocated; 688 void* fLastAllocated;
683 mutable SkTypefacePlayback fTypefacePlayback; 689 mutable SkTypefacePlayback fTypefacePlayback;
684 }; 690 };
685 691
686 #endif 692 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698