forked from mirrors/gecko-dev
		
	 126bd9e1a4
			
		
	
	
		126bd9e1a4
		
	
	
	
	
		
			
			This patch was generated automatically by the "modeline.py" script, available here: https://github.com/amccreight/moz-source-tools/blob/master/modeline.py For every file that is modified in this patch, the changes are as follows: (1) The patch changes the file to use the exact C++ mode lines from the Mozilla coding style guide, available here: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Mode_Line (2) The patch deletes any blank lines between the mode line & the MPL boilerplate comment. (3) If the file previously had the mode lines and MPL boilerplate in a single contiguous C++ comment, then the patch splits them into separate C++ comments, to match the boilerplate in the coding style. MozReview-Commit-ID: 77D61xpSmIl --HG-- extra : rebase_source : c6162fa3cf539a07177a19838324bf368faa162b
		
			
				
	
	
		
			340 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			340 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "DeviceAttachmentsD3D11.h"
 | |
| #include "mozilla/Telemetry.h"
 | |
| #include "mozilla/layers/Compositor.h"
 | |
| #include "CompositorD3D11Shaders.h"
 | |
| #include "gfxPrefs.h"
 | |
| #include "ShaderDefinitionsD3D11.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace layers {
 | |
| 
 | |
| using namespace gfx;
 | |
| 
 | |
| static const size_t kInitialMaximumTriangles = 64;
 | |
| 
 | |
| DeviceAttachmentsD3D11::DeviceAttachmentsD3D11(ID3D11Device* device)
 | |
|  : mMaximumTriangles(kInitialMaximumTriangles),
 | |
|    mDevice(device),
 | |
|    mContinueInit(true),
 | |
|    mInitialized(false),
 | |
|    mDeviceReset(false)
 | |
| {
 | |
| }
 | |
| 
 | |
| DeviceAttachmentsD3D11::~DeviceAttachmentsD3D11()
 | |
| {
 | |
| }
 | |
| 
 | |
| /* static */ RefPtr<DeviceAttachmentsD3D11>
 | |
| DeviceAttachmentsD3D11::Create(ID3D11Device* aDevice)
 | |
