Bug 1022624 - Share code for constructing repeated linear and radial gradients. r=jrmuizel, a=lmandel
authorMarkus Stange <mstange@themasta.com>
Tue, 10 Jun 2014 22:27:45 +0200
changeset 207123 f5dc2ae02b195567eedc10630425f9b06d691214
parent 207122 f3007d054fe20d265b838f88fd70beee4aee76be
child 207124 f0a87ca6c29dac1c39c0b024cfc45a2da22bceef
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, lmandel
bugs1022624
milestone32.0a2
Bug 1022624 - Share code for constructing repeated linear and radial gradients. r=jrmuizel, a=lmandel
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