aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-16 18:21:56 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-16 18:21:56 +0000
commita02bc1519cf49afa31fb38bed097dd5014880d04 (patch)
tree64d0638ce6c287317467d07bb5f7aeeb290d7940 /src/core
parentb2aacb6dc29f853e3f37fad208ad8fe8c8138a03 (diff)
WeakRefCnt
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkTypefaceCache.cpp47
-rw-r--r--src/core/SkTypefaceCache.h11
2 files changed, 42 insertions, 16 deletions
diff --git a/src/core/SkTypefaceCache.cpp b/src/core/SkTypefaceCache.cpp
index f4397a6cf5..ee5ced908c 100644
--- a/src/core/SkTypefaceCache.cpp
+++ b/src/core/SkTypefaceCache.cpp
@@ -13,7 +13,9 @@
#define TYPEFACE_CACHE_LIMIT 128
-void SkTypefaceCache::add(SkTypeface* face, SkTypeface::Style requestedStyle) {
+void SkTypefaceCache::add(SkTypeface* face,
+ SkTypeface::Style requestedStyle,
+ bool strong) {
if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
this->purge(TYPEFACE_CACHE_LIMIT >> 2);
}
@@ -21,7 +23,12 @@ void SkTypefaceCache::add(SkTypeface* face, SkTypeface::Style requestedStyle) {
Rec* rec = fArray.append();
rec->fFace = face;
rec->fRequestedStyle = requestedStyle;
- face->ref();
+ rec->fStrong = strong;
+ if (strong) {
+ face->ref();
+ } else {
+ face->weak_ref();
+ }
}
SkTypeface* SkTypefaceCache::findByID(SkFontID fontID) const {
@@ -36,12 +43,20 @@ SkTypeface* SkTypefaceCache::findByID(SkFontID fontID) const {
return NULL;
}
-SkTypeface* SkTypefaceCache::findByProc(FindProc proc, void* ctx) const {
+SkTypeface* SkTypefaceCache::findByProcAndRef(FindProc proc, void* ctx) const {
const Rec* curr = fArray.begin();
const Rec* stop = fArray.end();
while (curr < stop) {
- if (proc(curr->fFace, curr->fRequestedStyle, ctx)) {
- return curr->fFace;
+ SkTypeface* currFace = curr->fFace;
+ if (proc(currFace, curr->fRequestedStyle, ctx)) {
+ if (curr->fStrong) {
+ currFace->ref();
+ return currFace;
+ } else if (currFace->try_ref()) {
+ return currFace;
+ } else {
+ //remove currFace from fArray?
+ }
}
curr += 1;
}
@@ -53,8 +68,15 @@ void SkTypefaceCache::purge(int numToPurge) {
int i = 0;
while (i < count) {
SkTypeface* face = fArray[i].fFace;
- if (1 == face->getRefCnt()) {
- face->unref();
+ bool strong = fArray[i].fStrong;
+ if ((strong && face->getRefCnt() == 1) ||
+ (!strong && face->weak_expired()))
+ {
+ if (strong) {
+ face->unref();
+ } else {
+ face->weak_unref();
+ }
fArray.remove(i);
--count;
if (--numToPurge == 0) {
@@ -84,9 +106,11 @@ SkFontID SkTypefaceCache::NewFontID() {
SK_DECLARE_STATIC_MUTEX(gMutex);
-void SkTypefaceCache::Add(SkTypeface* face, SkTypeface::Style requestedStyle) {
+void SkTypefaceCache::Add(SkTypeface* face,
+ SkTypeface::Style requestedStyle,
+ bool strong) {
SkAutoMutexAcquire ama(gMutex);
- Get().add(face, requestedStyle);
+ Get().add(face, requestedStyle, strong);
}
SkTypeface* SkTypefaceCache::FindByID(SkFontID fontID) {
@@ -96,8 +120,7 @@ SkTypeface* SkTypefaceCache::FindByID(SkFontID fontID) {
SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) {
SkAutoMutexAcquire ama(gMutex);
- SkTypeface* typeface = Get().findByProc(proc, ctx);
- SkSafeRef(typeface);
+ SkTypeface* typeface = Get().findByProcAndRef(proc, ctx);
return typeface;
}
@@ -119,7 +142,7 @@ static bool DumpProc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
void SkTypefaceCache::Dump() {
#ifdef SK_DEBUG
SkAutoMutexAcquire ama(gMutex);
- (void)Get().findByProc(DumpProc, NULL);
+ (void)Get().findByProcAndRef(DumpProc, NULL);
#endif
}
diff --git a/src/core/SkTypefaceCache.h b/src/core/SkTypefaceCache.h
index e65ec90d7d..b6cab8163f 100644
--- a/src/core/SkTypefaceCache.h
+++ b/src/core/SkTypefaceCache.h
@@ -26,7 +26,7 @@ public:
/**
* Callback for FindByProc. Returns true if the given typeface is a match
* for the given context. The passed typeface is owned by the cache and is
- * not additionally ref()ed.
+ * not additionally ref()ed. The typeface may be in the disposed state.
*/
typedef bool (*FindProc)(SkTypeface*, SkTypeface::Style, void* context);
@@ -42,7 +42,9 @@ public:
* whose refcnt is 1 (meaning only the cache is an owner) will be
* unref()ed.
*/
- static void Add(SkTypeface*, SkTypeface::Style requested);
+ static void Add(SkTypeface*,
+ SkTypeface::Style requested,
+ bool strong = true);
/**
* Search the cache for a typeface with the specified fontID (uniqueID).
@@ -75,14 +77,15 @@ public:
private:
static SkTypefaceCache& Get();
- void add(SkTypeface*, SkTypeface::Style requested);
+ void add(SkTypeface*, SkTypeface::Style requested, bool strong = true);
SkTypeface* findByID(SkFontID findID) const;
- SkTypeface* findByProc(FindProc proc, void* ctx) const;
+ SkTypeface* findByProcAndRef(FindProc proc, void* ctx) const;
void purge(int count);
void purgeAll();
struct Rec {
SkTypeface* fFace;
+ bool fStrong;
SkTypeface::Style fRequestedStyle;
};
SkTDArray<Rec> fArray;