Enable basic stereoscopic rendering support for D3D9 layers with 3D Vision. r=bas
authorAtul Apte <aapte135@gmail.com>
Thu, 26 Aug 2010 20:44:53 +0000
changeset 51527 e9992d1e029f147860cf747e76d86c30ac238edd
parent 51526 84e883bbc11ac7f82861c672a3a108936ecf61aa
child 51528 86766e0cfa0ca21e9750cdd20d27f0a6e64fc04c
push id15344
push userbschouten@mozilla.com
push dateThu, 26 Aug 2010 20:48:22 +0000
treeherdermozilla-central@c584dd85b461 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
milestone2.0b5pre
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
Enable basic stereoscopic rendering support for D3D9 layers with 3D Vision. r=bas
gfx/layers/Makefile.in
gfx/layers/d3d9/DeviceManagerD3D9.cpp
gfx/layers/d3d9/DeviceManagerD3D9.h
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/d3d9/LayerManagerD3D9.cpp
gfx/layers/d3d9/LayerManagerD3D9.h
gfx/layers/d3d9/Nv3DVUtils.cpp
gfx/layers/d3d9/Nv3DVUtils.h
gfx/thebes/gfxWindowsPlatform.cpp
modules/libpref/src/init/all.js
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -92,16 +92,17 @@ EXPORTS += \
 CPPSRCS += \
         LayerManagerD3D9.cpp \
         ThebesLayerD3D9.cpp \
         ContainerLayerD3D9.cpp \
         ImageLayerD3D9.cpp \
         ColorLayerD3D9.cpp \
         CanvasLayerD3D9.cpp \
         DeviceManagerD3D9.cpp \
+        Nv3DVUtils.cpp \
         $(NULL)
 endif
 endif
 
 ifdef MOZ_IPC #{
 EXPORTS_NAMESPACES = mozilla/layers
 EXPORTS_mozilla/layers =\
         ShadowLayers.h \
--- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp
@@ -36,16 +36,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "DeviceManagerD3D9.h"
 #include "LayerManagerD3D9Shaders.h"
 #include "ThebesLayerD3D9.h"
 #include "nsIServiceManager.h"
 #include "nsIConsoleService.h"
 #include "nsPrintfCString.h"
+#include "nsIPrefService.h" 
+#include "Nv3DVUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 const LPCWSTR kClassName       = L"D3D9WindowClass";
 
 #define USE_D3D9EX
 
@@ -208,16 +210,29 @@ DeviceManagerD3D9::Init()
                               CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
                               NULL, GetModuleHandle(NULL), NULL);
 
   if (!mFocusWnd) {
     NS_WARNING("Failed to create DeviceManagerD3D9 Window.");
     return false;
   }
 
+  /* Create an Nv3DVUtils instance */ 
+  if (!mNv3DVUtils) { 
+    mNv3DVUtils = new Nv3DVUtils(); 
+    if (!mNv3DVUtils) { 
+      NS_WARNING("Could not create a new instance of Nv3DVUtils.\n"); 
+    } 
+  } 
+
+  /* Initialize the Nv3DVUtils object */ 
+  if (mNv3DVUtils) { 
+    mNv3DVUtils->Initialize(); 
+  } 
+
   HMODULE d3d9 = LoadLibraryW(L"d3d9.dll");
   Direct3DCreate9Func d3d9Create = (Direct3DCreate9Func)
     GetProcAddress(d3d9, "Direct3DCreate9");
   Direct3DCreate9ExFunc d3d9CreateEx = (Direct3DCreate9ExFunc)
     GetProcAddress(d3d9, "Direct3DCreate9Ex");
   
 #ifdef USE_D3D9EX
   if (d3d9CreateEx) {
@@ -293,16 +308,27 @@ DeviceManagerD3D9::Init()
       return false;
     }
   }
 
   if (!VerifyCaps()) {
     return false;
   }
 
