Backed out 2 changesets (bug 814952) because it breaks the build
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 12 Dec 2012 16:16:35 -0500
changeset 115839 edd575426780
parent 115838 1d6f209c9067
child 115840 b2b5567fe14a
push id24028
push useremorley@mozilla.com
push dateThu, 13 Dec 2012 15:56:02 +0000
treeherdermozilla-central@9db79b97abbb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs814952
milestone20.0a1
backs out974417414266
315707349606
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
Backed out 2 changesets (bug 814952) because it breaks the build Backed out changeset 974417414266 (bug 814952) Backed out changeset 315707349606 (bug 814952)
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
layout/reftests/bugs/814952-1-ref.html
layout/reftests/bugs/814952-1.html
layout/reftests/bugs/reftest.list
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -202,19 +202,28 @@ gfxContext::Restore()
 
     if (CurrentState().clipWasReset &&
         CurrentState().drawTarget == mStateStack[mStateStack.Length() - 2].drawTarget) {
       PushClipsToDT(mDT);
     }
 
     mStateStack.RemoveElementAt(mStateStack.Length() - 1);
 
+    if ((mPathBuilder || mPath || mPathIsRect) && !mTransformChanged) {
+      // Support here isn't fully correct if the path is continued -after-
+      // the restore. We don't currently have users that do this and we should
+      // make sure there will not be any. Sadly we can't assert this easily.
+      mTransformChanged = true;
+      mPathTransform = mTransform;
+    }
+
     mDT = CurrentState().drawTarget;
 
