Add GrNextSizePow2

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4069

BUG=skia:5882

Change-Id: Ib9af5918716be594c3c07239eca179dbb4eb8566
Reviewed-on: https://skia-review.googlesource.com/4069
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2016-10-28 12:15:03 -04:00 committed by Skia Commit-Bot
parent 0186661e85
commit 9e38047c56
3 changed files with 62 additions and 2 deletions

View File

@ -154,6 +154,28 @@ static inline uint32_t GrNextPow2(uint32_t n) {
return n ? (1 << (32 - SkCLZ(n - 1))) : 1;
}
/**
* Returns the next power of 2 >= n or n if the next power of 2 can't be represented by size_t.
*/
static inline size_t GrNextSizePow2(size_t n) {
constexpr int kNumSizeTBits = 8 * sizeof(size_t);
constexpr size_t kHighBitSet = size_t(1) << (kNumSizeTBits - 1);
if (!n) {
return 1;
} else if (n >= kHighBitSet) {
return n;
}
n--;
uint32_t shift = 1;
while (shift < kNumSizeTBits) {
n |= n >> shift;
shift <<= 1;
}
return n + 1;
}
static inline int GrNextPow2(int n) {
SkASSERT(n >= 0); // this impl only works for non-neg.
return n ? (1 << (32 - SkCLZ(n - 1))) : 1;

View File

@ -109,8 +109,8 @@ GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedTyp
}
// bin by pow2 with a reasonable min
static const uint32_t MIN_SIZE = 1 << 12;
size_t allocSize = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
static const size_t MIN_SIZE = 1 << 12;
size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
GrScratchKey key;
GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);

View File

@ -685,3 +685,41 @@ DEF_TEST(divmod_s32, r) {
DEF_TEST(divmod_s64, r) {
test_divmod<int64_t>(r);
}
static void test_nextsizepow2(skiatest::Reporter* r, size_t test, size_t expectedAns) {
size_t ans = GrNextSizePow2(test);
REPORTER_ASSERT(r, ans == expectedAns);
//SkDebugf("0x%zx -> 0x%zx (0x%zx)\n", test, ans, expectedAns);
}
DEF_TEST(GrNextSizePow2, reporter) {
constexpr int kNumSizeTBits = 8 * sizeof(size_t);
size_t test = 0, expectedAns = 1;
test_nextsizepow2(reporter, test, expectedAns);
test = 1; expectedAns = 1;
for (int i = 1; i < kNumSizeTBits; ++i) {
test_nextsizepow2(reporter, test, expectedAns);
test++;
expectedAns <<= 1;
test_nextsizepow2(reporter, test, expectedAns);
test = expectedAns;
}
// For the remaining three tests there is no higher power (of 2)
test = 0x1;
test <<= kNumSizeTBits-1;
test_nextsizepow2(reporter, test, test);
test++;
test_nextsizepow2(reporter, test, test);
test_nextsizepow2(reporter, SIZE_MAX, SIZE_MAX);
}