diff options
-rw-r--r-- | include/core/SkString.h | 6 | ||||
-rw-r--r-- | include/core/SkTypes.h | 2 | ||||
-rw-r--r-- | src/core/SkTSort.h | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLExtensions.cpp | 25 |
4 files changed, 39 insertions, 10 deletions
diff --git a/include/core/SkString.h b/include/core/SkString.h index 4a6e2aa4e0..4366630ef2 100644 --- a/include/core/SkString.h +++ b/include/core/SkString.h @@ -244,4 +244,10 @@ private: /// Creates a new string and writes into it using a printf()-style format. SkString SkStringPrintf(const char* format, ...); +// Specialized to take advantage of SkString's fast swap path. The unspecialized function is +// declared in SkTypes.h and called by SkTSort. +template <> inline void SkTSwap(SkString& a, SkString& b) { + a.swap(b); +} + #endif diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h index cbba50cc1b..ae27089bf7 100644 --- a/include/core/SkTypes.h +++ b/include/core/SkTypes.h @@ -276,6 +276,8 @@ static inline int Sk32ToBool(uint32_t n) { return (n | (0-n)) >> 31; } +/** Generic swap function. Classes with efficient swaps should specialize this function to take + their fast path. This function is used by SkTSort. */ template <typename T> inline void SkTSwap(T& a, T& b) { T c(a); a = b; diff --git a/src/core/SkTSort.h b/src/core/SkTSort.h index 7d46ef9783..a5865a2892 100644 --- a/src/core/SkTSort.h +++ b/src/core/SkTSort.h @@ -92,7 +92,8 @@ void SkTHeapSort_SiftDown(T array[], size_t root, size_t bottom, C lessThan) { array[root-1] = x; } -/** Sorts the array of size count using comparator lessThan using a Heap Sort algorithm +/** Sorts the array of size count using comparator lessThan using a Heap Sort algorithm. Be sure to + * specialize SkTSwap if T has an efficient swap operation. * * @param array the array to be sorted. * @param count the number of elements in the array. @@ -180,7 +181,8 @@ template <typename T, typename C> void SkTIntroSort(int depth, T* left, T* right } } -/** Sorts the region from left to right using comparator lessThan using a Quick Sort algorithm. +/** Sorts the region from left to right using comparator lessThan using a Quick Sort algorithm. Be + * sure to specialize SkTSwap if T has an efficient swap operation. * * @param left the beginning of the region to be sorted. * @param right the end of the region to be sorted (inclusive). @@ -205,4 +207,14 @@ template <typename T> void SkTQSort(T** left, T** right) { SkTQSort(left, right, SkTPointerCompareLT<T>()); } +/** Adapts a tri-state SkTSearch comparison function to a bool less-than SkTSort functor */ +template <typename T, int (COMPARE)(const T*, const T*)> +class SkTSearchCompareLTFunctor { +public: + bool operator()(const T& a, const T& b) { + return COMPARE(&a, &b) < 0; + } +}; + + #endif diff --git a/src/gpu/gl/GrGLExtensions.cpp b/src/gpu/gl/GrGLExtensions.cpp index 9f31a054cc..2d8741479b 100644 --- a/src/gpu/gl/GrGLExtensions.cpp +++ b/src/gpu/gl/GrGLExtensions.cpp @@ -9,6 +9,15 @@ #include "gl/GrGLDefines.h" #include "gl/GrGLUtil.h" +#include "SkTSearch.h" +#include "SkTSort.h" + +namespace { +inline int extension_compare(const SkString* a, const SkString* b) { + return strcmp(a->c_str(), b->c_str()); +} +} + bool GrGLExtensions::init(GrGLBinding binding, GrGLGetStringProc getString, GrGLGetStringiProc getStringi, @@ -64,16 +73,16 @@ bool GrGLExtensions::init(GrGLBinding binding, } GrAssert(i == extensionCnt); } + SkTSearchCompareLTFunctor<SkString, extension_compare> cmp; + SkTQSort(&fStrings.front(), &fStrings.back(), cmp); return true; } bool GrGLExtensions::has(const char* ext) const { - // TODO: Sort the extensions and binary search. - int count = fStrings.count(); - for (int i = 0; i < count; ++i) { - if (fStrings[i].equals(ext)) { - return true; - } - } - return false; + SkString extensionStr(ext); + int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(), + fStrings.count(), + extensionStr, + sizeof(SkString)); + return idx >= 0; } |