| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2015 Google Inc. |    2  * Copyright 2015 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  |    7  | 
|    8 #include "SkAtomics.h" |    8 #include "SkAtomics.h" | 
|    9 #include "SkRWBuffer.h" |    9 #include "SkRWBuffer.h" | 
|   10 #include "SkStream.h" |   10 #include "SkStream.h" | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   35     // |   35     // | 
|   36     size_t append(const void* src, size_t length) { |   36     size_t append(const void* src, size_t length) { | 
|   37         this->validate(); |   37         this->validate(); | 
|   38         size_t amount = SkTMin(this->avail(), length); |   38         size_t amount = SkTMin(this->avail(), length); | 
|   39         memcpy(this->availData(), src, amount); |   39         memcpy(this->availData(), src, amount); | 
|   40         fUsed += amount; |   40         fUsed += amount; | 
|   41         this->validate(); |   41         this->validate(); | 
|   42         return amount; |   42         return amount; | 
|   43     } |   43     } | 
|   44  |   44  | 
 |   45     // Do not call in the reader thread, since the writer may be updating fUsed. | 
 |   46     // (The assertion is still true, but TSAN still may complain about its racin
     ess.) | 
|   45     void validate() const { |   47     void validate() const { | 
|   46 #ifdef SK_DEBUG |   48 #ifdef SK_DEBUG | 
|   47         SkASSERT(fCapacity > 0); |   49         SkASSERT(fCapacity > 0); | 
|   48         SkASSERT(fUsed <= fCapacity); |   50         SkASSERT(fUsed <= fCapacity); | 
|   49 #endif |   51 #endif | 
|   50     } |   52     } | 
|   51  |   53  | 
|   52 private: |   54 private: | 
|   53     static size_t LengthToCapacity(size_t length) { |   55     static size_t LengthToCapacity(size_t length) { | 
|   54         const size_t minSize = kMinAllocSize - sizeof(SkBufferBlock); |   56         const size_t minSize = kMinAllocSize - sizeof(SkBufferBlock); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   87             SkBufferBlock* block = fBlock.fNext; |   89             SkBufferBlock* block = fBlock.fNext; | 
|   88             sk_free((void*)this); |   90             sk_free((void*)this); | 
|   89             while (block) { |   91             while (block) { | 
|   90                 SkBufferBlock* next = block->fNext; |   92                 SkBufferBlock* next = block->fNext; | 
|   91                 sk_free(block); |   93                 sk_free(block); | 
|   92                 block = next; |   94                 block = next; | 
|   93             } |   95             } | 
|   94         } |   96         } | 
|   95     } |   97     } | 
|   96  |   98  | 
|   97     void validate(size_t minUsed, SkBufferBlock* tail = nullptr) const { |   99     void validate(size_t minUsed, const SkBufferBlock* tail = nullptr) const { | 
|   98 #ifdef SK_DEBUG |  100 #ifdef SK_DEBUG | 
|   99         SkASSERT(fRefCnt > 0); |  101         SkASSERT(fRefCnt > 0); | 
|  100         size_t totalUsed = 0; |  102         size_t totalUsed = 0; | 
|  101         const SkBufferBlock* block = &fBlock; |  103         const SkBufferBlock* block = &fBlock; | 
|  102         const SkBufferBlock* lastBlock = block; |  104         const SkBufferBlock* lastBlock = block; | 
|  103         while (block) { |  105         while (block) { | 
|  104             block->validate(); |  106             block->validate(); | 
|  105             totalUsed += block->fUsed; |  107             totalUsed += block->fUsed; | 
|  106             lastBlock = block; |  108             lastBlock = block; | 
|  107             block = block->fNext; |  109             block = block->fNext; | 
|  108         } |  110         } | 
|  109         SkASSERT(minUsed <= totalUsed); |  111         SkASSERT(minUsed <= totalUsed); | 
|  110         if (tail) { |  112         if (tail) { | 
|  111             SkASSERT(tail == lastBlock); |  113             SkASSERT(tail == lastBlock); | 
|  112         } |  114         } | 
|  113 #endif |  115 #endif | 
|  114     } |  116     } | 
|  115 }; |  117 }; | 
|  116  |  118  | 
|  117 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// |  119 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  118 // The reader can only access block.fCapacity (which never changes), and cannot 
     access |  120 // The reader can only access block.fCapacity (which never changes), and cannot 
     access | 
