Bug 1103621 - Get rid of GraphicsOperator::OPERATOR_CLEAR. r=mattwoodrow
authorJonathan Watt <jwatt@jwatt.org>
Thu, 20 Nov 2014 10:40:04 +0000
changeset 241343 e43fd991c15cb03804f98d6181e22f77187cdf37
parent 241342 e3601055862f52c106c1b891694cfffe27b83dd8
child 241344 4019b458cab756d7c8fddadccafa1fb089c0019c
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1103621
milestone36.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 1103621 - Get rid of GraphicsOperator::OPERATOR_CLEAR. r=mattwoodrow
gfx/layers/basic/BasicLayerManager.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
gfx/thebes/gfxDrawable.cpp
layout/svg/nsSVGPatternFrame.cpp
widget/windows/nsWindowGfx.cpp
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -522,23 +522,20 @@ BasicLayerManager::EndTransactionInterna
       MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
       if (mUsingDefaultTarget && mDoubleBuffering != BufferMode::BUFFER_NONE) {
         ApplyDoubleBuffering(mRoot, clipRect);
       }
     }
 
     PaintLayer(mTarget, mRoot, aCallback, aCallbackData);
     if (!mRegionToClear.IsEmpty()) {
-      AutoSetOperator op(mTarget, gfxContext::OPERATOR_CLEAR);
       nsIntRegionRectIterator iter(mRegionToClear);
       const nsIntRect *r;
       while ((r = iter.Next())) {
-        mTarget->NewPath();
-        mTarget->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
-        mTarget->Fill();
+        mTarget->GetDrawTarget()->ClearRect(Rect(r->x, r->y, r->width, r->height));
       }
     }
     if (mWidget) {
       FlashWidgetUpdateArea(mTarget);
     }
     RecordFrame();
     PostPresent();
 
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -535,21 +535,16 @@ gfxFloat
 gfxContext::CurrentLineWidth() const
 {
   return CurrentState().strokeOptions.mLineWidth;
 }
 
 void
 gfxContext::SetOperator(GraphicsOperator op)
 {
-  if (op == OPERATOR_CLEAR) {
-    CurrentState().opIsClear = true;
-    return;
-  }
-  CurrentState().opIsClear = false;
   CurrentState().op = CompositionOpForOp(op);
 }
 
 gfxContext::GraphicsOperator
 gfxContext::CurrentOperator() const
 {
   return ThebesOp(CurrentState().op);
 }
