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 | |
| 18 void SkCachedData::ref() { | |
| 19 const int32_t count = sk_atomic_add(&fRefCnt, 2) + 2; | |
| 20 const int owners = count >> 1; | |
| 21 const int in_cache = count & 1; | |
| 22 | |
| 23 SkASSERT(owners >= 2); | |
| 24 | |
| 25 if (2 == owners) { | |
| 26 sk_membar_acquire__after_atomic_dec(); | |
| 27 if (in_cache) { | |
|
mtklein
2014/09/23 22:16:55
So, if I add SkASSERT(in_cache) just before each i
reed2
2014/09/24 01:23:57
Sounds like I need to expand my tests to (try to)
| |
| 28 this->lock(); | |
| 29 } | |
| 30 } | |
| 31 } | |
| 32 | |
| 33 void SkCachedData::unref() { | |
| 34 const int32_t count = sk_atomic_add(&fRefCnt, -2) - 2; | |
| 35 const int owners = count >> 1; | |
| 36 const int in_cache = count & 1; | |
| 37 | |
| 38 switch (owners) { | |
| 39 case 0: | |
| 40 sk_membar_acquire__after_atomic_dec(); | |
| 41 SkDELETE(this); | |
| 42 break; | |
| 43 case 1: | |
| 44 sk_membar_acquire__after_atomic_dec(); | |
| 45 if (in_cache) { | |
| 46 this->unlock(); | |
| 47 } | |
| 48 break; | |
| 49 default: | |
| 50 break; | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 void SkCachedData::ref_from_cache() { | |
| 55 SkASSERT(0 == (fRefCnt & 1)); | |
| 56 sk_atomic_add(&fRefCnt, 3); | |
| 57 } | |
| 58 | |
| 59 void SkCachedData::unref_from_cache() { | |
| 60 SkASSERT(1 == (fRefCnt & 1)); | |
| 61 sk_atomic_add(&fRefCnt, -3); | |
| 62 } | |
| 63 | |
| 64 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 65 | |
| 66 class SkCachedData_Discardable : public SkCachedData { | |
| 67 public: | |
| 68 // we take ownership of dm | |
| 69 SkCachedData_Discardable(SkDiscardableMemory* dm, size_t size) | |
| 70 : INHERITED(dm->data(), size) | |
| 71 , fDM(dm) | |
| 72 , fSuccessfulLock(false) | |
| 73 {} | |
| 74 | |
| 75 virtual ~SkCachedData_Discardable() { | |
| 76 SkDELETE(fDM); | |
| 77 } | |
| 78 | |
| 79 protected: | |
| 80 virtual void onLock() SK_OVERRIDE { | |
| 81 fSuccessfulLock = fDM->lock(); | |
| 82 this->setData(fSuccessfulLock ? fDM->data() : NULL); | |
| 83 } | |
| 84 | |
| 85 virtual void onUnlock() SK_OVERRIDE { | |
| 86 if (fSuccessfulLock) { | |
| 87 fDM->unlock(); | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 private: | |
| 92 SkDiscardableMemory* fDM; | |
| 93 bool fSuccessfulLock; | |
| 94 | |
| 95 typedef SkCachedData INHERITED; | |
| 96 }; | |
| 97 | |
| 98 class SkCachedData_Malloc : public SkCachedData { | |
| 99 public: | |
| 100 // data was allocated via sk_malloc | |
| 101 SkCachedData_Malloc(void* data, size_t size) : INHERITED(data, size), fMallo cData(data) {} | |
| 102 | |
| 103 virtual ~SkCachedData_Malloc() { | |
| 104 sk_free(fMallocData); | |
| 105 } | |
| 106 | |
| 107 virtual void onLock() SK_OVERRIDE { | |
| 108 this->setData(fMallocData); | |
| 109 } | |
| 110 | |
| 111 virtual void onUnlock() SK_OVERRIDE {} | |
| 112 | |
| 113 private: | |
| 114 void* fMallocData; | |
| 115 | |
| 116 typedef SkCachedData INHERITED; | |
| 117 }; | |
| 118 | |
| 119 SkCachedData* SkCachedData::Create(size_t size, SkDiscardableMemory* dm) { | |
| 120 if (dm) { | |
| 121 return SkNEW_ARGS(SkCachedData_Discardable, (dm, size)); | |
| 122 } else { | |
| 123 return SkNEW_ARGS(SkCachedData_Malloc, (sk_malloc_throw(size), size)); | |
| 124 } | |
| 125 } | |
| 126 | |
| OLD | NEW |