Bug 1034404 - Get rid of the Thebes backed gfxContexts in ThebesLayerD3D9. r=Bas
authorJonathan Watt <jwatt@jwatt.org>
Sun, 06 Jul 2014 00:10:49 +0100
changeset 192506 0a63018c83a5cda09a8e9c8bd5c3e403d2496aac
parent 192505 60d0ee6ffa30363ba039dba26584b3384dcdf4a5
child 192507 f81a509fc014e4c9ec4fbc200535ff94152d4cbc
push id27088
push usercbook@mozilla.com
push dateMon, 07 Jul 2014 12:19:04 +0000
treeherdermozilla-central@699348fd356b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1034404
milestone33.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 1034404 - Get rid of the Thebes backed gfxContexts in ThebesLayerD3D9. r=Bas
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -466,21 +466,22 @@ TransparentRenderer::End()
   if (mTmpTexture)
 	  mTmpTexture->UnlockRect(0);
 }
 
 static void
 FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
             const nsIntPoint& aOffset, const gfxRGBA& aColor)
 {
-  nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-  ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
-  gfxUtils::ClipToRegion(ctx, aRegion);
-  ctx->SetColor(aColor);
-  ctx->Paint();
+  nsIntRegionRectIterator iter(aRegion);
+  const nsIntRect* r;
+  while ((r = iter.Next()) != nullptr) {
+    nsIntRect rect = *r + aOffset;
+    gfxUtils::ClearThebesSurface(aSurface, &rect, aColor);
+  }
 }
 
 void
 ThebesLayerD3D9::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode,
                             const nsTArray<ReadbackProcessor::Update>& aReadbackUpdates)
 {
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
 
@@ -521,27 +522,23 @@ ThebesLayerD3D9::DrawRegion(nsIntRegion 
       }
       break;
     }
   }
 
   if (!destinationSurface)
     return;
 
-  nsRefPtr<gfxContext> context;
-  if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(BackendType::CAIRO)) {
-     RefPtr<DrawTarget> dt =
-        gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(destinationSurface,
-                                                               IntSize(destinationSurface->GetSize().width,
-                                                                       destinationSurface->GetSize().height));
+  MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContentForType(BackendType::CAIRO));
+  RefPtr<DrawTarget> dt =
+    gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(destinationSurface,
+                                                           IntSize(destinationSurface->GetSize().width,
+                                                                   destinationSurface->GetSize().height));
 
-    context = new gfxContext(dt);
-  } else {
-    context = new gfxContext(destinationSurface);
-  }
+  nsRefPtr<gfxContext> context = new gfxContext(dt);
 
   context->Translate(gfxPoint(-bounds.x, -bounds.y));
   LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
   cbInfo.Callback(this, context, aRegion, DrawRegionClip::CLIP_NONE, nsIntRegion(), cbInfo.CallbackData);
 
   for (uint32_t i = 0; i < aReadbackUpdates.Length(); ++i) {
     NS_ASSERTION(aMode == SurfaceMode::SURFACE_OPAQUE,
                  "Transparent surfaces should not be used for readback");
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1000,28 +1000,38 @@ gfxUtils::ConvertYCbCrToRGB(const Planar
                                aData.mPicSize.height,
                                aData.mYStride,
                                aData.mCbCrStride,
                                aStride,
                                yuvtype);
   }
 }
 
-/* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface)
+/* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface,
+                                               nsIntRect* aRect,
+                                               const gfxRGBA& aColor)
 {
   if (aSurface->CairoStatus()) {
     return;
   }
   cairo_surface_t* surf = aSurface->CairoSurface();
   if (cairo_surface_status(surf)) {
     return;
   }
   cairo_t* ctx = cairo_create(surf);
-  cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR);
-  cairo_paint_with_alpha(ctx, 1.0);
+  cairo_set_source_rgba(ctx, aColor.r, aColor.g, aColor.b, aColor.a);
+  cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
+  nsIntRect bounds;
+  if (aRect) {
+    bounds = *aRect;
+  } else {
+    bounds = nsIntRect(nsIntPoint(0, 0), aSurface->GetSize());
+  }
+  cairo_rectangle(ctx, bounds.x, bounds.y, bounds.width, bounds.height);
+  cairo_fill(ctx);
   cairo_destroy(ctx);
 }
 
 /* static */ TemporaryRef<DataSourceSurface>
 gfxUtils::CopySurfaceToDataSourceSurfaceWithFormat(SourceSurface* aSurface,
                                                    SurfaceFormat aFormat)
 {
   MOZ_ASSERT(aFormat != aSurface->GetFormat(),
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_UTILS_H
 #define GFX_UTILS_H
 
+#include "gfxColor.h"
 #include "gfxTypes.h"
 #include "GraphicsFilter.h"
 #include "imgIContainer.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "nsPrintfCString.h"
 
 class gfxASurface;
@@ -166,19 +167,21 @@ public:
     static void
     ConvertYCbCrToRGB(const mozilla::layers::PlanarYCbCrData& aData,
                       const gfxImageFormat& aDestFormat,
                       const gfxIntSize& aDestSize,
                       unsigned char* aDestBuffer,
                       int32_t aStride);
 
     /**
-     * Clears surface to transparent black.
+     * Clears surface to aColor (which defaults to transparent black).
      */
-    static void ClearThebesSurface(gfxASurface* aSurface);
+    static void ClearThebesSurface(gfxASurface* aSurface,
+                                   nsIntRect* aRect = nullptr,
+                                   const gfxRGBA& aColor = gfxRGBA(0.0, 0.0, 0.0, 0.0));
 
     /**
      * Creates a copy of aSurface, but having the SurfaceFormat aFormat.
      *
      * This function always creates a new surface. Do not call it if aSurface's
      * format is the same as aFormat. Such a non-conversion would just be an
      * unnecessary and wasteful copy (this function asserts to prevent that).
      *