Bug 1022624 - Share code for constructing repeated linear and radial gradients. r=jrmuizel
authorMarkus Stange <mstange@themasta.com>
Tue, 10 Jun 2014 22:27:45 +0200
changeset 187925 2b76bb4c21c28eb93cbe590e97262c46e16a94c3
parent 187924 ebe4b9991f913967831351d83c4c8ccc9239de9e
child 187926 48dc31fc0fc48b150b11a9141187717349fc7de0
push id44703
push usermstange@themasta.com
push dateTue, 10 Jun 2014 20:30:11 +0000
treeherdermozilla-inbound@4e8c7d93078a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1022624
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1022624 - Share code for constructing repeated linear and radial gradients. r=jrmuizel
gfx/2d/DrawTargetCG.cpp
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -506,64 +506,73 @@ CalculateRepeatingGradientParams(CGPoint
   aEnd->y = aStart->y + dy * t_max;
   aStart->x = aStart->x + dx * t_min;
   aStart->y = aStart->y + dy * t_min;
 
   *aRepeatStartFactor = t_min;
   *aRepeatEndFactor = t_max;
 }
 
+static CGGradientRef
+CreateRepeatingGradient(CGContextRef cg, GradientStopsCG* aStops,
+                        int aRepeatStartFactor, int aRepeatEndFactor,
+                        bool aReflect)
+{
+  int repeatCount = aRepeatEndFactor - aRepeatStartFactor;
+  uint32_t numStops = aStops->mStops.size();
+  double scale = 1./repeatCount;
+
+  std::vector<CGFloat> colors;
+  std::vector<CGFloat> offsets;
+  colors.reserve(numStops*repeatCount*4);
+  offsets.reserve(numStops*repeatCount);
+
+  for (int j = aRepeatStartFactor; j < aRepeatEndFactor; j++) {
+    bool isReflected = aReflect && (j % 2) != 0;
+    for (uint32_t i = 0; i < numStops; i++) {
+      uint32_t stopIndex = isReflected ? numStops - i - 1 : i;
+      colors.push_back(aStops->mStops[stopIndex].color.r);
+      colors.push_back(aStops->mStops[stopIndex].color.g);
+      colors.push_back(aStops->mStops[stopIndex].color.b);
+      colors.push_back(aStops->mStops[stopIndex].color.a);
+
+      CGFloat offset = aStops->mStops[stopIndex].offset;
+      if (isReflected) {
+        offset = 1 - offset;
+      }
+      offsets.push_back((offset + (j - aRepeatStartFactor)) * scale);
+    }
+  }
+
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
+                                                               &colors.front(),
+                                                               &offsets.front(),
+                                                               repeatCount*numStops);
+  CGColorSpaceRelease(colorSpace);
+  return gradient;
+}
+
 static void
 DrawLinearRepeatingGradient(CGContextRef cg, const LinearGradientPattern &aPattern,
                             const CGRect &aExtents, bool aReflect)
 {
   GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
   CGPoint startPoint = { aPattern.mBegin.x, aPattern.mBegin.y };
   CGPoint endPoint = { aPattern.mEnd.x, aPattern.mEnd.y };
 
   int repeatStartFactor = 0, repeatEndFactor = 1;
   // if we don't have a line then we can't extend it
   if (aPattern.mEnd.x != aPattern.mBegin.x ||
       aPattern.mEnd.y != aPattern.mBegin.y) {
     CalculateRepeatingGradientParams(&startPoint, &endPoint, aExtents,
                                      &repeatStartFactor, &repeatEndFactor);
   }
 
-  int repeatCount = repeatEndFactor - repeatStartFactor;
-  uint32_t numStops = stops->mStops.size();
-  double scale = 1./repeatCount;
-
-  std::vector<CGFloat> colors;
-  std::vector<CGFloat> offsets;
-  colors.reserve(numStops*repeatCount*4);
-  offsets.reserve(numStops*repeatCount);
-
-  for (int j = repeatStartFactor; j < repeatEndFactor; j++) {
-    bool isReflected = aReflect && (j % 2) != 0;
-    for (uint32_t i = 0; i < numStops; i++) {
-      uint32_t stopIndex = isReflected ? numStops - i - 1 : i;
-      colors.push_back(stops->mStops[stopIndex].color.r);
-      colors.push_back(stops->mStops[stopIndex].color.g);
-      colors.push_back(stops->mStops[stopIndex].color.b);
-      colors.push_back(stops->mStops[stopIndex].color.a);
-
-      CGFloat offset = stops->mStops[stopIndex].offset;
-      if (isReflected) {
-        offset = 1 - offset;
-      }
-      offsets.push_back((offset + (j - repeatStartFactor)) * scale);
-    }
-  }
-
-  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
-                                                               &colors.front(),
-                                                               &offsets.front(),
-                                                               repeatCount*numStops);
-  CGColorSpaceRelease(colorSpace);
+  CGGradientRef gradient = CreateRepeatingGradient(cg, stops, repeatStartFactor, repeatEndFactor, aReflect);
 
   CGContextDrawLinearGradient(cg, gradient, startPoint, endPoint,
                               kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
   CGGradientRelease(gradient);
 }
 
 static CGPoint CGRectTopLeft(CGRect a)
 { return a.origin; }
@@ -604,47 +613,17 @@ DrawRadialRepeatingGradient(CGContextRef
     repeatEndFactor++;
   }
 
   while (startRadius-length >= 0) {
     startRadius -= length;
     repeatStartFactor--;
   }
 
-  int repeatCount = repeatEndFactor - repeatStartFactor;
-  uint32_t numStops = stops->mStops.size();
-  double scale = 1./repeatCount;
-
-  std::vector<CGFloat> colors;
-  std::vector<CGFloat> offsets;
-  colors.reserve(numStops*repeatCount*4);
-  offsets.reserve(numStops*repeatCount);
-  for (int j = repeatStartFactor; j < repeatEndFactor; j++) {
-    bool isReflected = aReflect && (j % 2) != 0;
-    for (uint32_t i = 0; i < numStops; i++) {
-      uint32_t stopIndex = isReflected ? numStops - i - 1 : i;
-      colors.push_back(stops->mStops[stopIndex].color.r);
-      colors.push_back(stops->mStops[stopIndex].color.g);
-      colors.push_back(stops->mStops[stopIndex].color.b);
-      colors.push_back(stops->mStops[stopIndex].color.a);
-
-      CGFloat offset = stops->mStops[stopIndex].offset;
-      if (isReflected) {
-        offset = 1 - offset;
-      }
-      offsets.push_back((offset + (j - repeatStartFactor)) * scale);
-    }
-  }
-
-  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-  CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
-                                                               &colors.front(),
-                                                               &offsets.front(),
-                                                               repeatCount*numStops);
-  CGColorSpaceRelease(colorSpace);
+  CGGradientRef gradient = CreateRepeatingGradient(cg, stops, repeatStartFactor, repeatEndFactor, aReflect);
 
   //XXX: are there degenerate radial gradients that we should avoid drawing?
   CGContextDrawRadialGradient(cg, gradient, startCenter, startRadius, endCenter, endRadius,
                               kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
   CGGradientRelease(gradient);
 }
 
 static void