Bug 615316 - Part 1: Factor out SurfaceToTexture conversion for D3D10 Image Layers. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Wed, 15 Dec 2010 21:37:10 +0100
changeset 59256 e6ee4b05d44af68c9b8500f6364a033722d68aed
parent 59255 74bd849a56d633fbb4afdf93468ae33268ef878f
child 59257 97bbced8ab7148239a1b20aeea9e99e43db0502a
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs615316
milestone2.0b9pre
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 615316 - Part 1: Factor out SurfaceToTexture conversion for D3D10 Image Layers. r=jrmuizel
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d10/ImageLayerD3D10.h
--- a/gfx/layers/d3d10/ImageLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp
@@ -32,23 +32,69 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ImageLayerD3D10.h"
 #include "gfxImageSurface.h"
+#include "gfxWindowsSurface.h"
 #include "yuv_convert.h"
 
 namespace mozilla {
 namespace layers {
 
 using mozilla::MutexAutoLock;
 
+static already_AddRefed<ID3D10Texture2D>
+SurfaceToTexture(ID3D10Device *aDevice,
+                 gfxASurface *aSurface,
+                 const gfxIntSize &aSize)
+{
+  if (aSurface && aSurface->GetType() == gfxASurface::SurfaceTypeD2D) {
+    void *data = aSurface->GetData(&gKeyD3D10Texture);
+    if (data) {
+      nsRefPtr<ID3D10Texture2D> texture = static_cast<ID3D10Texture2D*>(data);
+      ID3D10Device *dev;
+      texture->GetDevice(&dev);
+      if (dev == aDevice) {
+        return texture.forget();
+      }
+    }
+  }
+
+  nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
+
+  if (!imageSurface) {
+    imageSurface = new gfxImageSurface(aSize,
+                                       gfxASurface::ImageFormatARGB32);
+    
+    nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
+    context->SetSource(aSurface);
+    context->SetOperator(gfxContext::OPERATOR_SOURCE);
+    context->Paint();
+  }
+
+  D3D10_SUBRESOURCE_DATA data;
+  
+  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+                             imageSurface->GetSize().width,
+                             imageSurface->GetSize().height,
+                             1, 1);
+  desc.Usage = D3D10_USAGE_IMMUTABLE;
+  
+  data.pSysMem = imageSurface->Data();
+  data.SysMemPitch = imageSurface->Stride();
+
+  nsRefPtr<ID3D10Texture2D> texture;
+  aDevice->CreateTexture2D(&desc, &data, getter_AddRefs(texture));
+  return texture.forget();
+}
+
 ImageContainerD3D10::ImageContainerD3D10(LayerManagerD3D10 *aManager)
   : ImageContainer(aManager)
   , mDevice(aManager->device())
   , mActiveImageLock("mozilla.layers.ImageContainerD3D10.mActiveImageLock")
 {
 }
 
 already_AddRefed<Image>
@@ -182,20 +228,28 @@ ImageLayerD3D10::RenderLayer()
         (float)0,
         (float)yuvImage->mSize.width,
         (float)yuvImage->mSize.height)
       );
   } else if (image->GetFormat() == Image::CAIRO_SURFACE) {
     CairoImageD3D10 *cairoImage =
       static_cast<CairoImageD3D10*>(image.get());
 
-    if (mFilter == gfxPattern::FILTER_NEAREST) {
-      technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
+    if (cairoImage->mHasAlpha) {
+      if (mFilter == gfxPattern::FILTER_NEAREST) {
+        technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
+      } else {
+        technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
+      }
     } else {
-      technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
+      if (mFilter == gfxPattern::FILTER_NEAREST) {
+        technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
+      } else {
+        technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
+      }
     }
 
     if (cairoImage->mSRView) {
       effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(cairoImage->mSRView);
     }
 
     effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
       ShaderConstantRectD3D10(
@@ -351,40 +405,27 @@ PlanarYCbCrImageD3D10::GetAsSurface()
 CairoImageD3D10::~CairoImageD3D10()
 {
 }
 
 void
 CairoImageD3D10::SetData(const CairoImage::Data &aData)
 {
   mSize = aData.mSize;
-
-  nsRefPtr<gfxImageSurface> imageSurface;
+  NS_ASSERTION(aData.mSurface->GetContentType() != gfxASurface::CONTENT_ALPHA,
+               "Invalid content type passed to CairoImageD3D10.");
 
-  if (aData.mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
-    imageSurface = static_cast<gfxImageSurface*>(aData.mSurface);
+  mTexture = SurfaceToTexture(mDevice, aData.mSurface, mSize);
+
+  if (aData.mSurface->GetContentType() == gfxASurface::CONTENT_COLOR) {
+    mHasAlpha = false;
   } else {
-    imageSurface = new gfxImageSurface(aData.mSize,
-                                       gfxASurface::ImageFormatARGB32);
-    
-    nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
-    context->SetSource(aData.mSurface);
-    context->SetOperator(gfxContext::OPERATOR_SOURCE);
-    context->Paint();
+    mHasAlpha = true;
   }
 
-  D3D10_SUBRESOURCE_DATA data;
-  
-  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mSize.width, mSize.height, 1, 1);
-  desc.Usage = D3D10_USAGE_IMMUTABLE;
-  
-  data.pSysMem = imageSurface->Data();
-  data.SysMemPitch = imageSurface->Stride();
-
-  mDevice->CreateTexture2D(&desc, &data, getter_AddRefs(mTexture));
   mDevice->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
 }
 
 already_AddRefed<gfxASurface>
 CairoImageD3D10::GetAsSurface()
 {
   return nsnull;
 }
--- a/gfx/layers/d3d10/ImageLayerD3D10.h
+++ b/gfx/layers/d3d10/ImageLayerD3D10.h
@@ -133,24 +133,26 @@ public:
 
 class THEBES_API CairoImageD3D10 : public CairoImage,
                                    public ImageD3D10
 {
 public:
   CairoImageD3D10(ID3D10Device1 *aDevice)
     : CairoImage(static_cast<ImageD3D10*>(this))
     , mDevice(aDevice)
+    , mHasAlpha(true)
   { }
   ~CairoImageD3D10();
 
   virtual void SetData(const Data &aData);
 
   virtual already_AddRefed<gfxASurface> GetAsSurface();
 
   nsRefPtr<ID3D10Device1> mDevice;
   nsRefPtr<ID3D10Texture2D> mTexture;
   nsRefPtr<ID3D10ShaderResourceView> mSRView;
   gfxIntSize mSize;
+  bool mHasAlpha;
 };
 
 } /* layers */
 } /* mozilla */
 #endif /* GFX_IMAGELAYERD3D10_H */