Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2014 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkCachedData_priv.h" | |
| 9 #include "SkRefCnt.h" | |
| 10 #include "SkDiscardableMemory.h" | |
| 11 | |
| 12 SkCachedData::SkCachedData(void* data, size_t size) | |
| 13 : fData(data) | |
| 14 , fSize(size) | |
| 15 , fRefCnt(2) // 1 owner, not in cache | |
| 16 { | |
| 17 fStorage.fMalloc = data; | |
| 18 fStorageType = kMalloc_StorageType; | |
| 19 } | |
| 20 | |
| 21 SkCachedData::SkCachedData(size_t size, SkDiscardableMemory* dm) | |
| 22 : fData(dm->data()) | |
| 23 , fSize(size) | |
| 24 , fRefCnt(2) // 1 owner, not in cache | |
| 25 { | |
| 26 fStorage.fDM = dm; | |
| 27 fStorageType = kDiscardableMemory_StorageType; | |
| 28 } | |
| 29 | |
| 30 SkCachedData::~SkCachedData() { | |
| 31 switch (fStorageType) { | |
| 32 case kMalloc_StorageType: | |
| 33 sk_free(fStorage.fMalloc); | |
| 34 break; | |
| 35 case kDiscardableMemory_StorageType: | |
| 36 SkDELETE(fStorage.fDM); | |
| 37 break; | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 void SkCachedData::internalRef(int refAmount) { | |
| 42 #ifdef SK_DEBUG | |
| 43 SkASSERT(2 == refAmount || 3 == refAmount); | |
| 44 if (3 == refAmount) { | |
| 45 // assert that we are not already attached (i.e. the low-bit is 0) | |
| 46 SkASSERT(0 == (fRefCnt & 1)); | |
| 47 } | |
| 48 #endif | |
| 49 | |
| 50 const int32_t new_count = sk_atomic_add(&fRefCnt, refAmount) + refAmount; | |
| 51 const int owners = new_count >> 1; | |
| 52 const int in_cache = new_count & 1; | |
| 53 | |
| 54 SkASSERT(owners >= 2); | |
| 55 | |
| 56 if (2 == owners) { | |
|
qiankun
2014/09/25 07:15:11
In some cases, owners may exceed 2 before SkCached
| |
| 57 sk_membar_acquire__after_atomic_dec(); | |
| 58 if (in_cache) { | |
| 59 this->lock(); | |
| 60 } | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 void SkCachedData::internalUnref(int refAmount) { | |
| 65 #ifdef SK_DEBUG | |
| 66 SkASSERT(2 == refAmount || 3 == refAmount); | |
| 67 if (3 == refAmount) { | |
| 68 // assert that we are already attached (i.e. the low-bit is 1) | |
| 69 SkASSERT(1 == (fRefCnt & 1)); | |
| 70 } | |
| 71 #endif | |
| 72 | |
| 73 const int32_t new_count = sk_atomic_add(&fRefCnt, -refAmount) - refAmount; | |
| 74 const int owners = new_count >> 1; | |
| 75 const int in_cache = new_count & 1; | |
| 76 | |
| 77 switch (owners) { | |
| 78 case 0: | |
| 79 sk_membar_acquire__after_atomic_dec(); | |
| 80 SkDELETE(this); | |
| 81 break; | |
| 82 case 1: | |
| 83 sk_membar_acquire__after_atomic_dec(); | |
| 84 if (in_cache) { | |
| 85 this->unlock(); | |
| 86 } | |
| 87 break; | |
| 88 default: | |
| 89 break; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 void SkCachedData::lock() { | |
| 94 switch (fStorageType) { | |
| 95 case kMalloc_StorageType: | |
| 96 fData = fStorage.fMalloc; | |
| 97 break; | |
| 98 case kDiscardableMemory_StorageType: | |
| 99 if (fStorage.fDM->lock()) { | |
| 100 fData = fStorage.fDM->data(); | |
| 101 } else { | |
| 102 fData = NULL; // signal failure to lock, contents are gone | |
| 103 } | |
| 104 break; | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void SkCachedData::unlock() { | |
| 109 switch (fStorageType) { | |
| 110 case kMalloc_StorageType: | |
| 111 // nothing to do/check | |
| 112 break; | |
| 113 case kDiscardableMemory_StorageType: | |
| 114 if (fData) { // did the previous lock succeed? | |
| 115 fStorage.fDM->unlock(); | |
| 116 } | |
| 117 break; | |
| 118 } | |
| 119 fData = NULL; // signal that we're in an unlocked state | |
| 120 } | |
| 121 | |
| OLD | NEW |