[Webkit-unassigned] [Bug 103693] Remove conversion to/from float and float division from ImageFrame::setRGBA
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Thu Nov 29 17:43:56 PST 2012
https://bugs.webkit.org/show_bug.cgi?id=103693
Viatcheslav Ostapenko <ostap73 at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Attachment #176859|ImageDecoderPerf.cpp |setRGBPerf.cpp
filename| |
--- Comment #2 from Viatcheslav Ostapenko <ostap73 at gmail.com> 2012-11-29 17:46:14 PST ---
(From update of attachment 176859)
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned PixelData;
bool m_premultiplyAlpha = true;
inline void setRGBA_orig(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
if (m_premultiplyAlpha && a < 255) {
if (!a) {
*dest = 0;
return;
}
float alphaPercent = a / 255.0f;
r = static_cast<unsigned>(r * alphaPercent);
g = static_cast<unsigned>(g * alphaPercent);
b = static_cast<unsigned>(b * alphaPercent);
}
*dest = (a << 24 | r << 16 | g << 8 | b);
}
const int fixPointShift = 24;
const unsigned fixPointMult = unsigned(1.0 / 255.0 * (1 << fixPointShift)) + 1;
inline void setRGBA_fixPointMult(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
if (m_premultiplyAlpha && a < 255) {
if (!a) {
*dest = 0;
return;
}
unsigned alphaMult = a * fixPointMult;
r = (r * alphaMult) >> fixPointShift;
g = (g * alphaMult) >> fixPointShift;
b = (b * alphaMult) >> fixPointShift;
}
*dest = (a << 24 | r << 16 | g << 8 | b);
}
inline void setRGBA_integerDiv(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
if (m_premultiplyAlpha && a < 255) {
if (!a) {
*dest = 0;
return;
}
r = r * a / 255;
g = g * a / 255;
b = b * a / 255;
}
*dest = (a << 24 | r << 16 | g << 8 | b);
}
inline unsigned fastDiv255(unsigned a)
{
return (a + (a >> 8) + 1) >> 8;
}
inline void setRGBA_fastDiv255(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
if (m_premultiplyAlpha && a < 255) {
if (!a) {
*dest = 0;
return;
}
r = fastDiv255(r * a);
g = fastDiv255(g * a);
b = fastDiv255(b * a);
}
*dest = (a << 24 | r << 16 | g << 8 | b);
}
const unsigned bufferSize = 256 * 1024 * 1024; // Something bigger than all cpu caches
PixelData source[bufferSize];
PixelData dest[bufferSize];
inline unsigned char* castUChar(void* p)
{
return static_cast<unsigned char *>(p);
}
void runTests()
{
unsigned i, tmp;
unsigned char *bytesEnd = castUChar(&(source[bufferSize]));
PixelData* destPosition;
unsigned char *bytes;
clock_t start;
clock_t end;
start = clock();
for(bytes = castUChar(&(source[0])), destPosition = &dest[0]; bytes < bytesEnd; bytes += 4, destPosition++) {
setRGBA_integerDiv(destPosition, bytes[0], bytes[1], bytes[2], bytes[3]);
}
end = clock();
printf("1: %lu\t", end - start);
start = clock();
for(bytes = castUChar(&(source[0])), destPosition = &dest[0]; bytes < bytesEnd; bytes += 4, destPosition++) {
setRGBA_fastDiv255(destPosition, bytes[0], bytes[1], bytes[2], bytes[3]);
}
end = clock();
printf("2: %lu\t", end - start);
start = clock();
for(bytes = castUChar(&(source[0])), destPosition = &dest[0]; bytes < bytesEnd; bytes += 4, destPosition++) {
setRGBA_fixPointMult(destPosition, bytes[0], bytes[1], bytes[2], bytes[3]);
}
end = clock();
printf("3: %lu\t", end - start);
start = clock();
for(bytes = castUChar(&(source[0])), destPosition = &dest[0]; bytes < bytesEnd; bytes += 4, destPosition++) {
setRGBA_orig(destPosition, bytes[0], bytes[1], bytes[2], bytes[3]);
}
end = clock();
printf("4: %lu\n", end - start);
}
int main(int argc, char *argv[])
{
unsigned i, j;
unsigned diffValues = 0;
// Fastdiv and fixedpoint mult precision check
for(i = 0; i < 256; i++) {
for(j = 0; j < 256; j++) {
unsigned a = fastDiv255(i * j);
unsigned alphaMult = i * fixPointMult;
unsigned b = (j * alphaMult) >> fixPointShift;
unsigned c = j * i / 255;
float alphaPercent = i / 255.0f;
unsigned d = static_cast<unsigned>(j * alphaPercent);
if (a != d || b != d || c != d) {
printf("Alpha; %u,\t color: %u,\t a: %u,\t b: %u,\t c: %u,\t d: %u\n", i, j, a, b, c, d);
diffValues++;
}
}
}
printf("Different %u values\n", diffValues);
memset(&dest[0], 0, sizeof(dest));
do { // Run benchmarks with both values of m_premultiplyAlpha to make sure it is not optimized out
printf("Premultiply Alpha: %d\n",m_premultiplyAlpha);
printf("All 0 buffer:\n");
memset(&source[0], 0, sizeof(source));
runTests();
printf("All 255 buffer:\n");
memset(&source[0], 255, sizeof(source));
runTests();
printf("Pseudo random buffer:\n");
// Fill buffer with 25% 0 alpha, 25% 255 alpha and other random values
for(i = 0; i < bufferSize; i += 4) {
source[i] = PixelData(rand()) & 0xFFFFFF;
source[i] = PixelData(rand());
source[i] = PixelData(rand()) | 0xFF000000;
source[i] = PixelData(rand());
}
runTests();
m_premultiplyAlpha = 1 - m_premultiplyAlpha;
} while(m_premultiplyAlpha == false);
}
--
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
More information about the webkit-unassigned
mailing list