зеркало из https://github.com/mozilla/gecko-dev.git
Bug 711043 - Make filters code more consistent in performance. r=roc
This commit is contained in:
Родитель
dc403d892f
Коммит
19b598c34c
|
@ -3800,17 +3800,10 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance,
|
|||
PRUint8* sourceData = aSources[0]->mImage->Data();
|
||||
PRUint8* targetData = aTarget->mImage->Data();
|
||||
PRUint32 stride = aTarget->mImage->Stride();
|
||||
PRUint32 xExt[4], yExt[4]; // X, Y indices of RGBA extrema
|
||||
PRUint8 extrema[4]; // RGBA magnitude of extrema
|
||||
PRUint16 op = mEnumAttributes[OPERATOR].GetAnimValue();
|
||||
|
||||
/* Scan the kernel for each pixel to determine max/min RGBA values. Note that
|
||||
* as we advance in the x direction, each kernel overlaps the previous kernel.
|
||||
* Thus, we can avoid iterating over the entire kernel by comparing the
|
||||
* leading edge of the new kernel against the extrema found in the previous
|
||||
* kernel. We must still scan the entire kernel if the previous extrema do
|
||||
* not fall within the current kernel or if we are starting a new row.
|
||||
*/
|
||||
// Scan the kernel for each pixel to determine max/min RGBA values.
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
PRUint32 startY = NS_MAX(0, y - ry);
|
||||
// We need to read pixels not just in 'rect', which is limited to
|
||||
|
@ -3822,39 +3815,18 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance,
|
|||
PRUint32 endX = NS_MIN(x + rx, instance->GetSurfaceWidth() - 1);
|
||||
PRUint32 targIndex = y * stride + 4 * x;
|
||||
|
||||
// We need to scan the entire kernel
|
||||
if (x == rect.x || xExt[0] <= startX || xExt[1] <= startX ||
|
||||
xExt[2] <= startX || xExt[3] <= startX) {
|
||||
PRUint32 i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
extrema[i] = sourceData[targIndex + i];
|
||||
}
|
||||
for (PRUint32 y1 = startY; y1 <= endY; y1++) {
|
||||
for (PRUint32 x1 = startX; x1 <= endX; x1++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
PRUint8 pixel = sourceData[y1 * stride + 4 * x1 + i];
|
||||
if ((extrema[i] >= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE) ||
|
||||
(extrema[i] <= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE)) {
|
||||
extrema[i] = pixel;
|
||||
xExt[i] = x1;
|
||||
yExt[i] = y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // We only need to look at the newest column
|
||||
for (PRUint32 y1 = startY; y1 <= endY; y1++) {
|
||||
for (PRUint32 i = 0; i < 4; i++) {
|
||||
extrema[i] = sourceData[targIndex + i];
|
||||
}
|
||||
for (PRUint32 y1 = startY; y1 <= endY; y1++) {
|
||||
for (PRUint32 x1 = startX; x1 <= endX; x1++) {
|
||||
for (PRUint32 i = 0; i < 4; i++) {
|
||||
PRUint8 pixel = sourceData[y1 * stride + 4 * endX + i];
|
||||
if ((extrema[i] >= pixel &&
|
||||
PRUint8 pixel = sourceData[y1 * stride + 4 * x1 + i];
|
||||
if ((extrema[i] > pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE) ||
|
||||
(extrema[i] <= pixel &&
|
||||
(extrema[i] < pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE)) {
|
||||
extrema[i] = pixel;
|
||||
xExt[i] = endX;
|
||||
yExt[i] = y1;
|
||||
extrema[i] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5119,14 +5091,11 @@ nsSVGFELightingElement::Filter(nsSVGFilterInstance *instance,
|
|||
S[2] = pointsAt[2] - lightPos[2];
|
||||
NORMALIZE(S);
|
||||
float dot = -DOT(L, S);
|
||||
if (dot < cosConeAngle) {
|
||||
color = NS_RGB(0, 0, 0);
|
||||
} else {
|
||||
float tmp = pow(dot, specularExponent);
|
||||
color = NS_RGB(PRUint8(NS_GET_R(lightColor) * tmp),
|
||||
PRUint8(NS_GET_G(lightColor) * tmp),
|
||||
PRUint8(NS_GET_B(lightColor) * tmp));
|
||||
}
|
||||
if (dot < cosConeAngle) dot = 0;
|
||||
float tmp = pow(dot, specularExponent);
|
||||
color = NS_RGB(PRUint8(NS_GET_R(lightColor) * tmp),
|
||||
PRUint8(NS_GET_G(lightColor) * tmp),
|
||||
PRUint8(NS_GET_B(lightColor) * tmp));
|
||||
} else {
|
||||
color = lightColor;
|
||||
}
|
||||
|
@ -5293,19 +5262,14 @@ nsSVGFEDiffuseLightingElement::LightPixel(const float *N, const float *L,
|
|||
float diffuseNL =
|
||||
mNumberAttributes[DIFFUSE_CONSTANT].GetAnimValue() * DOT(N, L);
|
||||
|
||||
if (diffuseNL > 0) {
|
||||
targetData[GFX_ARGB32_OFFSET_B] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_B(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_G] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_G(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_R] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_R(color)), 255U);
|
||||
} else {
|
||||
targetData[GFX_ARGB32_OFFSET_B] = 0;
|
||||
targetData[GFX_ARGB32_OFFSET_G] = 0;
|
||||
targetData[GFX_ARGB32_OFFSET_R] = 0;
|
||||
}
|
||||
if (diffuseNL < 0) diffuseNL = 0;
|
||||
|
||||
targetData[GFX_ARGB32_OFFSET_B] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_B(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_G] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_G(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_R] =
|
||||
NS_MIN(PRUint32(diffuseNL * NS_GET_R(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_A] = 255;
|
||||
}
|
||||
|
||||
|
@ -5460,27 +5424,24 @@ nsSVGFESpecularLightingElement::LightPixel(const float *N, const float *L,
|
|||
float kS = mNumberAttributes[SPECULAR_CONSTANT].GetAnimValue();
|
||||
float dotNH = DOT(N, H);
|
||||
|
||||
if (dotNH > 0 && kS > 0) {
|
||||
float specularNH =
|
||||
kS * pow(dotNH, mNumberAttributes[SPECULAR_EXPONENT].GetAnimValue());
|
||||
bool invalid = dotNH <= 0 || kS <= 0;
|
||||
kS *= invalid ? 0 : 1;
|
||||
PRUint8 minAlpha = invalid ? 255 : 0;
|
||||
|
||||
targetData[GFX_ARGB32_OFFSET_B] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_B(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_G] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_G(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_R] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_R(color)), 255U);
|
||||
float specularNH =
|
||||
kS * pow(dotNH, mNumberAttributes[SPECULAR_EXPONENT].GetAnimValue());
|
||||
|
||||
targetData[GFX_ARGB32_OFFSET_A] =
|
||||
NS_MAX(targetData[GFX_ARGB32_OFFSET_B],
|
||||
NS_MAX(targetData[GFX_ARGB32_OFFSET_G],
|
||||
targetData[GFX_ARGB32_OFFSET_R]));
|
||||
} else {
|
||||
targetData[GFX_ARGB32_OFFSET_B] = 0;
|
||||
targetData[GFX_ARGB32_OFFSET_G] = 0;
|
||||
targetData[GFX_ARGB32_OFFSET_R] = 0;
|
||||
targetData[GFX_ARGB32_OFFSET_A] = 255;
|
||||
}
|
||||
targetData[GFX_ARGB32_OFFSET_B] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_B(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_G] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_G(color)), 255U);
|
||||
targetData[GFX_ARGB32_OFFSET_R] =
|
||||
NS_MIN(PRUint32(specularNH * NS_GET_R(color)), 255U);
|
||||
|
||||
targetData[GFX_ARGB32_OFFSET_A] =
|
||||
NS_MAX(minAlpha, NS_MAX(targetData[GFX_ARGB32_OFFSET_B],
|
||||
NS_MAX(targetData[GFX_ARGB32_OFFSET_G],
|
||||
targetData[GFX_ARGB32_OFFSET_R])));
|
||||
}
|
||||
|
||||
//---------------------Image------------------------
|
||||
|
@ -5989,6 +5950,8 @@ nsSVGFEDisplacementMapElement::Filter(nsSVGFilterInstance *instance,
|
|||
PRUint8* targetData = aTarget->mImage->Data();
|
||||
PRUint32 stride = aTarget->mImage->Stride();
|
||||
|
||||
static PRUint8 dummyData[4] = { 0, 0, 0, 0 };
|
||||
|
||||
static const PRUint16 channelMap[5] = {
|
||||
0,
|
||||
GFX_ARGB32_OFFSET_R,
|
||||
|
@ -6011,13 +5974,20 @@ nsSVGFEDisplacementMapElement::Filter(nsSVGFilterInstance *instance,
|
|||
PRInt32 sourceY = y +
|
||||
NSToIntFloor(scaleOver255 * displacementData[targIndex + yChannel] +
|
||||
scaleAdjustment);
|
||||
if (sourceX < 0 || sourceX >= width ||
|
||||
sourceY < 0 || sourceY >= height) {
|
||||
*(PRUint32*)(targetData + targIndex) = 0;
|
||||
|
||||
bool outOfBounds = sourceX < 0 || sourceX >= width ||
|
||||
sourceY < 0 || sourceY >= height;
|
||||
PRUint8* data;
|
||||
PRInt32 multiplier;
|
||||
if (outOfBounds) {
|
||||
data = dummyData;
|
||||
multiplier = 0;
|
||||
} else {
|
||||
*(PRUint32*)(targetData + targIndex) =
|
||||
*(PRUint32*)(sourceData + sourceY * stride + 4 * sourceX);
|
||||
data = sourceData;
|
||||
multiplier = 1;
|
||||
}
|
||||
*(PRUint32*)(targetData + targIndex) =
|
||||
*(PRUint32*)(data + multiplier * (sourceY * stride + 4 * sourceX));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче