Bug 637852. Part 8: Remove resolution support from D3D9 layers. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 23 Jun 2011 00:11:27 +1200
changeset 71523 602d13dcab537ff844d20e9698658619d35f24fa
parent 71522 198d6364abb9747d612f4c20e244fe02e49a1e77
child 71524 123d2c2f626066e8b5d393ea13da451e09594ea3
push id20559
push usereakhgari@mozilla.com
push dateWed, 22 Jun 2011 19:51:00 +0000
treeherdermozilla-central@cd95d565c4d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs637852
milestone7.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 637852. Part 8: Remove resolution support from D3D9 layers. r=mattwoodrow Layer-system resolution support is no longer needed.
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/layers/d3d9/ThebesLayerD3D9.h
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -72,42 +72,40 @@ void
 ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
 {
   mValidRegion.Sub(mValidRegion, aRegion);
 }
 
 void
 ThebesLayerD3D9::CopyRegion(IDirect3DTexture9* aSrc, const nsIntPoint &aSrcOffset,
                             IDirect3DTexture9* aDest, const nsIntPoint &aDestOffset,
-                            const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion,
-                            float aXRes, float aYRes)
+                            const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion)
 {
   nsRefPtr<IDirect3DSurface9> srcSurface, dstSurface;
   aSrc->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
   aDest->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
 
   nsIntRegion retainedRegion;
   nsIntRegionRectIterator iter(aCopyRegion);
   const nsIntRect *r;
   while ((r = iter.Next())) {
     if (r->width * r->height > RETENTION_THRESHOLD) {
       RECT oldRect, newRect;
 
       // Calculate the retained rectangle's position on the old and the new
-      // surface. We need to scale these rectangles since the visible
-      // region is in unscaled units, and the texture size has been scaled.
-      oldRect.left = UINT(floor((r->x - aSrcOffset.x) * aXRes));
-      oldRect.top = UINT(floor((r->y - aSrcOffset.y) * aYRes));
-      oldRect.right = oldRect.left + UINT(ceil(r->width * aXRes));
-      oldRect.bottom = oldRect.top + UINT(ceil(r->height * aYRes));
+      // surface.
+      oldRect.left = r->x - aSrcOffset.x;
+      oldRect.top = r->y - aSrcOffset.y;
+      oldRect.right = oldRect.left + r->width;
+      oldRect.bottom = oldRect.top + r->height;
 
-      newRect.left = UINT(floor((r->x - aDestOffset.x) * aXRes));
-      newRect.top = UINT(floor((r->y - aDestOffset.y) * aYRes));
-      newRect.right = newRect.left + UINT(ceil(r->width * aXRes));
-      newRect.bottom = newRect.top + UINT(ceil(r->height * aYRes));
+      newRect.left = r->x - aDestOffset.x;
+      newRect.top = r->y - aDestOffset.y;
+      newRect.right = newRect.left + r->width;
+      newRect.bottom = newRect.top + r->height;
 
       // Copy data from our old texture to the new one
       HRESULT hr = device()->
         StretchRect(srcSurface, &oldRect, dstSurface, &newRect, D3DTEXF_NONE);
 
       if (SUCCEEDED(hr)) {
         retainedRegion.Or(retainedRegion, *r);
       }
@@ -123,25 +121,16 @@ static PRUint64 RectArea(const nsIntRect
   return aRect.width*PRUint64(aRect.height);
 }
 
 void
 ThebesLayerD3D9::UpdateTextures(SurfaceMode aMode)
 {
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
 
-  float xres, yres;
-  GetDesiredResolutions(xres, yres);
-
-  // If our resolution changed, we need new sized textures, delete the old ones.
-  if (ResolutionChanged(xres, yres)) {
-      mTexture = nsnull;
-      mTextureOnWhite = nsnull;
-  }
-
   if (HaveTextures(aMode)) {
     if (!mTextureRect.IsEqualInterior(visibleRect)) {
       nsRefPtr<IDirect3DTexture9> oldTexture = mTexture;
       nsRefPtr<IDirect3DTexture9> oldTextureOnWhite = mTextureOnWhite;
 
       NS_ASSERTION(mTextureRect.Contains(mValidRegion.GetBounds()),
                    "How can we have valid data outside the texture?");
       nsIntRegion retainRegion;
@@ -154,20 +143,20 @@ ThebesLayerD3D9::UpdateTextures(SurfaceM
       // If our texture creation failed this can mean a device reset is pending and we
       // should silently ignore the failure. In the future when device failures
       // are properly handled we should test for the type of failure and gracefully
       // handle different failures. See bug 569081.
       if (!HaveTextures(aMode)) {
         mValidRegion.SetEmpty();
       } else {
         CopyRegion(oldTexture, mTextureRect.TopLeft(), mTexture, visibleRect.TopLeft(),
-                   retainRegion, &mValidRegion, xres, yres);
+                   retainRegion, &mValidRegion);
         if (aMode == SURFACE_COMPONENT_ALPHA) {
           CopyRegion(oldTextureOnWhite, mTextureRect.TopLeft(), mTextureOnWhite, visibleRect.TopLeft(),
-                     retainRegion, &mValidRegion, xres, yres);
+                     retainRegion, &mValidRegion);
         }
       }
 
       mTextureRect = visibleRect;
     }
   } else {
     CreateNewTextures(gfxIntSize(visibleRect.width, visibleRect.height), aMode);
     mTextureRect = visibleRect;
@@ -364,37 +353,34 @@ ThebesLayerD3D9::VerifyContentType(Surfa
   mValidRegion.SetEmpty();
 }
 
 class OpaqueRenderer {
 public:
   OpaqueRenderer(const nsIntRegion& aUpdateRegion) :
     mUpdateRegion(aUpdateRegion), mDC(NULL) {}
   ~OpaqueRenderer() { End(); }
-  already_AddRefed<gfxWindowsSurface> Begin(LayerD3D9* aLayer, float aXRes, float aYRes);
+  already_AddRefed<gfxWindowsSurface> Begin(LayerD3D9* aLayer);
   void End();
   IDirect3DTexture9* GetTexture() { return mTmpTexture; }
 
 private:
   const nsIntRegion& mUpdateRegion;
   nsRefPtr<IDirect3DTexture9> mTmpTexture;
   nsRefPtr<IDirect3DSurface9> mSurface;
   HDC mDC;
 };
 
 already_AddRefed<gfxWindowsSurface>
-OpaqueRenderer::Begin(LayerD3D9* aLayer, float aXRes, float aYRes)
+OpaqueRenderer::Begin(LayerD3D9* aLayer)
 {
   nsIntRect bounds = mUpdateRegion.GetBounds();
-  gfxIntSize scaledSize;
-  scaledSize.width = PRInt32(ceil(bounds.width * aXRes));
-  scaledSize.height = PRInt32(ceil(bounds.height * aYRes));
 
   HRESULT hr = aLayer->device()->
-      CreateTexture(scaledSize.width, scaledSize.height, 1, 0, D3DFMT_X8R8G8B8,
+      CreateTexture(bounds.width, bounds.height, 1, 0, D3DFMT_X8R8G8B8,
                     D3DPOOL_SYSTEMMEM, getter_AddRefs(mTmpTexture), NULL);
 
   if (FAILED(hr)) {
     aLayer->ReportFailure(NS_LITERAL_CSTRING("Failed to create temporary texture in system memory."), hr);
     return nsnull;
   }
 
   hr = mTmpTexture->GetSurfaceLevel(0, getter_AddRefs(mSurface));
@@ -422,99 +408,89 @@ OpaqueRenderer::End()
     mSurface->ReleaseDC(mDC);
     mSurface = NULL;
     mDC = NULL;
   }
 }
 
 static void
 FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
-            const nsIntPoint& aOffset, const gfxRGBA& aColor,
-            float aXRes, float aYRes)
+            const nsIntPoint& aOffset, const gfxRGBA& aColor)
 {
   nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-  ctx->Scale(aXRes, aYRes);
   ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
   gfxUtils::ClipToRegion(ctx, aRegion);
   ctx->SetColor(aColor);
   ctx->Paint();
 }
 
 void
 ThebesLayerD3D9::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode,
                             const nsTArray<ReadbackProcessor::Update>& aReadbackUpdates)
 {
   HRESULT hr;
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
-  float xres, yres;
-  GetDesiredResolutions(xres, yres);
 
   nsRefPtr<gfxASurface> destinationSurface;
   nsIntRect bounds = aRegion.GetBounds();
-  gfxIntSize scaledSize;
-  scaledSize.width = PRInt32(ceil(bounds.width * xres));
-  scaledSize.height = PRInt32(ceil(bounds.height * yres));
   nsRefPtr<IDirect3DTexture9> tmpTexture;
   OpaqueRenderer opaqueRenderer(aRegion);
   OpaqueRenderer opaqueRendererOnWhite(aRegion);
 
   switch (aMode)
   {
     case SURFACE_OPAQUE:
-      destinationSurface = opaqueRenderer.Begin(this, xres, yres);
+      destinationSurface = opaqueRenderer.Begin(this);
       break;
 
     case SURFACE_SINGLE_CHANNEL_ALPHA: {
-      hr = device()->CreateTexture(scaledSize.width, scaledSize.height, 1,
+      hr = device()->CreateTexture(bounds.width, bounds.height, 1,
                                    0, D3DFMT_A8R8G8B8,
                                    D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), NULL);
 
       if (FAILED(hr)) {
         ReportFailure(NS_LITERAL_CSTRING("Failed to create temporary texture in system memory."), hr);
         return;
       }
 
       // XXX - We may consider retaining a SYSTEMMEM texture texture the size
       // of our DEFAULT texture and then use UpdateTexture and add dirty rects
       // to update in a single call.
       nsRefPtr<gfxWindowsSurface> dest = new gfxWindowsSurface(
-          gfxIntSize(scaledSize.width, scaledSize.height), gfxASurface::ImageFormatARGB32);
+          gfxIntSize(bounds.width, bounds.height), gfxASurface::ImageFormatARGB32);
       // If the contents of this layer don't require component alpha in the
       // end of rendering, it's safe to enable Cleartype since all the Cleartype
       // glyphs must be over (or under) opaque pixels.
       dest->SetSubpixelAntialiasingEnabled(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
       destinationSurface = dest.forget();
       break;
     }
 
     case SURFACE_COMPONENT_ALPHA: {
-      nsRefPtr<gfxWindowsSurface> onBlack = opaqueRenderer.Begin(this, xres, yres);
-      nsRefPtr<gfxWindowsSurface> onWhite = opaqueRendererOnWhite.Begin(this, xres, yres);
+      nsRefPtr<gfxWindowsSurface> onBlack = opaqueRenderer.Begin(this);
+      nsRefPtr<gfxWindowsSurface> onWhite = opaqueRendererOnWhite.Begin(this);
       if (onBlack && onWhite) {
-        FillSurface(onBlack, aRegion, bounds.TopLeft(), gfxRGBA(0.0, 0.0, 0.0, 1.0), xres, yres);
-        FillSurface(onWhite, aRegion, bounds.TopLeft(), gfxRGBA(1.0, 1.0, 1.0, 1.0), xres, yres);
+        FillSurface(onBlack, aRegion, bounds.TopLeft(), gfxRGBA(0.0, 0.0, 0.0, 1.0));
+        FillSurface(onWhite, aRegion, bounds.TopLeft(), gfxRGBA(1.0, 1.0, 1.0, 1.0));
         gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() };
         destinationSurface = new gfxTeeSurface(surfaces, NS_ARRAY_LENGTH(surfaces));
         // Using this surface as a source will likely go horribly wrong, since
         // only the onBlack surface will really be used, so alpha information will
         // be incorrect.
         destinationSurface->SetAllowUseAsSource(PR_FALSE);
       }
       break;
     }
   }
 
   if (!destinationSurface)
     return;
 
   nsRefPtr<gfxContext> context = new gfxContext(destinationSurface);
-  // Draw content scaled at our current resolution.
-  context->Scale(xres, yres);
   context->Translate(gfxPoint(-bounds.x, -bounds.y));
-  aRegion.ExtendForScaling(xres, yres);
   LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
   cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
 
   for (PRUint32 i = 0; i < aReadbackUpdates.Length(); ++i) {
     NS_ASSERTION(aMode == SURFACE_OPAQUE,
                  "Transparent surfaces should not be used for readback");
     const ReadbackProcessor::Update& update = aReadbackUpdates[i];
     nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
@@ -540,17 +516,17 @@ ThebesLayerD3D9::DrawRegion(nsIntRegion 
       break;
 
     case SURFACE_SINGLE_CHANNEL_ALPHA: {
       D3DLOCKED_RECT r;
       tmpTexture->LockRect(0, &r, NULL, 0);
 
       nsRefPtr<gfxImageSurface> imgSurface =
         new gfxImageSurface((unsigned char *)r.pBits,
-                            scaledSize,
+                            bounds.Size(),
                             r.Pitch,
                             gfxASurface::ImageFormatARGB32);
 
       if (destinationSurface) {
         nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
         context->SetSource(destinationSurface);
         context->SetOperator(gfxContext::OPERATOR_SOURCE);
         context->Paint();
@@ -572,95 +548,58 @@ ThebesLayerD3D9::DrawRegion(nsIntRegion 
       destTextures.AppendElement(mTexture);
       srcTextures.AppendElement(opaqueRendererOnWhite.GetTexture());
       destTextures.AppendElement(mTextureOnWhite);
       break;
     }
   }
   NS_ASSERTION(srcTextures.Length() == destTextures.Length(), "Mismatched lengths");
 
-  // Copy to the texture. We need to scale these rectangles since the visible
-  // region is in unscaled units, and the texture sizes have been scaled.
+  // Copy to the texture.
   for (PRUint32 i = 0; i < srcTextures.Length(); ++i) {
     nsRefPtr<IDirect3DSurface9> srcSurface;
     nsRefPtr<IDirect3DSurface9> dstSurface;
 
     destTextures[i]->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
     srcTextures[i]->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
 
     nsIntRegionRectIterator iter(aRegion);
     const nsIntRect *iterRect;
     while ((iterRect = iter.Next())) {
       RECT rect;
-      rect.left = NS_MAX<LONG>(0, LONG(floor((iterRect->x - bounds.x) * xres)));
-      rect.top = NS_MAX<LONG>(0, LONG(floor((iterRect->y - bounds.y) * yres)));
-      rect.right = NS_MIN<LONG>(scaledSize.width,
-                                LONG(ceil((iterRect->XMost() - bounds.x) * xres)));
-      rect.bottom = NS_MIN<LONG>(scaledSize.height,
-                                 LONG(ceil((iterRect->YMost() - bounds.y) * yres)));
+      rect.left = iterRect->x - bounds.x;
+      rect.top = iterRect->y - bounds.y;
+      rect.right = iterRect->XMost() - bounds.x;
+      rect.bottom = iterRect->YMost() - bounds.y;
 
       POINT point;
-      point.x = NS_MAX<LONG>(0, LONG(floor((iterRect->x - visibleRect.x) * xres)));
-      point.y = NS_MAX<LONG>(0, LONG(floor((iterRect->y - visibleRect.y) * yres)));
+      point.x = iterRect->x - visibleRect.x;
+      point.y = iterRect->y - visibleRect.y;
       device()->UpdateSurface(srcSurface, &rect, dstSurface, &point);
     }
   }
 }
 
 void
 ThebesLayerD3D9::CreateNewTextures(const gfxIntSize &aSize,
                                    SurfaceMode aMode)
 {
   if (aSize.width == 0 || aSize.height == 0) {
     // Nothing to do.
     return;
   }
 
-  // Scale the requested size (in unscaled units) to the actual
-  // texture size we require.
-  gfxIntSize scaledSize;
-  float xres, yres;
-  GetDesiredResolutions(xres, yres);
-  scaledSize.width = PRInt32(ceil(aSize.width * xres));
-  scaledSize.height = PRInt32(ceil(aSize.height * yres));
-
   mTexture = nsnull;
   mTextureOnWhite = nsnull;
-  device()->CreateTexture(scaledSize.width, scaledSize.height, 1,
+  device()->CreateTexture(aSize.width, aSize.height, 1,
                           D3DUSAGE_RENDERTARGET,
                           aMode != SURFACE_SINGLE_CHANNEL_ALPHA ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
                           D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
   if (aMode == SURFACE_COMPONENT_ALPHA) {
-    device()->CreateTexture(scaledSize.width, scaledSize.height, 1,
+    device()->CreateTexture(aSize.width, aSize.height, 1,
                             D3DUSAGE_RENDERTARGET,
                             D3DFMT_X8R8G8B8,
                             D3DPOOL_DEFAULT, getter_AddRefs(mTextureOnWhite), NULL);
   }
-
-  mXResolution = xres;
-  mYResolution = yres;
-}
-
-void 
-ThebesLayerD3D9::GetDesiredResolutions(float& aXRes, float& aYRes)
-{
-  const gfx3DMatrix& transform = GetLayer()->GetEffectiveTransform();
-  gfxMatrix transform2d;
-  if (transform.Is2D(&transform2d)) {     
-    //Scale factors are normalized to a power of 2 to reduce the number of resolution changes
-    gfxSize scale = transform2d.ScaleFactors(PR_TRUE);
-    aXRes = gfxUtils::ClampToScaleFactor(scale.width);
-    aYRes = gfxUtils::ClampToScaleFactor(scale.height);
-  } else {
-    aXRes = 1.0;
-    aYRes = 1.0;
-  }
-}
-
-bool 
-ThebesLayerD3D9::ResolutionChanged(float aXRes, float aYRes)
-{
-  return aXRes != mXResolution ||
-         aYRes != mYResolution;
 }
 
 } /* namespace layers */
 } /* namespace mozilla */
--- a/gfx/layers/d3d9/ThebesLayerD3D9.h
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.h
@@ -104,25 +104,14 @@ private:
   void DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode,
                   const nsTArray<ReadbackProcessor::Update>& aReadbackUpdates);
 
   /* Create a new texture */
   void CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode);
 
   void CopyRegion(IDirect3DTexture9* aSrc, const nsIntPoint &aSrcOffset,
                   IDirect3DTexture9* aDest, const nsIntPoint &aDestOffset,
-                  const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion,
-                  float aXRes, float aYRes);
-
-  /**
-   * Calculate the desired texture resolution based on
-   * the layer managers resolution, and the current
-   * transforms scale factor.
-   */
-  void GetDesiredResolutions(float& aXRes, float& aYRes);
-
-  /* Check if the current texture resolution matches */
-  bool ResolutionChanged(float aXRes, float aYRes);
+                  const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion);
 };
 
 } /* layers */
 } /* mozilla */
 #endif /* GFX_THEBESLAYERD3D9_H */