Bug 1427063: Have D2D interpret colors in premultiplied space. As it says is its default. r=rhunt draft
authorBas Schouten <bschouten@mozilla.com>
Mon, 23 Apr 2018 16:06:29 +0200
changeset 786537 33834abcc470efd8c05cd7100ad67fcf8b345c07
parent 786536 d1479b21a2848f1ed2b73fb54202b5ba5e042ef3
push id107502
push userbschouten@mozilla.com
push dateMon, 23 Apr 2018 14:08:00 +0000
reviewersrhunt
bugs1427063
milestone61.0a1
Bug 1427063: Have D2D interpret colors in premultiplied space. As it says is its default. r=rhunt MozReview-Commit-ID: 5OWjHW1CqjN
gfx/2d/DrawTargetD2D1.cpp
layout/painting/nsCSSRenderingGradients.cpp
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -1015,21 +1015,23 @@ DrawTargetD2D1::CreateGradientStops(Grad
 
   D2D1_GRADIENT_STOP *stops = new D2D1_GRADIENT_STOP[aNumStops];
 
   for (uint32_t i = 0; i < aNumStops; i++) {
     stops[i].position = rawStops[i].offset;
     stops[i].color = D2DColor(rawStops[i].color);
   }
 
-  RefPtr<ID2D1GradientStopCollection> stopCollection;
+  RefPtr<ID2D1GradientStopCollection1> stopCollection;
 
   HRESULT hr =
     mDC->CreateGradientStopCollection(stops, aNumStops,
-                                      D2D1_GAMMA_2_2, D2DExtend(aExtendMode, Axis::BOTH),
+                                      D2D1_COLOR_SPACE_SRGB, D2D1_COLOR_SPACE_SRGB,
+                                      D2D1_BUFFER_PRECISION_8BPC_UNORM, D2DExtend(aExtendMode, Axis::BOTH),
+                                      D2D1_COLOR_INTERPOLATION_MODE_PREMULTIPLIED,
                                       getter_AddRefs(stopCollection));
   delete [] stops;
 
   if (FAILED(hr)) {
     gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: " << hexa(hr);
     return nullptr;
   }
 
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -418,18 +418,20 @@ static const float kAlphaIncrementPerGra
 static void
 ResolvePremultipliedAlpha(nsTArray<ColorStop>& aStops)
 {
   for (size_t x = 1; x < aStops.Length(); x++) {
     const ColorStop leftStop = aStops[x - 1];
     const ColorStop rightStop = aStops[x];
 
     // if the left and right stop have the same alpha value, we don't need
-    // to do anything
-    if (leftStop.mColor.a == rightStop.mColor.a) {
+    // to do anything. Hardstops should be instant, and also should never
+    // require dealing with interpolation.
+    if (leftStop.mColor.a == rightStop.mColor.a ||
+        leftStop.mPosition == rightStop.mPosition) {
       continue;
     }
 
     // Is the stop on the left 100% transparent? If so, have it adopt the color
     // of the right stop
     if (leftStop.mColor.a == 0) {
       aStops[x - 1].mColor = TransparentColor(rightStop.mColor);
       continue;