зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset d55b7b5e620c (bug 1852513) for causing gradient-eval-* failures. CLOSED TREE
This commit is contained in:
Родитель
72a8dd101f
Коммит
3d9f0b337e
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче