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

Unified Diff: src/core/SkPtrRecorder.h

Issue 574773003: Refactor SkPtrSet Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkFlattenable.cpp ('k') | src/core/SkPtrRecorder.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPtrRecorder.h
diff --git a/src/core/SkPtrRecorder.h b/src/core/SkPtrRecorder.h
index 06e14ab6ec03de555e41a57274deec4424906afd..7759c530b2d201f7f23c0c08c08b58cfde8c5cf6 100644
--- a/src/core/SkPtrRecorder.h
+++ b/src/core/SkPtrRecorder.h
@@ -13,6 +13,7 @@
#include "SkRefCnt.h"
#include "SkFlattenable.h"
#include "SkTDArray.h"
+#include "SkTSearch.h"
/**
* Maintains a set of ptrs, assigning each a unique ID [1...N]. Duplicate ptrs
@@ -20,15 +21,30 @@
* and decPtr(). incPtr() is called each time a unique ptr is added ot the
* set. decPtr() is called on each ptr when the set is destroyed or reset.
*/
-class SkPtrSet : public SkRefCnt {
+template <typename T>
+class SkTPtrSet : public SkRefCnt {
public:
- SK_DECLARE_INST_COUNT(SkPtrSet)
+ SK_DECLARE_INST_COUNT(SkTPtrSet)
/**
* Search for the specified ptr in the set. If it is found, return its
* 32bit ID [1..N], or if not found, return 0. Always returns 0 for NULL.
*/
- uint32_t find(void*) const;
+ uint32_t find(T* ptr) const {
+ if (NULL == ptr) {
+ return 0;
+ }
+
+ int count = fList.count();
+ Pair pair;
+ pair.fPtr = ptr;
+
+ int index = SkTSearch<Pair, SkTPtrSet<T>::Less>(fList.begin(), count, pair, sizeof(pair));
+ if (index < 0) {
+ return 0;
+ }
+ return fList[index].fIndex;
+ }
/**
* Add the specified ptr to the set, returning a unique 32bit ID for it
@@ -36,7 +52,26 @@ public:
*
* If the ptr is NULL, it is not added, and 0 is returned.
*/
- uint32_t add(void*);
+ uint32_t add(T* ptr) {
+ if (NULL == ptr) {
+ return 0;
+ }
+
+ int count = fList.count();
+ Pair pair;
+ pair.fPtr = ptr;
+
+ int index = SkTSearch<Pair, SkTPtrSet<T>::Less>(fList.begin(), count, pair, sizeof(pair));
+ if (index < 0) {
+ index = ~index; // turn it back into an index for insertion
+ this->incPtr(ptr);
+ pair.fIndex = count + 1;
+ *fList.insert(index) = pair;
+ return count + 1;
+ } else {
+ return fList[index].fIndex;
+ }
+ }
/**
* Return the number of (non-null) ptrs in the set.
@@ -50,22 +85,58 @@ public:
*
* incPtr() and decPtr() are not called during this operation.
*/
- void copyToArray(void* array[]) const;
+ void copyToArray(T* array[]) const {
+ int count = fList.count();
+ if (count > 0) {
+ SkASSERT(array);
+ const Pair* p = fList.begin();
+ // p->fIndex is base-1, so we need to subtract to find its slot
+ for (int i = 0; i < count; i++) {
+ int index = p[i].fIndex - 1;
+ SkASSERT((unsigned)index < (unsigned)count);
+ array[index] = p[i].fPtr;
+ }
+ }
+ }
/**
* Call decPtr() on each ptr in the set, and the reset the size of the set
* to 0.
*/
- void reset();
+ void reset() {
+ Iter iter(*this);
+ for (T* ptr = iter.next(); NULL != ptr; ptr = iter.next()) {
+ this->decPtr(ptr);
+ }
-protected:
- virtual void incPtr(void*) {}
- virtual void decPtr(void*) {}
+ fList.reset();
+ }
+
+ class Iter {
+ public:
+ Iter(const SkTPtrSet<T>& set)
+ : fSet(set)
+ , fIndex(0) {}
+
+ T* next() {
+ if (fIndex >= fSet.fList.count()) {
+ return NULL;
+ }
+ return fSet.fList[fIndex++].fPtr;
+ }
+
+ private:
+ const SkTPtrSet<T>& fSet;
+ int fIndex;
+ };
private:
+ void incPtr(T*) {}
+ void decPtr(T*) {}
+
struct Pair {
- void* fPtr; // never NULL
- uint32_t fIndex; // 1...N
+ T* fPtr; // never NULL
+ uint32_t fIndex; // 1...N
};
// we store the ptrs in sorted-order (using Cmp) so that we can efficiently
@@ -74,48 +145,27 @@ private:
// is not related to its "index".
SkTDArray<Pair> fList;
- static bool Less(const Pair& a, const Pair& b);
+ static bool Less(const Pair& a, const Pair& b) {
+ return (char*)a.fPtr < (char*)b.fPtr;
+ }
typedef SkRefCnt INHERITED;
};
-/**
- * Templated wrapper for SkPtrSet, just meant to automate typecasting
- * parameters to and from void* (which the base class expects).
- */
-template <typename T> class SkTPtrSet : public SkPtrSet {
-public:
- uint32_t find(T ptr) {
- return this->INHERITED::find((void*)ptr);
- }
- uint32_t add(T ptr) {
- return this->INHERITED::add((void*)ptr);
- }
+template <>
+inline void SkTPtrSet<SkRefCnt>::incPtr(SkRefCnt* ptr) { ptr->ref(); }
- void copyToArray(T* array) const {
- this->INHERITED::copyToArray((void**)array);
- }
-
-private:
- typedef SkPtrSet INHERITED;
-};
+template <>
+inline void SkTPtrSet<SkRefCnt>::decPtr(SkRefCnt* ptr) { ptr->unref(); }
-/**
- * Subclass of SkTPtrSet specialed to call ref() and unref() when the
- * base class's incPtr() and decPtr() are called. This makes it a valid owner
- * of each ptr, which is released when the set is reset or destroyed.
- */
-class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
+class SkRefCntSet : public SkTPtrSet<SkRefCnt> {
public:
- virtual ~SkRefCntSet();
-
-protected:
- // overrides
- virtual void incPtr(void*);
- virtual void decPtr(void*);
+ virtual ~SkRefCntSet() {
+ this->reset();
+ }
};
-class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
+class SkFactorySet : public SkTPtrSet<SkFlattenable::FactoryRef> {};
/**
* Similar to SkFactorySet, but only allows Factorys that have registered names.
« no previous file with comments | « src/core/SkFlattenable.cpp ('k') | src/core/SkPtrRecorder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698