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

Side by Side Diff: src/core/SkCachedData.cpp

Issue 592843003: Add SkCachedData and use it for SkMipMap (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: use explicit runtime flag to recognize Discardable, to allow clients to subclass Created 6 years, 2 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
« no previous file with comments | « src/core/SkCachedData.h ('k') | src/core/SkCachedData_priv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « src/core/SkCachedData.h ('k') | src/core/SkCachedData_priv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698