Bug 1151145 - Add assertions to detect unbalanced calls to CGContextSaveGState / CGContextRestoreGState. r=jrmuizel
authorMarkus Stange <mstange@themasta.com>
Sat, 04 Apr 2015 18:12:12 -0400
changeset 237775 135120efabd3
parent 237774 852527d009a4
child 237776 92b866002a30
push id28549
push userryanvm@gmail.com
push date2015-04-07 01:19 +0000
treeherdermozilla-central@335f1295e99b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1151145
milestone40.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 1151145 - Add assertions to detect unbalanced calls to CGContextSaveGState / CGContextRestoreGState. r=jrmuizel
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