add SkChecksum as a static class, for the replacement API
after this lands, plan to deprecate/remove the older APIs Review URL: https://codereview.appspot.com/6356059 git-svn-id: http://skia.googlecode.com/svn/trunk@4457 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
54823c227d
commit
88db9ef0cd
@ -61,15 +61,33 @@ private:
|
||||
class ComputeChecksum64Bench : public ComputeChecksumBench {
|
||||
public:
|
||||
ComputeChecksum64Bench(void* param)
|
||||
: INHERITED(param, "64") { }
|
||||
|
||||
: INHERITED(param, "64") { }
|
||||
|
||||
protected:
|
||||
virtual void computeChecksum(const uint64_t* data, size_t len) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
volatile uint64_t result = SkComputeChecksum64(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef ComputeChecksumBench INHERITED;
|
||||
};
|
||||
|
||||
/*
|
||||
* Use SkComputeChecksum64 to compute a checksum on a datablock
|
||||
*/
|
||||
class ComputeChecksumXXBench : public ComputeChecksumBench {
|
||||
public:
|
||||
ComputeChecksumXXBench(void* param) : INHERITED(param, "XX") { }
|
||||
|
||||
protected:
|
||||
virtual void computeChecksum(const uint64_t* data, size_t len) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
volatile uint32_t result = SkChecksum::Compute(reinterpret_cast<const uint32_t*>(data), len);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef ComputeChecksumBench INHERITED;
|
||||
};
|
||||
@ -78,6 +96,8 @@ private:
|
||||
|
||||
static SkBenchmark* Fact0(void* p) { return new ComputeChecksum32Bench(p); }
|
||||
static SkBenchmark* Fact1(void* p) { return new ComputeChecksum64Bench(p); }
|
||||
static SkBenchmark* Fact2(void* p) { return new ComputeChecksumXXBench(p); }
|
||||
|
||||
static BenchRegistry gReg0(Fact0);
|
||||
static BenchRegistry gReg1(Fact1);
|
||||
static BenchRegistry gReg2(Fact2);
|
||||
|
@ -67,5 +67,78 @@ inline uint32_t SkComputeChecksum32(const uint32_t* ptr, size_t size) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
class SkChecksum : SkNoncopyable {
|
||||
private:
|
||||
/*
|
||||
* Our Rotate and Mash helpers are meant to automatically do the right
|
||||
* thing depending if sizeof(uintptr_t) is 4 or 8.
|
||||
*/
|
||||
enum {
|
||||
ROTR = 17,
|
||||
ROTL = sizeof(uintptr_t) * 8 - ROTR,
|
||||
HALFBITS = sizeof(uintptr_t) * 4
|
||||
};
|
||||
|
||||
static inline uintptr_t Mash(uintptr_t total, uintptr_t value) {
|
||||
return ((total >> ROTR) | (total << ROTL)) ^ value;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Compute a 32-bit checksum for a given data block
|
||||
*
|
||||
* @param data Memory address of the data block to be processed. Must be
|
||||
* 32-bit aligned.
|
||||
* @param size Size of the data block in bytes. Must be a multiple of 4.
|
||||
* @return checksum result
|
||||
*/
|
||||
static uint32_t Compute(const uint32_t* data, size_t size) {
|
||||
SkASSERT(SkIsAlign4(size));
|
||||
|
||||
/*
|
||||
* We want to let the compiler use 32bit or 64bit addressing and math
|
||||
* so we use uintptr_t as our magic type. This makes the code a little
|
||||
* more obscure (we can't hard-code 32 or 64 anywhere, but have to use
|
||||
* sizeof()).
|
||||
*/
|
||||
uintptr_t result = 0;
|
||||
const uintptr_t* ptr = reinterpret_cast<const uintptr_t*>(data);
|
||||
|
||||
/*
|
||||
* count the number of quad element chunks. This takes into account
|
||||
* if we're on a 32bit or 64bit arch, since we use sizeof(uintptr_t)
|
||||
* to compute how much to shift-down the size.
|
||||
*/
|
||||
int n4 = size / (sizeof(uintptr_t) << 2);
|
||||
for (int i = 0; i < n4; ++i) {
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
result = Mash(result, *ptr++);
|
||||
}
|
||||
size &= ((sizeof(uintptr_t) << 2) - 1);
|
||||
|
||||
data = reinterpret_cast<const uint32_t*>(ptr);
|
||||
const uint32_t* stop = data + (size >> 2);
|
||||
while (data < stop) {
|
||||
result = Mash(result, *data++);
|
||||
}
|
||||
|
||||
/*
|
||||
* smash us down to 32bits if we were 64. Note that when uintptr_t is
|
||||
* 32bits, this code-path should go away, but I still got a warning
|
||||
* when I wrote
|
||||
* result ^= result >> 32;
|
||||
* since >>32 is undefined for 32bit ints, hence the wacky HALFBITS
|
||||
* define.
|
||||
*/
|
||||
if (8 == sizeof(result)) {
|
||||
result ^= result >> HALFBITS;
|
||||
}
|
||||
return static_cast<uint32_t>(result);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user