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 71797 602d13dcab537ff844d20e9698658619d35f24fa
parent 71796 198d6364abb9747d612f4c20e244fe02e49a1e77
child 71798 123d2c2f626066e8b5d393ea13da451e09594ea3
push idunknown
push userunknown
push dateunknown
reviewersmattwoodrow
bugs637852
milestone7.0a1
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 */