Bug 1151145 - Add assertions to detect unbalanced calls to CGContextSaveGState / CGContextRestoreGState. r=jrmuizel, a=lizzard
authorMarkus Stange <mstange@themasta.com>
Sat, 04 Apr 2015 18:12:12 -0400
changeset 254979 969ad710b89e
parent 254978 c4248bd6b7c3
child 254980 77b9d633dfb9
push id7914
push userryanvm@gmail.com
push date2015-04-13 18:28 +0000
treeherdermozilla-aurora@428734cf3a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, lizzard
bugs1151145
milestone39.0a2
Bug 1151145 - Add assertions to detect unbalanced calls to CGContextSaveGState / CGContextRestoreGState. r=jrmuizel, a=lizzard
gfx/2d/DrawTargetCG.cpp
gfx/2d/DrawTargetCG.h
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -1956,16 +1956,20 @@ DrawTargetCG::Mask(const Pattern &aSourc
 
 void
 DrawTargetCG::PushClipRect(const Rect &aRect)
 {
   if (MOZ2D_ERROR_IF(!mCg)) {
     return;
   }
 
+#ifdef DEBUG
+  mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
+#endif
+
   CGContextSaveGState(mCg);
 
   /* We go through a bit of trouble to temporarilly set the transform
    * while we add the path */
   CGAffineTransform previousTransform = CGContextGetCTM(mCg);
   CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
   CGContextClipToRect(mCg, RectToCGRect(aRect));
   CGContextSetCTM(mCg, previousTransform);
@@ -1974,16 +1978,20 @@ DrawTargetCG::PushClipRect(const Rect &a
 
 void
 DrawTargetCG::PushClip(const Path *aPath)
 {
   if (MOZ2D_ERROR_IF(!mCg)) {
     return;
   }
 
+#ifdef DEBUG
+  mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
+#endif
+
   CGContextSaveGState(mCg);
 
   CGContextBeginPath(mCg);
   assert(aPath->GetBackendType() == BackendType::COREGRAPHICS);
 
   const PathCG *cgPath = static_cast<const PathCG*>(aPath);
 
   // Weirdly, CoreGraphics clips empty paths as all shown
@@ -2008,16 +2016,23 @@ DrawTargetCG::PushClip(const Path *aPath
   else
     CGContextClip(mCg);
 }
 
 void
 DrawTargetCG::PopClip()
 {
   CGContextRestoreGState(mCg);
+
+#ifdef DEBUG
+  MOZ_ASSERT(!mSavedClipBounds.empty(), "Unbalanced PopClip");
+  MOZ_ASSERT(CGRectEqualToRect(mSavedClipBounds.back(), CGContextGetClipBoundingBox(mCg)),
+             "PopClip didn't restore original clip");
+  mSavedClipBounds.pop_back();
+#endif
 }
 
 void
 DrawTargetCG::MarkChanged()
 {
   if (mSnapshot) {
     if (mSnapshot->refCount() > 1) {
       // We only need to worry about snapshots that someone else knows about
--- a/gfx/2d/DrawTargetCG.h
+++ b/gfx/2d/DrawTargetCG.h
@@ -202,15 +202,19 @@ private:
    * If the DrawTarget was created for a pre-existing buffer or if the buffer's
    * lifetime is managed by CoreGraphics, mData will be null.
    * Data owned by DrawTargetCG will be deallocated in the destructor.
    */
   AlignedArray<uint8_t> mData;
 
   RefPtr<SourceSurfaceCGContext> mSnapshot;
   bool mMayContainInvalidPremultipliedData;
+
+#ifdef DEBUG
+  std::vector<CGRect> mSavedClipBounds;
+#endif
 };
 
 }
 }
 
 #endif