Bug 897532. Add support for better filtering in Azure. r=bas
☠☠ backed out by 55b6b3b78d37 ☠ ☠
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Wed, 31 Jul 2013 14:46:25 -0400
changeset 154601 d10581fd820204c09e6124a1d53e4bff9a2fd88d
parent 154600 7583b9cff5401582fadeca7c269baef4bdb9e105
child 154602 8b241c4e3eec80c5740a3b943d4205bec341136e
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs897532
milestone26.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 897532. Add support for better filtering in Azure. r=bas This fixes the quality regression on OS X.
gfx/2d/2D.h
gfx/2d/DrawTargetCG.cpp
gfx/2d/DrawTargetSkia.cpp
gfx/2d/HelpersCairo.h
gfx/2d/Types.h
gfx/thebes/gfx2DGlue.h
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -287,17 +287,17 @@ public:
   /*
    * aSourceSurface Surface to use for drawing
    * aExtendMode This determines how the image is extended outside the bounds
    *             of the image.
    * aMatrix A matrix that transforms the pattern into user space
    * aFilter Resampling filter used for resampling the image.
    */
   SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
-                 const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_LINEAR)
+                 const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_GOOD)
     : mSurface(aSourceSurface)
     , mExtendMode(aExtendMode)
     , mFilter(aFilter)
     , mMatrix(aMatrix)
   {}
 
   virtual PatternType GetType() const { return PATTERN_SURFACE; }
 
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -118,16 +118,29 @@ CGBlendMode ToBlendMode(CompositionOp op
       mode = kCGBlendModeClear;
       break;*/
     default:
       mode = kCGBlendModeNormal;
   }
   return mode;
 }
 
+static CGInterpolationQuality
+InterpolationQualityFromFilter(Filter aFilter)
+{
+  switch (aFilter) {
+    default:
+    case FILTER_LINEAR:
+      return kCGInterpolationLow;
+    case FILTER_POINT:
+      return kCGInterpolationNone;
+    case FILTER_GOOD:
+      return kCGInterpolationDefault;
+  }
+}
 
 
 DrawTargetCG::DrawTargetCG() : mCg(nullptr), mSnapshot(nullptr)
 {
 }
 
 DrawTargetCG::~DrawTargetCG()
 {
@@ -286,20 +299,17 @@ DrawTargetCG::DrawSurface(SourceSurface 
     image = subimage;
   }
 
   CGContextScaleCTM(cg, 1, -1);
 
   CGRect flippedRect = CGRectMake(aDest.x, -(aDest.y + aDest.height),
                                   aDest.width, aDest.height);
 
-  if (aSurfOptions.mFilter == FILTER_POINT)
-    CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
-  else
-    CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
+  CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(aSurfOptions.mFilter));
 
   CGContextDrawImage(cg, flippedRect, image);
 
   fixer.Fix(mCg);
 
   CGContextRestoreGState(mCg);
 
   CGImageRelease(subimage);
@@ -648,20 +658,17 @@ SetFillFromPattern(CGContextRef cg, CGCo
 
     CGColorSpaceRef patternSpace;
     patternSpace = CGColorSpaceCreatePattern (nullptr);
     CGContextSetFillColorSpace(cg, patternSpace);
     CGColorSpaceRelease(patternSpace);
 
     CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg));
     const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
-    if (pat.mFilter == FILTER_POINT)
-      CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
-    else
-      CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
+    CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
     CGFloat alpha = 1.;
     CGContextSetFillPattern(cg, pattern, &alpha);
     CGPatternRelease(pattern);
   }
 }
 
 static void
 SetStrokeFromPattern(CGContextRef cg, CGColorSpaceRef aColorSpace, const Pattern &aPattern)
@@ -676,20 +683,17 @@ SetStrokeFromPattern(CGContextRef cg, CG
   } else if (aPattern.GetType() == PATTERN_SURFACE) {
     CGColorSpaceRef patternSpace;
     patternSpace = CGColorSpaceCreatePattern (nullptr);
     CGContextSetStrokeColorSpace(cg, patternSpace);
     CGColorSpaceRelease(patternSpace);
 
     CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg));
     const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
