Bug 1322729 - fix DrawTargetTiled to forward SetPermitSubpixelAA. r=mchang
authorLee Salzman <lsalzman@mozilla.com>
Fri, 16 Dec 2016 11:02:04 -0500
changeset 371168 47015fe3036da24de8da2d4e320f75d55651ccc8
parent 371167 5eb3412c5bd760e43625f404eb8e91bc1d6925fe
child 371169 dfefdea36361d89f8ccd2d633d51385cce4e2d48
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1322729
milestone53.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 1322729 - fix DrawTargetTiled to forward SetPermitSubpixelAA. r=mchang MozReview-Commit-ID: 7aicn9Crru9
gfx/2d/DrawTargetSkia.cpp
gfx/2d/DrawTargetTiled.cpp
gfx/2d/DrawTargetTiled.h
layout/reftests/bugs/reftest.list
layout/reftests/transform-3d/reftest.list
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -560,17 +560,17 @@ struct AutoPaintSetup {
     // clear the clip rect. The other operators would be harder
     // but could be worth it to skip pushing a group.
     if (needsGroup) {
       mPaint.setBlendMode(SkBlendMode::kSrcOver);
       SkPaint temp;
       temp.setBlendMode(GfxOpToSkiaOp(aOptions.mCompositionOp));
       temp.setAlpha(ColorFloatToByte(aOptions.mAlpha));
       //TODO: Get a rect here
-      mCanvas->saveLayer(nullptr, &temp);
+      mCanvas->saveLayerPreserveLCDTextRequests(nullptr, &temp);
       mNeedsRestore = true;
     } else {
       mPaint.setAlpha(ColorFloatToByte(aOptions.mAlpha));
       mAlpha = aOptions.mAlpha;
     }
     mPaint.setFilterQuality(kLow_SkFilterQuality);
   }
 
