Bug 1083245 - Pop all clips before copying to the destination blending surface. r=jrmuizel, a=sledru
authorBas Schouten <bschouten@mozilla.com>
Wed, 04 Feb 2015 22:03:21 +0100
changeset 243744 33a2305f846a
parent 243743 d02e363ecb6f
child 243745 3ef577b545b8
push id4460
push userryanvm@gmail.com
push date2015-02-10 14:41 +0000
treeherdermozilla-beta@a00e758a0460 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, sledru
bugs1083245
milestone36.0
Bug 1083245 - Pop all clips before copying to the destination blending surface. r=jrmuizel, a=sledru We need to pop the clips from the decide context before flushing and copying to the destination blending surface, otherwise drawing commands executed on a pushed layer for clipping will not be realized on the destination surface for blending. Note that this fixes most situation, but in the case of doing custom blending to an area of a surface which is not opaque while having a complex clip pushed this will still lead to some artifacts. I haven't seen this be a problem in practice though.
gfx/2d/DrawTargetD2D1.cpp
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -963,26 +963,31 @@ DrawTargetD2D1::FinalizeDrawing(Composit
         return;
       }
     }
 
     RefPtr<ID2D1Bitmap> tmpBitmap;
     mDC->CreateBitmap(D2DIntSize(mSize), D2D1::BitmapProperties(D2DPixelFormat(mFormat)), byRef(tmpBitmap));
 
     // This flush is important since the copy method will not know about the context drawing to the surface.
+    // We also need to pop all the clips to make sure any drawn content will have made it to the final bitmap.
+    PopAllClips();
     mDC->Flush();
 
     // We need to use a copy here because affects don't accept a surface on
     // both their in- and outputs.
     tmpBitmap->CopyFromBitmap(nullptr, mBitmap, nullptr);
 
     mBlendEffect->SetInput(0, tmpBitmap);
     mBlendEffect->SetInput(1, mTempBitmap);
     mBlendEffect->SetValue(D2D1_BLEND_PROP_MODE, D2DBlendMode(aOp));
 
+    PushClipsToDC(mDC);
+    mClipsArePushed = true;
+
     mDC->DrawImage(mBlendEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY);
     return;
   }
 
   const RadialGradientPattern *pat = static_cast<const RadialGradientPattern*>(&aPattern);
   if (pat->mCenter1 == pat->mCenter2 && pat->mRadius1 == pat->mRadius2) {
     // Draw nothing!
     return;