1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d11/CompositorD3D11.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1026 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "CompositorD3D11.h" 1.10 + 1.11 +#include "TextureD3D11.h" 1.12 +#include "CompositorD3D11Shaders.h" 1.13 + 1.14 +#include "gfxWindowsPlatform.h" 1.15 +#include "nsIWidget.h" 1.16 +#include "mozilla/layers/ImageHost.h" 1.17 +#include "mozilla/layers/ContentHost.h" 1.18 +#include "mozilla/layers/Effects.h" 1.19 +#include "nsWindowsHelpers.h" 1.20 +#include "gfxPrefs.h" 1.21 + 1.22 +#ifdef MOZ_METRO 1.23 +#include <DXGI1_2.h> 1.24 +#endif 1.25 + 1.26 +namespace mozilla { 1.27 + 1.28 +using namespace gfx; 1.29 + 1.30 +namespace layers { 1.31 + 1.32 +struct Vertex 1.33 +{ 1.34 + float position[2]; 1.35 +}; 1.36 + 1.37 +// {1E4D7BEB-D8EC-4A0B-BF0A-63E6DE129425} 1.38 +static const GUID sDeviceAttachmentsD3D11 = 1.39 +{ 0x1e4d7beb, 0xd8ec, 0x4a0b, { 0xbf, 0xa, 0x63, 0xe6, 0xde, 0x12, 0x94, 0x25 } }; 1.40 +// {88041664-C835-4AA8-ACB8-7EC832357ED8} 1.41 +static const GUID sLayerManagerCount = 1.42 +{ 0x88041664, 0xc835, 0x4aa8, { 0xac, 0xb8, 0x7e, 0xc8, 0x32, 0x35, 0x7e, 0xd8 } }; 1.43 + 1.44 +const FLOAT sBlendFactor[] = { 0, 0, 0, 0 }; 1.45 + 1.46 +struct DeviceAttachmentsD3D11 1.47 +{ 1.48 + RefPtr<ID3D11InputLayout> mInputLayout; 1.49 + RefPtr<ID3D11Buffer> mVertexBuffer; 1.50 + RefPtr<ID3D11VertexShader> mVSQuadShader[3]; 1.51 + RefPtr<ID3D11PixelShader> mSolidColorShader[2]; 1.52 + RefPtr<ID3D11PixelShader> mRGBAShader[3]; 1.53 + RefPtr<ID3D11PixelShader> mRGBShader[2]; 1.54 + RefPtr<ID3D11PixelShader> mYCbCrShader[2]; 1.55 + RefPtr<ID3D11PixelShader> mComponentAlphaShader[2]; 1.56 + RefPtr<ID3D11Buffer> mPSConstantBuffer; 1.57 + RefPtr<ID3D11Buffer> mVSConstantBuffer; 1.58 + RefPtr<ID3D11RasterizerState> mRasterizerState; 1.59 + RefPtr<ID3D11SamplerState> mLinearSamplerState; 1.60 + RefPtr<ID3D11SamplerState> mPointSamplerState; 1.61 + RefPtr<ID3D11BlendState> mPremulBlendState; 1.62 + RefPtr<ID3D11BlendState> mNonPremulBlendState; 1.63 + RefPtr<ID3D11BlendState> mComponentBlendState; 1.64 + RefPtr<ID3D11BlendState> mDisabledBlendState; 1.65 +}; 1.66 + 1.67 +CompositorD3D11::CompositorD3D11(nsIWidget* aWidget) 1.68 + : mAttachments(nullptr) 1.69 + , mWidget(aWidget) 1.70 + , mHwnd(nullptr) 1.71 + , mDisableSequenceForNextFrame(false) 1.72 +{ 1.73 + SetBackend(LayersBackend::LAYERS_D3D11); 1.74 +} 1.75 + 1.76 +CompositorD3D11::~CompositorD3D11() 1.77 +{ 1.78 + if (mDevice) { 1.79 + int referenceCount = 0; 1.80 + UINT size = sizeof(referenceCount); 1.81 + HRESULT hr = mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount); 1.82 + NS_ASSERTION(SUCCEEDED(hr), "Reference count not found on device."); 1.83 + referenceCount--; 1.84 + mDevice->SetPrivateData(sLayerManagerCount, 1.85 + sizeof(referenceCount), 1.86 + &referenceCount); 1.87 + 1.88 + if (!referenceCount) { 1.89 + DeviceAttachmentsD3D11 *attachments; 1.90 + size = sizeof(attachments); 1.91 + mDevice->GetPrivateData(sDeviceAttachmentsD3D11, &size, &attachments); 1.92 + // No LayerManagers left for this device. Clear out interfaces stored 1.93 + // which hold a reference to the device. 1.94 + mDevice->SetPrivateData(sDeviceAttachmentsD3D11, 0, nullptr); 1.95 + 1.96 + delete attachments; 1.97 + } 1.98 + } 1.99 +} 1.100 + 1.101 +bool 1.102 +CompositorD3D11::Initialize() 1.103 +{ 1.104 + HRESULT hr; 1.105 + 1.106 + mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D11Device(); 1.107 + 1.108 + if (!mDevice) { 1.109 + return false; 1.110 + } 1.111 + 1.112 + mDevice->GetImmediateContext(byRef(mContext)); 1.113 + 1.114 + if (!mContext) { 1.115 + return false; 1.116 + } 1.117 + 1.118 + mHwnd = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW); 1.119 + 1.120 + memset(&mVSConstants, 0, sizeof(VertexShaderConstants)); 1.121 + 1.122 + int referenceCount = 0; 1.123 + UINT size = sizeof(referenceCount); 1.124 + // If this isn't there yet it'll fail, count will remain 0, which is correct. 1.125 + mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount); 1.126 + referenceCount++; 1.127 + mDevice->SetPrivateData(sLayerManagerCount, 1.128 + sizeof(referenceCount), 1.129 + &referenceCount); 1.130 + 1.131 + size = sizeof(DeviceAttachmentsD3D11*); 1.132 + if (FAILED(mDevice->GetPrivateData(sDeviceAttachmentsD3D11, 1.133 + &size, 1.134 + &mAttachments))) { 1.135 + mAttachments = new DeviceAttachmentsD3D11; 1.136 + mDevice->SetPrivateData(sDeviceAttachmentsD3D11, 1.137 + sizeof(mAttachments), 1.138 + &mAttachments); 1.139 + 1.140 + D3D11_INPUT_ELEMENT_DESC layout[] = 1.141 + { 1.142 + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 1.143 + }; 1.144 + 1.145 + hr = mDevice->CreateInputLayout(layout, 1.146 + sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC), 1.147 + LayerQuadVS, 1.148 + sizeof(LayerQuadVS), 1.149 + byRef(mAttachments->mInputLayout)); 1.150 + 1.151 + if (FAILED(hr)) { 1.152 + return false; 1.153 + } 1.154 + 1.155 + Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} }; 1.156 + CD3D11_BUFFER_DESC bufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); 1.157 + D3D11_SUBRESOURCE_DATA data; 1.158 + data.pSysMem = (void*)vertices; 1.159 + 1.160 + hr = mDevice->CreateBuffer(&bufferDesc, &data, byRef(mAttachments->mVertexBuffer)); 1.161 + 1.162 + if (FAILED(hr)) { 1.163 + return false; 1.164 + } 1.165 + 1.166 + if (!CreateShaders()) { 1.167 + return false; 1.168 + } 1.169 + 1.170 + CD3D11_BUFFER_DESC cBufferDesc(sizeof(VertexShaderConstants), 1.171 + D3D11_BIND_CONSTANT_BUFFER, 1.172 + D3D11_USAGE_DYNAMIC, 1.173 + D3D11_CPU_ACCESS_WRITE); 1.174 + 1.175 + hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mVSConstantBuffer)); 1.176 + if (FAILED(hr)) { 1.177 + return false; 1.178 + } 1.179 + 1.180 + cBufferDesc.ByteWidth = sizeof(PixelShaderConstants); 1.181 + hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mPSConstantBuffer)); 1.182 + if (FAILED(hr)) { 1.183 + return false; 1.184 + } 1.185 + 1.186 + CD3D11_RASTERIZER_DESC rastDesc(D3D11_DEFAULT); 1.187 + rastDesc.CullMode = D3D11_CULL_NONE; 1.188 + rastDesc.ScissorEnable = TRUE; 1.189 + 1.190 + hr = mDevice->CreateRasterizerState(&rastDesc, byRef(mAttachments->mRasterizerState)); 1.191 + if (FAILED(hr)) { 1.192 + return false; 1.193 + } 1.194 + 1.195 + CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT); 1.196 + samplerDesc.AddressU = samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 1.197 + hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mLinearSamplerState)); 1.198 + if (FAILED(hr)) { 1.199 + return false; 1.200 + } 1.201 + 1.202 + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; 1.203 + hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mPointSamplerState)); 1.204 + if (FAILED(hr)) { 1.205 + return false; 1.206 + } 1.207 + 1.208 + CD3D11_BLEND_DESC blendDesc(D3D11_DEFAULT); 1.209 + D3D11_RENDER_TARGET_BLEND_DESC rtBlendPremul = { 1.210 + TRUE, 1.211 + D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.212 + D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.213 + D3D11_COLOR_WRITE_ENABLE_ALL 1.214 + }; 1.215 + blendDesc.RenderTarget[0] = rtBlendPremul; 1.216 + hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mPremulBlendState)); 1.217 + if (FAILED(hr)) { 1.218 + return false; 1.219 + } 1.220 + 1.221 + D3D11_RENDER_TARGET_BLEND_DESC rtBlendNonPremul = { 1.222 + TRUE, 1.223 + D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.224 + D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.225 + D3D11_COLOR_WRITE_ENABLE_ALL 1.226 + }; 1.227 + blendDesc.RenderTarget[0] = rtBlendNonPremul; 1.228 + hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mNonPremulBlendState)); 1.229 + if (FAILED(hr)) { 1.230 + return false; 1.231 + } 1.232 + 1.233 + if (gfxPrefs::ComponentAlphaEnabled()) { 1.234 + D3D11_RENDER_TARGET_BLEND_DESC rtBlendComponent = { 1.235 + TRUE, 1.236 + D3D11_BLEND_ONE, 1.237 + D3D11_BLEND_INV_SRC1_COLOR, 1.238 + D3D11_BLEND_OP_ADD, 1.239 + D3D11_BLEND_ONE, 1.240 + D3D11_BLEND_INV_SRC_ALPHA, 1.241 + D3D11_BLEND_OP_ADD, 1.242 + D3D11_COLOR_WRITE_ENABLE_ALL 1.243 + }; 1.244 + blendDesc.RenderTarget[0] = rtBlendComponent; 1.245 + hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mComponentBlendState)); 1.246 + if (FAILED(hr)) { 1.247 + return false; 1.248 + } 1.249 + } 1.250 + 1.251 + D3D11_RENDER_TARGET_BLEND_DESC rtBlendDisabled = { 1.252 + FALSE, 1.253 + D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.254 + D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, 1.255 + D3D11_COLOR_WRITE_ENABLE_ALL 1.256 + }; 1.257 + blendDesc.RenderTarget[0] = rtBlendDisabled; 1.258 + hr = mDevice->CreateBlendState(&blendDesc, byRef(mAttachments->mDisabledBlendState)); 1.259 + if (FAILED(hr)) { 1.260 + return false; 1.261 + } 1.262 + } 1.263 + 1.264 + nsRefPtr<IDXGIDevice> dxgiDevice; 1.265 + nsRefPtr<IDXGIAdapter> dxgiAdapter; 1.266 + 1.267 + mDevice->QueryInterface(dxgiDevice.StartAssignment()); 1.268 + dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)); 1.269 + 1.270 +#ifdef MOZ_METRO 1.271 + if (IsRunningInWindowsMetro()) { 1.272 + nsRefPtr<IDXGIFactory2> dxgiFactory; 1.273 + dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment())); 1.274 + 1.275 + nsIntRect rect; 1.276 + mWidget->GetClientBounds(rect); 1.277 + 1.278 + DXGI_SWAP_CHAIN_DESC1 swapDesc = { 0 }; 1.279 + // Automatically detect the width and the height from the winrt CoreWindow 1.280 + swapDesc.Width = rect.width; 1.281 + swapDesc.Height = rect.height; 1.282 + // This is the most common swapchain format 1.283 + swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; 1.284 + swapDesc.Stereo = false; 1.285 + // Don't use multi-sampling 1.286 + swapDesc.SampleDesc.Count = 1; 1.287 + swapDesc.SampleDesc.Quality = 0; 1.288 + swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 1.289 + // Use double buffering to enable flip 1.290 + swapDesc.BufferCount = 2; 1.291 + swapDesc.Scaling = DXGI_SCALING_NONE; 1.292 + // All Metro style apps must use this SwapEffect 1.293 + swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; 1.294 + swapDesc.Flags = 0; 1.295 + 1.296 + /** 1.297 + * Create a swap chain, this swap chain will contain the backbuffer for 1.298 + * the window we draw to. The front buffer is the full screen front 1.299 + * buffer. 1.300 + */ 1.301 + nsRefPtr<IDXGISwapChain1> swapChain1; 1.302 + hr = dxgiFactory->CreateSwapChainForCoreWindow( 1.303 + dxgiDevice, (IUnknown *)mWidget->GetNativeData(NS_NATIVE_ICOREWINDOW), 1.304 + &swapDesc, nullptr, getter_AddRefs(swapChain1)); 1.305 + if (FAILED(hr)) { 1.306 + return false; 1.307 + } 1.308 + mSwapChain = swapChain1; 1.309 + } else 1.310 +#endif 1.311 + { 1.312 + nsRefPtr<IDXGIFactory> dxgiFactory; 1.313 + dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment())); 1.314 + 1.315 + DXGI_SWAP_CHAIN_DESC swapDesc; 1.316 + ::ZeroMemory(&swapDesc, sizeof(swapDesc)); 1.317 + swapDesc.BufferDesc.Width = 0; 1.318 + swapDesc.BufferDesc.Height = 0; 1.319 + swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; 1.320 + swapDesc.BufferDesc.RefreshRate.Numerator = 60; 1.321 + swapDesc.BufferDesc.RefreshRate.Denominator = 1; 1.322 + swapDesc.SampleDesc.Count = 1; 1.323 + swapDesc.SampleDesc.Quality = 0; 1.324 + swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 1.325 + swapDesc.BufferCount = 1; 1.326 + swapDesc.OutputWindow = mHwnd; 1.327 + swapDesc.Windowed = TRUE; 1.328 + // We don't really need this flag, however it seems on some NVidia hardware 1.329 + // smaller area windows do not present properly without this flag. This flag 1.330 + // should have no negative consequences by itself. See bug 613790. This flag 1.331 + // is broken on optimus devices. As a temporary solution we don't set it 1.332 + // there, the only way of reliably detecting we're on optimus is looking for 1.333 + // the DLL. See Bug 623807. 1.334 + if (gfxWindowsPlatform::IsOptimus()) { 1.335 + swapDesc.Flags = 0; 1.336 + } else { 1.337 + swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; 1.338 + } 1.339 + 1.340 + /** 1.341 + * Create a swap chain, this swap chain will contain the backbuffer for 1.342 + * the window we draw to. The front buffer is the full screen front 1.343 + * buffer. 1.344 + */ 1.345 + hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, byRef(mSwapChain)); 1.346 + if (FAILED(hr)) { 1.347 + return false; 1.348 + } 1.349 + 1.350 + // We need this because we don't want DXGI to respond to Alt+Enter. 1.351 + dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow, 1.352 + DXGI_MWA_NO_WINDOW_CHANGES); 1.353 + } 1.354 + 1.355 + return true; 1.356 +} 1.357 + 1.358 +TemporaryRef<DataTextureSource> 1.359 +CompositorD3D11::CreateDataTextureSource(TextureFlags aFlags) 1.360 +{ 1.361 + RefPtr<DataTextureSource> result = new DataTextureSourceD3D11(gfx::SurfaceFormat::UNKNOWN, 1.362 + this, aFlags); 1.363 + return result.forget(); 1.364 +} 1.365 + 1.366 +TextureFactoryIdentifier 1.367 +CompositorD3D11::GetTextureFactoryIdentifier() 1.368 +{ 1.369 + TextureFactoryIdentifier ident; 1.370 + ident.mMaxTextureSize = GetMaxTextureSize(); 1.371 + ident.mParentProcessId = XRE_GetProcessType(); 1.372 + ident.mParentBackend = LayersBackend::LAYERS_D3D11; 1.373 + return ident; 1.374 +} 1.375 + 1.376 +bool 1.377 +CompositorD3D11::CanUseCanvasLayerForSize(const gfx::IntSize& aSize) 1.378 +{ 1.379 + int32_t maxTextureSize = GetMaxTextureSize(); 1.380 + 1.381 + if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) { 1.382 + return false; 1.383 + } 1.384 + 1.385 + return true; 1.386 +} 1.387 + 1.388 +int32_t 1.389 +CompositorD3D11::GetMaxTextureSize() const 1.390 +{ 1.391 + return GetMaxTextureSizeForFeatureLevel(mFeatureLevel); 1.392 +} 1.393 + 1.394 +TemporaryRef<CompositingRenderTarget> 1.395 +CompositorD3D11::CreateRenderTarget(const gfx::IntRect& aRect, 1.396 + SurfaceInitMode aInit) 1.397 +{ 1.398 + CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aRect.width, aRect.height, 1, 1, 1.399 + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); 1.400 + 1.401 + RefPtr<ID3D11Texture2D> texture; 1.402 + mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); 1.403 + NS_ASSERTION(texture, "Could not create texture"); 1.404 + if (!texture) { 1.405 + return nullptr; 1.406 + } 1.407 + 1.408 + RefPtr<CompositingRenderTargetD3D11> rt = new CompositingRenderTargetD3D11(texture, aRect.TopLeft()); 1.409 + rt->SetSize(IntSize(aRect.width, aRect.height)); 1.410 + 1.411 + if (aInit == INIT_MODE_CLEAR) { 1.412 + FLOAT clear[] = { 0, 0, 0, 0 }; 1.413 + mContext->ClearRenderTargetView(rt->mRTView, clear); 1.414 + } 1.415 + 1.416 + return rt; 1.417 +} 1.418 + 1.419 +TemporaryRef<CompositingRenderTarget> 1.420 +CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect, 1.421 + const CompositingRenderTarget* aSource, 1.422 + const gfx::IntPoint &aSourcePoint) 1.423 +{ 1.424 + CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 1.425 + aRect.width, aRect.height, 1, 1, 1.426 + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); 1.427 + 1.428 + RefPtr<ID3D11Texture2D> texture; 1.429 + mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); 1.430 + NS_ASSERTION(texture, "Could not create texture"); 1.431 + if (!texture) { 1.432 + return nullptr; 1.433 + } 1.434 + 1.435 + if (aSource) { 1.436 + const CompositingRenderTargetD3D11* sourceD3D11 = 1.437 + static_cast<const CompositingRenderTargetD3D11*>(aSource); 1.438 + 1.439 + D3D11_BOX srcBox; 1.440 + srcBox.left = aSourcePoint.x; 1.441 + srcBox.top = aSourcePoint.y; 1.442 + srcBox.front = 0; 1.443 + srcBox.right = aSourcePoint.x + aRect.width; 1.444 + srcBox.bottom = aSourcePoint.y + aRect.height; 1.445 + srcBox.back = 0; 1.446 + 1.447 + const IntSize& srcSize = sourceD3D11->GetSize(); 1.448 + MOZ_ASSERT(srcSize.width >= 0 && srcSize.height >= 0, 1.449 + "render targets should have nonnegative sizes"); 1.450 + if (srcBox.right <= static_cast<uint32_t>(srcSize.width) && 1.451 + srcBox.bottom <= static_cast<uint32_t>(srcSize.height)) { 1.452 + mContext->CopySubresourceRegion(texture, 0, 1.453 + 0, 0, 0, 1.454 + sourceD3D11->GetD3D11Texture(), 0, 1.455 + &srcBox); 1.456 + } else { 1.457 + NS_WARNING("Could not copy render target - source rect out of bounds"); 1.458 + } 1.459 + } 1.460 + 1.461 + RefPtr<CompositingRenderTargetD3D11> rt = 1.462 + new CompositingRenderTargetD3D11(texture, aRect.TopLeft()); 1.463 + rt->SetSize(aRect.Size()); 1.464 + 1.465 + return rt; 1.466 +} 1.467 + 1.468 +void 1.469 +CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget) 1.470 +{ 1.471 + MOZ_ASSERT(aRenderTarget); 1.472 + CompositingRenderTargetD3D11* newRT = 1.473 + static_cast<CompositingRenderTargetD3D11*>(aRenderTarget); 1.474 + ID3D11RenderTargetView* view = newRT->mRTView; 1.475 + mCurrentRT = newRT; 1.476 + mContext->OMSetRenderTargets(1, &view, nullptr); 1.477 + PrepareViewport(newRT->GetSize(), gfx::Matrix()); 1.478 +} 1.479 + 1.480 +void 1.481 +CompositorD3D11::SetPSForEffect(Effect* aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat) 1.482 +{ 1.483 + switch (aEffect->mType) { 1.484 + case EFFECT_SOLID_COLOR: 1.485 + mContext->PSSetShader(mAttachments->mSolidColorShader[aMaskType], nullptr, 0); 1.486 + return; 1.487 + case EFFECT_RENDER_TARGET: 1.488 + mContext->PSSetShader(mAttachments->mRGBAShader[aMaskType], nullptr, 0); 1.489 + return; 1.490 + case EFFECT_RGB: 1.491 + mContext->PSSetShader((aFormat == SurfaceFormat::B8G8R8A8 || aFormat == SurfaceFormat::R8G8B8A8) 1.492 + ? mAttachments->mRGBAShader[aMaskType] 1.493 + : mAttachments->mRGBShader[aMaskType], nullptr, 0); 1.494 + return; 1.495 + case EFFECT_YCBCR: 1.496 + mContext->PSSetShader(mAttachments->mYCbCrShader[aMaskType], nullptr, 0); 1.497 + return; 1.498 + case EFFECT_COMPONENT_ALPHA: 1.499 + mContext->PSSetShader(mAttachments->mComponentAlphaShader[aMaskType], nullptr, 0); 1.500 + return; 1.501 + default: 1.502 + NS_WARNING("No shader to load"); 1.503 + return; 1.504 + } 1.505 +} 1.506 + 1.507 +void 1.508 +CompositorD3D11::ClearRect(const gfx::Rect& aRect) 1.509 +{ 1.510 + mContext->OMSetBlendState(mAttachments->mDisabledBlendState, sBlendFactor, 0xFFFFFFFF); 1.511 + 1.512 + Matrix4x4 identity; 1.513 + memcpy(&mVSConstants.layerTransform, &identity._11, 64); 1.514 + 1.515 + mVSConstants.layerQuad = aRect; 1.516 + mVSConstants.renderTargetOffset[0] = 0; 1.517 + mVSConstants.renderTargetOffset[1] = 0; 1.518 + mPSConstants.layerOpacity[0] = 1.0f; 1.519 + 1.520 + D3D11_RECT scissor; 1.521 + scissor.left = aRect.x; 1.522 + scissor.right = aRect.XMost(); 1.523 + scissor.top = aRect.y; 1.524 + scissor.bottom = aRect.YMost(); 1.525 + mContext->RSSetScissorRects(1, &scissor); 1.526 + mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); 1.527 + mContext->VSSetShader(mAttachments->mVSQuadShader[MaskNone], nullptr, 0); 1.528 + 1.529 + mContext->PSSetShader(mAttachments->mSolidColorShader[MaskNone], nullptr, 0); 1.530 + mPSConstants.layerColor[0] = 0; 1.531 + mPSConstants.layerColor[1] = 0; 1.532 + mPSConstants.layerColor[2] = 0; 1.533 + mPSConstants.layerColor[3] = 0; 1.534 + 1.535 + UpdateConstantBuffers(); 1.536 + 1.537 + mContext->Draw(4, 0); 1.538 + 1.539 + mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF); 1.540 +} 1.541 + 1.542 +void 1.543 +CompositorD3D11::DrawQuad(const gfx::Rect& aRect, 1.544 + const gfx::Rect& aClipRect, 1.545 + const EffectChain& aEffectChain, 1.546 + gfx::Float aOpacity, 1.547 + const gfx::Matrix4x4& aTransform) 1.548 +{ 1.549 + MOZ_ASSERT(mCurrentRT, "No render target"); 1.550 + memcpy(&mVSConstants.layerTransform, &aTransform._11, 64); 1.551 + IntPoint origin = mCurrentRT->GetOrigin(); 1.552 + mVSConstants.renderTargetOffset[0] = origin.x; 1.553 + mVSConstants.renderTargetOffset[1] = origin.y; 1.554 + mVSConstants.layerQuad = aRect; 1.555 + 1.556 + mPSConstants.layerOpacity[0] = aOpacity; 1.557 + 1.558 + bool restoreBlendMode = false; 1.559 + 1.560 + MaskType maskType = MaskNone; 1.561 + 1.562 + if (aEffectChain.mSecondaryEffects[EFFECT_MASK]) { 1.563 + if (aTransform.Is2D()) { 1.564 + maskType = Mask2d; 1.565 + } else { 1.566 + MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EFFECT_RGB); 1.567 + maskType = Mask3d; 1.568 + } 1.569 + 1.570 + EffectMask* maskEffect = 1.571 + static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get()); 1.572 + TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11(); 1.573 + 1.574 + if (!source) { 1.575 + NS_WARNING("Missing texture source!"); 1.576 + return; 1.577 + } 1.578 + 1.579 + RefPtr<ID3D11ShaderResourceView> view; 1.580 + mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view)); 1.581 + 1.582 + ID3D11ShaderResourceView* srView = view; 1.583 + mContext->PSSetShaderResources(3, 1, &srView); 1.584 + 1.585 + const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform; 1.586 + NS_ASSERTION(maskTransform.Is2D(), "How did we end up with a 3D transform here?!"); 1.587 + Rect bounds = Rect(Point(), Size(maskEffect->mSize)); 1.588 + 1.589 + mVSConstants.maskQuad = maskTransform.As2D().TransformBounds(bounds); 1.590 + } 1.591 + 1.592 + 1.593 + D3D11_RECT scissor; 1.594 + scissor.left = aClipRect.x; 1.595 + scissor.right = aClipRect.XMost(); 1.596 + scissor.top = aClipRect.y; 1.597 + scissor.bottom = aClipRect.YMost(); 1.598 + mContext->RSSetScissorRects(1, &scissor); 1.599 + mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); 1.600 + mContext->VSSetShader(mAttachments->mVSQuadShader[maskType], nullptr, 0); 1.601 + 1.602 + 1.603 + switch (aEffectChain.mPrimaryEffect->mType) { 1.604 + case EFFECT_SOLID_COLOR: { 1.605 + SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, SurfaceFormat::UNKNOWN); 1.606 + 1.607 + Color color = 1.608 + static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor; 1.609 + mPSConstants.layerColor[0] = color.r * color.a * aOpacity; 1.610 + mPSConstants.layerColor[1] = color.g * color.a * aOpacity; 1.611 + mPSConstants.layerColor[2] = color.b * color.a * aOpacity; 1.612 + mPSConstants.layerColor[3] = color.a * aOpacity; 1.613 + } 1.614 + break; 1.615 + case EFFECT_RGB: 1.616 + case EFFECT_RENDER_TARGET: 1.617 + { 1.618 + TexturedEffect* texturedEffect = 1.619 + static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get()); 1.620 + 1.621 + mVSConstants.textureCoords = texturedEffect->mTextureCoords; 1.622 + 1.623 + TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11(); 1.624 + 1.625 + if (!source) { 1.626 + NS_WARNING("Missing texture source!"); 1.627 + return; 1.628 + } 1.629 + 1.630 + SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, texturedEffect->mTexture->GetFormat()); 1.631 + 1.632 + RefPtr<ID3D11ShaderResourceView> view; 1.633 + mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view)); 1.634 + 1.635 + ID3D11ShaderResourceView* srView = view; 1.636 + mContext->PSSetShaderResources(0, 1, &srView); 1.637 + 1.638 + if (!texturedEffect->mPremultiplied) { 1.639 + mContext->OMSetBlendState(mAttachments->mNonPremulBlendState, sBlendFactor, 0xFFFFFFFF); 1.640 + restoreBlendMode = true; 1.641 + } 1.642 + 1.643 + SetSamplerForFilter(texturedEffect->mFilter); 1.644 + } 1.645 + break; 1.646 + case EFFECT_YCBCR: { 1.647 + EffectYCbCr* ycbcrEffect = 1.648 + static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get()); 1.649 + 1.650 + SetSamplerForFilter(Filter::LINEAR); 1.651 + 1.652 + mVSConstants.textureCoords = ycbcrEffect->mTextureCoords; 1.653 + 1.654 + const int Y = 0, Cb = 1, Cr = 2; 1.655 + TextureSource* source = ycbcrEffect->mTexture; 1.656 + 1.657 + if (!source) { 1.658 + NS_WARNING("No texture to composite"); 1.659 + return; 1.660 + } 1.661 + 1.662 + SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, ycbcrEffect->mTexture->GetFormat()); 1.663 + 1.664 + if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) { 1.665 + // This can happen if we failed to upload the textures, most likely 1.666 + // because of unsupported dimensions (we don't tile YCbCr textures). 1.667 + return; 1.668 + } 1.669 + 1.670 + TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11(); 1.671 + TextureSourceD3D11* sourceCb = source->GetSubSource(Cb)->AsSourceD3D11(); 1.672 + TextureSourceD3D11* sourceCr = source->GetSubSource(Cr)->AsSourceD3D11(); 1.673 + 1.674 + RefPtr<ID3D11ShaderResourceView> views[3]; 1.675 + mDevice->CreateShaderResourceView(sourceY->GetD3D11Texture(), 1.676 + nullptr, byRef(views[0])); 1.677 + mDevice->CreateShaderResourceView(sourceCb->GetD3D11Texture(), 1.678 + nullptr, byRef(views[1])); 1.679 + mDevice->CreateShaderResourceView(sourceCr->GetD3D11Texture(), 1.680 + nullptr, byRef(views[2])); 1.681 + 1.682 + ID3D11ShaderResourceView* srViews[3] = { views[0], views[1], views[2] }; 1.683 + mContext->PSSetShaderResources(0, 3, srViews); 1.684 + } 1.685 + break; 1.686 + case EFFECT_COMPONENT_ALPHA: 1.687 + { 1.688 + MOZ_ASSERT(gfxPrefs::ComponentAlphaEnabled()); 1.689 + MOZ_ASSERT(mAttachments->mComponentBlendState); 1.690 + EffectComponentAlpha* effectComponentAlpha = 1.691 + static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get()); 1.692 + 1.693 + TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11(); 1.694 + TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11(); 1.695 + 1.696 + if (!sourceOnWhite || !sourceOnBlack) { 1.697 + NS_WARNING("Missing texture source(s)!"); 1.698 + return; 1.699 + } 1.700 + 1.701 + SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, effectComponentAlpha->mOnWhite->GetFormat()); 1.702 + 1.703 + SetSamplerForFilter(effectComponentAlpha->mFilter); 1.704 + 1.705 + mVSConstants.textureCoords = effectComponentAlpha->mTextureCoords; 1.706 + RefPtr<ID3D11ShaderResourceView> views[2]; 1.707 + mDevice->CreateShaderResourceView(sourceOnBlack->GetD3D11Texture(), nullptr, byRef(views[0])); 1.708 + mDevice->CreateShaderResourceView(sourceOnWhite->GetD3D11Texture(), nullptr, byRef(views[1])); 1.709 + 1.710 + ID3D11ShaderResourceView* srViews[2] = { views[0], views[1] }; 1.711 + mContext->PSSetShaderResources(0, 2, srViews); 1.712 + 1.713 + mContext->OMSetBlendState(mAttachments->mComponentBlendState, sBlendFactor, 0xFFFFFFFF); 1.714 + restoreBlendMode = true; 1.715 + } 1.716 + break; 1.717 + default: 1.718 + NS_WARNING("Unknown shader type"); 1.719 + return; 1.720 + } 1.721 + UpdateConstantBuffers(); 1.722 + 1.723 + mContext->Draw(4, 0); 1.724 + if (restoreBlendMode) { 1.725 + mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF); 1.726 + } 1.727 +} 1.728 + 1.729 +void 1.730 +CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, 1.731 + const Rect* aClipRectIn, 1.732 + const gfx::Matrix& aTransform, 1.733 + const Rect& aRenderBounds, 1.734 + Rect* aClipRectOut, 1.735 + Rect* aRenderBoundsOut) 1.736 +{ 1.737 + // Don't composite if we are minimised. Other than for the sake of efficency, 1.738 + // this is important because resizing our buffers when mimised will fail and 1.739 + // cause a crash when we're restored. 1.740 + NS_ASSERTION(mHwnd, "Couldn't find an HWND when initialising?"); 1.741 + if (::IsIconic(mHwnd)) { 1.742 + *aRenderBoundsOut = Rect(); 1.743 + return; 1.744 + } 1.745 + 1.746 + UpdateRenderTarget(); 1.747 + 1.748 + // Failed to create a render target or the view. 1.749 + if (!mDefaultRT || !mDefaultRT->mRTView || 1.750 + mSize.width == 0 || mSize.height == 0) { 1.751 + *aRenderBoundsOut = Rect(); 1.752 + return; 1.753 + } 1.754 + 1.755 + mContext->IASetInputLayout(mAttachments->mInputLayout); 1.756 + 1.757 + ID3D11Buffer* buffer = mAttachments->mVertexBuffer; 1.758 + UINT size = sizeof(Vertex); 1.759 + UINT offset = 0; 1.760 + mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset); 1.761 + 1.762 + if (aClipRectOut) { 1.763 + *aClipRectOut = Rect(0, 0, mSize.width, mSize.height); 1.764 + } 1.765 + if (aRenderBoundsOut) { 1.766 + *aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height); 1.767 + } 1.768 + 1.769 + D3D11_RECT scissor; 1.770 + if (aClipRectIn) { 1.771 + scissor.left = aClipRectIn->x; 1.772 + scissor.right = aClipRectIn->XMost(); 1.773 + scissor.top = aClipRectIn->y; 1.774 + scissor.bottom = aClipRectIn->YMost(); 1.775 + } else { 1.776 + scissor.left = scissor.top = 0; 1.777 + scissor.right = mSize.width; 1.778 + scissor.bottom = mSize.height; 1.779 + } 1.780 + mContext->RSSetScissorRects(1, &scissor); 1.781 + 1.782 + FLOAT black[] = { 0, 0, 0, 0 }; 1.783 + mContext->ClearRenderTargetView(mDefaultRT->mRTView, black); 1.784 + 1.785 + mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF); 1.786 + mContext->RSSetState(mAttachments->mRasterizerState); 1.787 + 1.788 + SetRenderTarget(mDefaultRT); 1.789 +} 1.790 + 1.791 +void 1.792 +CompositorD3D11::EndFrame() 1.793 +{ 1.794 + mContext->Flush(); 1.795 + 1.796 + nsIntSize oldSize = mSize; 1.797 + EnsureSize(); 1.798 + if (oldSize == mSize) { 1.799 + mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0); 1.800 + mDisableSequenceForNextFrame = false; 1.801 + if (mTarget) { 1.802 + PaintToTarget(); 1.803 + } 1.804 + } 1.805 + 1.806 + mCurrentRT = nullptr; 1.807 +} 1.808 + 1.809 +void 1.810 +CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize, 1.811 + const gfx::Matrix& aWorldTransform) 1.812 +{ 1.813 + D3D11_VIEWPORT viewport; 1.814 + viewport.MaxDepth = 1.0f; 1.815 + viewport.MinDepth = 0; 1.816 + viewport.Width = aSize.width; 1.817 + viewport.Height = aSize.height; 1.818 + viewport.TopLeftX = 0; 1.819 + viewport.TopLeftY = 0; 1.820 + 1.821 + mContext->RSSetViewports(1, &viewport); 1.822 + 1.823 + Matrix viewMatrix; 1.824 + viewMatrix.Translate(-1.0, 1.0); 1.825 + viewMatrix.Scale(2.0f / float(aSize.width), 2.0f / float(aSize.height)); 1.826 + viewMatrix.Scale(1.0f, -1.0f); 1.827 + 1.828 + viewMatrix = aWorldTransform * viewMatrix; 1.829 + 1.830 + Matrix4x4 projection = Matrix4x4::From2D(viewMatrix); 1.831 + projection._33 = 0.0f; 1.832 + 1.833 + memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection)); 1.834 +} 1.835 + 1.836 +void 1.837 +CompositorD3D11::EnsureSize() 1.838 +{ 1.839 + nsIntRect rect; 1.840 + mWidget->GetClientBounds(rect); 1.841 + 1.842 + mSize = rect.Size(); 1.843 +} 1.844 + 1.845 +void 1.846 +CompositorD3D11::VerifyBufferSize() 1.847 +{ 1.848 + DXGI_SWAP_CHAIN_DESC swapDesc; 1.849 + mSwapChain->GetDesc(&swapDesc); 1.850 + 1.851 + if ((swapDesc.BufferDesc.Width == mSize.width && 1.852 + swapDesc.BufferDesc.Height == mSize.height) || 1.853 + mSize.width == 0 || mSize.height == 0) { 1.854 + return; 1.855 + } 1.856 + 1.857 + mDefaultRT = nullptr; 1.858 + 1.859 + if (IsRunningInWindowsMetro()) { 1.860 + mSwapChain->ResizeBuffers(2, mSize.width, mSize.height, 1.861 + DXGI_FORMAT_B8G8R8A8_UNORM, 1.862 + 0); 1.863 + mDisableSequenceForNextFrame = true; 1.864 + } else if (gfxWindowsPlatform::IsOptimus()) { 1.865 + mSwapChain->ResizeBuffers(1, mSize.width, mSize.height, 1.866 + DXGI_FORMAT_B8G8R8A8_UNORM, 1.867 + 0); 1.868 + } else { 1.869 + mSwapChain->ResizeBuffers(1, mSize.width, mSize.height, 1.870 + DXGI_FORMAT_B8G8R8A8_UNORM, 1.871 + DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE); 1.872 + } 1.873 +} 1.874 + 1.875 +void 1.876 +CompositorD3D11::UpdateRenderTarget() 1.877 +{ 1.878 + EnsureSize(); 1.879 + VerifyBufferSize(); 1.880 + 1.881 + if (mDefaultRT) { 1.882 + return; 1.883 + } 1.884 + 1.885 + HRESULT hr; 1.886 + 1.887 + nsRefPtr<ID3D11Texture2D> backBuf; 1.888 + 1.889 + hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment()); 1.890 + if (FAILED(hr)) { 1.891 + return; 1.892 + } 1.893 + 1.894 + mDefaultRT = new CompositingRenderTargetD3D11(backBuf, IntPoint(0, 0)); 1.895 + mDefaultRT->SetSize(mSize.ToIntSize()); 1.896 +} 1.897 + 1.898 +bool 1.899 +CompositorD3D11::CreateShaders() 1.900 +{ 1.901 + HRESULT hr; 1.902 + 1.903 + hr = mDevice->CreateVertexShader(LayerQuadVS, 1.904 + sizeof(LayerQuadVS), 1.905 + nullptr, 1.906 + byRef(mAttachments->mVSQuadShader[MaskNone])); 1.907 + if (FAILED(hr)) { 1.908 + return false; 1.909 + } 1.910 + 1.911 + hr = mDevice->CreateVertexShader(LayerQuadMaskVS, 1.912 + sizeof(LayerQuadMaskVS), 1.913 + nullptr, 1.914 + byRef(mAttachments->mVSQuadShader[Mask2d])); 1.915 + if (FAILED(hr)) { 1.916 + return false; 1.917 + } 1.918 + 1.919 + hr = mDevice->CreateVertexShader(LayerQuadMask3DVS, 1.920 + sizeof(LayerQuadMask3DVS), 1.921 + nullptr, 1.922 + byRef(mAttachments->mVSQuadShader[Mask3d])); 1.923 + if (FAILED(hr)) { 1.924 + return false; 1.925 + } 1.926 + 1.927 +#define LOAD_PIXEL_SHADER(x) hr = mDevice->CreatePixelShader(x, sizeof(x), nullptr, byRef(mAttachments->m##x[MaskNone])); \ 1.928 + if (FAILED(hr)) { \ 1.929 + return false; \ 1.930 + } \ 1.931 + hr = mDevice->CreatePixelShader(x##Mask, sizeof(x##Mask), nullptr, byRef(mAttachments->m##x[Mask2d])); \ 1.932 + if (FAILED(hr)) { \ 1.933 + return false; \ 1.934 + } 1.935 + 1.936 + LOAD_PIXEL_SHADER(SolidColorShader); 1.937 + LOAD_PIXEL_SHADER(RGBShader); 1.938 + LOAD_PIXEL_SHADER(RGBAShader); 1.939 + LOAD_PIXEL_SHADER(YCbCrShader); 1.940 + if (gfxPrefs::ComponentAlphaEnabled()) { 1.941 + LOAD_PIXEL_SHADER(ComponentAlphaShader); 1.942 + } 1.943 + 1.944 +#undef LOAD_PIXEL_SHADER 1.945 + 1.946 + hr = mDevice->CreatePixelShader(RGBAShaderMask3D, 1.947 + sizeof(RGBAShaderMask3D), 1.948 + nullptr, 1.949 + byRef(mAttachments->mRGBAShader[Mask3d])); 1.950 + if (FAILED(hr)) { 1.951 + return false; 1.952 + } 1.953 + 1.954 + return true; 1.955 +} 1.956 + 1.957 +void 1.958 +CompositorD3D11::UpdateConstantBuffers() 1.959 +{ 1.960 + D3D11_MAPPED_SUBRESOURCE resource; 1.961 + mContext->Map(mAttachments->mVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); 1.962 + *(VertexShaderConstants*)resource.pData = mVSConstants; 1.963 + mContext->Unmap(mAttachments->mVSConstantBuffer, 0); 1.964 + mContext->Map(mAttachments->mPSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); 1.965 + *(PixelShaderConstants*)resource.pData = mPSConstants; 1.966 + mContext->Unmap(mAttachments->mPSConstantBuffer, 0); 1.967 + 1.968 + ID3D11Buffer *buffer = mAttachments->mVSConstantBuffer; 1.969 + 1.970 + mContext->VSSetConstantBuffers(0, 1, &buffer); 1.971 + 1.972 + buffer = mAttachments->mPSConstantBuffer; 1.973 + mContext->PSSetConstantBuffers(0, 1, &buffer); 1.974 +} 1.975 + 1.976 +void 1.977 +CompositorD3D11::SetSamplerForFilter(Filter aFilter) 1.978 +{ 1.979 + ID3D11SamplerState *sampler; 1.980 + switch (aFilter) { 1.981 + default: 1.982 + case Filter::LINEAR: 1.983 + sampler = mAttachments->mLinearSamplerState; 1.984 + break; 1.985 + case Filter::POINT: 1.986 + sampler = mAttachments->mPointSamplerState; 1.987 + break; 1.988 + } 1.989 + 1.990 + mContext->PSSetSamplers(0, 1, &sampler); 1.991 +} 1.992 + 1.993 +void 1.994 +CompositorD3D11::PaintToTarget() 1.995 +{ 1.996 + nsRefPtr<ID3D11Texture2D> backBuf; 1.997 + 1.998 + mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment()); 1.999 + 1.1000 + D3D11_TEXTURE2D_DESC bbDesc; 1.1001 + backBuf->GetDesc(&bbDesc); 1.1002 + 1.1003 + CD3D11_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height); 1.1004 + softDesc.MipLevels = 1; 1.1005 + softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; 1.1006 + softDesc.Usage = D3D11_USAGE_STAGING; 1.1007 + softDesc.BindFlags = 0; 1.1008 + 1.1009 + nsRefPtr<ID3D11Texture2D> readTexture; 1.1010 + 1.1011 + HRESULT hr = mDevice->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture)); 1.1012 + mContext->CopyResource(readTexture, backBuf); 1.1013 + 1.1014 + D3D11_MAPPED_SUBRESOURCE map; 1.1015 + mContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &map); 1.1016 + RefPtr<DataSourceSurface> sourceSurface = 1.1017 + Factory::CreateWrappingDataSourceSurface((uint8_t*)map.pData, 1.1018 + map.RowPitch, 1.1019 + IntSize(bbDesc.Width, bbDesc.Height), 1.1020 + SurfaceFormat::B8G8R8A8); 1.1021 + mTarget->CopySurface(sourceSurface, 1.1022 + IntRect(0, 0, bbDesc.Width, bbDesc.Height), 1.1023 + IntPoint()); 1.1024 + mTarget->Flush(); 1.1025 + mContext->Unmap(readTexture, 0); 1.1026 +} 1.1027 + 1.1028 +} 1.1029 +}