Changeset 262070 in webkit
- Timestamp:
- May 22, 2020 1:16:20 PM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r262069 r262070 1 2020-05-22 Sam Weinig <weinig@apple.com> 2 3 Extended Color Cleanup: Make alpha premultiplication code more consistent and clear regarding what works with extended colors 4 https://bugs.webkit.org/show_bug.cgi?id=212265 5 6 Reviewed by Simon Fraser. 7 8 - Adds premultiplied(const FloatComponents&) to do premutiplication directly on FloatComponents 9 rather than doing it on the ints and losing precision. 10 - Makes non-FloatComponent alpha premultiplication all take place only for SimpleColors as that 11 is what callers need. The existing premulitplication for ExtendedColors in blend() was incorrect 12 as it never did a conversion to sRGB. 13 - Adds new toSRGBASimpleColorLossy() (to complement toSRGBAComponentsLossy()). Will make it easy 14 to find all the conversions in the future. 15 - Broke non-premultiplying blend() out of blend() (removing parameter) and made a new blendWithoutPremultiply() 16 function for it (no callers needed to make this decision dynamically). 17 18 * css/CSSGradientValue.cpp: 19 (WebCore::CSSGradientValue::computeStops): 20 Use blendWithoutPremultiply() explicitly. 21 22 * platform/graphics/Color.h: 23 * platform/graphics/Color.cpp: 24 (WebCore::makePremultipliedRGBA): Renamed from premultipliedARGBFromColor and now only operates on SimpleColors. 25 (WebCore::makeUnPremultipliedRGBA): Renamed from colorFromPremultipliedARGB and now only operates on SimpleColors. 26 (WebCore::colorFromPremultipliedARGB): Deleted. 27 (WebCore::premultipliedARGBFromColor): Deleted. 28 29 (WebCore::Color::toSRGBASimpleColorLossy const): 30 Added. Useful for finding all non-colorspace preserving users of the color channels. 31 32 (WebCore::blend): 33 (WebCore::blendWithoutPremultiply): 34 Split these out from each other. Made blend() use toSRGBASimpleColorLossy() and do all 35 operations on SimpleColors directly. The old code that preported to work with extended 36 colors was nonsense as it didn't actually take the colorspaces into account, just grabbed 37 the channels regardless of space. 38 39 * platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp: 40 (WebCore::ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace): 41 Adopt update premulitiplication names and stay in SimpleColor for entire conversion. 42 43 * platform/graphics/cairo/NativeImageCairo.cpp: 44 (WebCore::nativeImageSinglePixelSolidColor): 45 Adopt update premulitiplication names. 46 47 * platform/graphics/ColorUtilities.cpp: 48 (WebCore::premultiplied): 49 * platform/graphics/ColorUtilities.h: 50 * platform/graphics/texmap/TextureMapperGL.cpp: 51 (WebCore::TextureMapperGL::drawBorder): 52 (WebCore::prepareFilterProgram): 53 (WebCore::TextureMapperGL::drawSolidColor): 54 Add and adopt premultiplied(const FloatComponents&). 55 1 56 2020-05-22 Andy Estes <aestes@apple.com> 2 57 -
trunk/Source/WebCore/css/CSSGradientValue.cpp
r259703 r262070 484 484 float multiplier = std::pow(relativeOffset, std::log(.5f) / std::log(midpoint)); 485 485 // FIXME: Why not premultiply here? 486 newStops[y].color = blend (color1, color2, multiplier, false /* do not premultiply */);486 newStops[y].color = blendWithoutPremultiply(color1, color2, multiplier); 487 487 } 488 488 -
trunk/Source/WebCore/platform/graphics/Color.cpp
r262035 r262070 56 56 } 57 57 58 RGBA32 makePremultipliedRGBA(RGBA32 pixelColor) 59 { 60 if (pixelColor.isOpaque()) 61 return pixelColor; 62 return makePremultipliedRGBA(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent()); 63 } 64 58 65 RGBA32 makeUnPremultipliedRGBA(int r, int g, int b, int a) 59 66 { 60 67 return makeRGBA(unpremultipliedChannel(r, a), unpremultipliedChannel(g, a), unpremultipliedChannel(b, a), a); 68 } 69 70 RGBA32 makeUnPremultipliedRGBA(RGBA32 pixelColor) 71 { 72 if (pixelColor.isVisible() && !pixelColor.isOpaque()) 73 return makeUnPremultipliedRGBA(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent()); 74 return pixelColor; 61 75 } 62 76 … … 497 511 } 498 512 513 SimpleColor Color::toSRGBASimpleColorLossy() const 514 { 515 if (!isExtended()) 516 return rgb(); 517 518 auto [r, g, b, a] = toSRGBAComponentsLossy(); 519 return makeRGBA32FromFloats(r, g, b, a); 520 } 521 499 522 FloatComponents Color::toSRGBAComponentsLossy() const 500 523 { … … 512 535 } 513 536 514 Color colorFromPremultipliedARGB(RGBA32 pixelColor)515 {516 if (pixelColor.isVisible() && !pixelColor.isOpaque())517 return makeUnPremultipliedRGBA(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent());518 return pixelColor;519 }520 521 RGBA32 premultipliedARGBFromColor(const Color& color)522 {523 if (color.isOpaque()) {524 if (color.isExtended())525 return makeRGB(color.asExtended().red() * 255, color.asExtended().green() * 255, color.asExtended().blue() * 255);526 return color.rgb();527 }528 529 if (color.isExtended())530 return makePremultipliedRGBA(color.asExtended().red() * 255, color.asExtended().green() * 255, color.asExtended().blue() * 255, color.asExtended().alpha() * 255);531 532 return makePremultipliedRGBA(color.red(), color.green(), color.blue(), color.alpha());533 }534 535 537 bool extendedColorsEqual(const Color& a, const Color& b) 536 538 { … … 542 544 } 543 545 544 Color blend(const Color& from, const Color& to, double progress , bool blendPremultiplied)546 Color blend(const Color& from, const Color& to, double progress) 545 547 { 546 548 // FIXME: ExtendedColor - needs to handle color spaces. … … 549 551 return Color(); 550 552 551 if (blendPremultiplied) { 552 // Since premultipliedARGBFromColor() bails on zero alpha, special-case that. 553 Color premultFrom = from.alpha() ? premultipliedARGBFromColor(from) : Color::transparent; 554 Color premultTo = to.alpha() ? premultipliedARGBFromColor(to) : Color::transparent; 555 556 Color premultBlended(blend(premultFrom.red(), premultTo.red(), progress), 557 blend(premultFrom.green(), premultTo.green(), progress), 558 blend(premultFrom.blue(), premultTo.blue(), progress), 559 blend(premultFrom.alpha(), premultTo.alpha(), progress)); 560 561 return Color(colorFromPremultipliedARGB(premultBlended.rgb())); 562 } 563 564 return Color(blend(from.red(), to.red(), progress), 565 blend(from.green(), to.green(), progress), 566 blend(from.blue(), to.blue(), progress), 567 blend(from.alpha(), to.alpha(), progress)); 553 // Since makePremultipliedRGBA() bails on zero alpha, special-case that. 554 auto premultFrom = from.alpha() ? makePremultipliedRGBA(from.toSRGBASimpleColorLossy()) : Color::transparent; 555 auto premultTo = to.alpha() ? makePremultipliedRGBA(to.toSRGBASimpleColorLossy()) : Color::transparent; 556 557 RGBA32 premultBlended = makeRGBA( 558 WebCore::blend(premultFrom.redComponent(), premultTo.redComponent(), progress), 559 WebCore::blend(premultFrom.greenComponent(), premultTo.greenComponent(), progress), 560 WebCore::blend(premultFrom.blueComponent(), premultTo.blueComponent(), progress), 561 WebCore::blend(premultFrom.alphaComponent(), premultTo.alphaComponent(), progress) 562 ); 563 564 return makeUnPremultipliedRGBA(premultBlended); 565 } 566 567 Color blendWithoutPremultiply(const Color& from, const Color& to, double progress) 568 { 569 // FIXME: ExtendedColor - needs to handle color spaces. 570 // We need to preserve the state of the valid flag at the end of the animation 571 if (progress == 1 && !to.isValid()) 572 return { }; 573 574 auto fromSRGB = from.toSRGBASimpleColorLossy(); 575 auto toSRGB = from.toSRGBASimpleColorLossy(); 576 577 return { 578 WebCore::blend(fromSRGB.redComponent(), toSRGB.redComponent(), progress), 579 WebCore::blend(fromSRGB.greenComponent(), toSRGB.greenComponent(), progress), 580 WebCore::blend(fromSRGB.blueComponent(), toSRGB.blueComponent(), progress), 581 WebCore::blend(fromSRGB.alphaComponent(), toSRGB.alphaComponent(), progress) 582 }; 568 583 } 569 584 -
trunk/Source/WebCore/platform/graphics/Color.h
r262045 r262070 91 91 92 92 RGBA32 makePremultipliedRGBA(int r, int g, int b, int a, bool ceiling = true); 93 RGBA32 makePremultipliedRGBA(RGBA32); 93 94 RGBA32 makeUnPremultipliedRGBA(int r, int g, int b, int a); 95 RGBA32 makeUnPremultipliedRGBA(RGBA32); 94 96 95 97 WEBCORE_EXPORT RGBA32 makeRGBA32FromFloats(float r, float g, float b, float a); … … 206 208 207 209 WEBCORE_EXPORT std::pair<ColorSpace, FloatComponents> colorSpaceAndComponents() const; 210 211 // This will convert non-sRGB colorspace colors into sRGB. 212 WEBCORE_EXPORT SimpleColor toSRGBASimpleColorLossy() const; 208 213 209 214 // This will convert non-sRGB colorspace colors into sRGB. … … 318 323 bool operator!=(const Color&, const Color&); 319 324 320 Color colorFromPremultipliedARGB(RGBA32);321 RGBA32 premultipliedARGBFromColor(const Color&);322 325 // One or both must be extended colors. 323 326 WEBCORE_EXPORT bool extendedColorsEqual(const Color&, const Color&); 324 327 325 Color blend(const Color& from, const Color& to, double progress, bool blendPremultiplied = true); 328 Color blend(const Color& from, const Color& to, double progress); 329 Color blendWithoutPremultiply(const Color& from, const Color& to, double progress); 326 330 327 331 int differenceSquared(const Color&, const Color&); -
trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp
r261967 r262070 284 284 } 285 285 286 FloatComponents premultiplied(const FloatComponents& sRGBComponents) 287 { 288 auto [r, g, b, a] = sRGBComponents; 289 return { 290 r * a, 291 g * a, 292 b * a, 293 a 294 }; 295 } 296 286 297 ColorMatrix::ColorMatrix() 287 298 { -
trunk/Source/WebCore/platform/graphics/ColorUtilities.h
r261967 r262070 192 192 float contrastRatio(const FloatComponents&, const FloatComponents&); 193 193 194 FloatComponents premultiplied(const FloatComponents& sRGBCompontents); 195 194 196 class ColorMatrix { 195 197 public: -
trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp
r256892 r262070 81 81 for (int x = 0; x < m_logicalSize.width(); x++) { 82 82 unsigned* pixel = row + x; 83 Color pixelColor = colorFromPremultipliedARGB(*pixel);84 pixelColor = Color(lookUpTable[pixelColor.red()], lookUpTable[pixelColor.green()], lookUpTable[pixelColor.blue()], pixelColor.alpha());85 *pixel = premultipliedARGBFromColor(pixelColor).value();83 auto pixelColor = makeUnPremultipliedRGBA(*pixel); 84 pixelColor = makeRGBA(lookUpTable[pixelColor.redComponent()], lookUpTable[pixelColor.greenComponent()], lookUpTable[pixelColor.blueComponent()], pixelColor.alphaComponent()); 85 *pixel = makePremultipliedRGBA(pixelColor).value(); 86 86 } 87 87 } -
trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp
r249217 r262070 55 55 56 56 RGBA32* pixel = reinterpret_cast_ptr<RGBA32*>(cairo_image_surface_get_data(image.get())); 57 return colorFromPremultipliedARGB(*pixel);57 return makeUnPremultipliedRGBA(*pixel); 58 58 } 59 59 -
trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
r261901 r262070 254 254 glUseProgram(program->programID()); 255 255 256 // FIXME: Do the premultiply on FloatComponents directly. 257 auto [r, g, b, a] = Color(premultipliedARGBFromColor(color)).toSRGBAComponentsLossy(); 256 auto [r, g, b, a] = premultiplied(color.toSRGBAComponentsLossy()); 258 257 glUniform4f(program->colorLocation(), r, g, b, a); 259 258 glLineWidth(width); … … 416 415 case 1: 417 416 // Second pass: we need the shadow color and the content texture for compositing. 418 // FIXME: Do the premultiply on FloatComponents directly. 419 auto [r, g, b, a] = Color(premultipliedARGBFromColor(shadow.color())).toSRGBAComponentsLossy(); 417 auto [r, g, b, a] = premultiplied(shadow.color().toSRGBAComponentsLossy()); 420 418 glUniform4f(program.colorLocation(), r, g, b, a); 421 419 glUniform2f(program.blurRadiusLocation(), 0, shadow.stdDeviation() / float(size.height())); … … 679 677 glUseProgram(program->programID()); 680 678 681 // FIXME: Do the premultiply on FloatComponents directly. 682 auto [r, g, b, a] = Color(premultipliedARGBFromColor(color)).toSRGBAComponentsLossy(); 679 auto [r, g, b, a] = premultiplied(color.toSRGBAComponentsLossy()); 683 680 glUniform4f(program->colorLocation(), r, g, b, a); 684 681 if (a < 1 && isBlendingAllowed)
Note: See TracChangeset
for help on using the changeset viewer.