-    if (pat.mFilter == FILTER_POINT)
-      CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
-    else
-      CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
+    CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
     CGFloat alpha = 1.;
     CGContextSetStrokePattern(cg, pattern, &alpha);
     CGPatternRelease(pattern);
   }
 
 }
 
 void
@@ -765,20 +769,17 @@ DrawTargetCG::FillRect(const Rect &aRect
       CGImageRef image = GetImageFromSourceSurface(pat.mSurface.get());
       CGContextClipToRect(cg, RectToCGRect(aRect));
       CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
       CGContextTranslateCTM(cg, 0, CGImageGetHeight(image));
       CGContextScaleCTM(cg, 1, -1);
 
       CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image));
 
-      if (pat.mFilter == FILTER_POINT)
-        CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
-      else
-        CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
+      CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
 
       CGContextDrawImage(cg, imageRect, image);
     } else {
       SetFillFromPattern(cg, mColorSpace, aPattern);
       CGContextFillRect(cg, RectToCGRect(aRect));
     }
   }
 
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -280,17 +280,17 @@ DrawTargetSkia::DrawSurface(SourceSurfac
   boundingSource.RoundOut();
 
   SkRect sourceBoundingRect = RectToSkRect(boundingSource);
   SkIRect sourceBoundingIRect = RectToSkIRect(boundingSource);
 
   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
  
   AutoPaintSetup paint(mCanvas.get(), aOptions);
-  if (aSurfOptions.mFilter != FILTER_LINEAR) {
+  if (aSurfOptions.mFilter == FILTER_POINT) {
     paint.mPaint.setFilterBitmap(false);
   }
 
   if (!integerAligned) {
     // We need to inflate our destRect by the same amount we inflated sourceRect
     // by when we rounded up to the nearest integer size to ensure we interpolate
     // the edge pixels properly, but clip to the true destination rect first so
     // we don't draw outside our designated area.
--- a/gfx/2d/HelpersCairo.h
+++ b/gfx/2d/HelpersCairo.h
@@ -77,16 +77,18 @@ GfxOpToCairoOp(CompositionOp op)
   return CAIRO_OPERATOR_OVER;
 }
 
 static inline cairo_filter_t
 GfxFilterToCairoFilter(Filter filter)
 {
   switch (filter)
   {
+    case FILTER_GOOD:
+      return CAIRO_FILTER_GOOD;
     case FILTER_LINEAR:
       return CAIRO_FILTER_BILINEAR;
     case FILTER_POINT:
       return CAIRO_FILTER_NEAREST;
   }
 
   return CAIRO_FILTER_BILINEAR;
 }
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -99,17 +99,17 @@ enum FontHinting
 };
 
 enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, 
   OP_MULTIPLY, OP_SCREEN, OP_OVERLAY, OP_DARKEN, OP_LIGHTEN, OP_COLOR_DODGE, OP_COLOR_BURN, OP_HARD_LIGHT, OP_SOFT_LIGHT,  OP_DIFFERENCE, OP_EXCLUSION, OP_HUE, OP_SATURATION, OP_COLOR, OP_LUMINOSITY, OP_COUNT };
 enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
 enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
 enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
 enum Snapping { SNAP_NONE, SNAP_ALIGNED };
-enum Filter { FILTER_LINEAR, FILTER_POINT };
+enum Filter { FILTER_GOOD, FILTER_LINEAR, FILTER_POINT };
 enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
 enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
 enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE };
 enum SamplingBounds { SAMPLING_UNBOUNDED, SAMPLING_BOUNDED };
 
 /* Color is stored in non-premultiplied form */
 struct Color
 {
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -59,16 +59,18 @@ inline IntSize ToIntSize(const gfxIntSiz
   return IntSize(aSize.width, aSize.height);
 }
 
 inline Filter ToFilter(gfxPattern::GraphicsFilter aFilter)
 {
   switch (aFilter) {
   case gfxPattern::FILTER_NEAREST:
     return FILTER_POINT;
+  case gfxPattern::FILTER_GOOD:
+    return FILTER_GOOD;
   default:
     return FILTER_LINEAR;
   }
 }
 
 inline gfxPattern::GraphicsFilter ThebesFilter(Filter aFilter)
 {
   switch (aFilter) {