| {
 | |
|   // We don't return null even if the attachments object even if it fails to
 | |
|   // initialize, so the compositor can grab the failure ID.
 | |
|   RefPtr<DeviceAttachmentsD3D11> attachments = new DeviceAttachmentsD3D11(aDevice);
 | |
|   attachments->Initialize();
 | |
|   return attachments.forget();
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::Initialize()
 | |
| {
 | |
|   D3D11_INPUT_ELEMENT_DESC layout[] =
 | |
|   {
 | |
|     { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 | |
|   };
 | |
| 
 | |
|   HRESULT hr;
 | |
|   hr = mDevice->CreateInputLayout(layout,
 | |
|                                   sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
 | |
|                                   LayerQuadVS,
 | |
|                                   sizeof(LayerQuadVS),
 | |
|                                   getter_AddRefs(mInputLayout));
 | |
| 
 | |
|   if (Failed(hr, "CreateInputLayout")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_INPUT_LAYOUT";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   Vertex vertices[] = { {{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}} };
 | |
|   CD3D11_BUFFER_DESC bufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
 | |
|   D3D11_SUBRESOURCE_DATA data;
 | |
|   data.pSysMem = (void*)vertices;
 | |
| 
 | |
|   hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer));
 | |
|   if (Failed(hr, "create vertex buffer")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Create a second input layout for layers with dynamic geometry.
 | |
|   D3D11_INPUT_ELEMENT_DESC dynamicLayout[] =
 | |
|   {
 | |
|     { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 | |
|     { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 | |
|   };
 | |
| 
 | |
|   hr = mDevice->CreateInputLayout(dynamicLayout,
 | |
|                                   sizeof(dynamicLayout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
 | |
|                                   LayerDynamicVS,
 | |
|                                   sizeof(LayerDynamicVS),
 | |
|                                   getter_AddRefs(mDynamicInputLayout));
 | |
| 
 | |
|   if (Failed(hr, "CreateInputLayout")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_INPUT_LAYOUT";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Allocate memory for the dynamic vertex buffer.
 | |
|   bufferDesc = CD3D11_BUFFER_DESC(sizeof(TexturedVertex) * mMaximumTriangles * 3,
 | |
|                                   D3D11_BIND_VERTEX_BUFFER,
 | |
|                                   D3D11_USAGE_DYNAMIC,
 | |
|                                   D3D11_CPU_ACCESS_WRITE);
 | |
| 
 | |
|   hr = mDevice->CreateBuffer(&bufferDesc, nullptr, getter_AddRefs(mDynamicVertexBuffer));
 | |
|   if (Failed(hr, "create dynamic vertex buffer")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (!CreateShaders()) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_CREATE_SHADERS";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   CD3D11_BUFFER_DESC cBufferDesc(sizeof(VertexShaderConstants),
 | |
|                                  D3D11_BIND_CONSTANT_BUFFER,
 | |
|                                  D3D11_USAGE_DYNAMIC,
 | |
|                                  D3D11_CPU_ACCESS_WRITE);
 | |
| 
 | |
|   hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, getter_AddRefs(mVSConstantBuffer));
 | |
|   if (Failed(hr, "create vs buffer")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_VS_BUFFER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   cBufferDesc.ByteWidth = sizeof(PixelShaderConstants);
 | |
|   hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, getter_AddRefs(mPSConstantBuffer));
 | |
|   if (Failed(hr, "create ps buffer")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_PS_BUFFER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   CD3D11_RASTERIZER_DESC rastDesc(D3D11_DEFAULT);
 | |
|   rastDesc.CullMode = D3D11_CULL_NONE;
 | |
|   rastDesc.ScissorEnable = TRUE;
 | |
| 
 | |
|   hr = mDevice->CreateRasterizerState(&rastDesc, getter_AddRefs(mRasterizerState));
 | |
|   if (Failed(hr, "create rasterizer")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_RASTERIZER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT);
 | |
|   hr = mDevice->CreateSamplerState(&samplerDesc, getter_AddRefs(mLinearSamplerState));
 | |
|   if (Failed(hr, "create linear sampler")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_LINEAR_SAMPLER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
 | |
|   hr = mDevice->CreateSamplerState(&samplerDesc, getter_AddRefs(mPointSamplerState));
 | |
|   if (Failed(hr, "create point sampler")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_POINT_SAMPLER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   CD3D11_BLEND_DESC blendDesc(D3D11_DEFAULT);
 | |
|   D3D11_RENDER_TARGET_BLEND_DESC rtBlendPremul = {
 | |
|     TRUE,
 | |
|     D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_COLOR_WRITE_ENABLE_ALL
 | |
|   };
 | |
|   blendDesc.RenderTarget[0] = rtBlendPremul;
 | |
|   hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mPremulBlendState));
 | |
|   if (Failed(hr, "create pm blender")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_PM_BLENDER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   D3D11_RENDER_TARGET_BLEND_DESC rtBlendNonPremul = {
 | |
|     TRUE,
 | |
|     D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_COLOR_WRITE_ENABLE_ALL
 | |
|   };
 | |
|   blendDesc.RenderTarget[0] = rtBlendNonPremul;
 | |
|   hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mNonPremulBlendState));
 | |
|   if (Failed(hr, "create npm blender")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_NPM_BLENDER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (gfxPrefs::ComponentAlphaEnabled()) {
 | |
|     D3D11_RENDER_TARGET_BLEND_DESC rtBlendComponent = {
 | |
|       TRUE,
 | |
|       D3D11_BLEND_ONE,
 | |
|       D3D11_BLEND_INV_SRC1_COLOR,
 | |
|       D3D11_BLEND_OP_ADD,
 | |
|       D3D11_BLEND_ONE,
 | |
|       D3D11_BLEND_INV_SRC_ALPHA,
 | |
|       D3D11_BLEND_OP_ADD,
 | |
|       D3D11_COLOR_WRITE_ENABLE_ALL
 | |
|     };
 | |
|     blendDesc.RenderTarget[0] = rtBlendComponent;
 | |
|     hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mComponentBlendState));
 | |
|     if (Failed(hr, "create component blender")) {
 | |
|       mInitFailureId = "FEATURE_FAILURE_D3D11_COMP_BLENDER";
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   D3D11_RENDER_TARGET_BLEND_DESC rtBlendDisabled = {
 | |
|     FALSE,
 | |
|     D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD,
 | |
|     D3D11_COLOR_WRITE_ENABLE_ALL
 | |
|   };
 | |
|   blendDesc.RenderTarget[0] = rtBlendDisabled;
 | |
|   hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mDisabledBlendState));
 | |
|   if (Failed(hr, "create null blender")) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_NULL_BLENDER";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (!InitSyncObject()) {
 | |
|     mInitFailureId = "FEATURE_FAILURE_D3D11_OBJ_SYNC";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   mInitialized = true;
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::InitSyncObject()
 | |
| {
 | |
|   // Sync object is not supported on WARP.
 | |
|   if (DeviceManagerDx::Get()->IsWARP()) {
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   MOZ_ASSERT(!mSyncObject);
 | |
|   MOZ_ASSERT(mDevice);
 | |
| 
 | |
|   mSyncObject = SyncObjectHost::CreateSyncObjectHost(mDevice);
 | |
|   MOZ_ASSERT(mSyncObject);
 | |
| 
 | |
|   return mSyncObject->Init();
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::InitBlendShaders()
 | |
| {
 | |
|   if (!mVSQuadBlendShader[MaskType::MaskNone]) {
 | |
|     InitVertexShader(sLayerQuadBlendVS, mVSQuadBlendShader, MaskType::MaskNone);
 | |
|     InitVertexShader(sLayerQuadBlendMaskVS, mVSQuadBlendShader, MaskType::Mask);
 | |
|   }
 | |
| 
 | |
|   if (!mVSDynamicBlendShader[MaskType::MaskNone]) {
 | |
|     InitVertexShader(sLayerDynamicBlendVS, mVSDynamicBlendShader, MaskType::MaskNone);
 | |
|     InitVertexShader(sLayerDynamicBlendMaskVS, mVSDynamicBlendShader, MaskType::Mask);
 | |
|   }
 | |
| 
 | |
|   if (!mBlendShader[MaskType::MaskNone]) {
 | |
|     InitPixelShader(sBlendShader, mBlendShader, MaskType::MaskNone);
 | |
|   }
 | |
|   return mContinueInit;
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::CreateShaders()
 | |
| {
 | |
|   InitVertexShader(sLayerQuadVS, mVSQuadShader, MaskType::MaskNone);
 | |
|   InitVertexShader(sLayerQuadMaskVS, mVSQuadShader, MaskType::Mask);
 | |
| 
 | |
|   InitVertexShader(sLayerDynamicVS, mVSDynamicShader, MaskType::MaskNone);
 | |
|   InitVertexShader(sLayerDynamicMaskVS, mVSDynamicShader, MaskType::Mask);
 | |
| 
 | |
|   InitPixelShader(sSolidColorShader, mSolidColorShader, MaskType::MaskNone);
 | |
|   InitPixelShader(sSolidColorShaderMask, mSolidColorShader, MaskType::Mask);
 | |
|   InitPixelShader(sRGBShader, mRGBShader, MaskType::MaskNone);
 | |
|   InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask);
 | |
|   InitPixelShader(sRGBAShader, mRGBAShader, MaskType::MaskNone);
 | |
|   InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask);
 | |
|   InitPixelShader(sYCbCrShader, mYCbCrShader, MaskType::MaskNone);
 | |
|   InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask);
 | |
|   InitPixelShader(sNV12Shader, mNV12Shader, MaskType::MaskNone);
 | |
|   InitPixelShader(sNV12ShaderMask, mNV12Shader, MaskType::Mask);
 | |
|   if (gfxPrefs::ComponentAlphaEnabled()) {
 | |
|     InitPixelShader(sComponentAlphaShader, mComponentAlphaShader, MaskType::MaskNone);
 | |
|     InitPixelShader(sComponentAlphaShaderMask, mComponentAlphaShader, MaskType::Mask);
 | |
|   }
 | |
| 
 | |
|   return mContinueInit;
 | |
| }
 | |
| 
 | |
| void
 | |
| DeviceAttachmentsD3D11::InitVertexShader(const ShaderBytes& aShader, ID3D11VertexShader** aOut)
 | |
| {
 | |
|   if (!mContinueInit) {
 | |
|     return;
 | |
|   }
 | |
|   if (Failed(mDevice->CreateVertexShader(aShader.mData, aShader.mLength, nullptr, aOut), "create vs")) {
 | |
|     mContinueInit = false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void
 | |
| DeviceAttachmentsD3D11::InitPixelShader(const ShaderBytes& aShader, ID3D11PixelShader** aOut)
 | |
| {
 | |
|   if (!mContinueInit) {
 | |
|     return;
 | |
|   }
 | |
|   if (Failed(mDevice->CreatePixelShader(aShader.mData, aShader.mLength, nullptr, aOut), "create ps")) {
 | |
|     mContinueInit = false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::Failed(HRESULT hr, const char* aContext)
 | |
| {
 | |
|   if (SUCCEEDED(hr)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool
 | |
| DeviceAttachmentsD3D11::EnsureTriangleBuffer(size_t aNumTriangles)
 | |
| {
 | |
|   if (aNumTriangles > mMaximumTriangles) {
 | |
|     CD3D11_BUFFER_DESC bufferDesc(sizeof(TexturedVertex) * aNumTriangles * 3,
 | |
|                                   D3D11_BIND_VERTEX_BUFFER,
 | |
|                                   D3D11_USAGE_DYNAMIC,
 | |
|                                   D3D11_CPU_ACCESS_WRITE);
 | |
| 
 | |
|     HRESULT hr =
 | |
|       mDevice->CreateBuffer(&bufferDesc, nullptr, getter_AddRefs(mDynamicVertexBuffer));
 | |
| 
 | |
|     if (Failed(hr, "resize dynamic vertex buffer")) {
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     mMaximumTriangles = aNumTriangles;
 | |
|   }
 | |
| 
 | |
|   MOZ_ASSERT(mMaximumTriangles >= aNumTriangles);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| } // namespace layers
 | |
| } // namespace mozilla
 |