|  119 // block.fUsed, which may be updated by the writer. |  121 // block.fUsed, which may be updated by the writer. | 
|  120 // |  122 // | 
|  121 SkROBuffer::SkROBuffer(const SkBufferHead* head, size_t available) |  123 SkROBuffer::SkROBuffer(const SkBufferHead* head, size_t available, const SkBuffe
     rBlock* tail) | 
|  122     : fHead(head), fAvailable(available) |  124     : fHead(head), fAvailable(available), fTail(tail) | 
|  123 { |  125 { | 
|  124     if (head) { |  126     if (head) { | 
|  125         fHead->ref(); |  127         fHead->ref(); | 
|  126         SkASSERT(available > 0); |  128         SkASSERT(available > 0); | 
|  127         head->validate(available); |  129         head->validate(available, tail); | 
|  128     } else { |  130     } else { | 
|  129         SkASSERT(0 == available); |  131         SkASSERT(0 == available); | 
 |  132         SkASSERT(!tail); | 
|  130     } |  133     } | 
|  131 } |  134 } | 
|  132  |  135  | 
|  133 SkROBuffer::~SkROBuffer() { |  136 SkROBuffer::~SkROBuffer() { | 
|  134     if (fHead) { |  137     if (fHead) { | 
|  135         fHead->validate(fAvailable); |  | 
|  136         fHead->unref(); |  138         fHead->unref(); | 
|  137     } |  139     } | 
|  138 } |  140 } | 
|  139  |  141  | 
|  140 SkROBuffer::Iter::Iter(const SkROBuffer* buffer) { |  142 SkROBuffer::Iter::Iter(const SkROBuffer* buffer) { | 
|  141     this->reset(buffer); |  143     this->reset(buffer); | 
|  142 } |  144 } | 
|  143  |  145  | 
|  144 void SkROBuffer::Iter::reset(const SkROBuffer* buffer) { |  146 void SkROBuffer::Iter::reset(const SkROBuffer* buffer) { | 
|  145     if (buffer) { |  147     fBuffer = buffer; | 
 |  148     if (buffer && buffer->fHead) { | 
|  146         fBlock = &buffer->fHead->fBlock; |  149         fBlock = &buffer->fHead->fBlock; | 
|  147         fRemaining = buffer->fAvailable; |  150         fRemaining = buffer->fAvailable; | 
|  148     } else { |  151     } else { | 
|  149         fBlock = nullptr; |  152         fBlock = nullptr; | 
|  150         fRemaining = 0; |  153         fRemaining = 0; | 
|  151     } |  154     } | 
|  152 } |  155 } | 
|  153  |  156  | 
|  154 const void* SkROBuffer::Iter::data() const { |  157 const void* SkROBuffer::Iter::data() const { | 
|  155     return fRemaining ? fBlock->startData() : nullptr; |  158     return fRemaining ? fBlock->startData() : nullptr; | 
|  156 } |  159 } | 
|  157  |  160  | 
|  158 size_t SkROBuffer::Iter::size() const { |  161 size_t SkROBuffer::Iter::size() const { | 
|  159     if (!fBlock) { |  162     if (!fBlock) { | 
|  160         return 0; |  163         return 0; | 
|  161     } |  164     } | 
|  162     return SkTMin(fBlock->fCapacity, fRemaining); |  165     return SkTMin(fBlock->fCapacity, fRemaining); | 
|  163 } |  166 } | 
|  164  |  167  | 
|  165 bool SkROBuffer::Iter::next() { |  168 bool SkROBuffer::Iter::next() { | 
|  166     if (fRemaining) { |  169     if (fRemaining) { | 
|  167         fRemaining -= this->size(); |  170         fRemaining -= this->size(); | 
|  168         fBlock = fBlock->fNext; |  171         if (fBuffer->fTail == fBlock) { | 
 |  172             // There are more blocks, but fBuffer does not know about them. | 
 |  173             SkASSERT(0 == fRemaining); | 
 |  174             fBlock = nullptr; | 
 |  175         } else { | 
 |  176             fBlock = fBlock->fNext; | 
 |  177         } | 
|  169     } |  178     } | 
|  170     return fRemaining != 0; |  179     return fRemaining != 0; | 
|  171 } |  180 } | 
|  172  |  181  | 
|  173 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// |  182 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  174  |  183  | 
|  175 SkRWBuffer::SkRWBuffer(size_t initialCapacity) : fHead(nullptr), fTail(nullptr),
      fTotalUsed(0) {} |  184 SkRWBuffer::SkRWBuffer(size_t initialCapacity) : fHead(nullptr), fTail(nullptr),
      fTotalUsed(0) {} | 
