Bug 869178 - Use SkCanvas::drawBitmapRect instead of a bitmap SkShader; it's slightly faster r=snorp
authorGeorge Wright <gw@gwright.org.uk>
Thu, 15 Nov 2012 19:57:40 -0500
changeset 149622 f5cc97a9ea3088c5ddfe70e84093bb39a745b32b
parent 149621 a995eb241d7d0c8431cac5051d27e9d94e642664
child 149623 b6e23760745e536b6b47073b851cd5159197b6dd
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs869178
milestone25.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 869178 - Use SkCanvas::drawBitmapRect instead of a bitmap SkShader; it's slightly faster r=snorp
gfx/2d/DrawTargetSkia.cpp
layout/reftests/svg/as-image/reftest.list
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -270,32 +270,53 @@ DrawTargetSkia::DrawSurface(SourceSurfac
   }
 
   if (aSource.IsEmpty()) {
     return;
   }
 
   MarkChanged();
 
+  IntRect sourceIntRect;
+  bool integerAligned = aSource.ToIntRect(&sourceIntRect);
+
   SkRect destRect = RectToSkRect(aDest);
   SkRect sourceRect = RectToSkRect(aSource);
 
-  SkMatrix matrix;
-  matrix.setRectToRect(sourceRect, destRect, SkMatrix::kFill_ScaleToFit);
-  
+  Rect boundingSource = aSource;
+  boundingSource.RoundOut();
+
+  SkRect sourceBoundingRect = RectToSkRect(boundingSource);
+  SkIRect sourceBoundingIRect = RectToSkIRect(boundingSource);
+
   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
  
   AutoPaintSetup paint(mCanvas.get(), aOptions);
-  SkShader *shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
-  shader->setLocalMatrix(matrix);
-  SkSafeUnref(paint.mPaint.setShader(shader));
   if (aSurfOptions.mFilter != FILTER_LINEAR) {
     paint.mPaint.setFilterBitmap(false);
   }
-  mCanvas->drawRect(destRect, paint.mPaint);
+
+  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.
+    mCanvas->save();
+    mCanvas->clipRect(destRect);
+
+    SkMatrix rectTransform;
+    rectTransform.setRectToRect(sourceRect, sourceBoundingRect, SkMatrix::kFill_ScaleToFit);
+    rectTransform.mapRect(&destRect);
+  }
+
+  mCanvas->drawBitmapRect(bitmap, &sourceBoundingIRect, destRect, &paint.mPaint);
+
+  if (!integerAligned) {
+    mCanvas->restore();
+  }
 }
 
 void
 DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface,
                                       const Point &aDest,
                                       const Color &aColor,
                                       const Point &aOffset,
                                       Float aSigma,
--- a/layout/reftests/svg/as-image/reftest.list
+++ b/layout/reftests/svg/as-image/reftest.list
@@ -34,17 +34,17 @@ skip-if(B2G) == background-image-rect-1s
 skip-if(B2G) == canvas-drawImage-scale-1a.html lime100x100-ref.html
 skip-if(B2G) == canvas-drawImage-scale-1b.html lime100x100-ref.html
 skip-if(B2G) == canvas-drawImage-scale-1c.html lime100x100-ref.html
 
 fails == canvas-drawImage-scale-2a.html canvas-drawImage-scale-2-ref.html # XXX all edges fuzzy
 fails == canvas-drawImage-scale-2b.html canvas-drawImage-scale-2-ref.html # XXX all edges fuzzy
 
 skip-if(B2G) == canvas-drawImage-slice-1a.html lime100x100-ref.html
-fails-if(!azureQuartz) == canvas-drawImage-slice-1b.html lime100x100-ref.html # XXX all edges fuzzy
+fails-if(!azureQuartz&&!azureSkia) == canvas-drawImage-slice-1b.html lime100x100-ref.html # XXX all edges fuzzy
 
 == canvas-drawImage-origin-clean-1.html lime100x100-ref.html
 
 # Simple <img> tests
 == img-simple-1.html  lime100x100-ref.html
 == img-simple-2.html  lime100x100-ref.html
 == img-simple-3.html  img-simple-3-ref.html
 == img-simple-4.html  lime100x100-ref.html