OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "SkAshmemImageCache.h" | 8 #include "SkAshmemImageCache.h" |
9 #include "SkThread.h" | 9 #include "SkThread.h" |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 #endif | 34 #endif |
35 | 35 |
36 // ashmem likes lengths on page boundaries. | 36 // ashmem likes lengths on page boundaries. |
37 static size_t roundToPageSize(size_t size) { | 37 static size_t roundToPageSize(size_t size) { |
38 const size_t mask = getpagesize() - 1; | 38 const size_t mask = getpagesize() - 1; |
39 size_t newSize = (size + mask) & ~mask; | 39 size_t newSize = (size + mask) & ~mask; |
40 return newSize; | 40 return newSize; |
41 } | 41 } |
42 | 42 |
43 void* SkAshmemImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { | 43 void* SkAshmemImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { |
| 44 SkASSERT(ID != NULL); |
| 45 |
| 46 SkAutoMutexAcquire ac(&gAshmemMutex); |
| 47 |
| 48 if (*ID != SkImageCache::UNINITIALIZED_ID) { |
| 49 // This rec was previously allocated, but pinCache subsequently |
| 50 // failed. |
| 51 AshmemRec* pRec = reinterpret_cast<AshmemRec*>(*ID); |
| 52 SkASSERT(roundToPageSize(bytes) == pRec->fSize); |
| 53 SkASSERT(pRec->fFD != -1); |
| 54 (void) ashmem_pin_region(pRec->fFD, 0, 0); |
| 55 #ifdef SK_DEBUG |
| 56 pRec->fPinned = true; |
| 57 #endif |
| 58 return pRec->fAddr; |
| 59 } |
| 60 |
44 AshmemRec rec; | 61 AshmemRec rec; |
45 rec.fSize = roundToPageSize(bytes); | 62 rec.fSize = roundToPageSize(bytes); |
46 | 63 |
47 SkAutoMutexAcquire ac(&gAshmemMutex); | |
48 | |
49 rec.fFD = ashmem_create_region(NULL, rec.fSize); | 64 rec.fFD = ashmem_create_region(NULL, rec.fSize); |
50 if (-1 == rec.fFD) { | 65 if (-1 == rec.fFD) { |
51 SkDebugf("ashmem_create_region failed\n"); | 66 SkDebugf("ashmem_create_region failed\n"); |
52 return NULL; | 67 return NULL; |
53 } | 68 } |
54 int err = ashmem_set_prot_region(rec.fFD, PROT_READ | PROT_WRITE); | 69 int err = ashmem_set_prot_region(rec.fFD, PROT_READ | PROT_WRITE); |
55 if (err != 0) { | 70 if (err != 0) { |
56 SkDebugf("ashmem_set_prot_region failed\n"); | 71 SkDebugf("ashmem_set_prot_region failed\n"); |
57 close(rec.fFD); | 72 close(rec.fFD); |
58 return NULL; | 73 return NULL; |
59 } | 74 } |
60 rec.fAddr = mmap(NULL, rec.fSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, rec.f
FD, 0); | 75 rec.fAddr = mmap(NULL, rec.fSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, rec.f
FD, 0); |
61 if (-1 == (long) rec.fAddr) { | 76 if (-1 == (long) rec.fAddr) { |
62 SkDebugf("mmap failed\n"); | 77 SkDebugf("mmap failed\n"); |
63 close(rec.fFD); | 78 close(rec.fFD); |
64 return NULL; | 79 return NULL; |
65 } | 80 } |
66 (void) ashmem_pin_region(rec.fFD, 0, 0); | 81 (void) ashmem_pin_region(rec.fFD, 0, 0); |
67 #ifdef SK_DEBUG | 82 #ifdef SK_DEBUG |
68 rec.fPinned = true; | 83 rec.fPinned = true; |
69 #endif | 84 #endif |
70 // In release mode, we do not keep a pointer to this object. It will be dest
royed | 85 // In release mode, we do not keep a pointer to this object. It will be dest
royed |
71 // either when pinCache returns NULL or when throwAwayCache is called. | 86 // either when pinCache returns NULL or when throwAwayCache is called. |
72 AshmemRec* pRec = SkNEW_ARGS(AshmemRec, (rec)); | 87 AshmemRec* pRec = SkNEW_ARGS(AshmemRec, (rec)); |
73 SkASSERT(ID != NULL); | |
74 *ID = reinterpret_cast<intptr_t>(pRec); | 88 *ID = reinterpret_cast<intptr_t>(pRec); |
75 #ifdef SK_DEBUG | 89 #ifdef SK_DEBUG |
76 this->appendRec(pRec); | 90 this->appendRec(pRec); |
77 #endif | 91 #endif |
78 return rec.fAddr; | 92 return rec.fAddr; |
79 } | 93 } |
80 | 94 |
81 void* SkAshmemImageCache::pinCache(intptr_t ID) { | 95 void* SkAshmemImageCache::pinCache(intptr_t ID) { |
82 SkAutoMutexAcquire ac(&gAshmemMutex); | 96 SkAutoMutexAcquire ac(&gAshmemMutex); |
83 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); | 97 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
84 const int fd = rec->fFD; | 98 const int fd = rec->fFD; |
85 int pin = ashmem_pin_region(fd, 0, 0); | 99 int pin = ashmem_pin_region(fd, 0, 0); |
86 if (ASHMEM_NOT_PURGED == pin) { | 100 if (ASHMEM_NOT_PURGED == pin) { |
87 #ifdef SK_DEBUG | 101 #ifdef SK_DEBUG |
88 rec->fPinned = true; | 102 rec->fPinned = true; |
89 #endif | 103 #endif |
90 return rec->fAddr; | 104 return rec->fAddr; |
91 } | 105 } |
92 // Purged. Remove the associated AshmemRec: | |
93 this->removeRec(rec); | |
94 ashmem_unpin_region(fd, 0, 0); | 106 ashmem_unpin_region(fd, 0, 0); |
95 return NULL; | 107 return NULL; |
96 } | 108 } |
97 | 109 |
98 void SkAshmemImageCache::releaseCache(intptr_t ID) { | 110 void SkAshmemImageCache::releaseCache(intptr_t ID) { |
99 SkAutoMutexAcquire ac(&gAshmemMutex); | 111 SkAutoMutexAcquire ac(&gAshmemMutex); |
100 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); | 112 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
101 ashmem_unpin_region(rec->fFD, 0, 0); | 113 ashmem_unpin_region(rec->fFD, 0, 0); |
102 #ifdef SK_DEBUG | 114 #ifdef SK_DEBUG |
103 rec->fPinned = false; | 115 rec->fPinned = false; |
104 #endif | 116 #endif |
105 } | 117 } |
106 | 118 |
107 void SkAshmemImageCache::throwAwayCache(intptr_t ID) { | 119 void SkAshmemImageCache::throwAwayCache(intptr_t ID) { |
108 SkAutoMutexAcquire ac(&gAshmemMutex); | 120 SkAutoMutexAcquire ac(&gAshmemMutex); |
109 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); | 121 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
110 #ifdef SK_DEBUG | |
111 SkASSERT(!rec->fPinned); | |
112 #endif | |
113 this->removeRec(rec); | |
114 } | |
115 | |
116 void SkAshmemImageCache::removeRec(SkAshmemImageCache::AshmemRec* rec) { | |
117 munmap(rec->fAddr, rec->fSize); | 122 munmap(rec->fAddr, rec->fSize); |
118 close(rec->fFD); | 123 close(rec->fFD); |
119 #ifdef SK_DEBUG | 124 #ifdef SK_DEBUG |
| 125 SkASSERT(!rec->fPinned); |
120 int index = this->findRec(rec); | 126 int index = this->findRec(rec); |
121 SkASSERT(index >= 0); | 127 SkASSERT(index >= 0); |
122 fRecs.remove(index); | 128 fRecs.remove(index); |
123 #endif | 129 #endif |
124 SkDELETE(rec); | 130 SkDELETE(rec); |
125 } | 131 } |
126 | 132 |
127 #ifdef SK_DEBUG | 133 #ifdef SK_DEBUG |
128 void SkAshmemImageCache::appendRec(SkAshmemImageCache::AshmemRec* rec) { | 134 void SkAshmemImageCache::appendRec(SkAshmemImageCache::AshmemRec* rec) { |
129 int index = this->findRec(rec); | 135 int index = this->findRec(rec); |
(...skipping 16 matching lines...) Expand all Loading... |
146 SkAutoMutexAcquire ac(&gAshmemMutex); | 152 SkAutoMutexAcquire ac(&gAshmemMutex); |
147 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); | 153 AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
148 int index = this->findRec(rec); | 154 int index = this->findRec(rec); |
149 if (index < 0) { | 155 if (index < 0) { |
150 return SkImageCache::kThrownAway_CacheStatus; | 156 return SkImageCache::kThrownAway_CacheStatus; |
151 } | 157 } |
152 return rec->fPinned ? SkImageCache::kPinned_CacheStatus | 158 return rec->fPinned ? SkImageCache::kPinned_CacheStatus |
153 : SkImageCache::kUnpinned_CacheStatus; | 159 : SkImageCache::kUnpinned_CacheStatus; |
154 } | 160 } |
155 #endif | 161 #endif |
OLD | NEW |