@@ -846,17 +841,17 @@ void
 gfxContext::Paint(gfxFloat alpha)
 {
   PROFILER_LABEL("gfxContext", "Paint",
     js::ProfileEntry::Category::GRAPHICS);
 
   AzureState &state = CurrentState();
 
   if (state.sourceSurface && !state.sourceSurfCairo &&
-      !state.patternTransformChanged && !state.opIsClear)
+      !state.patternTransformChanged)
   {
     // This is the case where a PopGroupToSource has been done and this
     // paint is executed without changing the transform or the source.
     Matrix oldMat = mDT->GetTransform();
 
     IntSize surfSize = state.sourceSurface->GetSize();
 
     mDT->SetTransform(Matrix::Translation(-state.deviceOffset.x,
@@ -869,22 +864,18 @@ gfxContext::Paint(gfxFloat alpha)
     mDT->SetTransform(oldMat);
     return;
   }
 
   Matrix mat = mDT->GetTransform();
   mat.Invert();
   Rect paintRect = mat.TransformBounds(Rect(Point(0, 0), Size(mDT->GetSize())));
 
-  if (state.opIsClear) {
-    mDT->ClearRect(paintRect);
-  } else {
-    mDT->FillRect(paintRect, PatternFromState(this),
-                  DrawOptions(Float(alpha), GetOp()));
-  }
+  mDT->FillRect(paintRect, PatternFromState(this),
+                DrawOptions(Float(alpha), GetOp()));
 }
 
 // groups
 
 void
 gfxContext::PushGroup(gfxContentType content)
 {
   DrawTarget* oldDT = mDT;
@@ -1133,30 +1124,25 @@ gfxContext::FillAzure(const Pattern& aPa
 {
   AzureState &state = CurrentState();
 
   CompositionOp op = GetOp();
 
   if (mPathIsRect) {
     MOZ_ASSERT(!mTransformChanged);
 
-    if (state.opIsClear) {
-      mDT->ClearRect(mRect);
-    } else if (op == CompositionOp::OP_SOURCE) {
+    if (op == CompositionOp::OP_SOURCE) {
       // Emulate cairo operator source which is bound by mask!
       mDT->ClearRect(mRect);
       mDT->FillRect(mRect, aPattern, DrawOptions(aOpacity));
     } else {
       mDT->FillRect(mRect, aPattern, DrawOptions(aOpacity, op, state.aaMode));
     }
   } else {
     EnsurePath();
-
-    NS_ASSERTION(!state.opIsClear, "We shouldn't be clearing complex paths!");
-
     mDT->Fill(mPath, aPattern, DrawOptions(aOpacity, op, state.aaMode));
   }
 }
 
 void
 gfxContext::PushClipsToDT(DrawTarget *aDT)
 {
   // Tricky, we have to restore all clips -since the last time- the clip
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -393,17 +393,16 @@ public:
     FillRule CurrentFillRule() const;
 
     /**
      ** Operators and Rendering control
      **/
 
     // define enum for operators (clear, src, dst, etc)
     enum GraphicsOperator {
-        OPERATOR_CLEAR,
         OPERATOR_SOURCE,
 
         OPERATOR_OVER,
         OPERATOR_IN,
         OPERATOR_OUT,
         OPERATOR_ATOP,
 
         OPERATOR_DEST,
@@ -550,26 +549,24 @@ private:
   typedef mozilla::gfx::Float Float;
   typedef mozilla::gfx::CompositionOp CompositionOp;
   typedef mozilla::gfx::PathBuilder PathBuilder;
   typedef mozilla::gfx::SourceSurface SourceSurface;
   
   struct AzureState {
     AzureState()
       : op(mozilla::gfx::CompositionOp::OP_OVER)
-      , opIsClear(false)
       , color(0, 0, 0, 1.0f)
       , clipWasReset(false)
       , fillRule(mozilla::gfx::FillRule::FILL_WINDING)
       , aaMode(mozilla::gfx::AntialiasMode::SUBPIXEL)
       , patternTransformChanged(false)
     {}
 
     mozilla::gfx::CompositionOp op;
-    bool opIsClear;
     Color color;
     nsRefPtr<gfxPattern> pattern;
     nsRefPtr<gfxASurface> sourceSurfCairo;
     mozilla::RefPtr<SourceSurface> sourceSurface;
     mozilla::gfx::Point sourceSurfaceDeviceOffset;
     Matrix surfTransform;
     Matrix transform;
     struct PushedClip {
--- a/gfx/thebes/gfxDrawable.cpp
+++ b/gfx/thebes/gfxDrawable.cpp
@@ -84,20 +84,18 @@ gfxSurfaceDrawable::DrawInternal(gfxCont
     patternTransform.Invert();
 
     SurfacePattern pattern(mSourceSurface, extend,
                            patternTransform, ToFilter(aFilter), aSamplingRect);
 
     Rect fillRect = ToRect(aFillRect);
     DrawTarget* dt = aContext->GetDrawTarget();
 
-    if (aContext->CurrentOperator() == gfxContext::OPERATOR_CLEAR) {
-        dt->ClearRect(fillRect);
-    } else if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE &&
-               aOpacity == 1.0) {
+    if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE &&
+        aOpacity == 1.0) {
         // Emulate cairo operator source which is bound by mask!
         dt->ClearRect(fillRect);
         dt->FillRect(fillRect, pattern);
     } else {
         dt->FillRect(fillRect, pattern,
                      DrawOptions(aOpacity,
                                  CompositionOpForOp(aContext->CurrentOperator()),
                                  aContext->CurrentAntialiasMode()));
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -371,24 +371,20 @@ nsSVGPatternFrame::PaintPattern(const Dr
                             patternHeight / surfaceSize.height);
   }
 
   RefPtr<DrawTarget> dt =
     aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8);
   if (!dt) {
     return nullptr;
   }
+  dt->ClearRect(Rect(0, 0, surfaceSize.width, surfaceSize.height));
 
   nsRefPtr<gfxContext> gfx = new gfxContext(dt);
 
-  // Fill with transparent black
-  gfx->SetOperator(gfxContext::OPERATOR_CLEAR);
-  gfx->Paint();
-  gfx->SetOperator(gfxContext::OPERATOR_OVER);
-
   if (aGraphicOpacity != 1.0f) {
     gfx->Save();
     gfx->PushGroup(gfxContentType::COLOR_ALPHA);
   }
 
   // OK, now render -- note that we use "firstKid", which
   // we got at the beginning because it takes care of the
   // referenced pattern situation for us
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -374,43 +374,42 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
           }
 
           RECT paintRect;
           ::GetClientRect(mWnd, &paintRect);
           RefPtr<DrawTarget> dt =
             gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(targetSurface,
                                                                    IntSize(paintRect.right - paintRect.left,
                                                                    paintRect.bottom - paintRect.top));
-          nsRefPtr<gfxContext> thebesContext = new gfxContext(dt);
-
           // don't need to double buffer with anything but GDI
           BufferMode doubleBuffering = mozilla::layers::BufferMode::BUFFER_NONE;
           if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) ||
               IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) {
 #ifdef MOZ_XUL
             switch (mTransparencyMode) {
               case eTransparencyGlass:
               case eTransparencyBorderlessGlass:
               default:
                 // If we're not doing translucency, then double buffer
                 doubleBuffering = mozilla::layers::BufferMode::BUFFERED;
                 break;
               case eTransparencyTransparent:
                 // If we're rendering with translucency, we're going to be
                 // rendering the whole window; make sure we clear it first
-                thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-                thebesContext->Paint();
-                thebesContext->SetOperator(gfxContext::OPERATOR_OVER);
+                dt->ClearRect(Rect(0.f, 0.f,
+                                   dt->GetSize().width, dt->GetSize().height));
                 break;
             }
 #else
             doubleBuffering = mozilla::layers::BufferMode::BUFFERED;
 #endif
           }
 
+          nsRefPtr<gfxContext> thebesContext = new gfxContext(dt);
+
           {
             AutoLayerManagerSetup
                 setupLayerManager(this, thebesContext, doubleBuffering);
             result = listener->PaintWindow(this, region);
           }
 
 #ifdef MOZ_XUL
           if ((IsRenderMode(gfxWindowsPlatform::RENDER_GDI) ||