-    ChangeTransform(CurrentState().transform, false);
+    mTransform = CurrentState().transform;
+    mDT->SetTransform(GetDTTransform());
   }
 }
 
 // drawing
 void
 gfxContext::NewPath()
 {
   if (mCairo) {
@@ -276,18 +285,16 @@ gfxContext::CurrentPoint()
 void
 gfxContext::Stroke()
 {
   if (mCairo) {
     cairo_stroke_preserve(mCairo);
   } else {
     AzureState &state = CurrentState();
     if (mPathIsRect) {
-      MOZ_ASSERT(!mTransformChanged);
-
       mDT->StrokeRect(mRect, GeneralPattern(this),
                       state.strokeOptions,
                       DrawOptions(1.0f, GetOp(), state.aaMode));
     } else {
       EnsurePath();
 
       mDT->Stroke(mPath, GeneralPattern(this), state.strokeOptions,
                   DrawOptions(1.0f, GetOp(), state.aaMode));
@@ -462,20 +469,20 @@ gfxContext::Rectangle(const gfxRect& rec
         rec = ToRect(mat.TransformBounds(newRect));
       }
     }
 
     if (!mPathBuilder && !mPathIsRect) {
       mPathIsRect = true;
       mRect = rec;
       return;
+    } else if (!mPathBuilder) {
+      EnsurePathBuilder();
     }
-
-    EnsurePathBuilder();
-
+    
     mPathBuilder->MoveTo(rec.TopLeft());
     mPathBuilder->LineTo(rec.TopRight());
     mPathBuilder->LineTo(rec.BottomRight());
     mPathBuilder->LineTo(rec.BottomLeft());
     mPathBuilder->Close();
   }
 }
 
@@ -1126,19 +1133,17 @@ gfxContext::Clip(const gfxRect& rect)
 }
 
 void
 gfxContext::Clip()
 {
   if (mCairo) {
     cairo_clip_preserve(mCairo);
   } else {
-    if (mPathIsRect) {
-      MOZ_ASSERT(!mTransformChanged);
-
+    if (mPathIsRect && !mTransformChanged) {
       AzureState::PushedClip clip = { NULL, mRect, mTransform };
       CurrentState().pushedClips.AppendElement(clip);
       mDT->PushClipRect(mRect);
     } else {
       EnsurePath();
       mDT->PushClip(mPath);
       AzureState::PushedClip clip = { mPath, Rect(), mTransform };
       CurrentState().pushedClips.AppendElement(clip);
@@ -1940,75 +1945,56 @@ gfxContext::EnsurePath()
   EnsurePathBuilder();
   mPath = mPathBuilder->Finish();
   mPathBuilder = NULL;
 }
 
 void
 gfxContext::EnsurePathBuilder()
 {
-  if (mPathBuilder && !mTransformChanged) {
+  if (mPathBuilder) {
     return;
   }
 
   if (mPath) {
-    if (!mTransformChanged) {
-      mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule);
-      mPath = NULL;
-    } else {
-      Matrix invTransform = mTransform;
-      invTransform.Invert();
-      Matrix toNewUS = mPathTransform * invTransform;
-      mPathBuilder = mPath->TransformedCopyToBuilder(toNewUS, CurrentState().fillRule);
-    }
-    return;
+    mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule);
+    mPath = NULL;
   }
 
-  DebugOnly<PathBuilder*> oldPath = mPathBuilder;
-
-  if (!mPathBuilder) {
-    mPathBuilder = mDT->CreatePathBuilder(CurrentState().fillRule);
-
-    if (mPathIsRect) {
-      mPathBuilder->MoveTo(mRect.TopLeft());
-      mPathBuilder->LineTo(mRect.TopRight());
-      mPathBuilder->LineTo(mRect.BottomRight());
-      mPathBuilder->LineTo(mRect.BottomLeft());
-      mPathBuilder->Close();
-    }
-  }
+  mPathBuilder = mDT->CreatePathBuilder(CurrentState().fillRule);
 
-  if (mTransformChanged) {
-    // This could be an else if since this should never happen when
-    // mPathBuilder is NULL and mPath is NULL. But this way we can assert
-    // if all the state is as expected.
-    MOZ_ASSERT(oldPath);
-    MOZ_ASSERT(!mPathIsRect);
-
-    Matrix invTransform = mTransform;
-    invTransform.Invert();
-    Matrix toNewUS = mPathTransform * invTransform;
-
-    RefPtr<Path> path = mPathBuilder->Finish();
-    mPathBuilder = path->TransformedCopyToBuilder(toNewUS, CurrentState().fillRule);
+  if (mPathIsRect && !mTransformChanged) {
+    mPathBuilder->MoveTo(mRect.TopLeft());
+    mPathBuilder->LineTo(mRect.TopRight());
+    mPathBuilder->LineTo(mRect.BottomRight());
+    mPathBuilder->LineTo(mRect.BottomLeft());
+    mPathBuilder->Close();
+  } else if (mPathIsRect) {
+    mTransformChanged = false;
+    Matrix mat = mTransform;
+    mat.Invert();
+    mat = mPathTransform * mat;
+    mPathBuilder->MoveTo(mat * mRect.TopLeft());
+    mPathBuilder->LineTo(mat * mRect.TopRight());
+    mPathBuilder->LineTo(mat * mRect.BottomRight());
+    mPathBuilder->LineTo(mat * mRect.BottomLeft());
+    mPathBuilder->Close();
   }
 
   mPathIsRect = false;
 }
 
 void
 gfxContext::FillAzure(Float aOpacity)
 {
   AzureState &state = CurrentState();
 
   CompositionOp op = GetOp();
 
-  if (mPathIsRect) {
-    MOZ_ASSERT(!mTransformChanged);
-
+  if (mPathIsRect && !mTransformChanged) {
     if (state.opIsClear) {
       mDT->ClearRect(mRect);
     } else if (op == OP_SOURCE) {
       // Emulate cairo operator source which is bound by mask!
       mDT->ClearRect(mRect);
       mDT->FillRect(mRect, GeneralPattern(this), DrawOptions(aOpacity));
     } else {
       mDT->FillRect(mRect, GeneralPattern(this), DrawOptions(aOpacity, op, state.aaMode));
@@ -2078,62 +2064,55 @@ gfxContext::GetOp()
       return OP_SOURCE;
     }
   }
 }
 
 /* SVG font code can change the transform after having set the pattern on the
  * context. When the pattern is set it is in user space, if the transform is
  * changed after doing so the pattern needs to be converted back into userspace.
- * We just store the old pattern transform here so that we only do the work
- * needed here if the pattern is actually used.
- * We need to avoid doing this when this ChangeTransform comes from a restore,
- * since the current pattern and the current transform are both part of the
- * state we know the new CurrentState()'s values are valid. But if we assume
- * a change they might become invalid since patternTransformChanged is part of
- * the state and might be false for the restored AzureState.
+ * We just store the old pattern here so that we only do the work needed here
+ * if the pattern is actually used.
  */
 void
-gfxContext::ChangeTransform(const Matrix &aNewMatrix, bool aUpdatePatternTransform)
+gfxContext::ChangeTransform(const Matrix &aNewMatrix)
 {
   AzureState &state = CurrentState();
 
-  if (aUpdatePatternTransform && (state.pattern || state.sourceSurface)
+  if ((state.pattern || state.sourceSurface)
       && !state.patternTransformChanged) {
     state.patternTransform = mTransform;
     state.patternTransformChanged = true;
   }
 
-  if (mPathIsRect) {
+  if (mPathBuilder || mPathIsRect) {
     Matrix invMatrix = aNewMatrix;
     
     invMatrix.Invert();
 
     Matrix toNewUS = mTransform * invMatrix;
 
-    if (toNewUS.IsRectilinear()) {
+    if (toNewUS.IsRectilinear() && mPathIsRect) {
       mRect = toNewUS.TransformBounds(mRect);
       mRect.NudgeToIntegers();
-    } else {
+    } else if (mPathIsRect) {
       mPathBuilder = mDT->CreatePathBuilder(CurrentState().fillRule);
       
       mPathBuilder->MoveTo(toNewUS * mRect.TopLeft());
       mPathBuilder->LineTo(toNewUS * mRect.TopRight());
       mPathBuilder->LineTo(toNewUS * mRect.BottomRight());
       mPathBuilder->LineTo(toNewUS * mRect.BottomLeft());
       mPathBuilder->Close();
-
-      mPathIsRect = false;
+    } else {
+      RefPtr<Path> path = mPathBuilder->Finish();
+      // Create path in device space.
+      mPathBuilder = path->TransformedCopyToBuilder(toNewUS);
     }
-
     // No need to consider the transform changed now!
     mTransformChanged = false;
-  } else if ((mPath || mPathBuilder) && !mTransformChanged) {
-    mTransformChanged = true;
-    mPathTransform = mTransform;
   }
 
   mTransform = aNewMatrix;
 
   mDT->SetTransform(GetDTTransform());
 }
 
 Rect
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -760,17 +760,17 @@ private:
 
   // This ensures mPath contains a valid path (in user space!)
   void EnsurePath();
   // This ensures mPathBuilder contains a valid PathBuilder (in user space!)
   void EnsurePathBuilder();
   void FillAzure(mozilla::gfx::Float aOpacity);
   void PushClipsToDT(mozilla::gfx::DrawTarget *aDT);
   CompositionOp GetOp();
-  void ChangeTransform(const mozilla::gfx::Matrix &aNewMatrix, bool aUpdatePatternTransform = true);
+  void ChangeTransform(const mozilla::gfx::Matrix &aNewMatrix);
   Rect GetAzureDeviceSpaceClipBounds();
   Matrix GetDeviceTransform() const;
   Matrix GetDTTransform() const;
   void PushNewDT(gfxASurface::gfxContentType content);
 
   bool mPathIsRect;
   bool mTransformChanged;
   Matrix mPathTransform;
deleted file mode 100644
--- a/layout/reftests/bugs/814952-1-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-    <title>non-scaling-stroke reftest</title>
-</head>
-<body>
-<svg height="2000" width="2000" xmlns="http://www.w3.org/2000/svg">
-    <path fill="red" stroke-width="2" stroke="black" d="m10,18 100,0 0,100 -100,00z"></path>
-</svg>
-</body></html>
\ No newline at end of file
deleted file mode 100644
--- a/layout/reftests/bugs/814952-1.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-    <title>non-scaling-stroke reftest</title>
-    <style>
-        * {
-            vector-effect: non-scaling-stroke;
-        }
-    </style>
-</head>
-<body>
-<svg height="2000" width="2000" xmlns="http://www.w3.org/2000/svg">
-    <path fill="red" stroke-width="2" stroke="black" d="m10,18 100,0 0,100 -100,00z"></path>
-</svg>
-</body></html>
\ No newline at end of file
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1729,11 +1729,10 @@ fuzzy-if(true,17,5859) == 759036-2.html 
 fuzzy(40,800) == 797797-1.html 797797-1-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 fuzzy(40,800) == 797797-2.html 797797-2-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 == 801994-1.html 801994-1-ref.html
 == 804323-1.html 804323-1-ref.html
 == 811301-1.html 811301-1-ref.html
 == 812824-1.html 812824-1-ref.html
 == 814677.html 814677-ref.html
 == 815593-1.html 815593-1-ref.html
-== 814592-1.html 814592-1-ref.html
 == 816458-1.html 816458-1-ref.html
 == 818276-1.html 818276-1-ref.html