Bug 1284408: Ensure hard stops are aligned on pixel boundaries for D2D 1.1 internal gradient texture. r=jrmuizel
MozReview-Commit-ID: G37qMe1sz2x
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -907,16 +907,25 @@ DrawTargetD2D1::CreateGradientStops(Grad
gfxWarning() << *this << ": Failed to create GradientStopCollection with no stops.";
return nullptr;
}
D2D1_GRADIENT_STOP *stops = new D2D1_GRADIENT_STOP[aNumStops];
for (uint32_t i = 0; i < aNumStops; i++) {
stops[i].position = rawStops[i].offset;
+
+ if (i > 0 && rawStops[i - 1].offset == rawStops[i].offset ||
+ i < (aNumStops - 1) && rawStops[i + 1].offset == rawStops[i].offset) {
+ // For hard stops we ensure they're aligned on pixel boundaries for D2Ds
+ // 1024 pixel internal texture. This ensures when drawing to larger surfaces we
+ // don't get drawing artifacts on hard stops from blending between two stops.
+ stops[i].position += (0.5 - (stops[i].position * 1024 - floor(stops[i].position * 1024))) / 1024;
+ }
+
stops[i].color = D2DColor(rawStops[i].color);
}
RefPtr<ID2D1GradientStopCollection> stopCollection;
HRESULT hr =
mDC->CreateGradientStopCollection(stops, aNumStops,
D2D1_GAMMA_2_2, D2DExtend(aExtendMode, Axis::BOTH),