mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 815473 - Replace runtime computed sUnpremultiplyTable/sPremultiplyTable with constants. r=roc
This commit is contained in:
parent
8b51d4f17e
commit
daa4759375
@ -525,8 +525,6 @@ NS_INTERFACE_MAP_END
|
||||
|
||||
// Initialize our static variables.
|
||||
uint32_t CanvasRenderingContext2D::sNumLivingContexts = 0;
|
||||
uint8_t (*CanvasRenderingContext2D::sUnpremultiplyTable)[256] = nullptr;
|
||||
uint8_t (*CanvasRenderingContext2D::sPremultiplyTable)[256] = nullptr;
|
||||
DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
|
||||
|
||||
|
||||
@ -551,10 +549,6 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
|
||||
}
|
||||
sNumLivingContexts--;
|
||||
if (!sNumLivingContexts) {
|
||||
delete[] sUnpremultiplyTable;
|
||||
delete[] sPremultiplyTable;
|
||||
sUnpremultiplyTable = nullptr;
|
||||
sPremultiplyTable = nullptr;
|
||||
NS_IF_RELEASE(sErrorTarget);
|
||||
}
|
||||
}
|
||||
@ -3325,33 +3319,6 @@ CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
|
||||
// device pixel getting/setting
|
||||
//
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::EnsureUnpremultiplyTable() {
|
||||
if (sUnpremultiplyTable)
|
||||
return;
|
||||
|
||||
// Infallably alloc the unpremultiply table.
|
||||
sUnpremultiplyTable = new uint8_t[256][256];
|
||||
|
||||
// It's important that the array be indexed first by alpha and then by rgb
|
||||
// value. When we unpremultiply a pixel, we're guaranteed to do three
|
||||
// lookups with the same alpha; indexing by alpha first makes it likely that
|
||||
// those three lookups will be close to one another in memory, thus
|
||||
// increasing the chance of a cache hit.
|
||||
|
||||
// a == 0 case
|
||||
for (uint32_t c = 0; c <= 255; c++) {
|
||||
sUnpremultiplyTable[0][c] = c;
|
||||
}
|
||||
|
||||
for (int a = 1; a <= 255; a++) {
|
||||
for (int c = 0; c <= 255; c++) {
|
||||
sUnpremultiplyTable[a][c] = (uint8_t)((c * 255) / a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<ImageData>
|
||||
CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
|
||||
double aSy, double aSw,
|
||||
@ -3484,9 +3451,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
}
|
||||
}
|
||||
|
||||
// make sure sUnpremultiplyTable has been created
|
||||
EnsureUnpremultiplyTable();
|
||||
|
||||
// NOTE! dst is the same as src, and this relies on reading
|
||||
// from src and advancing that ptr before writing to dst.
|
||||
// NOTE! I'm not sure that it is, I think this comment might have been
|
||||
@ -3508,9 +3472,9 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
uint8_t b = *src++;
|
||||
#endif
|
||||
// Convert to non-premultiplied color
|
||||
*dst++ = sUnpremultiplyTable[a][r];
|
||||
*dst++ = sUnpremultiplyTable[a][g];
|
||||
*dst++ = sUnpremultiplyTable[a][b];
|
||||
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + r];
|
||||
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];
|
||||
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + b];
|
||||
*dst++ = a;
|
||||
}
|
||||
src += srcStride - (dstWriteRect.width * 4);
|
||||
@ -3521,25 +3485,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::EnsurePremultiplyTable() {
|
||||
if (sPremultiplyTable)
|
||||
return;
|
||||
|
||||
// Infallably alloc the premultiply table.
|
||||
sPremultiplyTable = new uint8_t[256][256];
|
||||
|
||||
// Like the unpremultiply table, it's important that we index the premultiply
|
||||
// table with the alpha value as the first index to ensure good cache
|
||||
// performance.
|
||||
|
||||
for (int a = 0; a <= 255; a++) {
|
||||
for (int c = 0; c <= 255; c++) {
|
||||
sPremultiplyTable[a][c] = (a * c + 254) / 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::EnsureErrorTarget()
|
||||
{
|
||||
@ -3662,9 +3607,6 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// ensure premultiply table has been created
|
||||
EnsurePremultiplyTable();
|
||||
|
||||
uint8_t *src = aData;
|
||||
uint8_t *dst = imgsurf->Data();
|
||||
|
||||
@ -3677,15 +3619,15 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
|
||||
|
||||
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
*dst++ = sPremultiplyTable[a][b];
|
||||
*dst++ = sPremultiplyTable[a][g];
|
||||
*dst++ = sPremultiplyTable[a][r];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
|
||||
*dst++ = a;
|
||||
#else
|
||||
*dst++ = a;
|
||||
*dst++ = sPremultiplyTable[a][r];
|
||||
*dst++ = sPremultiplyTable[a][g];
|
||||
*dst++ = sPremultiplyTable[a][b];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
|
||||
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -393,3 +393,9 @@ ifdef SOLARIS_SUNPRO_CXX
|
||||
gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: CONSTANT_TABLES
|
||||
CONSTANT_TABLES:
|
||||
$(PYTHON) $(srcdir)/genTables.py
|
||||
|
||||
gfxUtils.$(OBJ_SUFFIX): CONSTANT_TABLES
|
||||
|
12
gfx/thebes/genTables.py
Normal file
12
gfx/thebes/genTables.py
Normal file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
def table_generator(f):
|
||||
return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
|
||||
|
||||
f = open("sPremultiplyTable.h", "w")
|
||||
f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
|
||||
f.close()
|
||||
|
||||
f = open("sUnpremultiplyTable.h", "w")
|
||||
f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n")
|
||||
f.close()
|
@ -20,49 +20,20 @@ using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
static uint8_t sUnpremultiplyTable[256*256];
|
||||
static uint8_t sPremultiplyTable[256*256];
|
||||
static bool sTablesInitialized = false;
|
||||
const uint8_t gfxUtils::sPremultiplyTable[256*256] = {
|
||||
#include "sPremultiplyTable.h"
|
||||
};
|
||||
|
||||
const uint8_t gfxUtils::sUnpremultiplyTable[256*256] = {
|
||||
#include "sUnpremultiplyTable.h"
|
||||
};
|
||||
|
||||
static const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
||||
return sPremultiplyTable[a*256+v];
|
||||
return gfxUtils::sPremultiplyTable[a*256+v];
|
||||
}
|
||||
|
||||
static const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
|
||||
return sUnpremultiplyTable[a*256+v];
|
||||
}
|
||||
|
||||
static void
|
||||
CalculateTables()
|
||||
{
|
||||
// It's important that the array be indexed first by alpha and then by rgb
|
||||
// value. When we unpremultiply a pixel, we're guaranteed to do three
|
||||
// lookups with the same alpha; indexing by alpha first makes it likely that
|
||||
// those three lookups will be close to one another in memory, thus
|
||||
// increasing the chance of a cache hit.
|
||||
|
||||
// Unpremultiply table
|
||||
|
||||
// a == 0 case
|
||||
for (uint32_t c = 0; c <= 255; c++) {
|
||||
sUnpremultiplyTable[c] = c;
|
||||
}
|
||||
|
||||
for (int a = 1; a <= 255; a++) {
|
||||
for (int c = 0; c <= 255; c++) {
|
||||
sUnpremultiplyTable[a*256+c] = (uint8_t)((c * 255) / a);
|
||||
}
|
||||
}
|
||||
|
||||
// Premultiply table
|
||||
|
||||
for (int a = 0; a <= 255; a++) {
|
||||
for (int c = 0; c <= 255; c++) {
|
||||
sPremultiplyTable[a*256+c] = (a * c + 254) / 255;
|
||||
}
|
||||
}
|
||||
|
||||
sTablesInitialized = true;
|
||||
return gfxUtils::sUnpremultiplyTable[a*256+v];
|
||||
}
|
||||
|
||||
void
|
||||
@ -90,9 +61,6 @@ gfxUtils::PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sTablesInitialized)
|
||||
CalculateTables();
|
||||
|
||||
uint8_t *src = aSourceSurface->Data();
|
||||
uint8_t *dst = aDestSurface->Data();
|
||||
|
||||
@ -147,9 +115,6 @@ gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sTablesInitialized)
|
||||
CalculateTables();
|
||||
|
||||
uint8_t *src = aSourceSurface->Data();
|
||||
uint8_t *dst = aDestSurface->Data();
|
||||
|
||||
|
@ -125,6 +125,8 @@ public:
|
||||
unsigned char* aDestBuffer,
|
||||
int32_t aStride);
|
||||
|
||||
static const uint8_t sUnpremultiplyTable[256*256];
|
||||
static const uint8_t sPremultiplyTable[256*256];
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
/**
|
||||
* Writes a binary PNG file.
|
||||
|
Loading…
Reference in New Issue
Block a user