|  176  |  185  | 
|  177 SkRWBuffer::~SkRWBuffer() { |  186 SkRWBuffer::~SkRWBuffer() { | 
|  178     this->validate(); |  187     this->validate(); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  217 void SkRWBuffer::validate() const { |  226 void SkRWBuffer::validate() const { | 
|  218     if (fHead) { |  227     if (fHead) { | 
|  219         fHead->validate(fTotalUsed, fTail); |  228         fHead->validate(fTotalUsed, fTail); | 
|  220     } else { |  229     } else { | 
|  221         SkASSERT(nullptr == fTail); |  230         SkASSERT(nullptr == fTail); | 
|  222         SkASSERT(0 == fTotalUsed); |  231         SkASSERT(0 == fTotalUsed); | 
|  223     } |  232     } | 
|  224 } |  233 } | 
|  225 #endif |  234 #endif | 
|  226  |  235  | 
|  227 SkROBuffer* SkRWBuffer::newRBufferSnapshot() const { return new SkROBuffer(fHead
     , fTotalUsed); } |  236 SkROBuffer* SkRWBuffer::newRBufferSnapshot() const { | 
 |  237     return new SkROBuffer(fHead, fTotalUsed, fTail); | 
 |  238 } | 
|  228  |  239  | 
|  229 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// |  240 ////////////////////////////////////////////////////////////////////////////////
     /////////////////// | 
|  230  |  241  | 
|  231 class SkROBufferStreamAsset : public SkStreamAsset { |  242 class SkROBufferStreamAsset : public SkStreamAsset { | 
|  232     void validate() const { |  243     void validate() const { | 
|  233 #ifdef SK_DEBUG |  244 #ifdef SK_DEBUG | 
|  234         SkASSERT(fGlobalOffset <= fBuffer->size()); |  245         SkASSERT(fGlobalOffset <= fBuffer->size()); | 
|  235         SkASSERT(fLocalOffset <= fIter.size()); |  246         SkASSERT(fLocalOffset <= fIter.size()); | 
|  236         SkASSERT(fLocalOffset <= fGlobalOffset); |  247         SkASSERT(fLocalOffset <= fGlobalOffset); | 
|  237 #endif |  248 #endif | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  335     const SkROBuffer*   fBuffer; |  346     const SkROBuffer*   fBuffer; | 
|  336     SkROBuffer::Iter    fIter; |  347     SkROBuffer::Iter    fIter; | 
|  337     size_t              fLocalOffset; |  348     size_t              fLocalOffset; | 
|  338     size_t              fGlobalOffset; |  349     size_t              fGlobalOffset; | 
|  339 }; |  350 }; | 
|  340  |  351  | 
|  341 SkStreamAsset* SkRWBuffer::newStreamSnapshot() const { |  352 SkStreamAsset* SkRWBuffer::newStreamSnapshot() const { | 
|  342     SkAutoTUnref<SkROBuffer> buffer(this->newRBufferSnapshot()); |  353     SkAutoTUnref<SkROBuffer> buffer(this->newRBufferSnapshot()); | 
|  343     return new SkROBufferStreamAsset(buffer); |  354     return new SkROBufferStreamAsset(buffer); | 
|  344 } |  355 } | 
| OLD | NEW |