gfx/layers/d3d10/LayerManagerD3D10.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     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 <algorithm>
     8 #include "LayerManagerD3D10.h"
     9 #include "LayerManagerD3D10Effect.h"
    10 #include "gfxWindowsPlatform.h"
    11 #include "gfx2DGlue.h"
    12 #include "gfxD2DSurface.h"
    13 #include "gfxFailure.h"
    14 #include "cairo-win32.h"
    15 #include "dxgi.h"
    17 #include "ContainerLayerD3D10.h"
    18 #include "ThebesLayerD3D10.h"
    19 #include "ColorLayerD3D10.h"
    20 #include "CanvasLayerD3D10.h"
    21 #include "ReadbackLayerD3D10.h"
    22 #include "ImageLayerD3D10.h"
    23 #include "mozilla/layers/PLayerChild.h"
    24 #include "mozilla/WidgetUtils.h"
    26 #include "../d3d9/Nv3DVUtils.h"
    28 #include "gfxCrashReporterUtils.h"
    29 #include "nsWindowsHelpers.h"
    30 #ifdef MOZ_METRO
    31 #include "DXGI1_2.h"
    32 #endif
    34 using namespace std;
    35 using namespace mozilla::dom;
    36 using namespace mozilla::gfx;
    38 namespace mozilla {
    39 namespace layers {
    41 struct Vertex
    42 {
    43     float position[2];
    44 };
    46 // {592BF306-0EED-4F76-9D03-A0846450F472}
    47 static const GUID sDeviceAttachments = 
    48 { 0x592bf306, 0xeed, 0x4f76, { 0x9d, 0x3, 0xa0, 0x84, 0x64, 0x50, 0xf4, 0x72 } };
    49 // {716AEDB1-C9C3-4B4D-8332-6F65D44AF6A8}
    50 static const GUID sLayerManagerCount = 
    51 { 0x716aedb1, 0xc9c3, 0x4b4d, { 0x83, 0x32, 0x6f, 0x65, 0xd4, 0x4a, 0xf6, 0xa8 } };
    53 LayerManagerD3D10::LayerManagerD3D10(nsIWidget *aWidget)
    54   : mWidget(aWidget)
    55   , mDisableSequenceForNextFrame(false)
    56 {
    57 }
    59 struct DeviceAttachments
    60 {
    61   nsRefPtr<ID3D10Effect> mEffect;
    62   nsRefPtr<ID3D10InputLayout> mInputLayout;
    63   nsRefPtr<ID3D10Buffer> mVertexBuffer;
    64   nsRefPtr<ReadbackManagerD3D10> mReadbackManager;
    65 };
    67 LayerManagerD3D10::~LayerManagerD3D10()
    68 {
    69   if (mDevice) {
    70     int referenceCount = 0;
    71     UINT size = sizeof(referenceCount);
    72     HRESULT hr = mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
    73     NS_ASSERTION(SUCCEEDED(hr), "Reference count not found on device.");
    74     referenceCount--;
    75     mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
    77     if (!referenceCount) {
    78       DeviceAttachments *attachments;
    79       size = sizeof(attachments);
    80       mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments);
    81       // No LayerManagers left for this device. Clear out interfaces stored which
    82       // hold a reference to the device.
    83       mDevice->SetPrivateData(sDeviceAttachments, 0, nullptr);
    85       delete attachments;
    86     }
    87   }
    89   Destroy();
    90 }
    92 static inline void
    93 SetHRESULT(HRESULT* aHresultPtr, HRESULT aHresult)
    94 {
    95   if (aHresultPtr) {
    96     *aHresultPtr = aHresult;
    97   }
    98 }
   100 bool
   101 LayerManagerD3D10::Initialize(bool force, HRESULT* aHresultPtr)
   102 {
   103   ScopedGfxFeatureReporter reporter("D3D10 Layers", force);
   105   HRESULT hr = E_UNEXPECTED;
   107   /* Create an Nv3DVUtils instance */
   108   if (!mNv3DVUtils) {
   109     mNv3DVUtils = new Nv3DVUtils();
   110     if (!mNv3DVUtils) {
   111       NS_WARNING("Could not create a new instance of Nv3DVUtils.\n");
   112     }
   113   }
   115   /* Initialize the Nv3DVUtils object */
   116   if (mNv3DVUtils) {
   117     mNv3DVUtils->Initialize();
   118   }
   120   mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
   121   if (!mDevice) {
   122       SetHRESULT(aHresultPtr, hr);
   123       return false;
   124   }
   126   /*
   127    * Do some post device creation setup
   128    */
   129   if (mNv3DVUtils) {
   130     IUnknown* devUnknown = nullptr;
   131     if (mDevice) {
   132       mDevice->QueryInterface(IID_IUnknown, (void **)&devUnknown);
   133     }
   134     mNv3DVUtils->SetDeviceInfo(devUnknown);
   135   }
   137   int referenceCount = 0;
   138   UINT size = sizeof(referenceCount);
   139   // If this isn't there yet it'll fail, count will remain 0, which is correct.
   140   mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
   141   referenceCount++;
   142   mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
   144   DeviceAttachments *attachments;
   145   size = sizeof(DeviceAttachments*);
   146   if (FAILED(mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments))) {
   147     attachments = new DeviceAttachments;
   148     mDevice->SetPrivateData(sDeviceAttachments, sizeof(attachments), &attachments);
   150     SetLastError(0);
   151     decltype(D3D10CreateEffectFromMemory)* createEffect =
   152       (decltype(D3D10CreateEffectFromMemory)*)
   153         GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateEffectFromMemory");
   154     if (!createEffect) {
   155       SetHRESULT(aHresultPtr, HRESULT_FROM_WIN32(GetLastError()));
   156       return false;
   157     }
   159     hr = createEffect((void*)g_main,
   160                       sizeof(g_main),
   161                       D3D10_EFFECT_SINGLE_THREADED,
   162                       mDevice,
   163                       nullptr,
   164                       getter_AddRefs(mEffect));
   166     if (FAILED(hr)) {
   167       SetHRESULT(aHresultPtr, hr);
   168       return false;
   169     }
   171     attachments->mEffect = mEffect;
   173     D3D10_INPUT_ELEMENT_DESC layout[] =
   174     {
   175       { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
   176     };
   177     D3D10_PASS_DESC passDesc;
   178     mEffect->GetTechniqueByName("RenderRGBLayerPremul")->GetPassByIndex(0)->
   179       GetDesc(&passDesc);
   181     hr = mDevice->CreateInputLayout(layout,
   182                                     sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
   183                                     passDesc.pIAInputSignature,
   184                                     passDesc.IAInputSignatureSize,
   185                                     getter_AddRefs(mInputLayout));
   187     if (FAILED(hr)) {
   188       SetHRESULT(aHresultPtr, hr);
   189       return false;
   190     }
   192     attachments->mInputLayout = mInputLayout;
   194     Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} };
   195     CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
   196     D3D10_SUBRESOURCE_DATA data;
   197     data.pSysMem = (void*)vertices;
   199     hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer));
   201     if (FAILED(hr)) {
   202       SetHRESULT(aHresultPtr, hr);
   203       return false;
   204     }
   206     attachments->mVertexBuffer = mVertexBuffer;
   207   } else {
   208     mEffect = attachments->mEffect;
   209     mVertexBuffer = attachments->mVertexBuffer;
   210     mInputLayout = attachments->mInputLayout;
   211   }
   213   nsRefPtr<IDXGIDevice> dxgiDevice;
   214   nsRefPtr<IDXGIAdapter> dxgiAdapter;
   216   mDevice->QueryInterface(dxgiDevice.StartAssignment());
   217   dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));
   219 #ifdef MOZ_METRO
   220   if (IsRunningInWindowsMetro()) {
   221     nsRefPtr<IDXGIFactory2> dxgiFactory;
   222     dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
   224     nsIntRect rect;
   225     mWidget->GetClientBounds(rect);
   227     DXGI_SWAP_CHAIN_DESC1 swapDesc = { 0 };
   228     // Automatically detect the width and the height from the winrt CoreWindow
   229     swapDesc.Width = rect.width;
   230     swapDesc.Height = rect.height;
   231     // This is the most common swapchain format
   232     swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
   233     swapDesc.Stereo = false; 
   234     // Don't use multi-sampling
   235     swapDesc.SampleDesc.Count = 1;
   236     swapDesc.SampleDesc.Quality = 0;
   237     swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   238     // Use double buffering to enable flip
   239     swapDesc.BufferCount = 2;
   240     swapDesc.Scaling = DXGI_SCALING_NONE;
   241     // All Metro style apps must use this SwapEffect
   242     swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
   243     swapDesc.Flags = 0;
   245     /**
   246      * Create a swap chain, this swap chain will contain the backbuffer for
   247      * the window we draw to. The front buffer is the full screen front
   248      * buffer.
   249     */
   250     nsRefPtr<IDXGISwapChain1> swapChain1;
   251     hr = dxgiFactory->CreateSwapChainForCoreWindow(
   252            dxgiDevice, (IUnknown *)mWidget->GetNativeData(NS_NATIVE_ICOREWINDOW),
   253            &swapDesc, nullptr, getter_AddRefs(swapChain1));
   254     if (FAILED(hr)) {
   255       SetHRESULT(aHresultPtr, hr);
   256       return false;
   257     }
   258     mSwapChain = swapChain1;
   259   } else
   260 #endif
   261   {
   262     nsRefPtr<IDXGIFactory> dxgiFactory;
   263     dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
   265     DXGI_SWAP_CHAIN_DESC swapDesc;
   266     ::ZeroMemory(&swapDesc, sizeof(swapDesc));
   267     swapDesc.BufferDesc.Width = 0;
   268     swapDesc.BufferDesc.Height = 0;
   269     swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
   270     swapDesc.BufferDesc.RefreshRate.Numerator = 60;
   271     swapDesc.BufferDesc.RefreshRate.Denominator = 1;
   272     swapDesc.SampleDesc.Count = 1;
   273     swapDesc.SampleDesc.Quality = 0;
   274     swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
   275     swapDesc.BufferCount = 1;
   276     swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
   277     swapDesc.Windowed = TRUE;
   278     // We don't really need this flag, however it seems on some NVidia hardware
   279     // smaller area windows do not present properly without this flag. This flag
   280     // should have no negative consequences by itself. See bug 613790. This flag
   281     // is broken on optimus devices. As a temporary solution we don't set it
   282     // there, the only way of reliably detecting we're on optimus is looking for
   283     // the DLL. See Bug 623807.
   284     if (gfxWindowsPlatform::IsOptimus()) {
   285       swapDesc.Flags = 0;
   286     } else {
   287       swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
   288     }
   290     /**
   291      * Create a swap chain, this swap chain will contain the backbuffer for
   292      * the window we draw to. The front buffer is the full screen front
   293      * buffer.
   294     */
   295     hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain));
   296     if (FAILED(hr)) {
   297      return false;
   298     }
   300     // We need this because we don't want DXGI to respond to Alt+Enter.
   301     dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow, DXGI_MWA_NO_WINDOW_CHANGES);
   302   }
   304   reporter.SetSuccessful();
   305   return true;
   306 }
   308 void
   309 LayerManagerD3D10::Destroy()
   310 {
   311   if (!IsDestroyed()) {
   312     if (mRoot) {
   313       static_cast<LayerD3D10*>(mRoot->ImplData())->LayerManagerDestroyed();
   314     }
   315     // XXX need to be careful here about surface destruction
   316     // racing with share-to-chrome message
   317   }
   318   LayerManager::Destroy();
   319 }
   321 void
   322 LayerManagerD3D10::SetRoot(Layer *aRoot)
   323 {
   324   mRoot = aRoot;
   325 }
   327 void
   328 LayerManagerD3D10::BeginTransaction()
   329 {
   330   mInTransaction = true;
   332 #ifdef MOZ_LAYERS_HAVE_LOG
   333   MOZ_LAYERS_LOG(("[----- BeginTransaction"));
   334   Log();
   335 #endif
   336 }
   338 void
   339 LayerManagerD3D10::BeginTransactionWithTarget(gfxContext* aTarget)
   340 {
   341   mInTransaction = true;
   342   mTarget = aTarget;
   343 }
   345 bool
   346 LayerManagerD3D10::EndEmptyTransaction(EndTransactionFlags aFlags)
   347 {
   348   mInTransaction = false;
   350   if (!mRoot)
   351     return false;
   353   EndTransaction(nullptr, nullptr, aFlags);
   354   return true;
   355 }
   357 void
   358 LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback,
   359                                   void* aCallbackData,
   360                                   EndTransactionFlags aFlags)
   361 {
   362   mInTransaction = false;
   364   if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
   365     mCurrentCallbackInfo.Callback = aCallback;
   366     mCurrentCallbackInfo.CallbackData = aCallbackData;
   368     if (aFlags & END_NO_COMPOSITE) {
   369       // Apply pending tree updates before recomputing effective
   370       // properties.
   371       mRoot->ApplyPendingUpdatesToSubtree();
   372     }
   374     // The results of our drawing always go directly into a pixel buffer,
   375     // so we don't need to pass any global transform here.
   376     mRoot->ComputeEffectiveTransforms(Matrix4x4());
   378 #ifdef MOZ_LAYERS_HAVE_LOG
   379     MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
   380     Log();
   381 #endif
   383     Render(aFlags);
   384     mCurrentCallbackInfo.Callback = nullptr;
   385     mCurrentCallbackInfo.CallbackData = nullptr;
   386   }
   388 #ifdef MOZ_LAYERS_HAVE_LOG
   389   Log();
   390   MOZ_LAYERS_LOG(("]----- EndTransaction"));
   391 #endif
   393   mTarget = nullptr;
   394 }
   396 already_AddRefed<ThebesLayer>
   397 LayerManagerD3D10::CreateThebesLayer()
   398 {
   399   nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D10(this);
   400   return layer.forget();
   401 }
   403 already_AddRefed<ContainerLayer>
   404 LayerManagerD3D10::CreateContainerLayer()
   405 {
   406   nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D10(this);
   407   return layer.forget();
   408 }
   410 already_AddRefed<ImageLayer>
   411 LayerManagerD3D10::CreateImageLayer()
   412 {
   413   nsRefPtr<ImageLayer> layer = new ImageLayerD3D10(this);
   414   return layer.forget();
   415 }
   417 already_AddRefed<ColorLayer>
   418 LayerManagerD3D10::CreateColorLayer()
   419 {
   420   nsRefPtr<ColorLayer> layer = new ColorLayerD3D10(this);
   421   return layer.forget();
   422 }
   424 already_AddRefed<CanvasLayer>
   425 LayerManagerD3D10::CreateCanvasLayer()
   426 {
   427   nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D10(this);
   428   return layer.forget();
   429 }
   431 already_AddRefed<ReadbackLayer>
   432 LayerManagerD3D10::CreateReadbackLayer()
   433 {
   434   nsRefPtr<ReadbackLayer> layer = new ReadbackLayerD3D10(this);
   435   return layer.forget();
   436 }
   438 static void ReleaseTexture(void *texture)
   439 {
   440   static_cast<ID3D10Texture2D*>(texture)->Release();
   441 }
   443 TemporaryRef<DrawTarget>
   444 LayerManagerD3D10::CreateOptimalDrawTarget(const IntSize &aSize,
   445                                            SurfaceFormat aFormat)
   446 {
   447   if ((aFormat != SurfaceFormat::B8G8R8X8 &&
   448        aFormat != SurfaceFormat::B8G8R8A8)) {
   449     return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
   450   }
   452   nsRefPtr<ID3D10Texture2D> texture;
   454   CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
   455   desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
   456   desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
   458   HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
   460   if (FAILED(hr)) {
   461     NS_WARNING("Failed to create new texture for CreateOptimalDrawTarget!");
   462     return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
   463   }
   465   RefPtr<DrawTarget> dt =
   466     Factory::CreateDrawTargetForD3D10Texture(texture, aFormat);
   468   if (!dt) {
   469     return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
   470   }
   472   return dt;
   473 }
   476 TemporaryRef<DrawTarget>
   477 LayerManagerD3D10::CreateOptimalMaskDrawTarget(const IntSize &aSize)
   478 {
   479   return CreateOptimalDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
   480 }
   483 TemporaryRef<DrawTarget>
   484 LayerManagerD3D10::CreateDrawTarget(const IntSize &aSize,
   485                                     SurfaceFormat aFormat)
   486 {
   487   if ((aFormat != SurfaceFormat::B8G8R8A8 &&
   488        aFormat != SurfaceFormat::B8G8R8X8) ||
   489        gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() != BackendType::DIRECT2D) {
   490     return LayerManager::CreateDrawTarget(aSize, aFormat);
   491   }
   493   nsRefPtr<ID3D10Texture2D> texture;
   495   CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
   496   desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
   498   HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
   500   if (FAILED(hr)) {
   501     NS_WARNING("Failed to create new texture for CreateOptimalDrawTarget!");
   502     return LayerManager::CreateDrawTarget(aSize, aFormat);
   503   }
   505   RefPtr<DrawTarget> surface =
   506     Factory::CreateDrawTargetForD3D10Texture(texture, aFormat);
   508   if (!surface) {
   509     return LayerManager::CreateDrawTarget(aSize, aFormat);
   510   }
   512   return surface;
   513 }
   515 ReadbackManagerD3D10*
   516 LayerManagerD3D10::readbackManager()
   517 {
   518   EnsureReadbackManager();
   519   return mReadbackManager;
   520 }
   522 void
   523 LayerManagerD3D10::SetViewport(const nsIntSize &aViewport)
   524 {
   525   mViewport = aViewport;
   527   D3D10_VIEWPORT viewport;
   528   viewport.MaxDepth = 1.0f;
   529   viewport.MinDepth = 0;
   530   viewport.Width = aViewport.width;
   531   viewport.Height = aViewport.height;
   532   viewport.TopLeftX = 0;
   533   viewport.TopLeftY = 0;
   535   mDevice->RSSetViewports(1, &viewport);
   537   gfx3DMatrix projection;
   538   /*
   539    * Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
   540    * <1.0, -1.0> bottomright)
   541    */
   542   projection._11 = 2.0f / aViewport.width;
   543   projection._22 = -2.0f / aViewport.height;
   544   projection._33 = 0.0f;
   545   projection._41 = -1.0f;
   546   projection._42 = 1.0f;
   547   projection._44 = 1.0f;
   549   HRESULT hr = mEffect->GetVariableByName("mProjection")->
   550     SetRawValue(&projection._11, 0, 64);
   552   if (FAILED(hr)) {
   553     NS_WARNING("Failed to set projection matrix.");
   554   }
   555 }
   557 void
   558 LayerManagerD3D10::SetupInputAssembler()
   559 {
   560   mDevice->IASetInputLayout(mInputLayout);
   562   UINT stride = sizeof(Vertex);
   563   UINT offset = 0;
   564   ID3D10Buffer *buffer = mVertexBuffer;
   565   mDevice->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
   566   mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   567 }
   569 void
   570 LayerManagerD3D10::SetupPipeline()
   571 {
   572   VerifyBufferSize();
   573   UpdateRenderTarget();
   575   nsIntRect rect;
   576   mWidget->GetClientBounds(rect);
   578   HRESULT hr;
   580   hr = mEffect->GetVariableByName("vTextureCoords")->AsVector()->
   581     SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
   583   if (FAILED(hr)) {
   584     NS_WARNING("Failed to set Texture Coordinates.");
   585     return;
   586   }
   588   ID3D10RenderTargetView *view = mRTView;
   589   mDevice->OMSetRenderTargets(1, &view, nullptr);
   591   SetupInputAssembler();
   593   SetViewport(nsIntSize(rect.width, rect.height));
   594 }
   596 void
   597 LayerManagerD3D10::UpdateRenderTarget()
   598 {
   599   if (mRTView || !mSwapChain) {
   600     return;
   601   }
   603   HRESULT hr;
   605   nsRefPtr<ID3D10Texture2D> backBuf;
   606   hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
   607   if (FAILED(hr)) {
   608     return;
   609   }
   610   mDevice->CreateRenderTargetView(backBuf, nullptr, getter_AddRefs(mRTView));
   611 }
   613 void
   614 LayerManagerD3D10::VerifyBufferSize()
   615 {
   616   nsIntRect rect;
   617   mWidget->GetClientBounds(rect);
   619   if (mSwapChain) {
   620     DXGI_SWAP_CHAIN_DESC swapDesc;
   621     mSwapChain->GetDesc(&swapDesc);
   623     if (swapDesc.BufferDesc.Width == rect.width &&
   624         swapDesc.BufferDesc.Height == rect.height) {
   625       return;
   626     }
   628     mRTView = nullptr;
   629     if (IsRunningInWindowsMetro()) {
   630       mSwapChain->ResizeBuffers(2, rect.width, rect.height,
   631                                 DXGI_FORMAT_B8G8R8A8_UNORM,
   632                                 0);
   633       mDisableSequenceForNextFrame = true;
   634     } else if (gfxWindowsPlatform::IsOptimus()) {
   635       mSwapChain->ResizeBuffers(1, rect.width, rect.height,
   636                                 DXGI_FORMAT_B8G8R8A8_UNORM,
   637                                 0);
   638     } else {
   639       mSwapChain->ResizeBuffers(1, rect.width, rect.height,
   640                                 DXGI_FORMAT_B8G8R8A8_UNORM,
   641                                 DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
   642     }
   643   }
   644 }
   646 void
   647 LayerManagerD3D10::EnsureReadbackManager()
   648 {
   649   if (mReadbackManager) {
   650     return;
   651   }
   653   DeviceAttachments *attachments;
   654   UINT size = sizeof(DeviceAttachments*);
   655   if (FAILED(mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments))) {
   656     // Strange! This shouldn't happen ... return a readback manager for this
   657     // layer manager only.
   658     mReadbackManager = new ReadbackManagerD3D10();
   659     gfx::LogFailure(NS_LITERAL_CSTRING("Couldn't get device attachments for device."));
   660     return;
   661   }
   663   if (attachments->mReadbackManager) {
   664     mReadbackManager = attachments->mReadbackManager;
   665     return;
   666   }
   668   mReadbackManager = new ReadbackManagerD3D10();
   669   attachments->mReadbackManager = mReadbackManager;
   670 }
   672 void
   673 LayerManagerD3D10::Render(EndTransactionFlags aFlags)
   674 {
   675   static_cast<LayerD3D10*>(mRoot->ImplData())->Validate();
   677   if (aFlags & END_NO_COMPOSITE) {
   678     return;
   679   }
   681   SetupPipeline();
   683   float black[] = { 0, 0, 0, 0 };
   684   device()->ClearRenderTargetView(mRTView, black);
   686   nsIntRect rect;
   687   mWidget->GetClientBounds(rect);
   689   const nsIntRect *clipRect = mRoot->GetClipRect();
   690   D3D10_RECT r;
   691   if (clipRect) {
   692     r.left = (LONG)clipRect->x;
   693     r.top = (LONG)clipRect->y;
   694     r.right = (LONG)(clipRect->x + clipRect->width);
   695     r.bottom = (LONG)(clipRect->y + clipRect->height);
   696   } else {
   697     r.left = r.top = 0;
   698     r.right = rect.width;
   699     r.bottom = rect.height;
   700   }
   701   device()->RSSetScissorRects(1, &r);
   703   static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer();
   705   if (!mRegionToClear.IsEmpty()) {
   706     float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
   707     gfx::Matrix4x4 transform;
   708     effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform, 0, 64);
   709     effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
   711     ID3D10EffectTechnique *technique = effect()->GetTechniqueByName("RenderClearLayer");
   713     nsIntRegionRectIterator iter(mRegionToClear);
   714     const nsIntRect *r;
   715     while ((r = iter.Next())) {
   716       effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
   717         ShaderConstantRectD3D10(
   718         (float)r->x,
   719         (float)r->y,
   720         (float)r->width,
   721         (float)r->height)
   722         );
   724       technique->GetPassByIndex(0)->Apply(0);
   725       device()->Draw(4, 0);
   726     }
   727   }
   729   // See bug 630197 - we have some reasons to believe if an earlier call
   730   // returned an error, the upcoming present call may raise an exception.
   731   // This will check if any of the calls done recently has returned an error
   732   // and bails on composition. On the -next- frame we will then abandon
   733   // hardware acceleration from gfxWindowsPlatform::VerifyD2DDevice.
   734   // This might not be the 'optimal' solution but it will help us assert
   735   // whether our thoughts of the causes of the issues are correct.
   736   if (FAILED(mDevice->GetDeviceRemovedReason())) {
   737     return;
   738   }
   740   if (mTarget) {
   741     PaintToTarget();
   742   } else {
   743     mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
   744     mDisableSequenceForNextFrame = false;
   745   }
   746   RecordFrame();
   747   PostPresent();
   748 }
   750 void
   751 LayerManagerD3D10::PaintToTarget()
   752 {
   753   nsRefPtr<ID3D10Texture2D> backBuf;
   755   mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
   757   D3D10_TEXTURE2D_DESC bbDesc;
   758   backBuf->GetDesc(&bbDesc);
   760   CD3D10_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height);
   761   softDesc.MipLevels = 1;
   762   softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
   763   softDesc.Usage = D3D10_USAGE_STAGING;
   764   softDesc.BindFlags = 0;
   766   nsRefPtr<ID3D10Texture2D> readTexture;
   768   HRESULT hr = device()->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture));
   769   if (FAILED(hr)) {
   770     ReportFailure(NS_LITERAL_CSTRING("LayerManagerD3D10::PaintToTarget(): Failed to create texture"),
   771                   hr);
   772     return;
   773   }
   775   device()->CopyResource(readTexture, backBuf);
   777   D3D10_MAPPED_TEXTURE2D map;
   778   readTexture->Map(0, D3D10_MAP_READ, 0, &map);
   780   nsRefPtr<gfxImageSurface> tmpSurface =
   781     new gfxImageSurface((unsigned char*)map.pData,
   782                         gfxIntSize(bbDesc.Width, bbDesc.Height),
   783                         map.RowPitch,
   784                         gfxImageFormat::ARGB32);
   786   mTarget->SetSource(tmpSurface);
   787   mTarget->SetOperator(gfxContext::OPERATOR_OVER);
   788   mTarget->Paint();
   790   readTexture->Unmap(0);
   791 }
   793 void
   794 LayerManagerD3D10::ReportFailure(const nsACString &aMsg, HRESULT aCode)
   795 {
   796   // We could choose to abort here when hr == E_OUTOFMEMORY.
   797   nsCString msg;
   798   msg.Append(aMsg);
   799   msg.AppendLiteral(" Error code: ");
   800   msg.AppendInt(uint32_t(aCode));
   801   NS_WARNING(msg.BeginReading());
   803   gfx::LogFailure(msg);
   804 }
   806 LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager)
   807   : mD3DManager(aManager)
   808 {
   809 }
   811 ID3D10EffectTechnique*
   812 LayerD3D10::SelectShader(uint8_t aFlags)
   813 {
   814   switch (aFlags) {
   815   case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_MASK):
   816     return effect()->GetTechniqueByName("RenderRGBALayerNonPremulMask");
   817   case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
   818     return effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
   819   case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_NO_MASK):
   820     return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
   821   case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_MASK):
   822     return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPointMask");
   823   case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK_3D):
   824     return effect()->GetTechniqueByName("RenderRGBALayerPremulMask3D");
   825   case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
   826     return effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
   827   case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
   828     return effect()->GetTechniqueByName("RenderRGBALayerPremul");
   829   case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
   830     return effect()->GetTechniqueByName("RenderRGBALayerPremulPointMask");
   831   case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
   832     return effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
   833   case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
   834     return effect()->GetTechniqueByName("RenderRGBLayerPremulPointMask");
   835   case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
   836     return effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
   837   case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
   838     return effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
   839   case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
   840     return effect()->GetTechniqueByName("RenderRGBLayerPremul");
   841   case (SHADER_SOLID | SHADER_MASK):
   842     return effect()->GetTechniqueByName("RenderSolidColorLayerMask");
   843   case (SHADER_SOLID | SHADER_NO_MASK):
   844     return effect()->GetTechniqueByName("RenderSolidColorLayer");
   845   case (SHADER_COMPONENT_ALPHA | SHADER_MASK):
   846     return effect()->GetTechniqueByName("RenderComponentAlphaLayerMask");
   847   case (SHADER_COMPONENT_ALPHA | SHADER_NO_MASK):
   848     return effect()->GetTechniqueByName("RenderComponentAlphaLayer");
   849   case (SHADER_YCBCR | SHADER_MASK):
   850     return effect()->GetTechniqueByName("RenderYCbCrLayerMask");
   851   case (SHADER_YCBCR | SHADER_NO_MASK):
   852     return effect()->GetTechniqueByName("RenderYCbCrLayer");
   853   default:
   854     NS_ERROR("Invalid shader.");
   855     return nullptr;
   856   }
   857 }
   859 uint8_t
   860 LayerD3D10::LoadMaskTexture()
   861 {
   862   if (Layer* maskLayer = GetLayer()->GetMaskLayer()) {
   863     IntSize size;
   864     nsRefPtr<ID3D10ShaderResourceView> maskSRV =
   865       static_cast<LayerD3D10*>(maskLayer->ImplData())->GetAsTexture(&size);
   867     if (!maskSRV) {
   868       return SHADER_NO_MASK;
   869     }
   871     Matrix maskTransform;
   872     Matrix4x4 effectiveTransform = maskLayer->GetEffectiveTransform();
   873     bool maskIs2D = effectiveTransform.CanDraw2D(&maskTransform);
   874     NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
   875     Rect bounds = Rect(Point(), Size(size));
   876     bounds = maskTransform.TransformBounds(bounds);
   878     effect()->GetVariableByName("vMaskQuad")->AsVector()->SetFloatVector(
   879       ShaderConstantRectD3D10(
   880         (float)bounds.x,
   881         (float)bounds.y,
   882         (float)bounds.width,
   883         (float)bounds.height)
   884       );
   886     effect()->GetVariableByName("tMask")->AsShaderResource()->SetResource(maskSRV);
   887     return SHADER_MASK;
   888   }
   890   return SHADER_NO_MASK;
   891 }
   893 }
   894 }

mercurial