gfx/layers/d3d9/DeviceManagerD3D9.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "DeviceManagerD3D9.h"
     7 #include "LayerManagerD3D9Shaders.h"
     8 #include "ThebesLayerD3D9.h"
     9 #include "nsIServiceManager.h"
    10 #include "nsIConsoleService.h"
    11 #include "nsPrintfCString.h"
    12 #include "Nv3DVUtils.h"
    13 #include "plstr.h"
    14 #include <algorithm>
    15 #include "gfx2DGlue.h"
    16 #include "gfxPlatform.h"
    17 #include "gfxWindowsPlatform.h"
    18 #include "TextureD3D9.h"
    19 #include "mozilla/gfx/Point.h"
    21 using namespace mozilla::gfx;
    23 namespace mozilla {
    24 namespace layers {
    26 const LPCWSTR kClassName       = L"D3D9WindowClass";
    28 #define USE_D3D9EX
    30 struct vertex {
    31   float x, y;
    32 };
    34 SwapChainD3D9::SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager)
    35   : mDeviceManager(aDeviceManager)
    36   , mWnd(0)
    37 {
    38   mDeviceManager->mSwapChains.AppendElement(this);
    39 }
    41 SwapChainD3D9::~SwapChainD3D9()
    42 {
    43   mDeviceManager->mSwapChains.RemoveElement(this);
    44 }
    46 bool
    47 SwapChainD3D9::Init(HWND hWnd)
    48 {
    49   RECT r;
    50   ::GetClientRect(hWnd, &r);
    52   mWnd = hWnd;
    54   D3DPRESENT_PARAMETERS pp;
    55   memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
    57   pp.BackBufferFormat = D3DFMT_A8R8G8B8;
    58   pp.SwapEffect = D3DSWAPEFFECT_COPY;
    59   pp.Windowed = TRUE;
    60   pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    61   pp.hDeviceWindow = mWnd;
    62   if (r.left == r.right || r.top == r.bottom) {
    63     pp.BackBufferHeight = 1;
    64     pp.BackBufferWidth = 1;
    65   }
    67   HRESULT hr = mDeviceManager->device()->
    68     CreateAdditionalSwapChain(&pp,
    69                               getter_AddRefs(mSwapChain));
    71   if (FAILED(hr)) {
    72     NS_WARNING("Failed to create swap chain for window.");
    73     return false;
    74   }
    76   return true;
    77 }
    79 already_AddRefed<IDirect3DSurface9>
    80 SwapChainD3D9::GetBackBuffer()
    81 {
    82   nsRefPtr<IDirect3DSurface9> backBuffer;
    83     mSwapChain->GetBackBuffer(0,
    84                               D3DBACKBUFFER_TYPE_MONO,
    85                               getter_AddRefs(backBuffer));
    86   return backBuffer.forget();
    87 }
    89 DeviceManagerState
    90 SwapChainD3D9::PrepareForRendering()
    91 {
    92   RECT r;
    93   if (!::GetClientRect(mWnd, &r)) {
    94     return DeviceFail;
    95   }
    97   DeviceManagerState deviceState = mDeviceManager->VerifyReadyForRendering();
    98   if (deviceState != DeviceOK) {
    99     return deviceState;
   100   }
   102   if (!mSwapChain) {
   103     Init(mWnd);
   104   }
   106   if (mSwapChain) {
   107     nsRefPtr<IDirect3DSurface9> backBuffer = GetBackBuffer();
   109     D3DSURFACE_DESC desc;
   110     backBuffer->GetDesc(&desc);
   112     if (desc.Width == r.right - r.left && desc.Height == r.bottom - r.top) {
   113       mDeviceManager->device()->SetRenderTarget(0, backBuffer);
   114       return DeviceOK;
   115     }
   117     mSwapChain = nullptr;
   119     Init(mWnd);
   121     if (!mSwapChain) {
   122       return DeviceFail;
   123     }
   125     backBuffer = GetBackBuffer();
   126     mDeviceManager->device()->SetRenderTarget(0, backBuffer);
   128     return DeviceOK;
   129   }
   131   return DeviceFail;
   132 }
   134 void
   135 SwapChainD3D9::Present(const nsIntRect &aRect)
   136 {
   137   RECT r;
   138   r.left = aRect.x;
   139   r.top = aRect.y;
   140   r.right = aRect.XMost();
   141   r.bottom = aRect.YMost();
   143   mSwapChain->Present(&r, &r, 0, 0, 0);
   144 }
   146 void
   147 SwapChainD3D9::Present()
   148 {
   149   mSwapChain->Present(nullptr, nullptr, 0, 0, 0);
   150 }
   152 void
   153 SwapChainD3D9::Reset()
   154 {
   155   mSwapChain = nullptr;
   156 }
   158 #define HAS_CAP(a, b) (((a) & (b)) == (b))
   159 #define LACKS_CAP(a, b) !(((a) & (b)) == (b))
   161 uint32_t DeviceManagerD3D9::sMaskQuadRegister = 11;
   163 DeviceManagerD3D9::DeviceManagerD3D9()
   164   : mTextureHostList(nullptr)
   165   , mDeviceResetCount(0)
   166   , mMaxTextureSize(0)
   167   , mTextureAddressingMode(D3DTADDRESS_CLAMP)
   168   , mHasDynamicTextures(false)
   169   , mDeviceWasRemoved(false)
   170 {
   171 }
   173 DeviceManagerD3D9::~DeviceManagerD3D9()
   174 {
   175   DestroyDevice();
   176 }
   178 bool
   179 DeviceManagerD3D9::Init()
   180 {
   181   WNDCLASSW wc;
   182   HRESULT hr;
   184   if (!GetClassInfoW(GetModuleHandle(nullptr), kClassName, &wc)) {
   185       ZeroMemory(&wc, sizeof(WNDCLASSW));
   186       wc.hInstance = GetModuleHandle(nullptr);
   187       wc.lpfnWndProc = ::DefWindowProc;
   188       wc.lpszClassName = kClassName;
   189       if (!RegisterClassW(&wc)) {
   190           NS_WARNING("Failed to register window class for DeviceManager.");
   191           return false;
   192       }
   193   }
   195   mFocusWnd = ::CreateWindowW(kClassName, L"D3D9Window", WS_OVERLAPPEDWINDOW,
   196                               CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr,
   197                               nullptr, GetModuleHandle(nullptr), nullptr);
   199   if (!mFocusWnd) {
   200     NS_WARNING("Failed to create DeviceManagerD3D9 Window.");
   201     return false;
   202   }
   204   /* Create an Nv3DVUtils instance */ 
   205   if (!mNv3DVUtils) { 
   206     mNv3DVUtils = new Nv3DVUtils(); 
   207     if (!mNv3DVUtils) { 
   208       NS_WARNING("Could not create a new instance of Nv3DVUtils.\n"); 
   209     } 
   210   } 
   212   /* Initialize the Nv3DVUtils object */ 
   213   if (mNv3DVUtils) { 
   214     mNv3DVUtils->Initialize(); 
   215   } 
   217   HMODULE d3d9 = LoadLibraryW(L"d3d9.dll");
   218   decltype(Direct3DCreate9)* d3d9Create = (decltype(Direct3DCreate9)*)
   219     GetProcAddress(d3d9, "Direct3DCreate9");
   220   decltype(Direct3DCreate9Ex)* d3d9CreateEx = (decltype(Direct3DCreate9Ex)*)
   221     GetProcAddress(d3d9, "Direct3DCreate9Ex");
   223 #ifdef USE_D3D9EX
   224   if (d3d9CreateEx) {
   225     hr = d3d9CreateEx(D3D_SDK_VERSION, getter_AddRefs(mD3D9Ex));
   226     if (SUCCEEDED(hr)) {
   227       mD3D9 = mD3D9Ex;
   228     }
   229   }
   230 #endif
   232   if (!mD3D9) {
   233     if (!d3d9Create) {
   234       return false;
   235     }
   237     mD3D9 = dont_AddRef(d3d9Create(D3D_SDK_VERSION));
   239     if (!mD3D9) {
   240       return false;
   241     }
   242   }
   244   D3DADAPTER_IDENTIFIER9 ident;
   245   hr = mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &ident);
   247   if (FAILED(hr)) {
   248     return false;
   249   }
   251   D3DPRESENT_PARAMETERS pp;
   252   memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
   254   pp.BackBufferWidth = 1;
   255   pp.BackBufferHeight = 1;
   256   pp.BackBufferFormat = D3DFMT_A8R8G8B8;
   257   pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
   258   pp.Windowed = TRUE;
   259   pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
   260   pp.hDeviceWindow = mFocusWnd;
   262   if (mD3D9Ex) {
   263     hr = mD3D9Ex->CreateDeviceEx(D3DADAPTER_DEFAULT,
   264                                  D3DDEVTYPE_HAL,
   265                                  mFocusWnd,
   266                                  D3DCREATE_FPU_PRESERVE |
   267                                  D3DCREATE_MULTITHREADED |
   268                                  D3DCREATE_MIXED_VERTEXPROCESSING,
   269                                  &pp,
   270                                  nullptr,
   271                                  getter_AddRefs(mDeviceEx));
   272     if (SUCCEEDED(hr)) {
   273       mDevice = mDeviceEx;
   274     }
   276     D3DCAPS9 caps;
   277     if (mDeviceEx && mDeviceEx->GetDeviceCaps(&caps)) {
   278       if (LACKS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
   279         // XXX - Should we actually hit this we'll need a CanvasLayer that
   280         // supports static D3DPOOL_DEFAULT textures.
   281         NS_WARNING("D3D9Ex device not used because of lack of support for \
   282                    dynamic textures. This is unexpected.");
   283         mDevice = nullptr;
   284         mDeviceEx = nullptr;
   285       }
   286     }
   287   }
   289   if (!mDevice) {
   290     hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
   291                              D3DDEVTYPE_HAL,
   292                              mFocusWnd,
   293                              D3DCREATE_FPU_PRESERVE |
   294                              D3DCREATE_MULTITHREADED |
   295                              D3DCREATE_MIXED_VERTEXPROCESSING,
   296                              &pp,
   297                              getter_AddRefs(mDevice));
   299     if (FAILED(hr)) {
   300       NS_WARNING("Failed to create Device for DeviceManagerD3D9.");
   301       return false;
   302     }
   303   }
   305   if (!VerifyCaps()) {
   306     return false;
   307   }
   309   /* Grab the associated HMONITOR so that we can find out
   310    * if it changed later */
   311   D3DDEVICE_CREATION_PARAMETERS parameters;
   312   if (FAILED(mDevice->GetCreationParameters(&parameters)))
   313     return false;
   314   mDeviceMonitor = mD3D9->GetAdapterMonitor(parameters.AdapterOrdinal);
   317   /* 
   318    * Do some post device creation setup 
   319    */ 
   320   if (mNv3DVUtils) { 
   321     IUnknown* devUnknown = nullptr; 
   322     if (mDevice) { 
   323       mDevice->QueryInterface(IID_IUnknown, (void **)&devUnknown); 
   324     } 
   325     mNv3DVUtils->SetDeviceInfo(devUnknown); 
   326   } 
   328   hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
   329                                    getter_AddRefs(mLayerVS));
   331   if (FAILED(hr)) {
   332     return false;
   333   }
   335   hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
   336                                   getter_AddRefs(mRGBPS));
   338   if (FAILED(hr)) {
   339     return false;
   340   }
   342   hr = mDevice->CreatePixelShader((DWORD*)RGBAShaderPS,
   343                                   getter_AddRefs(mRGBAPS));
   345   if (FAILED(hr)) {
   346     return false;
   347   }
   349   hr = mDevice->CreatePixelShader((DWORD*)ComponentPass1ShaderPS,
   350                                   getter_AddRefs(mComponentPass1PS));
   352   if (FAILED(hr)) {
   353     return false;
   354   }
   356   hr = mDevice->CreatePixelShader((DWORD*)ComponentPass2ShaderPS,
   357                                   getter_AddRefs(mComponentPass2PS));
   359   if (FAILED(hr)) {
   360     return false;
   361   }
   363   hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPS,
   364                                   getter_AddRefs(mYCbCrPS));
   366   if (FAILED(hr)) {
   367     return false;
   368   }
   370   hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPS,
   371                                   getter_AddRefs(mSolidColorPS));
   373   if (FAILED(hr)) {
   374     return false;
   375   }
   377   hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVSMask,
   378                                    getter_AddRefs(mLayerVSMask));
   380   if (FAILED(hr)) {
   381     return false;
   382   }
   383   hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVSMask3D,
   384                                    getter_AddRefs(mLayerVSMask3D));
   386   if (FAILED(hr)) {
   387     return false;
   388   }
   390   hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPSMask,
   391                                   getter_AddRefs(mRGBPSMask));
   393   if (FAILED(hr)) {
   394     return false;
   395   }
   397   hr = mDevice->CreatePixelShader((DWORD*)RGBAShaderPSMask,
   398                                   getter_AddRefs(mRGBAPSMask));
   400   if (FAILED(hr)) {
   401     return false;
   402   }
   404   hr = mDevice->CreatePixelShader((DWORD*)RGBAShaderPSMask3D,
   405                                   getter_AddRefs(mRGBAPSMask3D));
   407   if (FAILED(hr)) {
   408     return false;
   409   }
   411   hr = mDevice->CreatePixelShader((DWORD*)ComponentPass1ShaderPSMask,
   412                                   getter_AddRefs(mComponentPass1PSMask));
   414   if (FAILED(hr)) {
   415     return false;
   416   }
   418   hr = mDevice->CreatePixelShader((DWORD*)ComponentPass2ShaderPSMask,
   419                                   getter_AddRefs(mComponentPass2PSMask));
   421   if (FAILED(hr)) {
   422     return false;
   423   }
   425   hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPSMask,
   426                                   getter_AddRefs(mYCbCrPSMask));
   428   if (FAILED(hr)) {
   429     return false;
   430   }
   432   hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPSMask,
   433                                   getter_AddRefs(mSolidColorPSMask));
   435   if (FAILED(hr)) {
   436     return false;
   437   }
   439   if (!CreateVertexBuffer()) {
   440     return false;
   441   }
   443   hr = mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
   444   if (FAILED(hr)) {
   445     return false;
   446   }
   448   D3DVERTEXELEMENT9 elements[] = {
   449     { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
   450       D3DDECLUSAGE_POSITION, 0 },
   451     D3DDECL_END()
   452   };
   454   mDevice->CreateVertexDeclaration(elements, getter_AddRefs(mVD));
   456   nsCOMPtr<nsIConsoleService>
   457     console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
   459   D3DADAPTER_IDENTIFIER9 identifier;
   460   mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
   462   if (console) {
   463     nsString msg;
   464     msg +=
   465       NS_LITERAL_STRING("Direct3D 9 DeviceManager Initialized Successfully.\nDriver: ");
   466     msg += NS_ConvertUTF8toUTF16(
   467       nsDependentCString((const char*)identifier.Driver));
   468     msg += NS_LITERAL_STRING("\nDescription: ");
   469     msg += NS_ConvertUTF8toUTF16(
   470       nsDependentCString((const char*)identifier.Description));
   471     msg += NS_LITERAL_STRING("\nVersion: ");
   472     msg += NS_ConvertUTF8toUTF16(
   473       nsPrintfCString("%d.%d.%d.%d",
   474                       HIWORD(identifier.DriverVersion.HighPart),
   475                       LOWORD(identifier.DriverVersion.HighPart),
   476                       HIWORD(identifier.DriverVersion.LowPart),
   477                       LOWORD(identifier.DriverVersion.LowPart)));
   478     console->LogStringMessage(msg.get());
   479   }
   481   return true;
   482 }
   484 void
   485 DeviceManagerD3D9::SetupRenderState()
   486 {
   487   mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
   488   mDevice->SetVertexDeclaration(mVD);
   489   mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
   490   mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
   491   mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
   492   mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
   493   mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
   494   mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
   495   mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
   496   mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
   497   mDevice->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
   498   mDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   499   mDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   500   mDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   501   mDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   502   mDevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   503   mDevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   504   mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mTextureAddressingMode);
   505   mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mTextureAddressingMode);
   506   mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, mTextureAddressingMode);
   507   mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, mTextureAddressingMode);
   508   mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, mTextureAddressingMode);
   509   mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, mTextureAddressingMode);
   510 }
   512 already_AddRefed<SwapChainD3D9>
   513 DeviceManagerD3D9::CreateSwapChain(HWND hWnd)
   514 {
   515   nsRefPtr<SwapChainD3D9> swapChain = new SwapChainD3D9(this);
   517   // See bug 604647. This line means that if we create a window while the
   518   // device is lost LayerManager initialization will fail, this window
   519   // will be permanently unaccelerated. This should be a rare situation
   520   // though and the need for a low-risk fix for this bug outweighs the
   521   // downside.
   522   if (VerifyReadyForRendering() != DeviceOK) {
   523     return nullptr;
   524   }
   526   if (!swapChain->Init(hWnd)) {
   527     return nullptr;
   528   }
   530   return swapChain.forget();
   531 }
   533 /*
   534   * Finds a texture for the mask layer and sets it as an
   535   * input to the shaders.
   536   * Returns true if a texture is loaded, false if 
   537   * a texture for the mask layer could not be loaded.
   538   */
   539 bool
   540 LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
   541                 uint32_t aMaskTexRegister)
   542 {
   543   IntSize size;
   544   nsRefPtr<IDirect3DTexture9> texture =
   545     static_cast<LayerD3D9*>(aMask->ImplData())->GetAsTexture(&size);
   547   if (!texture) {
   548     return false;
   549   }
   551   Matrix maskTransform;
   552   Matrix4x4 effectiveTransform = aMask->GetEffectiveTransform();
   553   bool maskIs2D = effectiveTransform.CanDraw2D(&maskTransform);
   554   NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
   555   Rect bounds = Rect(Point(), Size(size));
   556   bounds = maskTransform.TransformBounds(bounds);
   558   aDevice->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
   559                                     ShaderConstantRect((float)bounds.x,
   560                                                        (float)bounds.y,
   561                                                        (float)bounds.width,
   562                                                        (float)bounds.height),
   563                                     1);
   565   aDevice->SetTexture(aMaskTexRegister, texture);
   566   return true;
   567 }
   569 uint32_t
   570 DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, MaskType aMaskType)
   571 {
   572   if (aMaskType == MaskNone) {
   573     switch (aMode) {
   574       case RGBLAYER:
   575         mDevice->SetVertexShader(mLayerVS);
   576         mDevice->SetPixelShader(mRGBPS);
   577         break;
   578       case RGBALAYER:
   579         mDevice->SetVertexShader(mLayerVS);
   580         mDevice->SetPixelShader(mRGBAPS);
   581         break;
   582       case COMPONENTLAYERPASS1:
   583         mDevice->SetVertexShader(mLayerVS);
   584         mDevice->SetPixelShader(mComponentPass1PS);
   585         break;
   586       case COMPONENTLAYERPASS2:
   587         mDevice->SetVertexShader(mLayerVS);
   588         mDevice->SetPixelShader(mComponentPass2PS);
   589         break;
   590       case YCBCRLAYER:
   591         mDevice->SetVertexShader(mLayerVS);
   592         mDevice->SetPixelShader(mYCbCrPS);
   593         break;
   594       case SOLIDCOLORLAYER:
   595         mDevice->SetVertexShader(mLayerVS);
   596         mDevice->SetPixelShader(mSolidColorPS);
   597         break;
   598     }
   599     return 0;
   600   }
   602   uint32_t maskTexRegister;
   603   switch (aMode) {
   604     case RGBLAYER:
   605       mDevice->SetVertexShader(mLayerVSMask);
   606       mDevice->SetPixelShader(mRGBPSMask);
   607       maskTexRegister = 1;
   608       break;
   609     case RGBALAYER:
   610       if (aMaskType == Mask2d) {
   611         mDevice->SetVertexShader(mLayerVSMask);
   612         mDevice->SetPixelShader(mRGBAPSMask);
   613       } else {
   614         mDevice->SetVertexShader(mLayerVSMask3D);
   615         mDevice->SetPixelShader(mRGBAPSMask3D);
   616       }
   617       maskTexRegister = 1;
   618       break;
   619     case COMPONENTLAYERPASS1:
   620       mDevice->SetVertexShader(mLayerVSMask);
   621       mDevice->SetPixelShader(mComponentPass1PSMask);
   622       maskTexRegister = 2;
   623       break;
   624     case COMPONENTLAYERPASS2:
   625       mDevice->SetVertexShader(mLayerVSMask);
   626       mDevice->SetPixelShader(mComponentPass2PSMask);
   627       maskTexRegister = 2;
   628       break;
   629     case YCBCRLAYER:
   630       mDevice->SetVertexShader(mLayerVSMask);
   631       mDevice->SetPixelShader(mYCbCrPSMask);
   632       maskTexRegister = 3;
   633       break;
   634     case SOLIDCOLORLAYER:
   635       mDevice->SetVertexShader(mLayerVSMask);
   636       mDevice->SetPixelShader(mSolidColorPSMask);
   637       maskTexRegister = 0;
   638       break;
   639   }
   640   return maskTexRegister;
   641 }
   643 void
   644 DeviceManagerD3D9::SetShaderMode(ShaderMode aMode, Layer* aMask, bool aIs2D)
   645 {
   646   MaskType maskType = MaskNone;
   647   if (aMask) {
   648     maskType = aIs2D ? Mask2d : Mask3d;
   649   }
   650   uint32_t maskTexRegister = SetShaderMode(aMode, maskType);
   651   if (aMask) {
   652     // register allocations are taken from LayerManagerD3D9Shaders.h after
   653     // the shaders are compiled (genshaders.sh)
   654     if (!LoadMaskTexture(aMask, mDevice, maskTexRegister)) {
   655       // if we can't load the mask, fall back to unmasked rendering
   656       NS_WARNING("Could not load texture for mask layer.");
   657       SetShaderMode(aMode, MaskNone);
   658     }
   659   }
   660 }
   662 void
   663 DeviceManagerD3D9::DestroyDevice()
   664 {
   665   ++mDeviceResetCount;
   666   mDeviceWasRemoved = true;
   667   if (!IsD3D9Ex()) {
   668     ReleaseTextureResources();
   669   }
   670   gfxWindowsPlatform::GetPlatform()->OnDeviceManagerDestroy(this);
   671 }
   673 DeviceManagerState
   674 DeviceManagerD3D9::VerifyReadyForRendering()
   675 {
   676   if (mDeviceWasRemoved) {
   677     return DeviceMustRecreate;
   678   }
   680   HRESULT hr = mDevice->TestCooperativeLevel();
   682   if (SUCCEEDED(hr)) {
   683     if (IsD3D9Ex()) {
   684       hr = mDeviceEx->CheckDeviceState(mFocusWnd);
   686       if (FAILED(hr)) {
   687         DestroyDevice();
   688         return DeviceMustRecreate;
   689       }
   690     }
   691     return DeviceOK;
   692   }
   694   // We need to release all texture resources and swap chains before resetting.
   695   for (unsigned int i = 0; i < mLayersWithResources.Length(); i++) {
   696     mLayersWithResources[i]->CleanResources();
   697   }
   698   ReleaseTextureResources();
   699   for (unsigned int i = 0; i < mSwapChains.Length(); i++) {
   700     mSwapChains[i]->Reset();
   701   }
   703   mVB = nullptr;
   705   D3DPRESENT_PARAMETERS pp;
   706   memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
   708   pp.BackBufferWidth = 1;
   709   pp.BackBufferHeight = 1;
   710   pp.BackBufferFormat = D3DFMT_A8R8G8B8;
   711   pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
   712   pp.Windowed = TRUE;
   713   pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
   714   pp.hDeviceWindow = mFocusWnd;
   716   // Whatever happens from now on, either we reset the device, or we should
   717   // pretend we reset the device so that the layer manager or compositor
   718   // doesn't ignore it.
   719   ++mDeviceResetCount;
   721   // if we got this far, we know !SUCCEEDEED(hr), that means hr is one of
   722   // D3DERR_DEVICELOST, D3DERR_DEVICENOTRESET, D3DERR_DRIVERINTERNALERROR.
   723   // It is only worth resetting if we get D3DERR_DEVICENOTRESET. If we get
   724   // D3DERR_DEVICELOST we can wait and see if we get D3DERR_DEVICENOTRESET
   725   // later, then reset.
   726   if (hr == D3DERR_DEVICELOST) {
   727     HMONITOR hMonitorWindow;
   728     hMonitorWindow = MonitorFromWindow(mFocusWnd, MONITOR_DEFAULTTOPRIMARY);
   729     if (hMonitorWindow != mDeviceMonitor) {
   730       /* jrmuizel: I'm not sure how to trigger this case. Usually, we get
   731        * DEVICENOTRESET right away and Reset() succeeds without going through a
   732        * set of DEVICELOSTs. This is presumeably because we don't call
   733        * VerifyReadyForRendering when we don't have any reason to paint.
   734        * Hopefully comparing HMONITORs is not overly aggressive.
   735        * See bug 626678.
   736        */
   737       /* The monitor has changed. We have to assume that the
   738        * DEVICENOTRESET will not be coming. */
   739       DestroyDevice();
   740       return DeviceMustRecreate;
   741     }
   742     return DeviceFail;
   743   }
   744   if (hr == D3DERR_DEVICENOTRESET) {
   745     hr = mDevice->Reset(&pp);
   746   }
   748   if (FAILED(hr) || !CreateVertexBuffer()) {
   749     DestroyDevice();
   750     return DeviceMustRecreate;
   751   }
   753   return DeviceOK;
   754 }
   756 bool
   757 DeviceManagerD3D9::VerifyCaps()
   758 {
   759   D3DCAPS9 caps;
   760   HRESULT hr = mDevice->GetDeviceCaps(&caps);
   762   if (FAILED(hr)) {
   763     return false;
   764   }
   766   if (LACKS_CAP(caps.DevCaps, D3DDEVCAPS_TEXTUREVIDEOMEMORY)) {
   767     return false;
   768   }
   770   if (LACKS_CAP(caps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE)) {
   771     return false;
   772   }
   774   if (LACKS_CAP(caps.SrcBlendCaps, D3DPBLENDCAPS_ONE) ||
   775       LACKS_CAP(caps.SrcBlendCaps, D3DBLEND_SRCALPHA) ||
   776       LACKS_CAP(caps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA)) {
   777     return false;
   778   }
   780   if (LACKS_CAP(caps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST)) {
   781     return false;
   782   }
   784   if (LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_ALPHA) ||
   785       HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_SQUAREONLY) ||
   786       (HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_POW2) &&
   787        LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL))) {
   788     return false;
   789   }
   791   if (LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR) ||
   792       LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR)) {
   793     return false;
   794   }
   796   if (LACKS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP)) {
   797     return false;
   798   }
   800   if (caps.MaxTextureHeight < 4096 ||
   801       caps.MaxTextureWidth < 4096) {
   802     return false;
   803   }
   804   mMaxTextureSize = std::min(caps.MaxTextureHeight, caps.MaxTextureWidth);
   806   if ((caps.PixelShaderVersion & 0xffff) < 0x200 ||
   807       (caps.VertexShaderVersion & 0xffff) < 0x200) {
   808     return false;
   809   }
   811   if (HAS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
   812     mHasDynamicTextures = true;
   813   }
   815   if (HAS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP) &&
   816       LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) {
   817     mTextureAddressingMode = D3DTADDRESS_WRAP;
   818   } else {
   819     gfxPlatform::DisableBufferRotation();
   820   }
   822   return true;
   823 }
   825 bool
   826 DeviceManagerD3D9::CreateVertexBuffer()
   827 {
   828   HRESULT hr;
   830   hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
   831                                    D3DUSAGE_WRITEONLY,
   832                                    0,
   833                                    D3DPOOL_DEFAULT,
   834                                    getter_AddRefs(mVB),
   835                                    nullptr);
   837   if (FAILED(hr)) {
   838     return false;
   839   }
   841   vertex *vertices;
   842   hr = mVB->Lock(0, 0, (void**)&vertices, 0);
   843   if (FAILED(hr)) {
   844     return false;
   845   }
   847   vertices[0].x = vertices[0].y = 0;
   848   vertices[1].x = 1; vertices[1].y = 0;
   849   vertices[2].x = 0; vertices[2].y = 1;
   850   vertices[3].x = 1; vertices[3].y = 1;
   852   mVB->Unlock();
   854   return true;
   855 }
   857 TemporaryRef<IDirect3DTexture9>
   858 DeviceManagerD3D9::CreateTexture(const IntSize &aSize,
   859                                  _D3DFORMAT aFormat,
   860                                  D3DPOOL aPool,
   861                                  TextureSourceD3D9* aTextureHost)
   862 {
   863   if (mDeviceWasRemoved) {
   864     return nullptr;
   865   }
   866   RefPtr<IDirect3DTexture9> result;
   867   if (FAILED(device()->CreateTexture(aSize.width, aSize.height,
   868                                      1, 0, aFormat, aPool,
   869                                      byRef(result), nullptr))) {
   870     return nullptr;
   871   }
   873   NS_ASSERTION(aPool != D3DPOOL_MANAGED,
   874                "Should not be using MANAGED texture pool. We will get an error when we have to recreate the device");
   875   if (aPool == D3DPOOL_DEFAULT) {
   876     MOZ_ASSERT(aTextureHost, "We need a texture host to track so we can release the texture.");
   877     RegisterTextureHost(aTextureHost);
   878   }
   880   return result;
   881 }
   883 #ifdef DEBUG
   884 bool
   885 DeviceManagerD3D9::IsInTextureHostList(TextureSourceD3D9* aFind)
   886 {
   887   TextureSourceD3D9* cur = mTextureHostList;
   888   while(cur) {
   889     if (cur == aFind) {
   890       return true;
   891     }
   892     cur = cur->mNextHost;
   893   }
   895   return false;
   896 }
   897 #endif
   899 void
   900 DeviceManagerD3D9::RegisterTextureHost(TextureSourceD3D9* aHost)
   901 {
   902   if (!aHost) {
   903     return;
   904   }
   906   // Don't add aHost to the list twice.
   907   if (aHost->mPreviousHost ||
   908       mTextureHostList == aHost) {
   909     MOZ_ASSERT(IsInTextureHostList(aHost));
   910     return;
   911   }
   913   MOZ_ASSERT(!aHost->mNextHost);
   914   MOZ_ASSERT(!IsInTextureHostList(aHost));
   916   if (mTextureHostList) {
   917     MOZ_ASSERT(!mTextureHostList->mPreviousHost);
   918     mTextureHostList->mPreviousHost = aHost;
   919     aHost->mNextHost = mTextureHostList;
   920   }
   921   mTextureHostList = aHost;
   922   MOZ_ASSERT(!aHost->mCreatingDeviceManager, "Already created texture?");
   923   MOZ_ASSERT(IsInTextureHostList(aHost));
   924   aHost->mCreatingDeviceManager = this;
   925 }
   927 void
   928 DeviceManagerD3D9::ReleaseTextureResources()
   929 {
   930   TextureSourceD3D9* host = mTextureHostList;
   931   while (host) {
   932     host->ReleaseTextureResources();
   933     TextureSourceD3D9* oldHost = host;
   934     host = oldHost->mNextHost;
   935     oldHost->mPreviousHost = nullptr;
   936     oldHost->mNextHost = nullptr;
   937     oldHost->mCreatingDeviceManager = nullptr;
   938   }
   939   mTextureHostList = nullptr;
   940 }
   942 void
   943 DeviceManagerD3D9::RemoveTextureListHead(TextureSourceD3D9* aHost)
   944 {
   945   MOZ_ASSERT(!aHost->mCreatingDeviceManager || aHost->mCreatingDeviceManager == this,
   946              "Wrong device manager");
   947   MOZ_ASSERT(aHost && mTextureHostList == aHost,
   948              "aHost is not the head of the texture host list");
   949   mTextureHostList = aHost->mNextHost;
   950 }
   952 } /* namespace layers */
   953 } /* namespace mozilla */

mercurial