+  /* 
+   * Do some post device creation setup 
+   */ 
+  if (mNv3DVUtils) { 
+    IUnknown* devUnknown = NULL; 
+    if (mDevice) { 
+      mDevice->QueryInterface(IID_IUnknown, (void **)&devUnknown); 
+    } 
+    mNv3DVUtils->SetDeviceInfo(devUnknown); 
+  } 
+
   hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
                                    getter_AddRefs(mLayerVS));
 
   if (FAILED(hr)) {
     return false;
   }
 
   hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
--- a/gfx/layers/d3d9/DeviceManagerD3D9.h
+++ b/gfx/layers/d3d9/DeviceManagerD3D9.h
@@ -44,16 +44,17 @@
 #include "d3d9.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace layers {
 
 class DeviceManagerD3D9;
 class ThebesLayerD3D9;
+class Nv3DVUtils;
 
 /**
  * SwapChain class, this class manages the swap chain belonging to a
  * LayerManagerD3D9.
  */
 class THEBES_API SwapChainD3D9
 {
   NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9)
@@ -129,16 +130,21 @@ public:
   enum ShaderMode {
     RGBLAYER,
     YCBCRLAYER,
     SOLIDCOLORLAYER
   };
 
   void SetShaderMode(ShaderMode aMode);
 
+  /** 
+   * Return pointer to the Nv3DVUtils instance 
+   */ 
+  Nv3DVUtils *GetNv3DVUtils()  { return mNv3DVUtils; } 
+
   /**
    * We keep a list of all thebes layers since we need their D3DPOOL_DEFAULT
    * surfaces to be released when we want to reset the device.
    */
   nsTArray<ThebesLayerD3D9*> mThebesLayers;
 private:
   friend class SwapChainD3D9;
 
@@ -187,16 +193,19 @@ private:
   /* Our focus window - this is really a dummy window we can associate our
    * device with.
    */
   HWND mFocusWnd;
 
   /* If this device supports dynamic textures */
   bool mHasDynamicTextures;
 
+  /* Nv3DVUtils instance */ 
+  nsAutoPtr<Nv3DVUtils> mNv3DVUtils; 
+
   /**
    * Verifies all required device capabilities are present.
    */
   bool VerifyCaps();
 };
 
 } /* namespace layers */
 } /* namespace mozilla */
--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp
@@ -33,16 +33,20 @@
  * 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 "ImageLayerD3D9.h"
 #include "gfxImageSurface.h"
 #include "yuv_convert.h"
+#include "nsIServiceManager.h" 
+#include "nsIConsoleService.h" 
+#include "nsPrintfCString.h" 
+#include "Nv3DVUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 using mozilla::MutexAutoLock;
 
 ImageContainerD3D9::ImageContainerD3D9(LayerManagerD3D9 *aManager)
   : ImageContainer(aManager)
@@ -182,16 +186,28 @@ ImageLayerD3D9::RenderLayer()
      * We always upload a 4 component float, but the shader will
      * only use the the first component since it's declared as a 'float'.
      */
     opacity[0] = GetOpacity();
     device()->SetPixelShaderConstantF(0, opacity, 1);
 
     mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER);
 
+    /* 
+     * Send 3d control data and metadata 
+     */ 
+    if (mD3DManager->Is3DEnabled() && mD3DManager->GetNv3DVUtils()) { 
+      mD3DManager->GetNv3DVUtils()->SendNv3DVControl(STEREO_MODE_RIGHT_LEFT, true, FIREFOX_3DV_APP_HANDLE); 
+
+      nsRefPtr<IDirect3DSurface9> renderTarget; 
+      device()->GetRenderTarget(0, getter_AddRefs(renderTarget)); 
+      mD3DManager->GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->mSize.width, 
+        (unsigned int)yuvImage->mSize.height, (HANDLE)(yuvImage->mYTexture), (HANDLE)(renderTarget)); 
+    } 
+
     device()->SetTexture(0, yuvImage->mYTexture);
     device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
     device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
     device()->SetTexture(1, yuvImage->mCbTexture);
     device()->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
     device()->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
     device()->SetTexture(2, yuvImage->mCrTexture);
     device()->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
