Backed out changeset d55b7b5e620c (bug 1852513) for causing gradient-eval-* failures. CLOSED TREE

This commit is contained in:
Natalia Csoregi 2023-11-02 13:51:15 +02:00
Родитель 72a8dd101f
Коммит 3d9f0b337e
1 изменённых файлов: 5 добавлений и 69 удалений

Просмотреть файл

@ -37,8 +37,6 @@
#include "mozilla/webrender/WebRenderAPI.h"
#include "Units.h"
#include "mozilla/StaticPrefs_layout.h"
using namespace mozilla;
using namespace mozilla::gfx;
@ -1197,73 +1195,11 @@ void nsCSSGradientRenderer::BuildWebRenderParameters(
aMode =
mGradient->Repeating() ? wr::ExtendMode::Repeat : wr::ExtendMode::Clamp;
// If the interpolation space is not sRGB, or if color management is active,
// we need to add additional stops so that the sRGB interpolation in WebRender
// still closely approximates the correct curves. We prefer avoiding this if
// the gradient is simple because WebRender has fast rendering of linear
// gradients with 2 stops (which represent >99% of all gradients on the web).
//
// WebRender doesn't have easy access to StyleAbsoluteColor and CMS display
// color correction, so we just expand the gradient stop table significantly
// so that gamma and hue interpolation errors become imperceptible.
//
// This always turns into 128 stops inside WebRender as an implementation
// detail, so the number of stops we generate here should have very little
// impact on performance as the texture upload is always the same, except for
// the special linear gradient 2-stop case.
//
// Color management bugs that this addresses:
// * https://bugzilla.mozilla.org/show_bug.cgi?id=939387
// * https://bugzilla.mozilla.org/show_bug.cgi?id=1248178
StyleColorInterpolationMethod styleColorInterpolationMethod =
mGradient->ColorInterpolationMethod();
if (mStops.Length() >= 2 &&
(styleColorInterpolationMethod.space != StyleColorSpace::Srgb ||
gfxPlatform::GetCMSMode() == CMSMode::All)) {
aStops.SetLengthAndRetainStorage(0);
// this could be made tunable, but at 1/32nd the error is very very small.
//
// note that we don't attempt to place the positions of these stops
// precisely at intervals, we just add this many extra stops across the
// range where it is convenient.
const int fullRangeExtraStops = 32;
// we always emit at least two stops (start and end) for each input stop,
// which avoids ambiguity with incomplete oklch/lch/hsv/hsb color stops for
// the last stop pair, where the last color stop can't be interpreted on its
// own because it actually depends on the previous stop.
aStops.SetLength(mStops.Length() * 2 + fullRangeExtraStops);
uint32_t outputStop = 0;
for (uint32_t i = 0; i < mStops.Length() - 1; i++) {
auto& start = mStops[i];
auto& end = i + 1 < mStops.Length() ? mStops[i + 1] : mStops[i];
StyleAbsoluteColor startColor = start.mColor;
StyleAbsoluteColor endColor = end.mColor;
int extraStops = (int)(floor(end.mPosition * fullRangeExtraStops) -
floor(start.mPosition * fullRangeExtraStops));
extraStops = clamped(extraStops, 1, fullRangeExtraStops);
float step = 1.0f / (float)extraStops;
for (int extraStop = 0;
extraStop <= extraStops && outputStop < aStops.Capacity();
extraStop++) {
auto lerp = (float)extraStop * step;
auto position =
start.mPosition + lerp * (end.mPosition - start.mPosition);
StyleAbsoluteColor color = Servo_InterpolateColor(
styleColorInterpolationMethod, &endColor, &startColor, lerp);
aStops[outputStop].color = wr::ToColorF(ToDeviceColor(color));
aStops[outputStop].color.a *= aOpacity;
aStops[outputStop].offset = (float)position;
outputStop++;
}
}
aStops.SetLength(outputStop);
} else {
aStops.SetLength(mStops.Length());
for (uint32_t i = 0; i < mStops.Length(); i++) {
aStops[i].color = wr::ToColorF(ToDeviceColor(mStops[i].mColor));
aStops[i].color.a *= aOpacity;
aStops[i].offset = (float)mStops[i].mPosition;
}
aStops.SetLength(mStops.Length());
for (uint32_t i = 0; i < mStops.Length(); i++) {
aStops[i].color = wr::ToColorF(ToDeviceColor(mStops[i].mColor));
aStops[i].color.a *= aOpacity;
aStops[i].offset = mStops[i].mPosition;
}
aLineStart = LayoutDevicePoint(mLineStart.x, mLineStart.y);