@@ -837,18 +837,18 @@ DrawTargetSkia::Fill(const Path *aPath,
   }
 
   mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
 }
 
 bool
 DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialiasMode)
 {
-  // For non-opaque surfaces, only allow subpixel AA if explicitly permitted.
-  if (!IsOpaque(mFormat) && !mPermitSubpixelAA) {
+  // Only allow subpixel AA if explicitly permitted.
+  if (!GetPermitSubpixelAA()) {
     return false;
   }
 
   if (aAntialiasMode == AntialiasMode::DEFAULT) {
     switch (aFontType) {
       case FontType::MAC:
       case FontType::GDI:
       case FontType::DWRITE:
@@ -1768,16 +1768,17 @@ DrawTargetSkia::Init(const IntSize &aSiz
   mSurface = SkSurface::MakeRaster(info, stride, nullptr);
   if (!mSurface) {
     return false;
   }
 
   mSize = aSize;
   mFormat = aFormat;
   mCanvas = sk_ref_sp(mSurface->getCanvas());
+  SetPermitSubpixelAA(IsOpaque(mFormat));
 
   if (info.isOpaque()) {
     mCanvas->clear(SK_ColorBLACK);
   }
   return true;
 }
 
 bool
@@ -1796,16 +1797,17 @@ DrawTargetSkia::Init(SkCanvas* aCanvas)
     mCanvas->clear(clearColor);
   }
 
   SkISize size = mCanvas->getBaseLayerSize();
   mSize.width = size.width();
   mSize.height = size.height();
   mFormat = SkiaColorTypeToGfxFormat(imageInfo.colorType(),
                                      imageInfo.alphaType());
+  SetPermitSubpixelAA(IsOpaque(mFormat));
   return true;
 }
 
 #ifdef USE_SKIA_GPU
 /** Indicating a DT should be cached means that space will be reserved in Skia's cache
  * for the render target at creation time, with any unused resources exceeding the cache
  * limits being purged. When the DT is freed, it will then be guaranteed to be kept around
  * for subsequent allocations until it gets incidentally purged.
@@ -1845,16 +1847,17 @@ DrawTargetSkia::InitWithGrContext(GrCont
   if (!mSurface) {
     return false;
   }
 
   mGrContext = sk_ref_sp(aGrContext);
   mSize = aSize;
   mFormat = aFormat;
   mCanvas = sk_ref_sp(mSurface->getCanvas());
+  SetPermitSubpixelAA(IsOpaque(mFormat));
   return true;
 }
 
 #endif
 
 bool
 DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized)
 {
@@ -1864,16 +1867,17 @@ DrawTargetSkia::Init(unsigned char* aDat
   mSurface = SkSurface::MakeRasterDirect(MakeSkiaImageInfo(aSize, aFormat), aData, aStride);
   if (!mSurface) {
     return false;
   }
 
   mSize = aSize;
   mFormat = aFormat;
   mCanvas = sk_ref_sp(mSurface->getCanvas());
+  SetPermitSubpixelAA(IsOpaque(mFormat));
   return true;
 }
 
 void
 DrawTargetSkia::SetTransform(const Matrix& aTransform)
 {
   SkMatrix mat;
   GfxMatrixToSkiaMatrix(aTransform, mat);
@@ -2016,17 +2020,18 @@ DrawTargetSkia::PushLayer(bool aOpaque, 
     }
   }
 
   sk_sp<SkImageFilter> backdrop(aCopyBackground ? new CopyLayerImageFilter : nullptr);
 
   SkCanvas::SaveLayerRec saveRec(aBounds.IsEmpty() ? nullptr : &bounds,
                                  &paint,
                                  backdrop.get(),
-                                 aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0);
+                                 SkCanvas::kPreserveLCDText_SaveLayerFlag |
+                                   (aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0));
 
   mCanvas->saveLayer(saveRec);
 
   SetPermitSubpixelAA(aOpaque);
 
 #ifdef MOZ_WIDGET_COCOA
   CGContextRelease(mCG);
   mCG = nullptr;
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -25,31 +25,33 @@ DrawTargetTiled::Init(const TileSet& aTi
 
   mTiles.reserve(aTiles.mTileCount);
   for (size_t i = 0; i < aTiles.mTileCount; ++i) {
     mTiles.push_back(TileInternal(aTiles.mTiles[i]));
     if (!aTiles.mTiles[i].mDrawTarget) {
       return false;
     }
     if (mTiles[0].mDrawTarget->GetFormat() != mTiles.back().mDrawTarget->GetFormat() ||
-        mTiles[0].mDrawTarget->GetBackendType() != mTiles.back().mDrawTarget->GetBackendType()) {
+        mTiles[0].mDrawTarget->GetBackendType() != mTiles.back().mDrawTarget->GetBackendType() ||
+        mTiles[0].mDrawTarget->GetPermitSubpixelAA() != mTiles.back().mDrawTarget->GetPermitSubpixelAA()) {
       return false;
     }
     uint32_t newXMost = max(mRect.XMost(),
                             mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
     uint32_t newYMost = max(mRect.YMost(),
                             mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
     mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x);
     mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y);
     mRect.width = newXMost - mRect.x;
     mRect.height = newYMost - mRect.y;
     mTiles[i].mDrawTarget->SetTransform(Matrix::Translation(mTiles[i].mTileOrigin.x,
                                                             mTiles[i].mTileOrigin.y));
   }
   mFormat = mTiles[0].mDrawTarget->GetFormat();
+  mPermitSubpixelAA = mTiles[0].mDrawTarget->GetPermitSubpixelAA();
   return true;
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetTiled::Snapshot()
 {
   return MakeAndAddRef<SnapshotTiled>(mTiles, mRect);
 }
@@ -198,16 +200,25 @@ DrawTargetTiled::SetTransform(const Matr
     Matrix mat = aTransform;
     mat.PostTranslate(Float(-mTiles[i].mTileOrigin.x), Float(-mTiles[i].mTileOrigin.y));
     mTiles[i].mDrawTarget->SetTransform(mat);
   }
   DrawTarget::SetTransform(aTransform);
 }
 
 void
+DrawTargetTiled::SetPermitSubpixelAA(bool aPermitSubpixelAA)
+{
+  DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA);
+  for (size_t i = 0; i < mTiles.size(); i++) {
+    mTiles[i].mDrawTarget->SetPermitSubpixelAA(aPermitSubpixelAA);
+  }
+}
+
+void
 DrawTargetTiled::DrawSurface(SourceSurface* aSurface, const Rect& aDest, const Rect& aSource, const DrawSurfaceOptions& aSurfaceOptions, const DrawOptions& aDrawOptions)
 {
   Rect deviceRect = mTransform.TransformBounds(aDest);
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut &&
         deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
                                    mTiles[i].mTileOrigin.y,
                                    mTiles[i].mDrawTarget->GetSize().width,
@@ -318,24 +329,32 @@ DrawTargetTiled::PushLayer(bool aOpaque,
   // intermediate surface, that would require tweaking the code in here a little though.
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut) {
       IntRect bounds = aBounds;
       bounds.MoveBy(-mTiles[i].mTileOrigin);
       mTiles[i].mDrawTarget->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, bounds, aCopyBackground);
     }
   }
+
+  PushedLayer layer(GetPermitSubpixelAA());
+  mPushedLayers.push_back(layer);
+  SetPermitSubpixelAA(aOpaque);
 }
 
 void
 DrawTargetTiled::PopLayer()
 {
   // XXX - not sure this is what we want or whether we want to continue drawing to a larger
   // intermediate surface, that would require tweaking the code in here a little though.
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut) {
       mTiles[i].mDrawTarget->PopLayer();
     }
   }
+
+  MOZ_ASSERT(mPushedLayers.size());
+  const PushedLayer& layer = mPushedLayers.back();
+  SetPermitSubpixelAA(layer.mOldPermitSubpixelAA);
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -109,16 +109,18 @@ public:
                          const Matrix& aMaskTransform,
                          const IntRect& aBounds = IntRect(),
                          bool aCopyBackground = false) override;
   virtual void PopLayer() override;
 
 
   virtual void SetTransform(const Matrix &aTransform) override;
 
+  virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
+
   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                                   const IntSize &aSize,
                                                                   int32_t aStride,
                                                                   SurfaceFormat aFormat) const override
   {
     return mTiles[0].mDrawTarget->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
   }
   virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override
@@ -154,16 +156,25 @@ public:
   {
     return mTiles[0].mDrawTarget->CreateFilter(aType);
   }
 
 private:
   std::vector<TileInternal> mTiles;
   std::vector<std::vector<uint32_t> > mClippedOutTilesStack;
   IntRect mRect;
+
+  struct PushedLayer
+  {
+    explicit PushedLayer(bool aOldPermitSubpixelAA)
+      : mOldPermitSubpixelAA(aOldPermitSubpixelAA)
+    {}
+    bool mOldPermitSubpixelAA;
+  };
+  std::vector<PushedLayer> mPushedLayers;
 };
 
 class SnapshotTiled : public SourceSurface
 {
 public:
   SnapshotTiled(const std::vector<TileInternal>& aTiles, const IntRect& aRect)
     : mRect(aRect)
   {
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1557,18 +1557,18 @@ needs-focus == 568441.html 568441-ref.ht
 == 571347-2a.html 571347-2-ref.html
 == 571347-2b.html 571347-2-ref.html
 == 571347-2c.html 571347-2-ref.html
 == 571347-2d.html 571347-2-ref.html
 == 571347-3.html 571347-3-ref.html
 == 572598-1.html 572598-ref.html
 == 574898-1.html 574898-ref.html
 # 574907 is a windows-only issue, result on other platforms depends on details of font support
-random-if(!winWidget) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-1.html 574907-1-ref.html # Bug 1258240
-random-if(!winWidget) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-2.html 574907-2-ref.html # Bug 1258240
+random-if(!winWidget) random-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-1.html 574907-1-ref.html # Bug 1258240
+random-if(!winWidget) random-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-2.html 574907-2-ref.html # Bug 1258240
 # 574907-3 only worked under directwrite, and even there it now depends on the rendering mode; marking as random for now
 random-if(!winWidget) fails-if(winWidget&&!dwrite) random-if(winWidget&&dwrite) != 574907-3.html 574907-3-notref.html
 == 577838-1.html 577838-1-ref.html
 == 577838-2.html 577838-2-ref.html
 == 579323-1.html 579323-1-ref.html
 == 579349-1.html 579349-1-ref.html
 == 579655-1.html 579655-1-ref.html
 skip-if(!haveTestPlugin) fails-if(Android) == 579808-1.html 579808-1-ref.html
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -18,18 +18,18 @@ fuzzy-if(gtkWidget||winWidget,8,376) fuz
 == preserve3d-2b.html preserve3d-2-ref.html
 == preserve3d-2c.html preserve3d-2-ref.html
 == preserve3d-2d.html preserve3d-2-ref.html
 == preserve3d-3a.html preserve3d-3-ref.html
 == preserve3d-4a.html about:blank
 fuzzy-if(gtkWidget,4,200) fuzzy-if(Android,4,300) fuzzy-if(winWidget&&!layersGPUAccelerated,2,100) fuzzy-if(skiaContent,16,100) == preserve3d-5a.html preserve3d-5-ref.html
 == preserve3d-6a.html preserve3d-6-ref.html
 == scale3d-z.html scalez-1-ref.html
-fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fuzzy-if(OSX>=1008,224,924) == scale3d-all.html scale3d-1-ref.html # subpixel AA
-fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fuzzy-if(OSX>=1008,224,924) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
+fuzzy-if(winWidget,143,689) fuzzy-if(OSX>=1008,224,924) == scale3d-all.html scale3d-1-ref.html # subpixel AA
+fuzzy-if(winWidget,143,689) fuzzy-if(OSX>=1008,224,924) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
 == scale3d-xz.html scale3d-1-ref.html
 == translatez-1a.html translatez-1-ref.html
 != translatez-1b.html translatez-1-ref.html
 == translate3d-1a.html translate3d-1-ref.html
 fuzzy-if(skiaContent,1,4) == matrix3d-1a.html matrix3d-1-ref.html
 == matrix3d-2a.html matrix3d-2-ref.html
 == rotate3d-1a.html rotatex-1-ref.html
 == rotate3d-2a.html rotatey-1-ref.html