--- a/gfx/layers/d3d9/LayerManagerD3D9.cpp
+++ b/gfx/layers/d3d9/LayerManagerD3D9.cpp
@@ -37,23 +37,26 @@
 
 #include "LayerManagerD3D9.h"
 
 #include "ThebesLayerD3D9.h"
 #include "ContainerLayerD3D9.h"
 #include "ImageLayerD3D9.h"
 #include "ColorLayerD3D9.h"
 #include "CanvasLayerD3D9.h"
+#include "nsIServiceManager.h"
+#include "nsIPrefService.h"
 
 namespace mozilla {
 namespace layers {
 
 DeviceManagerD3D9 *LayerManagerD3D9::mDeviceManager = nsnull;
 
 LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
+  : mIs3DEnabled(PR_FALSE)
 {
     mWidget = aWidget;
     mCurrentCallbackInfo.Callback = NULL;
     mCurrentCallbackInfo.CallbackData = NULL;
 }
 
 LayerManagerD3D9::~LayerManagerD3D9()
 {
@@ -65,16 +68,20 @@ LayerManagerD3D9::~LayerManagerD3D9()
   if (mDeviceManager) {
     mDeviceManager->Release();
   }
 }
 
 PRBool
 LayerManagerD3D9::Initialize()
 {
+  /* Check the user preference for whether 3d video is enabled or not */ 
+  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); 
+  prefs->GetBoolPref("gfx.3d_video.enabled", &mIs3DEnabled); 
+
   if (!mDeviceManager) {
     mDeviceManager = new DeviceManagerD3D9;
 
     if (!mDeviceManager->Init()) {
       mDeviceManager = nsnull;
       return PR_FALSE;
     }
   }
--- a/gfx/layers/d3d9/LayerManagerD3D9.h
+++ b/gfx/layers/d3d9/LayerManagerD3D9.h
@@ -125,16 +125,26 @@ public:
   void SetClippingEnabled(PRBool aEnabled);
 
   void SetShaderMode(DeviceManagerD3D9::ShaderMode aMode)
     { mDeviceManager->SetShaderMode(aMode); }
 
   IDirect3DDevice9 *device() const { return mDeviceManager->device(); }
   DeviceManagerD3D9 *deviceManager() const { return mDeviceManager; }
 
+  /** 
+   * Return pointer to the Nv3DVUtils instance. Re-direct to mDeviceManager.
+   */ 
+  Nv3DVUtils *GetNv3DVUtils()  { return mDeviceManager ? mDeviceManager->GetNv3DVUtils() : NULL; } 
+
+  /** 
+   * Indicate whether 3D is enabled or not 
+   */ 
+  PRBool Is3DEnabled() { return mIs3DEnabled; } 
+
   static void OnDeviceManagerDestroy(DeviceManagerD3D9 *aDeviceManager) {
     if(aDeviceManager == mDeviceManager)
       mDeviceManager = nsnull;
   }
 
 private:
   /* Device manager instance */
   static DeviceManagerD3D9 *mDeviceManager;
@@ -151,16 +161,19 @@ private:
   nsRefPtr<gfxContext> mTarget;
 
   /* Current root layer. */
   LayerD3D9 *mRootLayer;
 
   /* Callback info for current transaction */
   CallbackInfo mCurrentCallbackInfo;
 
+  /* Flag that indicates whether 3D is enabled or not*/ 
+  PRBool mIs3DEnabled; 
+
   /*
    * Region we're clipping our current drawing to.
    */
   nsIntRegion mClippingRegion;
 
   /*
    * Render the current layer tree to the active target.
    */
new file mode 100644
--- /dev/null
+++ b/gfx/layers/d3d9/Nv3DVUtils.cpp
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Atul Apte <aapte135@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 "nsIServiceManager.h"
+#include "nsIConsoleService.h"
+#include "nsPrintfCString.h"
+#include <initguid.h>
+#include "Nv3DVUtils.h"
+
+DEFINE_GUID(CLSID_NV3DVStreaming, 
+0xf7747266, 0x777d, 0x4f61, 0xa1, 0x75, 0xdd, 0x5a, 0xdf, 0x1e, 0x37, 0xdf);
+
+DEFINE_GUID(IID_INV3DVStreaming, 
+0xf98f9bb2, 0xb914, 0x4d44, 0x98, 0xfa, 0x6e, 0x37, 0x85, 0x16, 0x98, 0x55);
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * Constructor and Destructor
+ */
+Nv3DVUtils::Nv3DVUtils()
+  : m3DVStreaming (NULL)
+{
+}
+
+Nv3DVUtils::~Nv3DVUtils()
+{
+  UnInitialize();
+}
+
+/**
+ * Initializes the Nv3DVUtils object.
+ */
+void
+Nv3DVUtils::Initialize()
+{
+  nsCOMPtr<nsIConsoleService>
+  consoleCustom(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+
+  /*
+   * Detect if 3D Streaming object is already loaded. Do nothing in that case.
+   */
+  if (m3DVStreaming) {
+    NS_WARNING("Nv3DVStreaming COM object already instantiated.\n");
+    return;
+  }
+
+  /*
+   * Create the COM object. If we fail at any stage, just return
+   */
+  HRESULT hr = CoCreateInstance(CLSID_NV3DVStreaming, NULL, CLSCTX_INPROC_SERVER, IID_INV3DVStreaming, (void**)(getter_AddRefs(m3DVStreaming)));
+  if (FAILED(hr) || !m3DVStreaming) {
+    if (consoleCustom) {
+      nsString msg;
+      msg += NS_LITERAL_STRING("CoCreateInstance() FAILED.\n");
+      consoleCustom->LogStringMessage(msg.get());
+    }
+    return;
+  }
+
+  if (consoleCustom) {
+    nsString msg;
+    msg += NS_LITERAL_STRING("Nv3DVStreaming COM object instantiated successfully.\n");
+    consoleCustom->LogStringMessage(msg.get());
+  }
+
+  /*
+   * Initialize the object. Note that m3DVStreaming cannot be NULL at this point.
+   */
+  bool bRetVal = m3DVStreaming->Nv3DVInitialize();
+
+  if (!bRetVal) {
+    if (consoleCustom) {
+      nsString msg;
+      msg += NS_LITERAL_STRING("Nv3DVInitialize() FAILED!\n");
+      consoleCustom->LogStringMessage(msg.get());
+    }
+    return;
+  }
+
+  /*
+   * Nv3DVUtils::Initialize() was successful
+   */
+  if (consoleCustom) {
+    nsString msg;
+    msg += NS_LITERAL_STRING("Nv3DVUtils::Initialize SUCCEEDED!\n");
+    consoleCustom->LogStringMessage(msg.get());
+  }
+}
+
+/**
+ * Release resources used by the COM Object, and then release 
+ * the COM Object (nsRefPtr gets released by setting to NULL) 
+ *
+ */
+void
+Nv3DVUtils::UnInitialize()
+{
+  if (m3DVStreaming) {
+    m3DVStreaming->Nv3DVRelease();
+  }
+}
+
+/**
+ * Sets the device info, along with any other initialization that is needed after device creation
+ * Pass the D3D9 device pointer is an IUnknown input argument.
+ */
+void 
+Nv3DVUtils::SetDeviceInfo(IUnknown *devUnknown)
+{
+  nsCOMPtr<nsIConsoleService>
+  consoleCustom(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+
+  if (!devUnknown) {
+    NS_WARNING("D3D Device Pointer (IUnknown) is NULL.\n");
+    return;
+  }
+
+  if (m3DVStreaming) {
+    bool rv = false;
+    rv = m3DVStreaming->Nv3DVSetDevice(devUnknown);
+    if (!rv) {
+      if (consoleCustom) {
+        nsString msg;
+        msg += NS_LITERAL_STRING("Nv3DVSetDevice() FAILED!\n");
+        consoleCustom->LogStringMessage(msg.get());
+      }
+      return;
+    }
+
+    rv = m3DVStreaming->Nv3DVControl(STEREO_MODE_RIGHT_LEFT, true, FIREFOX_3DV_APP_HANDLE);
+    if (!rv) {
+      if (consoleCustom) {
+        nsString msg;
+        msg += NS_LITERAL_STRING("Nv3DVControl() FAILED!\n");
+        consoleCustom->LogStringMessage(msg.get());
+      }
+      return;
+    }
+
+    if (consoleCustom) {
+      nsString msg;
+      msg += NS_LITERAL_STRING("Nv3DVSetDevice() and Nv3DVControl() both SUCCEEDED!\n");
+      consoleCustom->LogStringMessage(msg.get());
+    }
+
+  } // m3DVStreaming
+
+  return;
+}
+
+/*
+ * Send Stereo Control Information. Used mainly to re-route 
+ * calls from ImageLayerD3D9 to the 3DV COM object
+ */
+void 
+Nv3DVUtils::SendNv3DVControl(Stereo_Mode eStereoMode, bool bEnableStereo, DWORD dw3DVAppHandle)
+{
+  nsCOMPtr<nsIConsoleService>
+    consoleCustom(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+
+  if (m3DVStreaming) {
+    bool rv = m3DVStreaming->Nv3DVControl(eStereoMode, bEnableStereo, dw3DVAppHandle);
+    if (consoleCustom) {
+      nsString msg;
+      if (rv) {
+        msg += NS_LITERAL_STRING("Nv3DVControl() SUCCEEDED!\n");
+      } else {
+        msg += NS_LITERAL_STRING("Nv3DVControl()FAILED!\n");
+      }
+      consoleCustom->LogStringMessage(msg.get());
+    }
+  } // m3DVStreaming
+
+}
+
+/*
+ * Send Stereo Metadata. Used mainly to re-route calls 
+ * from ImageLayerD3D9 to the 3DV COM object
+ */
+void 
+Nv3DVUtils::SendNv3DVMetaData(unsigned int dwWidth, unsigned int dwHeight, HANDLE hSrcLuma, HANDLE hDst)
+{
+  nsCOMPtr<nsIConsoleService>
+    consoleCustom(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+
+  if (m3DVStreaming) {
+    bool rv = m3DVStreaming->Nv3DVMetaData((DWORD)dwWidth, (DWORD)dwHeight, hSrcLuma, hDst);
+    if (consoleCustom) {
+      nsString msg;
+      if (rv) {
+        msg += NS_LITERAL_STRING("Nv3DVMetaData() SUCCEEDED!\n");
+      } else {
+        msg += NS_LITERAL_STRING("Nv3DVMetaData() FAILED!\n");
+      }
+      consoleCustom->LogStringMessage(msg.get());
+    }
+  } // m3DVStreaming
+}
+
+} /* namespace layers */
+} /* namespace mozilla */
new file mode 100644
--- /dev/null
+++ b/gfx/layers/d3d9/Nv3DVUtils.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Atul Apte <aapte135@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+#ifndef GFX_NV3DVUTILS_H
+#define GFX_NV3DVUTILS_H
+
+#include "Layers.h"
+#include <windows.h>
+#include <d3d9.h>
+
+namespace mozilla {
+namespace layers {
+
+#define FIREFOX_3DV_APP_HANDLE    0xECB992B6
+
+typedef enum _Stereo_Mode {
+  STEREO_MODE_LEFT_RIGHT = 0,
+  STEREO_MODE_RIGHT_LEFT = 1,
+  STEREO_MODE_TOP_BOTTOM = 2,
+  STEREO_MODE_BOTTOM_TOP = 3,
+  STEREO_MODE_LAST       = 4 
+} Stereo_Mode;
+
+class INv3DVStreaming : public IUnknown {
+
+public:
+  virtual bool Nv3DVInitialize()                  = 0;
+  virtual bool Nv3DVRelease()                     = 0;
+  virtual bool Nv3DVSetDevice(IUnknown* pDevice)  = 0;
+  virtual bool Nv3DVControl(Stereo_Mode eStereoMode, bool bEnableStereo, DWORD dw3DVAppHandle) = 0;
+  virtual bool Nv3DVMetaData(DWORD dwWidth, DWORD dwHeight, HANDLE hSrcLuma, HANDLE hDst) = 0;
+};
+
+/*
+ * Nv3DVUtils class
+ */
+class Nv3DVUtils {
+
+public:
+  Nv3DVUtils();
+  ~Nv3DVUtils();
+
+  /*
+   * Initializes the Nv3DVUtils object.
+   */
+  void Initialize();
+
+  /*
+   * Release any resources if needed
+   *
+   */
+  void UnInitialize();
+
+  /*
+   * Sets the device info, along with any other initialization that is needed after device creation
+   * Pass the D3D9 device pointer is an IUnknown input argument
+   */
+  void SetDeviceInfo(IUnknown *devUnknown);
+
+  /*
+   * Send Stereo Control Information. Used mainly to re-route 
+   * calls from ImageLayerD3D9 to the 3DV COM object
+   */
+  void SendNv3DVControl(Stereo_Mode eStereoMode, bool bEnableStereo, DWORD dw3DVAppHandle);
+
+  /*
+   * Send Stereo Metadata. Used mainly to re-route calls 
+   * from ImageLayerD3D9 to the 3DV COM object
+   */
+  void SendNv3DVMetaData(unsigned int dwWidth, unsigned int dwHeight, HANDLE hSrcLuma, HANDLE hDst);
+
+private:
+
+  /* Nv3DVStreaming interface pointer */
+  nsRefPtr<INv3DVStreaming> m3DVStreaming;
+
+};
+
+
+} /* layers */
+} /* mozilla */
+
+#endif /* GFX_NV3DVUTILS_H */
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -193,16 +193,21 @@ BuildKeyNameFromFontName(nsAString &aNam
 
 gfxWindowsPlatform::gfxWindowsPlatform()
 {
     mPrefFonts.Init(50);
 
     mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
     mUseClearTypeAlways = UNINITIALIZED_VALUE;
 
+    /* 
+     * Initialize COM 
+     */ 
+    CoInitialize(NULL); 
+
     mScreenDC = GetDC(NULL);
 
 #ifdef MOZ_FT2_FONTS
     FT_Init_FreeType(&gPlatformFTLibrary);
 #endif
 
 /* Pick the default render mode differently between
  * desktop, Windows Mobile, and Windows CE.
@@ -351,16 +356,22 @@ gfxWindowsPlatform::~gfxWindowsPlatform(
     ::ReleaseDC(NULL, mScreenDC);
     // not calling FT_Done_FreeType because cairo may still hold references to
     // these FT_Faces.  See bug 458169.
 #ifdef CAIRO_HAS_D2D_SURFACE
     if (mD2DDevice) {
 	cairo_release_device(mD2DDevice);
     }
 #endif
+
+    /* 
+     * Uninitialize COM 
+     */ 
+    CoUninitialize(); 
+
 }
 
 gfxPlatformFontList*
 gfxWindowsPlatform::CreatePlatformFontList()
 {
 #ifdef MOZ_FT2_FONTS
     return new gfxFT2FontList();
 #else
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -173,16 +173,18 @@ pref("media.webm.enabled", true);
 pref("media.autoplay.enabled", true);
 
 // 0 = Off, 1 = Full, 2 = Tagged Images Only. 
 // See eCMSMode in gfx/thebes/gfxPlatform.h
 pref("gfx.color_management.mode", 2);
 pref("gfx.color_management.display_profile", "");
 pref("gfx.color_management.rendering_intent", 0);
 
+pref("gfx.3d_video.enabled", false);
+
 pref("gfx.downloadable_fonts.enabled", true);
 
 #ifdef XP_MACOSX
 pref("gfx.font_rendering.harfbuzz.level", 1);
 #else
 pref("gfx.font_rendering.harfbuzz.level", 0);
 #endif