diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrBinHashKey.h | 74 | ||||
-rw-r--r-- | src/gpu/GrResourceCache.h | 67 | ||||
-rw-r--r-- | src/gpu/GrTHashTable.h | 24 | ||||
-rw-r--r-- | src/gpu/GrTextStrike_impl.h | 8 | ||||
-rw-r--r-- | src/gpu/SkGrFontScaler.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.h | 17 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 15 | ||||
-rw-r--r-- | src/gpu/gr_unittests.cpp | 80 |
8 files changed, 184 insertions, 103 deletions
diff --git a/src/gpu/GrBinHashKey.h b/src/gpu/GrBinHashKey.h index 585a1a1c01..7d4aa0fbe8 100644 --- a/src/gpu/GrBinHashKey.h +++ b/src/gpu/GrBinHashKey.h @@ -13,19 +13,37 @@ #include "GrTypes.h" /** - * GrBinHashKey is a hash key class that can take a data chunk of any predetermined - * length. The hash function used is the One-at-a-Time Hash - * (http://burtleburtle.net/bob/hash/doobs.html). + * Hash function class that can take a data chunk of any predetermined length. The hash function + * used is the One-at-a-Time Hash (http://burtleburtle.net/bob/hash/doobs.html). + * + * Keys are computed from ENTRY objects. ENTRY must be fully ordered by a member: + * int compare(const GrTBinHashKey<ENTRY, ..>& k); + * which returns negative if the ENTRY < k, 0 if it equals k, and positive if k < the ENTRY. + * Additionally, ENTRY must be flattenable into the key using setKeyData. + * + * This class satisfies the requirements to be a key for a GrTHashTable. */ -template<size_t KEY_SIZE> -class GrBinHashKey { +template<typename ENTRY, size_t KEY_SIZE> +class GrTBinHashKey { public: enum { kKeySize = KEY_SIZE }; - GrBinHashKey() { + GrTBinHashKey() { this->reset(); } + GrTBinHashKey(const GrTBinHashKey<ENTRY, KEY_SIZE>& other) { + *this = other; + } + + GrTBinHashKey<ENTRY, KEY_SIZE>& operator=(const GrTBinHashKey<ENTRY, KEY_SIZE>& other) { + memcpy(this, &other, sizeof(*this)); + return *this; + } + + ~GrTBinHashKey() { + } + void reset() { fHash = 0; #ifdef SK_DEBUG @@ -34,49 +52,39 @@ public: } void setKeyData(const uint32_t* SK_RESTRICT data) { - SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch); + SkASSERT(GrIsALIGN4(KEY_SIZE)); memcpy(&fData, data, KEY_SIZE); uint32_t hash = 0; size_t len = KEY_SIZE; while (len >= 4) { hash += *data++; - hash += (hash << 10); + hash += (fHash << 10); hash ^= (hash >> 6); len -= 4; } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); + hash += (fHash << 3); + hash ^= (fHash >> 11); + hash += (fHash << 15); #ifdef SK_DEBUG fIsValid = true; #endif fHash = hash; } - bool operator==(const GrBinHashKey<KEY_SIZE>& key) const { + int compare(const GrTBinHashKey<ENTRY, KEY_SIZE>& key) const { SkASSERT(fIsValid && key.fIsValid); - if (fHash != key.fHash) { - return false; - } - for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) { - if (fData[i] != key.fData[i]) { - return false; - } - } - return true; + return memcmp(fData, key.fData, KEY_SIZE); } - bool operator<(const GrBinHashKey<KEY_SIZE>& key) const { - SkASSERT(fIsValid && key.fIsValid); - for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) { - if (fData[i] < key.fData[i]) { - return true; - } else if (fData[i] > key.fData[i]) { - return false; - } - } - return false; + static bool EQ(const ENTRY& entry, const GrTBinHashKey<ENTRY, KEY_SIZE>& key) { + SkASSERT(key.fIsValid); + return 0 == entry.compare(key); + } + + static bool LT(const ENTRY& entry, const GrTBinHashKey<ENTRY, KEY_SIZE>& key) { + SkASSERT(key.fIsValid); + return entry.compare(key) < 0; } uint32_t getHash() const { @@ -86,12 +94,12 @@ public: const uint8_t* getData() const { SkASSERT(fIsValid); - return reinterpret_cast<const uint8_t*>(fData); + return fData; } private: uint32_t fHash; - uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage. + uint8_t fData[KEY_SIZE]; // Buffer for key storage #ifdef SK_DEBUG public: diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h index ca30732bbc..38378ac771 100644 --- a/src/gpu/GrResourceCache.h +++ b/src/gpu/GrResourceCache.h @@ -54,7 +54,7 @@ public: } GrResourceKey() { - fKey.reset(); + fKey.fHashedKey.reset(); } void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { @@ -63,34 +63,41 @@ public: //!< returns hash value [0..kHashMask] for the key int getHash() const { - return fKey.getHash() & kHashMask; + return fKey.fHashedKey.getHash() & kHashMask; } bool isScratch() const { return ScratchDomain() == - *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + + *reinterpret_cast<const GrCacheID::Domain*>(fKey.fHashedKey.getData() + kCacheIDDomainOffset); } ResourceType getResourceType() const { - return *reinterpret_cast<const ResourceType*>(fKey.getData() + + return *reinterpret_cast<const ResourceType*>(fKey.fHashedKey.getData() + kResourceTypeOffset); } ResourceFlags getResourceFlags() const { - return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + + return *reinterpret_cast<const ResourceFlags*>(fKey.fHashedKey.getData() + kResourceFlagsOffset); } - bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; } - bool operator<(const GrResourceKey& other) const { return fKey < other.fKey; } + int compare(const GrResourceKey& other) const { + return fKey.fHashedKey.compare(other.fKey.fHashedKey); + } - static bool LessThan(const GrResourceEntry& entry, const GrResourceKey& key); - static bool Equals(const GrResourceEntry& entry, const GrResourceKey& key); -#ifdef SK_DEBUG - static bool LessThan(const GrResourceEntry& a, const GrResourceEntry& b); - static bool Equals(const GrResourceEntry& a, const GrResourceEntry& b); -#endif + static bool LT(const GrResourceKey& a, const GrResourceKey& b) { + return a.compare(b) < 0; + } + + static bool EQ(const GrResourceKey& a, const GrResourceKey& b) { + return 0 == a.compare(b); + } + + inline static bool LT(const GrResourceEntry& entry, const GrResourceKey& key); + inline static bool EQ(const GrResourceEntry& entry, const GrResourceKey& key); + inline static bool LT(const GrResourceEntry& a, const GrResourceEntry& b); + inline static bool EQ(const GrResourceEntry& a, const GrResourceEntry& b); private: enum { @@ -118,9 +125,21 @@ private: memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType)); memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags)); memset(k + kPadOffset, 0, kPadSize); - fKey.setKeyData(keyData.fKey32); + fKey.fHashedKey.setKeyData(keyData.fKey32); } - GrBinHashKey<kKeySize> fKey; + + struct Key; + typedef GrTBinHashKey<Key, kKeySize> HashedKey; + + struct Key { + int compare(const HashedKey& hashedKey) const { + return fHashedKey.compare(hashedKey); + } + + HashedKey fHashedKey; + }; + + Key fKey; }; // The cache listens for these messages to purge junk resources proactively. @@ -155,23 +174,21 @@ private: friend class GrDLinkedList; }; -inline bool GrResourceKey::LessThan(const GrResourceEntry& entry, const GrResourceKey& key) { - return entry.key() < key; +bool GrResourceKey::LT(const GrResourceEntry& entry, const GrResourceKey& key) { + return LT(entry.key(), key); } -inline bool GrResourceKey::Equals(const GrResourceEntry& entry, const GrResourceKey& key) { - return entry.key() == key; +bool GrResourceKey::EQ(const GrResourceEntry& entry, const GrResourceKey& key) { + return EQ(entry.key(), key); } -#ifdef SK_DEBUG -inline bool GrResourceKey::LessThan(const GrResourceEntry& a, const GrResourceEntry& b) { - return a.key() < b.key(); +bool GrResourceKey::LT(const GrResourceEntry& a, const GrResourceEntry& b) { + return LT(a.key(), b.key()); } -inline bool GrResourceKey::Equals(const GrResourceEntry& a, const GrResourceEntry& b) { - return a.key() == b.key(); +bool GrResourceKey::EQ(const GrResourceEntry& a, const GrResourceEntry& b) { + return EQ(a.key(), b.key()); } -#endif /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrTHashTable.h b/src/gpu/GrTHashTable.h index 83462c70c9..3b32977846 100644 --- a/src/gpu/GrTHashTable.h +++ b/src/gpu/GrTHashTable.h @@ -16,10 +16,8 @@ /** * Key needs - * static bool Equals(const Entry&, const Key&); - * static bool LessThan(const Entry&, const Key&); - * static bool Equals(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called - * static bool LessThan(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called + * static bool EQ(const Entry&, const HashKey&); + * static bool LT(const Entry&, const HashKey&); * uint32_t getHash() const; * * Allows duplicate key entries but on find you may get @@ -92,7 +90,7 @@ int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const { int low = 0; while (high > low) { int index = (low + high) >> 1; - if (Key::LessThan(*array[index], key)) { + if (Key::LT(*array[index], key)) { low = index + 1; } else { high = index; @@ -100,15 +98,15 @@ int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const { } // check if we found it - if (Key::Equals(*array[high], key)) { + if (Key::EQ(*array[high], key)) { // above search should have found the first occurrence if there // are multiple. - SkASSERT(0 == high || Key::LessThan(*array[high - 1], key)); + SkASSERT(0 == high || Key::LT(*array[high - 1], key)); return high; } // now return the ~ of where we should insert it - if (Key::LessThan(*array[high], key)) { + if (Key::LT(*array[high], key)) { high += 1; } return ~high; @@ -121,7 +119,7 @@ T* GrTHashTable<T, Key, kHashBits>::find(const Key& key, Filter filter) const { int hashIndex = hash2Index(key.getHash()); T* elem = fHash[hashIndex]; - if (NULL != elem && Key::Equals(*elem, key) && filter(elem)) { + if (NULL != elem && Key::EQ(*elem, key) && filter(elem)) { return elem; } @@ -135,9 +133,9 @@ T* GrTHashTable<T, Key, kHashBits>::find(const Key& key, Filter filter) const { // above search should have found the first occurrence if there // are multiple. - SkASSERT(0 == index || Key::LessThan(*array[index - 1], key)); + SkASSERT(0 == index || Key::LT(*array[index - 1], key)); - for ( ; index < count() && Key::Equals(*array[index], key); ++index) { + for ( ; index < count() && Key::EQ(*array[index], key); ++index) { if (filter(fSorted[index])) { // update the hash fHash[hashIndex] = fSorted[index]; @@ -194,8 +192,8 @@ template <typename T, typename Key, size_t kHashBits> void GrTHashTable<T, Key, kHashBits>::validate() const { int count = fSorted.count(); for (int i = 1; i < count; i++) { - SkASSERT(Key::LessThan(*fSorted[i - 1], *fSorted[i]) || - Key::Equals(*fSorted[i - 1], *fSorted[i])); + SkASSERT(Key::LT(*fSorted[i - 1], *fSorted[i]) || + Key::EQ(*fSorted[i - 1], *fSorted[i])); } } diff --git a/src/gpu/GrTextStrike_impl.h b/src/gpu/GrTextStrike_impl.h index 0691eaa643..42971855ff 100644 --- a/src/gpu/GrTextStrike_impl.h +++ b/src/gpu/GrTextStrike_impl.h @@ -19,10 +19,10 @@ public: intptr_t getHash() const { return fFontScalerKey->getHash(); } - static bool LessThan(const GrTextStrike& strike, const Key& key) { + static bool LT(const GrTextStrike& strike, const Key& key) { return *strike.getFontScalerKey() < *key.fFontScalerKey; } - static bool Equals(const GrTextStrike& strike, const Key& key) { + static bool EQ(const GrTextStrike& strike, const Key& key) { return *strike.getFontScalerKey() == *key.fFontScalerKey; } @@ -88,10 +88,10 @@ public: uint32_t getHash() const { return fPackedID; } - static bool LessThan(const GrGlyph& glyph, const Key& key) { + static bool LT(const GrGlyph& glyph, const Key& key) { return glyph.fPackedID < key.fPackedID; } - static bool Equals(const GrGlyph& glyph, const Key& key) { + static bool EQ(const GrGlyph& glyph, const Key& key) { return glyph.fPackedID == key.fPackedID; } diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp index 1ca9357c6b..651486665b 100644 --- a/src/gpu/SkGrFontScaler.cpp +++ b/src/gpu/SkGrFontScaler.cpp @@ -85,8 +85,6 @@ GrMaskFormat SkGrFontScaler::getMaskFormat() { return kA8_GrMaskFormat; case SkMask::kLCD16_Format: return kA565_GrMaskFormat; - // TODO: properly support kARGB32_Format. - case SkMask::kARGB32_Format: case SkMask::kLCD32_Format: return kA888_GrMaskFormat; default: diff --git a/src/gpu/effects/GrTextureStripAtlas.h b/src/gpu/effects/GrTextureStripAtlas.h index e06e273e26..e56e736d77 100644 --- a/src/gpu/effects/GrTextureStripAtlas.h +++ b/src/gpu/effects/GrTextureStripAtlas.h @@ -136,15 +136,12 @@ private: // Hash table entry for atlases class AtlasEntry; - class AtlasHashKey : public GrBinHashKey<sizeof(GrTextureStripAtlas::Desc)> { - public: - static bool Equals(const AtlasEntry& entry, const AtlasHashKey& key); - static bool LessThan(const AtlasEntry& entry, const AtlasHashKey& key); - }; + typedef GrTBinHashKey<AtlasEntry, sizeof(GrTextureStripAtlas::Desc)> AtlasHashKey; class AtlasEntry : public ::SkNoncopyable { public: AtlasEntry() : fAtlas(NULL) {} ~AtlasEntry() { SkDELETE(fAtlas); } + int compare(const AtlasHashKey& key) const { return fKey.compare(key); } AtlasHashKey fKey; GrTextureStripAtlas* fAtlas; }; @@ -181,14 +178,4 @@ private: SkTDArray<AtlasRow*> fKeyTable; }; -inline bool GrTextureStripAtlas::AtlasHashKey::Equals(const AtlasEntry& entry, - const AtlasHashKey& key) { - return entry.fKey == key; -} - -inline bool GrTextureStripAtlas::AtlasHashKey::LessThan(const AtlasEntry& entry, - const AtlasHashKey& key) { - return entry.fKey < key; -} - #endif diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 00d27b31ef..9cf39b6534 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1276,7 +1276,6 @@ void GrGpuGL::onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) { return; } } - this->flushRenderTarget(rect); GrAutoTRestore<ScissorState> asr(&fScissorState); fScissorState.fEnabled = (NULL != rect); @@ -1523,16 +1522,10 @@ void GrGpuGL::flushRenderTarget(const SkIRect* bound) { if (fHWBoundRenderTarget != rt) { GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); #ifdef SK_DEBUG - // don't do this check in Chromium -- this is causing - // lots of repeated command buffer flushes when the compositor is - // rendering with Ganesh, which is really slow; even too slow for - // Debug mode. - if (!this->glContext().info().isChromium()) { - GrGLenum status; - GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); - if (status != GR_GL_FRAMEBUFFER_COMPLETE) { - GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status); - } + GrGLenum status; + GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); + if (status != GR_GL_FRAMEBUFFER_COMPLETE) { + GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status); } #endif fHWBoundRenderTarget = rt; diff --git a/src/gpu/gr_unittests.cpp b/src/gpu/gr_unittests.cpp new file mode 100644 index 0000000000..ae9f67f28e --- /dev/null +++ b/src/gpu/gr_unittests.cpp @@ -0,0 +1,80 @@ + +/* + * Copyright 2010 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrBinHashKey.h" +#include "GrDrawTarget.h" +#include "SkMatrix.h" +#include "GrRedBlackTree.h" + +// FIXME: needs to be in a header +void gr_run_unittests(); + +// If we aren't inheriting these as #defines from elsewhere, +// clang demands they be declared before we #include the template +// that relies on them. +#ifdef SK_DEBUG +static bool LT(const int& elem, int value) { + return elem < value; +} +static bool EQ(const int& elem, int value) { + return elem == value; +} +#include "GrTBSearch.h" + +static void test_bsearch() { + const int array[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99 + }; + + for (int n = 0; n < static_cast<int>(GR_ARRAY_COUNT(array)); ++n) { + for (int i = 0; i < n; i++) { + int index = GrTBSearch<int, int>(array, n, array[i]); + SkASSERT(index == (int) i); + index = GrTBSearch<int, int>(array, n, -array[i]); + SkASSERT(index < 0); + } + } +} +#endif + +// bogus empty class for GrBinHashKey +class BogusEntry {}; + +static void test_binHashKey() +{ + const char* testStringA_ = "abcdABCD"; + const char* testStringB_ = "abcdBBCD"; + const uint32_t* testStringA = reinterpret_cast<const uint32_t*>(testStringA_); + const uint32_t* testStringB = reinterpret_cast<const uint32_t*>(testStringB_); + enum { + kDataLenUsedForKey = 8 + }; + + GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyA; + keyA.setKeyData(testStringA); + // test copy constructor and comparison + GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyA2(keyA); + SkASSERT(keyA.compare(keyA2) == 0); + SkASSERT(keyA.getHash() == keyA2.getHash()); + // test re-init + keyA2.setKeyData(testStringA); + SkASSERT(keyA.compare(keyA2) == 0); + SkASSERT(keyA.getHash() == keyA2.getHash()); + // test sorting + GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyB; + keyB.setKeyData(testStringB); + SkASSERT(keyA.compare(keyB) < 0); + SkASSERT(keyA.getHash() != keyB.getHash()); +} + + +void gr_run_unittests() { + SkDEBUGCODE(test_bsearch();) + test_binHashKey(); + GrRedBlackTree<int>::UnitTest(); +} |