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

Side by Side Diff: src/ports/SkMacImageCache.cpp

Issue 12433020: Improvements/additions to SkImageCache/SkLazyPixelRef. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Modified a comment. Created 7 years, 9 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 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 "SkMacImageCache.h"
9 #include "SkThread.h"
10
11 #ifdef SK_DEBUG
12 #include "SkTSearch.h"
13 #endif
14
15 SK_DECLARE_STATIC_MUTEX(gMacImageMutex);
16
17 SkMacImageCache* SkMacImageCache::GetMacImageCache() {
18 SkAutoMutexAcquire ac(&gMacImageMutex);
19 static SkMacImageCache gCache;
20 return &gCache;
21 }
22
23 SkMacImageCache::SkMacImageCache() {}
24
25 #ifdef SK_DEBUG
26 SkMacImageCache::~SkMacImageCache() {
27 SkASSERT(fRecs.count() == 0);
28 }
29 #endif
30
31 static size_t round_to_page_size(size_t size) {
32 const size_t mask = 4096 - 1;
33 return (size + mask) & ~mask;
34 }
35
36 void* SkMacImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) {
37 SkAutoMutexAcquire ac(&gMacImageMutex);
38 Rec rec;
39 rec.fAddr = 0;
40 rec.fSize = round_to_page_size(bytes);
41 kern_return_t ret = vm_allocate(mach_task_self(), &rec.fAddr, rec.fSize,
42 VM_FLAGS_PURGABLE | VM_FLAGS_ANYWHERE);
43 if (ret != KERN_SUCCESS) {
44 SkDebugf("SkMacImageCache::allocAndPinCache failed to allocate.\n");
45 return NULL;
46 }
47
48 Rec* pRec = SkNEW_ARGS(Rec, (rec));
49 SkASSERT(ID != NULL);
50 *ID = reinterpret_cast<intptr_t>(pRec);
51 #ifdef SK_DEBUG
52 pRec->fPinned = true;
53 // Insert into the array of all recs:
54 int index = this->findRec(*ID);
55 SkASSERT(index < 0);
56 fRecs.insert(~index, 1, ID);
57 #endif
58 return reinterpret_cast<void*>(pRec->fAddr);
59 }
60
61 void* SkMacImageCache::pinCache(intptr_t ID, SkImageCache::PurgeStatus* status) {
62 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID);
63 SkAutoMutexAcquire ac(&gMacImageMutex);
64 Rec* rec = reinterpret_cast<Rec*>(ID);
65 #ifdef SK_DEBUG
66 SkASSERT(!rec->fPinned);
67 #endif
68 int state = VM_PURGABLE_NONVOLATILE;
69 kern_return_t ret = vm_purgable_control(mach_task_self(), rec->fAddr, VM_PUR GABLE_SET_STATE,
70 &state);
71 if (ret != KERN_SUCCESS) {
72 // Could not pin the memory, so deallocate it. The caller will need to r eallocate.
73 ret = vm_deallocate(mach_task_self(), rec->fAddr, rec->fSize);
74 if (ret != KERN_SUCCESS) {
75 SkDebugf("SkMacImageCache::pinCache failed to deallocate.\n");
76 }
77 this->removeRec(ID);
78 return NULL;
79 }
80 SkASSERT(status != NULL);
81 #ifdef SK_DEBUG
82 rec->fPinned = true;
83 #endif
84 if (state & VM_PURGABLE_EMPTY) {
85 *status = SkImageCache::kPurged_PurgeStatus;
86 } else {
87 *status = SkImageCache::kNotPurged_PurgeStatus;
88 }
89 return reinterpret_cast<void*>(rec->fAddr);
90 }
91
92 void SkMacImageCache::releaseCache(intptr_t ID) {
93 if (SkImageCache::UNINITIALIZED_ID == ID) {
94 return;
95 }
96 SkAutoMutexAcquire ac(&gMacImageMutex);
97 Rec* rec = reinterpret_cast<Rec*>(ID);
98 int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
99 kern_return_t ret = vm_purgable_control(mach_task_self(), rec->fAddr, VM_PUR GABLE_SET_STATE,
100 &state);
101 if (ret != KERN_SUCCESS) {
102 SkDebugf("SkMacImageCache::releaseCache failed to unlock memory.\n");
103 }
104 #ifdef SK_DEBUG
105 SkASSERT(rec->fPinned);
106 rec->fPinned = false;
107 #endif
108 }
109
110 void SkMacImageCache::throwAwayCache(intptr_t ID) {
111 if (SkImageCache::UNINITIALIZED_ID == ID) {
112 return;
113 }
114 SkAutoMutexAcquire ac(&gMacImageMutex);
115 Rec* rec = reinterpret_cast<Rec*>(ID);
116 SkASSERT(!rec->fPinned);
117 kern_return_t ret = vm_deallocate(mach_task_self(), rec->fAddr, rec->fSize);
118 if (ret != KERN_SUCCESS) {
119 SkDebugf("SkMacImageCache::throwAwayCache failed to deallocate.\n");
120 }
121 this->removeRec(ID);
122 }
123
124 #ifdef SK_DEBUG
125 SkImageCache::PinStatus SkMacImageCache::getPinStatus(intptr_t ID) const {
126 SkAutoMutexAcquire ac(&gMacImageMutex);
127 if (SkImageCache::UNINITIALIZED_ID == ID || this->findRec(ID) < 0) {
128 return SkImageCache::kThrownAway_PinStatus;
129 }
130
131 Rec* rec = reinterpret_cast<Rec*>(ID);
132 int state = 0;
133 kern_return_t ret = vm_purgable_control(mach_task_self(), rec->fAddr, VM_PUR GABLE_GET_STATE,
134 &state);
135 if (ret != KERN_SUCCESS) {
136 return SkImageCache::kThrownAway_PinStatus;
137 }
138
139 if (VM_PURGABLE_NONVOLATILE == state) {
140 SkASSERT(rec->fPinned);
141 return SkImageCache::kPinned_PinStatus;
142 }
143
144 SkASSERT(!rec->fPinned);
145 return SkImageCache::kNeedsPin_PinStatus;
146 }
147
148 void SkMacImageCache::purgeAllCaches() {
149 SkAutoMutexAcquire ac(&gMacImageMutex);
150 int state = 0;
151 kern_return_t ret = vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PUR GE_ALL, &state);
152 if (ret != KERN_SUCCESS) {
153 SkDebugf("SkMacImageCache::purgeAllCaches failed to purge.\n");
154 }
155 }
156
157 int SkMacImageCache::findRec(intptr_t rec) const {
158 return SkTSearch(fRecs.begin(), fRecs.count(), rec, sizeof(intptr_t));
159 }
160 #endif
161
162 void SkMacImageCache::removeRec(intptr_t ID) {
163 #ifdef SK_DEBUG
164 int index = this->findRec(ID);
165 SkASSERT(index >= 0);
166 fRecs.remove(index);
167 #endif
168 Rec* rec = reinterpret_cast<Rec*>(ID);
169 SkASSERT(!rec->fPinned);
170 SkDELETE(rec);
171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698