зеркало из https://github.com/mozilla/gecko-dev.git
Bug 830347 - Part 2: Add the code for CompositorD3D11. r=jrmuizel
This commit is contained in:
Родитель
34f8ad7af9
Коммит
745964b1cd
|
@ -37,6 +37,7 @@ enum LayersBackend {
|
|||
LAYERS_OPENGL,
|
||||
LAYERS_D3D9,
|
||||
LAYERS_D3D10,
|
||||
LAYERS_D3D11,
|
||||
LAYERS_CLIENT,
|
||||
LAYERS_LAST
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ VPATH = \
|
|||
$(srcdir)/opengl \
|
||||
$(srcdir)/d3d9 \
|
||||
$(srcdir)/d3d10 \
|
||||
$(srcdir)/d3d11 \
|
||||
$(srcdir)/ipc \
|
||||
$(NULL)
|
||||
|
||||
|
@ -97,11 +98,13 @@ ifdef MOZ_ENABLE_D3D10_LAYER
|
|||
CPPSRCS += \
|
||||
CanvasLayerD3D10.cpp \
|
||||
ColorLayerD3D10.cpp \
|
||||
CompositorD3D11.cpp \
|
||||
ContainerLayerD3D10.cpp \
|
||||
ImageLayerD3D10.cpp \
|
||||
LayerManagerD3D10.cpp \
|
||||
ReadbackManagerD3D10.cpp \
|
||||
ShadowLayerUtilsD3D10.cpp \
|
||||
TextureD3D11.cpp \
|
||||
ThebesLayerD3D10.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -96,17 +100,20 @@ CompositableClient::CreateTextureClient(TextureClientType aTextureClientType)
|
|||
}
|
||||
break;
|
||||
case TEXTURE_YCBCR:
|
||||
if (parentBackend == LAYERS_OPENGL) {
|
||||
if (parentBackend == LAYERS_OPENGL || parentBackend == LAYERS_D3D11) {
|
||||
result = new TextureClientShmemYCbCr(GetForwarder(), GetTextureInfo());
|
||||
}
|
||||
break;
|
||||
case TEXTURE_CONTENT:
|
||||
#ifdef XP_WIN
|
||||
if (parentBackend == LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice()) {
|
||||
result = new TextureClientD3D11(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through to TEXTURE_SHMEM
|
||||
case TEXTURE_SHMEM:
|
||||
if (parentBackend == LAYERS_OPENGL ||
|
||||
parentBackend == LAYERS_BASIC) {
|
||||
result = new TextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
}
|
||||
result = new TextureClientShmem(GetForwarder(), GetTextureInfo());
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unhandled texture client type");
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include "gfxUtils.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#ifdef XP_WIN
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -21,11 +24,23 @@ namespace layers {
|
|||
ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
||||
{
|
||||
if (aForwarder->GetCompositorBackendType() != LAYERS_OPENGL &&
|
||||
aForwarder->GetCompositorBackendType() != LAYERS_D3D11 &&
|
||||
aForwarder->GetCompositorBackendType() != LAYERS_BASIC) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
if (LayerManagerComposite::SupportsDirectTexturing() ||
|
||||
PR_GetEnv("MOZ_FORCE_DOUBLE_BUFFERING")) {
|
||||
|
||||
bool useDoubleBuffering = false;
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (aForwarder->GetCompositorBackendType() == LAYERS_D3D11) {
|
||||
useDoubleBuffering = !!gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
useDoubleBuffering = LayerManagerComposite::SupportsDirectTexturing();
|
||||
}
|
||||
|
||||
if (useDoubleBuffering || PR_GetEnv("MOZ_FORCE_DOUBLE_BUFFERING")) {
|
||||
return new ContentClientDoubleBuffered(aForwarder);
|
||||
}
|
||||
return new ContentClientSingleBuffered(aForwarder);
|
||||
|
|
|
@ -28,19 +28,13 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
|
|||
RefPtr<ImageClient> result = nullptr;
|
||||
switch (aCompositableHostType) {
|
||||
case BUFFER_IMAGE_SINGLE:
|
||||
if (ImageClientSingle::SupportsBackend(aForwarder->GetCompositorBackendType())) {
|
||||
result = new ImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_SINGLE);
|
||||
}
|
||||
result = new ImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_SINGLE);
|
||||
break;
|
||||
case BUFFER_IMAGE_BUFFERED:
|
||||
if (ImageClientSingle::SupportsBackend(aForwarder->GetCompositorBackendType())) {
|
||||
result = new ImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_BUFFERED);
|
||||
}
|
||||
result = new ImageClientSingle(aForwarder, aFlags, BUFFER_IMAGE_BUFFERED);
|
||||
break;
|
||||
case BUFFER_BRIDGE:
|
||||
if (ImageClientBridge::SupportsBackend(aForwarder->GetCompositorBackendType())) {
|
||||
result = new ImageClientBridge(aForwarder, aFlags);
|
||||
}
|
||||
result = new ImageClientBridge(aForwarder, aFlags);
|
||||
break;
|
||||
case BUFFER_UNKNOWN:
|
||||
result = nullptr;
|
||||
|
@ -224,26 +218,6 @@ ImageClientSingle::Updated()
|
|||
mForwarder->UpdateTexture(this, 1, mTextureClient->GetDescriptor());
|
||||
}
|
||||
|
||||
bool
|
||||
ImageClientSingle::SupportsBackend(LayersBackend aBackend)
|
||||
{
|
||||
if (aBackend == LAYERS_OPENGL ||
|
||||
aBackend == LAYERS_BASIC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ImageClientBridge::SupportsBackend(LayersBackend aBackend)
|
||||
{
|
||||
if (aBackend == LAYERS_OPENGL ||
|
||||
aBackend == LAYERS_BASIC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,
|
||||
TextureFlags aFlags)
|
||||
: ImageClient(aFwd, BUFFER_BRIDGE)
|
||||
|
|
|
@ -102,8 +102,6 @@ public:
|
|||
return mTextureInfo;
|
||||
}
|
||||
|
||||
static bool SupportsBackend(LayersBackend aBackend);
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
TextureInfo mTextureInfo;
|
||||
|
@ -133,8 +131,6 @@ public:
|
|||
return TextureInfo(mType);
|
||||
}
|
||||
|
||||
static bool SupportsBackend(LayersBackend aBackend);
|
||||
|
||||
protected:
|
||||
uint64_t mAsyncContainerID;
|
||||
ShadowableLayer* mLayer;
|
||||
|
|
|
@ -28,6 +28,12 @@ TemporaryRef<TextureHost> CreateTextureHostD3D9(SurfaceDescriptorType aDescripto
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
TemporaryRef<TextureHost> CreateTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aTextureHostFlags,
|
||||
uint32_t aTextureFlags);
|
||||
#endif
|
||||
|
||||
/* static */ TemporaryRef<TextureHost>
|
||||
TextureHost::CreateTextureHost(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aTextureHostFlags,
|
||||
|
@ -42,6 +48,12 @@ TextureHost::CreateTextureHost(SurfaceDescriptorType aDescriptorType,
|
|||
return CreateTextureHostD3D9(aDescriptorType,
|
||||
aTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#ifdef XP_WIN
|
||||
case LAYERS_D3D11:
|
||||
return CreateTextureHostD3D11(aDescriptorType,
|
||||
aTextureHostFlags,
|
||||
aTextureFlags);
|
||||
#endif
|
||||
case LAYERS_BASIC:
|
||||
return CreateBasicTextureHost(aDescriptorType,
|
||||
aTextureHostFlags,
|
||||
|
|
|
@ -25,6 +25,7 @@ class Compositor;
|
|||
class SurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureSourceOGL;
|
||||
class TextureSourceD3D11;
|
||||
class TextureSourceBasic;
|
||||
class TextureParent;
|
||||
|
||||
|
@ -78,6 +79,11 @@ public:
|
|||
*/
|
||||
virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Cast to an TextureSource for the D3D11 backend.
|
||||
*/
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
|
||||
|
||||
virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,782 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "CompositorD3D11.h"
|
||||
|
||||
#include "TextureD3D11.h"
|
||||
#include "CompositorD3D11Shaders.h"
|
||||
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/layers/ImageHost.h"
|
||||
#include "mozilla/layers/ContentHost.h"
|
||||
#include "mozilla/layers/Effects.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#ifdef MOZ_METRO
|
||||
#include <DXGI1_2.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
float position[2];
|
||||
};
|
||||
|
||||
// {1E4D7BEB-D8EC-4A0B-BF0A-63E6DE129425}
|
||||
static const GUID sDeviceAttachmentsD3D11 =
|
||||
{ 0x1e4d7beb, 0xd8ec, 0x4a0b, { 0xbf, 0xa, 0x63, 0xe6, 0xde, 0x12, 0x94, 0x25 } };
|
||||
// {88041664-C835-4AA8-ACB8-7EC832357ED8}
|
||||
static const GUID sLayerManagerCount =
|
||||
{ 0x88041664, 0xc835, 0x4aa8, { 0xac, 0xb8, 0x7e, 0xc8, 0x32, 0x35, 0x7e, 0xd8 } };
|
||||
|
||||
const FLOAT sBlendFactor[] = { 0, 0, 0, 0 };
|
||||
|
||||
struct DeviceAttachmentsD3D11
|
||||
{
|
||||
RefPtr<ID3D11InputLayout> mInputLayout;
|
||||
RefPtr<ID3D11Buffer> mVertexBuffer;
|
||||
RefPtr<ID3D11VertexShader> mVSQuadShader[3];
|
||||
RefPtr<ID3D11PixelShader> mSolidColorShader[2];
|
||||
RefPtr<ID3D11PixelShader> mRGBAShader[3];
|
||||
RefPtr<ID3D11PixelShader> mRGBShader[2];
|
||||
RefPtr<ID3D11PixelShader> mYCbCrShader[2];
|
||||
RefPtr<ID3D11Buffer> mPSConstantBuffer;
|
||||
RefPtr<ID3D11Buffer> mVSConstantBuffer;
|
||||
RefPtr<ID3D11RasterizerState> mRasterizerState;
|
||||
RefPtr<ID3D11SamplerState> mLinearSamplerState;
|
||||
RefPtr<ID3D11SamplerState> mPointSamplerState;
|
||||
RefPtr<ID3D11BlendState> mPremulBlendState;
|
||||
RefPtr<ID3D11BlendState> mNonPremulBlendState;
|
||||
};
|
||||
|
||||
CompositorD3D11::CompositorD3D11(nsIWidget *aWidget)
|
||||
: mWidget(aWidget)
|
||||
, mAttachments(nullptr)
|
||||
{
|
||||
sBackend = LAYERS_D3D11;
|
||||
}
|
||||
|
||||
CompositorD3D11::~CompositorD3D11()
|
||||
{
|
||||
if (mDevice) {
|
||||
int referenceCount = 0;
|
||||
UINT size = sizeof(referenceCount);
|
||||
HRESULT hr = mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
|
||||
NS_ASSERTION(SUCCEEDED(hr), "Reference count not found on device.");
|
||||
referenceCount--;
|
||||
mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
|
||||
|
||||
if (!referenceCount) {
|
||||
DeviceAttachmentsD3D11 *attachments;
|
||||
size = sizeof(attachments);
|
||||
mDevice->GetPrivateData(sDeviceAttachmentsD3D11, &size, &attachments);
|
||||
// No LayerManagers left for this device. Clear out interfaces stored which
|
||||
// hold a reference to the device.
|
||||
mDevice->SetPrivateData(sDeviceAttachmentsD3D11, 0, NULL);
|
||||
|
||||
delete attachments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorD3D11::Initialize()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
|
||||
|
||||
if (!mDevice) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mDevice->GetImmediateContext(byRef(mContext));
|
||||
|
||||
if (!mContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&mVSConstants, 0, sizeof(VertexShaderConstants));
|
||||
|
||||
int referenceCount = 0;
|
||||
UINT size = sizeof(referenceCount);
|
||||
// If this isn't there yet it'll fail, count will remain 0, which is correct.
|
||||
mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
|
||||
referenceCount++;
|
||||
mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
|
||||
|
||||
size = sizeof(DeviceAttachmentsD3D11*);
|
||||
if (FAILED(mDevice->GetPrivateData(sDeviceAttachmentsD3D11, &size, &mAttachments))) {
|
||||
mAttachments = new DeviceAttachmentsD3D11;
|
||||
mDevice->SetPrivateData(sDeviceAttachmentsD3D11, sizeof(mAttachments), &mAttachments);
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
|
||||
hr = mDevice->CreateInputLayout(layout,
|
||||
sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
|
||||
LayerQuadVS,
|
||||
sizeof(LayerQuadVS),
|
||||
byRef(mAttachments->mInputLayout));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
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, byRef(mAttachments->mVertexBuffer));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateShaders()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CD3D11_BUFFER_DESC cBufferDesc(sizeof(VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER,
|
||||
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
|
||||
hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mVSConstantBuffer));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cBufferDesc.ByteWidth = sizeof(PixelShaderConstants);
|
||||
hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mPSConstantBuffer));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CD3D11_RASTERIZER_DESC rastDesc(D3D11_DEFAULT);
|
||||
rastDesc.CullMode = D3D11_CULL_NONE;
|
||||
rastDesc.ScissorEnable = TRUE;
|
||||
|
||||
hr = mDevice->CreateRasterizerState(&rastDesc, byRef(mAttachments->mRasterizerState));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT);
|
||||
samplerDesc.AddressU = samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mLinearSamplerState));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
hr = mDevice->CreateSamplerState(&samplerDesc, byRef(mAttachments->mPointSamplerState));
|
||||
if (FAILED(hr)) {
|
||||
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, byRef(mAttachments->mPremulBlendState));
|
||||
if (FAILED(hr)) {
|
||||
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, byRef(mAttachments->mNonPremulBlendState));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
||||
|
||||
mDevice->QueryInterface(dxgiDevice.StartAssignment());
|
||||
dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));
|
||||
|
||||
#ifdef MOZ_METRO
|
||||
if (IsRunningInWindowsMetro()) {
|
||||
nsRefPtr<IDXGIFactory2> dxgiFactory;
|
||||
dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapDesc = { 0 };
|
||||
// Automatically detect the width and the height from the winrt CoreWindow
|
||||
swapDesc.Width = rect.width;
|
||||
swapDesc.Height = rect.height;
|
||||
// This is the most common swapchain format
|
||||
swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
swapDesc.Stereo = false;
|
||||
// Don't use multi-sampling
|
||||
swapDesc.SampleDesc.Count = 1;
|
||||
swapDesc.SampleDesc.Quality = 0;
|
||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
// Use double buffering to enable flip
|
||||
swapDesc.BufferCount = 2;
|
||||
swapDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
// All Metro style apps must use this SwapEffect
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapDesc.Flags = 0;
|
||||
|
||||
/**
|
||||
* Create a swap chain, this swap chain will contain the backbuffer for
|
||||
* the window we draw to. The front buffer is the full screen front
|
||||
* buffer.
|
||||
*/
|
||||
nsRefPtr<IDXGISwapChain1> swapChain1;
|
||||
hr = dxgiFactory->CreateSwapChainForCoreWindow(
|
||||
dxgiDevice, (IUnknown *)mWidget->GetNativeData(NS_NATIVE_ICOREWINDOW),
|
||||
&swapDesc, nullptr, getter_AddRefs(swapChain1));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
mSwapChain = swapChain1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nsRefPtr<IDXGIFactory> dxgiFactory;
|
||||
dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
::ZeroMemory(&swapDesc, sizeof(swapDesc));
|
||||
swapDesc.BufferDesc.Width = 0;
|
||||
swapDesc.BufferDesc.Height = 0;
|
||||
swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
swapDesc.SampleDesc.Count = 1;
|
||||
swapDesc.SampleDesc.Quality = 0;
|
||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapDesc.BufferCount = 1;
|
||||
swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
swapDesc.Windowed = TRUE;
|
||||
// We don't really need this flag, however it seems on some NVidia hardware
|
||||
// smaller area windows do not present properly without this flag. This flag
|
||||
// should have no negative consequences by itself. See bug 613790. This flag
|
||||
// is broken on optimus devices. As a temporary solution we don't set it
|
||||
// there, the only way of reliably detecting we're on optimus is looking for
|
||||
// the DLL. See Bug 623807.
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
swapDesc.Flags = 0;
|
||||
} else {
|
||||
swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a swap chain, this swap chain will contain the backbuffer for
|
||||
* the window we draw to. The front buffer is the full screen front
|
||||
* buffer.
|
||||
*/
|
||||
hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, byRef(mSwapChain));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need this because we don't want DXGI to respond to Alt+Enter.
|
||||
dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow, DXGI_MWA_NO_WINDOW_CHANGES);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureFactoryIdentifier
|
||||
CompositorD3D11::GetTextureFactoryIdentifier()
|
||||
{
|
||||
TextureFactoryIdentifier ident;
|
||||
ident.mMaxTextureSize = GetMaxTextureSize();
|
||||
ident.mParentBackend = LAYERS_D3D11;
|
||||
return ident;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorD3D11::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
|
||||
{
|
||||
int32_t maxTextureSize = GetMaxTextureSize();
|
||||
|
||||
if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
CompositorD3D11::GetMaxTextureSize() const
|
||||
{
|
||||
return GetMaxTextureSizeForFeatureLevel(mFeatureLevel);
|
||||
}
|
||||
|
||||
TemporaryRef<CompositingRenderTarget>
|
||||
CompositorD3D11::CreateRenderTarget(const gfx::IntRect &aRect,
|
||||
SurfaceInitMode aInit)
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aRect.width, aRect.height, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
mDevice->CreateTexture2D(&desc, NULL, byRef(texture));
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D11> rt = new CompositingRenderTargetD3D11(texture);
|
||||
rt->SetSize(IntSize(aRect.width, aRect.height));
|
||||
|
||||
if (aInit == INIT_MODE_CLEAR) {
|
||||
FLOAT clear[] = { 0, 0, 0, 0 };
|
||||
mContext->ClearRenderTargetView(rt->mRTView, clear);
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
// TODO[Bas] this method doesn't actually use aSource
|
||||
TemporaryRef<CompositingRenderTarget>
|
||||
CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect,
|
||||
const CompositingRenderTarget *aSource)
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aRect.width, aRect.height, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
mDevice->CreateTexture2D(&desc, NULL, byRef(texture));
|
||||
|
||||
RefPtr<CompositingRenderTargetD3D11> rt = new CompositingRenderTargetD3D11(texture);
|
||||
rt->SetSize(IntSize(aRect.width, aRect.height));
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::SetRenderTarget(CompositingRenderTarget *aRenderTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRenderTarget);
|
||||
CompositingRenderTargetD3D11 *newRT =
|
||||
static_cast<CompositingRenderTargetD3D11*>(aRenderTarget);
|
||||
ID3D11RenderTargetView *view = newRT->mRTView;
|
||||
mCurrentRT = newRT;
|
||||
mContext->OMSetRenderTargets(1, &view, nullptr);
|
||||
PrepareViewport(newRT->GetSize(), gfxMatrix());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::SetPSForEffect(Effect *aEffect, MaskMode aMaskMode)
|
||||
{
|
||||
switch (aEffect->mType) {
|
||||
case EFFECT_SOLID_COLOR:
|
||||
mContext->PSSetShader(mAttachments->mSolidColorShader[aMaskMode], nullptr, 0);
|
||||
return;
|
||||
case EFFECT_BGRA:
|
||||
case EFFECT_RENDER_TARGET:
|
||||
mContext->PSSetShader(mAttachments->mRGBAShader[aMaskMode], nullptr, 0);
|
||||
return;
|
||||
case EFFECT_BGRX:
|
||||
mContext->PSSetShader(mAttachments->mRGBShader[aMaskMode], nullptr, 0);
|
||||
return;
|
||||
case EFFECT_YCBCR:
|
||||
mContext->PSSetShader(mAttachments->mYCbCrShader[aMaskMode], nullptr, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::DrawQuad(const gfx::Rect &aRect, const gfx::Rect &aClipRect,
|
||||
const EffectChain &aEffectChain,
|
||||
gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform,
|
||||
const gfx::Point &aOffset)
|
||||
{
|
||||
MOZ_ASSERT(mCurrentRT, "No render target");
|
||||
memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
|
||||
mVSConstants.renderTargetOffset[0] = aOffset.x;
|
||||
mVSConstants.renderTargetOffset[1] = aOffset.y;
|
||||
mVSConstants.layerQuad = aRect;
|
||||
|
||||
mPSConstants.layerOpacity[0] = aOpacity;
|
||||
|
||||
bool isPremultiplied = true;
|
||||
|
||||
MaskMode maskMode = UNMASKED;
|
||||
|
||||
if (aEffectChain.mSecondaryEffects[EFFECT_MASK]) {
|
||||
if (aTransform.Is2D()) {
|
||||
maskMode = MASKED;
|
||||
} else {
|
||||
MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EFFECT_BGRA);
|
||||
maskMode = MASKED3D;
|
||||
}
|
||||
|
||||
EffectMask *maskEffect = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get());
|
||||
TextureSourceD3D11 *source = maskEffect->mMaskTexture->AsSourceD3D11();
|
||||
|
||||
RefPtr<ID3D11ShaderResourceView> view;
|
||||
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
|
||||
|
||||
ID3D11ShaderResourceView *srView = view;
|
||||
mContext->PSSetShaderResources(3, 1, &srView);
|
||||
|
||||
const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform;
|
||||
NS_ASSERTION(maskTransform.Is2D(), "How did we end up with a 3D transform here?!");
|
||||
Rect bounds = Rect(Point(), Size(maskEffect->mSize));
|
||||
|
||||
mVSConstants.maskQuad = maskTransform.As2D().TransformBounds(bounds);
|
||||
}
|
||||
|
||||
|
||||
D3D11_RECT scissor;
|
||||
scissor.left = aClipRect.x;
|
||||
scissor.right = aClipRect.XMost();
|
||||
scissor.top = aClipRect.y;
|
||||
scissor.bottom = aClipRect.YMost();
|
||||
mContext->RSSetScissorRects(1, &scissor);
|
||||
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
mContext->VSSetShader(mAttachments->mVSQuadShader[maskMode], nullptr, 0);
|
||||
|
||||
SetPSForEffect(aEffectChain.mPrimaryEffect, maskMode);
|
||||
|
||||
switch (aEffectChain.mPrimaryEffect->mType) {
|
||||
case EFFECT_SOLID_COLOR: {
|
||||
Color color =
|
||||
static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
|
||||
mPSConstants.layerColor[0] = color.r * color.a * aOpacity;
|
||||
mPSConstants.layerColor[1] = color.g * color.a * aOpacity;
|
||||
mPSConstants.layerColor[2] = color.b * color.a * aOpacity;
|
||||
mPSConstants.layerColor[3] = color.a * aOpacity;
|
||||
}
|
||||
break;
|
||||
case EFFECT_BGRX:
|
||||
case EFFECT_BGRA:
|
||||
case EFFECT_RENDER_TARGET:
|
||||
{
|
||||
TexturedEffect *texturedEffect = static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
|
||||
|
||||
mVSConstants.textureCoords = texturedEffect->mTextureCoords;
|
||||
|
||||
TextureSourceD3D11 *source = texturedEffect->mTexture->AsSourceD3D11();
|
||||
|
||||
RefPtr<ID3D11ShaderResourceView> view;
|
||||
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
|
||||
|
||||
ID3D11ShaderResourceView *srView = view;
|
||||
mContext->PSSetShaderResources(0, 1, &srView);
|
||||
|
||||
isPremultiplied = texturedEffect->mPremultiplied;
|
||||
|
||||
SetSamplerForFilter(texturedEffect->mFilter);
|
||||
}
|
||||
break;
|
||||
case EFFECT_YCBCR: {
|
||||
EffectYCbCr *ycbcrEffect = static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get());
|
||||
|
||||
SetSamplerForFilter(FILTER_LINEAR);
|
||||
|
||||
mVSConstants.textureCoords = ycbcrEffect->mTextureCoords;
|
||||
|
||||
TextureSourceD3D11 *source = ycbcrEffect->mTexture->AsSourceD3D11();
|
||||
TextureSourceD3D11::YCbCrTextures textures = source->GetYCbCrTextures();
|
||||
|
||||
RefPtr<ID3D11ShaderResourceView> views[3];
|
||||
mDevice->CreateShaderResourceView(textures.mY, nullptr, byRef(views[0]));
|
||||
mDevice->CreateShaderResourceView(textures.mCb, nullptr, byRef(views[1]));
|
||||
mDevice->CreateShaderResourceView(textures.mCr, nullptr, byRef(views[2]));
|
||||
|
||||
ID3D11ShaderResourceView *srViews[3] = { views[0], views[1], views[2] };
|
||||
mContext->PSSetShaderResources(0, 3, srViews);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
UpdateConstantBuffers();
|
||||
|
||||
if (!isPremultiplied) {
|
||||
mContext->OMSetBlendState(mAttachments->mNonPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
mContext->Draw(4, 0);
|
||||
if (!isPremultiplied) {
|
||||
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::BeginFrame(const Rect *aClipRectIn,
|
||||
const gfxMatrix& aTransform,
|
||||
const Rect& aRenderBounds,
|
||||
Rect *aClipRectOut,
|
||||
Rect *aRenderBoundsOut)
|
||||
{
|
||||
VerifyBufferSize();
|
||||
UpdateRenderTarget();
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
if (rect.IsEmpty()) {
|
||||
*aRenderBoundsOut = Rect();
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT->SetSize(IntSize(rect.width, rect.height));
|
||||
|
||||
mContext->IASetInputLayout(mAttachments->mInputLayout);
|
||||
|
||||
ID3D11Buffer *buffer = mAttachments->mVertexBuffer;
|
||||
UINT size = sizeof(Vertex);
|
||||
UINT offset = 0;
|
||||
mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
|
||||
SetRenderTarget(mDefaultRT);
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, rect.width, rect.height);
|
||||
}
|
||||
if (aRenderBoundsOut) {
|
||||
*aRenderBoundsOut = Rect(0, 0, rect.width, rect.height);
|
||||
}
|
||||
|
||||
FLOAT black[] = { 0, 0, 0, 0 };
|
||||
mContext->ClearRenderTargetView(mDefaultRT->mRTView, black);
|
||||
|
||||
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
mContext->RSSetState(mAttachments->mRasterizerState);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::EndFrame()
|
||||
{
|
||||
mContext->Flush();
|
||||
mSwapChain->Present(0, 0);
|
||||
|
||||
if (mTarget) {
|
||||
PaintToTarget();
|
||||
}
|
||||
mCurrentRT = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
|
||||
const gfxMatrix &aWorldTransform)
|
||||
{
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
viewport.MinDepth = 0;
|
||||
viewport.Width = aSize.width;
|
||||
viewport.Height = aSize.height;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
|
||||
mContext->RSSetViewports(1, &viewport);
|
||||
|
||||
gfxMatrix viewMatrix;
|
||||
viewMatrix.Translate(-gfxPoint(1.0, -1.0));
|
||||
viewMatrix.Scale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
|
||||
viewMatrix.Scale(1.0f, -1.0f);
|
||||
|
||||
viewMatrix = aWorldTransform * viewMatrix;
|
||||
|
||||
gfx3DMatrix projection = gfx3DMatrix::From2D(viewMatrix);
|
||||
projection._33 = 0.0f;
|
||||
|
||||
memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection));
|
||||
}
|
||||
|
||||
const nsIntSize&
|
||||
CompositorD3D11::GetWidgetSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mSize = rect.Size();
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::VerifyBufferSize()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
mSwapChain->GetDesc(&swapDesc);
|
||||
|
||||
if ((swapDesc.BufferDesc.Width == rect.width &&
|
||||
swapDesc.BufferDesc.Height == rect.height) || rect.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT = nullptr;
|
||||
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
} else if (IsRunningInWindowsMetro()) {
|
||||
mSwapChain->ResizeBuffers(2, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
} else {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::UpdateRenderTarget()
|
||||
{
|
||||
if (mDefaultRT) {
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
nsRefPtr<ID3D11Texture2D> backBuf;
|
||||
|
||||
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment());
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDefaultRT = new CompositingRenderTargetD3D11(nullptr);
|
||||
mDevice->CreateRenderTargetView(backBuf, NULL, byRef(mDefaultRT->mRTView));
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorD3D11::CreateShaders()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
|
||||
hr = mDevice->CreateVertexShader(LayerQuadVS, sizeof(LayerQuadVS), nullptr, byRef(mAttachments->mVSQuadShader[UNMASKED]));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader(LayerQuadMaskVS, sizeof(LayerQuadMaskVS), nullptr, byRef(mAttachments->mVSQuadShader[MASKED]));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader(LayerQuadMask3DVS, sizeof(LayerQuadMask3DVS), nullptr, byRef(mAttachments->mVSQuadShader[MASKED3D]));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define LOAD_PIXEL_SHADER(x) hr = mDevice->CreatePixelShader(x, sizeof(x), nullptr, byRef(mAttachments->m##x[UNMASKED])); \
|
||||
if (FAILED(hr)) { \
|
||||
return false; \
|
||||
} \
|
||||
hr = mDevice->CreatePixelShader(x##Mask, sizeof(x##Mask), nullptr, byRef(mAttachments->m##x[MASKED])); \
|
||||
if (FAILED(hr)) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
LOAD_PIXEL_SHADER(SolidColorShader);
|
||||
LOAD_PIXEL_SHADER(RGBShader);
|
||||
LOAD_PIXEL_SHADER(RGBAShader);
|
||||
LOAD_PIXEL_SHADER(YCbCrShader);
|
||||
|
||||
#undef LOAD_PIXEL_SHADER
|
||||
|
||||
hr = mDevice->CreatePixelShader(RGBAShaderMask3D, sizeof(RGBAShaderMask3D), nullptr, byRef(mAttachments->mRGBAShader[MASKED3D]));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::UpdateConstantBuffers()
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
mContext->Map(mAttachments->mVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
*(VertexShaderConstants*)resource.pData = mVSConstants;
|
||||
mContext->Unmap(mAttachments->mVSConstantBuffer, 0);
|
||||
mContext->Map(mAttachments->mPSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
*(PixelShaderConstants*)resource.pData = mPSConstants;
|
||||
mContext->Unmap(mAttachments->mPSConstantBuffer, 0);
|
||||
|
||||
ID3D11Buffer *buffer = mAttachments->mVSConstantBuffer;
|
||||
|
||||
mContext->VSSetConstantBuffers(0, 1, &buffer);
|
||||
|
||||
buffer = mAttachments->mPSConstantBuffer;
|
||||
mContext->PSSetConstantBuffers(0, 1, &buffer);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::SetSamplerForFilter(Filter aFilter)
|
||||
{
|
||||
ID3D11SamplerState *sampler;
|
||||
switch (aFilter) {
|
||||
case FILTER_LINEAR:
|
||||
sampler = mAttachments->mLinearSamplerState;
|
||||
break;
|
||||
case FILTER_POINT:
|
||||
sampler = mAttachments->mPointSamplerState;
|
||||
break;
|
||||
}
|
||||
|
||||
mContext->PSSetSamplers(0, 1, &sampler);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorD3D11::PaintToTarget()
|
||||
{
|
||||
nsRefPtr<ID3D11Texture2D> backBuf;
|
||||
|
||||
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment());
|
||||
|
||||
D3D11_TEXTURE2D_DESC bbDesc;
|
||||
backBuf->GetDesc(&bbDesc);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height);
|
||||
softDesc.MipLevels = 1;
|
||||
softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
softDesc.Usage = D3D11_USAGE_STAGING;
|
||||
softDesc.BindFlags = 0;
|
||||
|
||||
nsRefPtr<ID3D11Texture2D> readTexture;
|
||||
|
||||
HRESULT hr = mDevice->CreateTexture2D(&softDesc, NULL, getter_AddRefs(readTexture));
|
||||
mContext->CopyResource(readTexture, backBuf);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
mContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &map);
|
||||
|
||||
nsRefPtr<gfxImageSurface> tmpSurface =
|
||||
new gfxImageSurface((unsigned char*)map.pData,
|
||||
gfxIntSize(bbDesc.Width, bbDesc.Height),
|
||||
map.RowPitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(tmpSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
mTarget->Paint();
|
||||
|
||||
mContext->Unmap(readTexture, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
typedef float4 rect;
|
||||
|
||||
float4x4 mLayerTransform : register(vs, c0);
|
||||
float4x4 mProjection : register(vs, c4);
|
||||
float4 vRenderTargetOffset : register(vs, c8);
|
||||
rect vTextureCoords : register(vs, c9);
|
||||
rect vLayerQuad : register(vs, c10);
|
||||
rect vMaskQuad : register(vs, c11);
|
||||
|
||||
float4 fLayerColor : register(ps, c0);
|
||||
float fLayerOpacity : register(ps, c1);
|
||||
|
||||
sampler sSampler : register(ps, s0);
|
||||
|
||||
BlendState NoBlendDual
|
||||
{
|
||||
AlphaToCoverageEnable = FALSE;
|
||||
BlendEnable[0] = FALSE;
|
||||
BlendEnable[1] = FALSE;
|
||||
RenderTargetWriteMask[0] = 0x0F; // All
|
||||
RenderTargetWriteMask[1] = 0x0F; // All
|
||||
};
|
||||
|
||||
BlendState ComponentAlphaBlend
|
||||
{
|
||||
AlphaToCoverageEnable = FALSE;
|
||||
BlendEnable[0] = TRUE;
|
||||
SrcBlend = One;
|
||||
DestBlend = Inv_Src1_Color;
|
||||
BlendOp = Add;
|
||||
SrcBlendAlpha = One;
|
||||
DestBlendAlpha = Inv_Src_Alpha;
|
||||
BlendOpAlpha = Add;
|
||||
RenderTargetWriteMask[0] = 0x0F; // All
|
||||
};
|
||||
|
||||
Texture2D tRGB;
|
||||
Texture2D tY;
|
||||
Texture2D tCb;
|
||||
Texture2D tCr;
|
||||
Texture2D tRGBWhite;
|
||||
// Always bind this to slot 3 since this is always available!
|
||||
Texture2D tMask : register(ps, t3);
|
||||
|
||||
struct VS_INPUT {
|
||||
float2 vPosition : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VS_MASK_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
float2 vMaskCoords : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct VS_MASK_3D_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
float3 vMaskCoords : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 vSrc;
|
||||
float4 vAlpha;
|
||||
};
|
||||
|
||||
struct PS_DUAL_OUTPUT {
|
||||
float4 vOutput1 : SV_Target0;
|
||||
float4 vOutput2 : SV_Target1;
|
||||
};
|
||||
|
||||
float2 TexCoords(const float2 aPosition)
|
||||
{
|
||||
float2 result;
|
||||
const float2 size = vTextureCoords.zw;
|
||||
result.x = vTextureCoords.x + aPosition.x * size.x;
|
||||
result.y = vTextureCoords.y + aPosition.y * size.y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SamplerState LayerTextureSamplerLinear
|
||||
{
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
float4 TransformedPosition(float2 aInPosition)
|
||||
{
|
||||
// the current vertex's position on the quad
|
||||
float4 position = float4(0, 0, 0, 1);
|
||||
|
||||
// We use 4 component floats to uniquely describe a rectangle, by the structure
|
||||
// of x, y, width, height. This allows us to easily generate the 4 corners
|
||||
// of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the
|
||||
// stream source for our LayerQuad vertex shader. We do this by doing:
|
||||
// Xout = x + Xin * width
|
||||
// Yout = y + Yin * height
|
||||
float2 size = vLayerQuad.zw;
|
||||
position.x = vLayerQuad.x + aInPosition.x * size.x;
|
||||
position.y = vLayerQuad.y + aInPosition.y * size.y;
|
||||
|
||||
position = mul(mLayerTransform, position);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
float4 VertexPosition(float4 aTransformedPosition)
|
||||
{
|
||||
float4 result;
|
||||
result.w = aTransformedPosition.w;
|
||||
result.xyz = aTransformedPosition.xyz / aTransformedPosition.w;
|
||||
result -= vRenderTargetOffset;
|
||||
result.xyz *= result.w;
|
||||
|
||||
result = mul(mProjection, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_OUTPUT outp;
|
||||
float4 position = TransformedPosition(aVertex.vPosition);
|
||||
|
||||
outp.vPosition = VertexPosition(position);
|
||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
VS_MASK_OUTPUT LayerQuadMaskVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_MASK_OUTPUT outp;
|
||||
float4 position = TransformedPosition(aVertex.vPosition);
|
||||
|
||||
outp.vPosition = VertexPosition(position);
|
||||
|
||||
// calculate the position on the mask texture
|
||||
outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
|
||||
outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
|
||||
|
||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
VS_MASK_3D_OUTPUT LayerQuadMask3DVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_MASK_3D_OUTPUT outp;
|
||||
float4 position = TransformedPosition(aVertex.vPosition);
|
||||
|
||||
outp.vPosition = VertexPosition(position);
|
||||
|
||||
// calculate the position on the mask texture
|
||||
position.xyz /= position.w;
|
||||
outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
|
||||
outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
|
||||
// We use the w coord to do non-perspective correct interpolation:
|
||||
// the quad might be transformed in 3D, in which case it will have some
|
||||
// perspective. The graphics card will do perspective-correct interpolation
|
||||
// of the texture, but our mask is already transformed and so we require
|
||||
// linear interpolation. Therefore, we must correct the interpolation
|
||||
// ourselves, we do this by multiplying all coords by w here, and dividing by
|
||||
// w in the pixel shader (post-interpolation), we pass w in outp.vMaskCoords.z.
|
||||
// See http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness
|
||||
outp.vMaskCoords.z = 1;
|
||||
outp.vMaskCoords *= position.w;
|
||||
|
||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).a;
|
||||
return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
|
||||
}
|
||||
|
||||
float4 RGBAShaderMask3D(const VS_MASK_3D_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
||||
return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
|
||||
}
|
||||
|
||||
float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float4 result;
|
||||
result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
result.a = fLayerOpacity;
|
||||
|
||||
float2 maskCoords = aVertex.vMaskCoords;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).a;
|
||||
return result * mask;
|
||||
}
|
||||
|
||||
float4 CalculateYCbCrColor(const float2 aTexCoords)
|
||||
{
|
||||
float4 yuv;
|
||||
float4 color;
|
||||
|
||||
yuv.r = tCr.Sample(sSampler, aTexCoords).r - 0.5;
|
||||
yuv.g = tY.Sample(sSampler, aTexCoords).r - 0.0625;
|
||||
yuv.b = tCb.Sample(sSampler, aTexCoords).r - 0.5;
|
||||
|
||||
color.r = yuv.g * 1.164 + yuv.r * 1.596;
|
||||
color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;
|
||||
color.b = yuv.g * 1.164 + yuv.b * 2.018;
|
||||
color.a = 1.0f;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).a;
|
||||
|
||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask;
|
||||
}
|
||||
|
||||
PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
PS_OUTPUT result;
|
||||
|
||||
result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
|
||||
result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
|
||||
result.vSrc.a = result.vAlpha.g;
|
||||
|
||||
float2 maskCoords = aVertex.vMaskCoords;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).a;
|
||||
result.vSrc *= fLayerOpacity * mask;
|
||||
result.vAlpha *= fLayerOpacity * mask;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).a;
|
||||
return fLayerColor * mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Un-masked versions
|
||||
*************************************************************
|
||||
*/
|
||||
float4 RGBAShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
float4 RGBShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float4 result;
|
||||
result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
result.a = fLayerOpacity;
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
PS_OUTPUT ComponentAlphaShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
PS_OUTPUT result;
|
||||
|
||||
result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
|
||||
result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
|
||||
result.vSrc.a = result.vAlpha.g;
|
||||
result.vSrc *= fLayerOpacity;
|
||||
result.vAlpha *= fLayerOpacity;
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return fLayerColor;
|
||||
}
|
||||
|
||||
PS_DUAL_OUTPUT AlphaExtractionPrepareShader(const VS_OUTPUT aVertex)
|
||||
{
|
||||
PS_DUAL_OUTPUT result;
|
||||
result.vOutput1 = float4(0, 0, 0, 1);
|
||||
result.vOutput2 = float4(1, 1, 1, 1);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_COMPOSITORD3D11_H
|
||||
#define MOZILLA_GFX_COMPOSITORD3D11_H
|
||||
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "TextureD3D11.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
class nsWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#define LOGD3D11(param)
|
||||
|
||||
struct VertexShaderConstants
|
||||
{
|
||||
float layerTransform[4][4];
|
||||
float projection[4][4];
|
||||
float renderTargetOffset[4];
|
||||
gfx::Rect textureCoords;
|
||||
gfx::Rect layerQuad;
|
||||
gfx::Rect maskQuad;
|
||||
};
|
||||
|
||||
struct PixelShaderConstants
|
||||
{
|
||||
float layerColor[4];
|
||||
float layerOpacity[4];
|
||||
};
|
||||
|
||||
struct DeviceAttachmentsD3D11;
|
||||
|
||||
class CompositorD3D11 : public Compositor
|
||||
{
|
||||
public:
|
||||
CompositorD3D11(nsIWidget *aWidget);
|
||||
~CompositorD3D11();
|
||||
|
||||
virtual bool Initialize();
|
||||
virtual void Destroy() { }
|
||||
|
||||
virtual TextureFactoryIdentifier
|
||||
GetTextureFactoryIdentifier() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
||||
virtual int32_t GetMaxTextureSize() const MOZ_FINAL;
|
||||
|
||||
virtual void SetTargetContext(gfxContext *aTarget) { mTarget = aTarget; }
|
||||
|
||||
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) { }
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
CreateRenderTarget(const gfx::IntRect &aRect,
|
||||
SurfaceInitMode aInit) MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<CompositingRenderTarget>
|
||||
CreateRenderTargetFromSource(const gfx::IntRect &aRect,
|
||||
const CompositingRenderTarget *aSource) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetRenderTarget(CompositingRenderTarget *aSurface) MOZ_OVERRIDE;
|
||||
virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE
|
||||
{
|
||||
return mCurrentRT;
|
||||
}
|
||||
|
||||
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE { }
|
||||
|
||||
/**
|
||||
* Declare an offset to use when rendering layers. This will be ignored when
|
||||
* rendering to a target instead of the screen.
|
||||
*/
|
||||
virtual void SetScreenRenderOffset(const gfx::Point& aOffset) MOZ_OVERRIDE {
|
||||
if (aOffset.x || aOffset.y) {
|
||||
NS_RUNTIMEABORT("SetScreenRenderOffset not supported by CompositorD3D11.");
|
||||
}
|
||||
// If the offset is 0, 0 that's okay.
|
||||
}
|
||||
|
||||
virtual void DrawQuad(const gfx::Rect &aRect, const gfx::Rect &aClipRect,
|
||||
const EffectChain &aEffectChain,
|
||||
gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform,
|
||||
const gfx::Point &aOffset) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Start a new frame. If aClipRectIn is null, sets *aClipRectOut to the screen dimensions.
|
||||
*/
|
||||
virtual void BeginFrame(const gfx::Rect *aClipRectIn,
|
||||
const gfxMatrix& aTransform,
|
||||
const gfx::Rect& aRenderBounds,
|
||||
gfx::Rect *aClipRectOut = nullptr,
|
||||
gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Flush the current frame to the screen.
|
||||
*/
|
||||
virtual void EndFrame() MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Post rendering stuff if the rendering is outside of this Compositor
|
||||
* e.g., by Composer2D
|
||||
*/
|
||||
virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE { }
|
||||
|
||||
/**
|
||||
* Tidy up if BeginFrame has been called, but EndFrame won't be
|
||||
*/
|
||||
virtual void AbortFrame() MOZ_OVERRIDE { }
|
||||
|
||||
/**
|
||||
* Setup the viewport and projection matrix for rendering
|
||||
* to a window of the given dimensions.
|
||||
*/
|
||||
virtual void PrepareViewport(const gfx::IntSize& aSize,
|
||||
const gfxMatrix& aWorldTransform) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE { return true; }
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
virtual const char* Name() const MOZ_OVERRIDE { return "Direct3D 11"; }
|
||||
#endif
|
||||
|
||||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
|
||||
|
||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE;
|
||||
|
||||
ID3D11Device *GetDevice() { return mDevice; }
|
||||
|
||||
private:
|
||||
enum MaskMode {
|
||||
UNMASKED = 0,
|
||||
MASKED = 1,
|
||||
MASKED3D
|
||||
};
|
||||
|
||||
void VerifyBufferSize();
|
||||
void UpdateRenderTarget();
|
||||
bool CreateShaders();
|
||||
void UpdateConstantBuffers();
|
||||
void SetSamplerForFilter(gfx::Filter aFilter);
|
||||
void SetPSForEffect(Effect *aEffect, MaskMode aMaskMode);
|
||||
void PaintToTarget();
|
||||
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<IDXGISwapChain> mSwapChain;
|
||||
RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
|
||||
RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
|
||||
|
||||
DeviceAttachmentsD3D11 *mAttachments;
|
||||
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsIWidget *mWidget;
|
||||
// XXX - Bas - wth?
|
||||
nsIntSize mSize;
|
||||
|
||||
HWND mHwnd;
|
||||
|
||||
D3D_FEATURE_LEVEL mFeatureLevel;
|
||||
|
||||
VertexShaderConstants mVSConstants;
|
||||
PixelShaderConstants mPSConstants;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,487 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "TextureD3D11.h"
|
||||
#include "CompositorD3D11.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "Effects.h"
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "ShmemYCbCrImage.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "gfxD2DSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
TemporaryRef<TextureHost>
|
||||
CreateTextureHostD3D11(SurfaceDescriptorType aDescriptorType,
|
||||
uint32_t aTextureHostFlags,
|
||||
uint32_t aTextureFlags)
|
||||
{
|
||||
RefPtr<TextureHost> result;
|
||||
if (aDescriptorType == SurfaceDescriptor::TYCbCrImage) {
|
||||
result = new TextureHostYCbCrD3D11();
|
||||
} else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorD3D10) {
|
||||
result = new TextureHostDXGID3D11();
|
||||
} else {
|
||||
result = new TextureHostShmemD3D11();
|
||||
}
|
||||
|
||||
result->SetFlags(aTextureFlags);
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
||||
CompositingRenderTargetD3D11::CompositingRenderTargetD3D11(ID3D11Texture2D *aTexture)
|
||||
{
|
||||
if (!aTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTextures[0] = aTexture;
|
||||
|
||||
RefPtr<ID3D11Device> device;
|
||||
mTextures[0]->GetDevice(byRef(device));
|
||||
|
||||
HRESULT hr = device->CreateRenderTargetView(mTextures[0], NULL, byRef(mRTView));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOGD3D11("Failed to create RenderTargetView.");
|
||||
}
|
||||
}
|
||||
|
||||
IntSize
|
||||
CompositingRenderTargetD3D11::GetSize() const
|
||||
{
|
||||
return TextureSourceD3D11::GetSize();
|
||||
}
|
||||
|
||||
TextureClientD3D11::TextureClientD3D11(CompositableForwarder* aCompositableForwarder, const TextureInfo& aTextureInfo)
|
||||
: TextureClient(aCompositableForwarder, aTextureInfo)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
mTextureInfo = aTextureInfo;
|
||||
}
|
||||
|
||||
TextureClientD3D11::~TextureClientD3D11()
|
||||
{
|
||||
mDescriptor = SurfaceDescriptor();
|
||||
|
||||
ClearDT();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType)
|
||||
{
|
||||
D3D10_TEXTURE2D_DESC desc;
|
||||
|
||||
if (mTexture) {
|
||||
mTexture->GetDesc(&desc);
|
||||
|
||||
if (desc.Width == aSize.width || desc.Height == aSize.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTexture = nullptr;
|
||||
mSurface = nullptr;
|
||||
ClearDT();
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
|
||||
ID3D10Device *device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
|
||||
|
||||
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
aSize.width, aSize.height, 1, 1,
|
||||
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
|
||||
|
||||
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
|
||||
HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOGD3D11("Error creating texture for client!");
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<IDXGIResource> resource;
|
||||
mTexture->QueryInterface((IDXGIResource**)byRef(resource));
|
||||
|
||||
HANDLE sharedHandle;
|
||||
hr = resource->GetSharedHandle(&sharedHandle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOGD3D11("Error getting shared handle for texture.");
|
||||
}
|
||||
|
||||
mDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, aType == gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
|
||||
mContentType = aType;
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
TextureClientD3D11::LockSurface()
|
||||
{
|
||||
EnsureSurface();
|
||||
|
||||
LockTexture();
|
||||
return mSurface.get();
|
||||
}
|
||||
|
||||
DrawTarget*
|
||||
TextureClientD3D11::LockDrawTarget()
|
||||
{
|
||||
EnsureDrawTarget();
|
||||
|
||||
LockTexture();
|
||||
return mDrawTarget.get();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::Unlock()
|
||||
{
|
||||
// TODO - Things seem to believe they can hold on to our surface... well...
|
||||
// They shouldn't!!
|
||||
ReleaseTexture();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::SetDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
if (aDescriptor.type() == SurfaceDescriptor::Tnull_t) {
|
||||
EnsureAllocated(mSize, mContentType);
|
||||
return;
|
||||
}
|
||||
|
||||
mDescriptor = aDescriptor;
|
||||
mSurface = nullptr;
|
||||
ClearDT();
|
||||
|
||||
if (aDescriptor.type() == SurfaceDescriptor::T__None) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorD3D10);
|
||||
ID3D10Device *device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
|
||||
|
||||
device->OpenSharedResource((HANDLE)aDescriptor.get_SurfaceDescriptorD3D10().handle(),
|
||||
__uuidof(ID3D10Texture2D),
|
||||
(void**)(ID3D10Texture2D**)byRef(mTexture));
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::EnsureSurface()
|
||||
{
|
||||
if (mSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
LockTexture();
|
||||
mSurface = new gfxD2DSurface(mTexture, mContentType);
|
||||
ReleaseTexture();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::EnsureDrawTarget()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
LockTexture();
|
||||
|
||||
SurfaceFormat format;
|
||||
switch (mContentType) {
|
||||
case gfxASurface::CONTENT_ALPHA:
|
||||
format = FORMAT_A8;
|
||||
break;
|
||||
case gfxASurface::CONTENT_COLOR:
|
||||
format = FORMAT_B8G8R8X8;
|
||||
break;
|
||||
case gfxASurface::CONTENT_COLOR_ALPHA:
|
||||
format = FORMAT_B8G8R8A8;
|
||||
break;
|
||||
default:
|
||||
format = FORMAT_B8G8R8A8;
|
||||
}
|
||||
|
||||
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, format);
|
||||
ReleaseTexture();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::LockTexture()
|
||||
{
|
||||
RefPtr<IDXGIKeyedMutex> mutex;
|
||||
mTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
|
||||
|
||||
mutex->AcquireSync(0, INFINITE);
|
||||
mIsLocked = true;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::ReleaseTexture()
|
||||
{
|
||||
// TODO - Bas - We seem to have places that unlock without ever having locked,
|
||||
// that's kind of bad.
|
||||
if (!mIsLocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
}
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> mutex;
|
||||
mTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
|
||||
|
||||
mutex->ReleaseSync(0);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D11::ClearDT()
|
||||
{
|
||||
// An Azure DrawTarget needs to be locked when it gets NULL'ed as this is
|
||||
// when it calls EndDraw. This EndDraw should not execute anything so it
|
||||
// shouldn't -really- need the lock but the debug layer chokes on this.
|
||||
//
|
||||
// Perhaps this should be debug only.
|
||||
if (mDrawTarget) {
|
||||
LockTexture();
|
||||
mDrawTarget = nullptr;
|
||||
ReleaseTexture();
|
||||
}
|
||||
}
|
||||
|
||||
IntSize
|
||||
TextureHostShmemD3D11::GetSize() const
|
||||
{
|
||||
if (mIterating) {
|
||||
gfx::IntRect rect = GetTileRect(mCurrentTile);
|
||||
return gfx::IntSize(rect.width, rect.height);
|
||||
}
|
||||
return TextureSourceD3D11::GetSize();
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
TextureHostShmemD3D11::GetTileRect()
|
||||
{
|
||||
IntRect rect = GetTileRect(mCurrentTile);
|
||||
return nsIntRect(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
static uint32_t GetRequiredTiles(uint32_t aSize, uint32_t aMaxSize)
|
||||
{
|
||||
uint32_t requiredTiles = aSize / aMaxSize;
|
||||
if (aSize % aMaxSize) {
|
||||
requiredTiles++;
|
||||
}
|
||||
return requiredTiles;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostShmemD3D11::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorD3D11 *d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
|
||||
mDevice = d3dCompositor ? d3dCompositor->GetDevice() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostShmemD3D11::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion *aRegion)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TShmem);
|
||||
|
||||
AutoOpenSurface openSurf(OPEN_READ_ONLY, aImage);
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = openSurf.GetAsImage();
|
||||
|
||||
gfxIntSize size = surf->GetSize();
|
||||
|
||||
uint32_t bpp = 0;
|
||||
|
||||
DXGI_FORMAT dxgiFormat;
|
||||
switch (surf->Format()) {
|
||||
case gfxImageSurface::ImageFormatRGB24:
|
||||
mFormat = FORMAT_B8G8R8X8;
|
||||
dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
bpp = 4;
|
||||
break;
|
||||
case gfxImageSurface::ImageFormatARGB32:
|
||||
mFormat = FORMAT_B8G8R8A8;
|
||||
dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
bpp = 4;
|
||||
break;
|
||||
case gfxImageSurface::ImageFormatA8:
|
||||
mFormat = FORMAT_A8;
|
||||
dxgiFormat = DXGI_FORMAT_A8_UNORM;
|
||||
bpp = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
mSize = IntSize(size.width, size.height);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC desc(dxgiFormat, size.width, size.height,
|
||||
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE);
|
||||
|
||||
int32_t maxSize = GetMaxTextureSizeForFeatureLevel(mDevice->GetFeatureLevel());
|
||||
if (size.width <= maxSize && size.height <= maxSize) {
|
||||
D3D11_SUBRESOURCE_DATA initData;
|
||||
initData.pSysMem = surf->Data();
|
||||
initData.SysMemPitch = surf->Stride();
|
||||
|
||||
mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[0]));
|
||||
mIsTiled = false;
|
||||
} else {
|
||||
mIsTiled = true;
|
||||
uint32_t tileCount = GetRequiredTiles(size.width, maxSize) *
|
||||
GetRequiredTiles(size.height, maxSize);
|
||||
|
||||
mTileTextures.resize(tileCount);
|
||||
|
||||
for (uint32_t i = 0; i < tileCount; i++) {
|
||||
IntRect tileRect = GetTileRect(i);
|
||||
|
||||
desc.Width = tileRect.width;
|
||||
desc.Height = tileRect.height;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA initData;
|
||||
initData.pSysMem = surf->Data() + tileRect.y * surf->Stride() + tileRect.x * bpp;
|
||||
initData.SysMemPitch = surf->Stride();
|
||||
|
||||
mDevice->CreateTexture2D(&desc, &initData, byRef(mTileTextures[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntRect
|
||||
TextureHostShmemD3D11::GetTileRect(uint32_t aID) const
|
||||
{
|
||||
uint32_t maxSize = GetMaxTextureSizeForFeatureLevel(mDevice->GetFeatureLevel());
|
||||
uint32_t horizontalTiles = GetRequiredTiles(mSize.width, maxSize);
|
||||
uint32_t verticalTiles = GetRequiredTiles(mSize.height, maxSize);
|
||||
|
||||
uint32_t verticalTile = aID / horizontalTiles;
|
||||
uint32_t horizontalTile = aID % horizontalTiles;
|
||||
|
||||
return IntRect(horizontalTile * maxSize,
|
||||
verticalTile * maxSize,
|
||||
horizontalTile < (horizontalTiles - 1) ? maxSize : mSize.width % maxSize,
|
||||
verticalTile < (verticalTiles - 1) ? maxSize : mSize.height % maxSize);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostDXGID3D11::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorD3D11 *d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
|
||||
mDevice = d3dCompositor ? d3dCompositor->GetDevice() : nullptr;
|
||||
}
|
||||
|
||||
IntSize
|
||||
TextureHostDXGID3D11::GetSize() const
|
||||
{
|
||||
return TextureSourceD3D11::GetSize();
|
||||
}
|
||||
|
||||
bool
|
||||
TextureHostDXGID3D11::Lock()
|
||||
{
|
||||
LockTexture();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostDXGID3D11::Unlock()
|
||||
{
|
||||
ReleaseTexture();
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostDXGID3D11::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion *aRegion)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorD3D10);
|
||||
|
||||
mDevice->OpenSharedResource((HANDLE)aImage.get_SurfaceDescriptorD3D10().handle(),
|
||||
__uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)byRef(mTextures[0]));
|
||||
mFormat = aImage.get_SurfaceDescriptorD3D10().hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
mTextures[0]->GetDesc(&desc);
|
||||
|
||||
mSize = IntSize(desc.Width, desc.Height);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostDXGID3D11::LockTexture()
|
||||
{
|
||||
RefPtr<IDXGIKeyedMutex> mutex;
|
||||
mTextures[0]->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
|
||||
|
||||
mutex->AcquireSync(0, INFINITE);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostDXGID3D11::ReleaseTexture()
|
||||
{
|
||||
RefPtr<IDXGIKeyedMutex> mutex;
|
||||
mTextures[0]->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
|
||||
|
||||
mutex->ReleaseSync(0);
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostYCbCrD3D11::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorD3D11 *d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
|
||||
mDevice = d3dCompositor ? d3dCompositor->GetDevice() : nullptr;
|
||||
}
|
||||
|
||||
IntSize
|
||||
TextureHostYCbCrD3D11::GetSize() const
|
||||
{
|
||||
return TextureSourceD3D11::GetSize();
|
||||
}
|
||||
|
||||
void
|
||||
TextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion *aRegion)
|
||||
{
|
||||
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
|
||||
|
||||
ShmemYCbCrImage shmemImage(aImage.get_YCbCrImage().data(),
|
||||
aImage.get_YCbCrImage().offset());
|
||||
|
||||
gfxIntSize gfxCbCrSize = shmemImage.GetCbCrSize();
|
||||
|
||||
gfxIntSize size = shmemImage.GetYSize();
|
||||
|
||||
D3D11_SUBRESOURCE_DATA initData;
|
||||
initData.pSysMem = shmemImage.GetYData();
|
||||
initData.SysMemPitch = shmemImage.GetYStride();
|
||||
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8_UNORM, size.width, size.height,
|
||||
1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE);
|
||||
|
||||
mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[0]));
|
||||
|
||||
initData.pSysMem = shmemImage.GetCbData();
|
||||
initData.SysMemPitch = shmemImage.GetCbCrStride();
|
||||
desc.Width = shmemImage.GetCbCrSize().width;
|
||||
desc.Height = shmemImage.GetCbCrSize().height;
|
||||
|
||||
mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[1]));
|
||||
|
||||
initData.pSysMem = shmemImage.GetCrData();
|
||||
mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[2]));
|
||||
|
||||
mSize = IntSize(size.width, size.height);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_TEXTURED3D11_H
|
||||
#define MOZILLA_GFX_TEXTURED3D11_H
|
||||
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include <d3d11.h>
|
||||
#include <vector>
|
||||
|
||||
class gfxD2DSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
TextureSourceD3D11()
|
||||
{ }
|
||||
|
||||
virtual ID3D11Texture2D *GetD3D11Texture() { return mTextures[0]; }
|
||||
virtual bool IsYCbCrSource() const { return false; }
|
||||
|
||||
struct YCbCrTextures
|
||||
{
|
||||
ID3D11Texture2D *mY;
|
||||
ID3D11Texture2D *mCb;
|
||||
ID3D11Texture2D *mCr;
|
||||
};
|
||||
virtual YCbCrTextures GetYCbCrTextures() {
|
||||
YCbCrTextures textures = { mTextures[0], mTextures[1], mTextures[2] };
|
||||
return textures;
|
||||
}
|
||||
protected:
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<ID3D11Texture2D> mTextures[3];
|
||||
};
|
||||
|
||||
class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
|
||||
public TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
// Use aTexture == nullptr for rendering to the window
|
||||
CompositingRenderTargetD3D11(ID3D11Texture2D *aTexture);
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
|
||||
|
||||
private:
|
||||
friend class CompositorD3D11;
|
||||
|
||||
RefPtr<ID3D11RenderTargetView> mRTView;
|
||||
};
|
||||
|
||||
class TextureClientD3D11 : public TextureClient
|
||||
{
|
||||
public:
|
||||
TextureClientD3D11(CompositableForwarder* aCompositableForwarder, const TextureInfo& aTextureInfo);
|
||||
~TextureClientD3D11();
|
||||
|
||||
virtual bool SupportsType(TextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_CONTENT; }
|
||||
|
||||
virtual void EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aType) MOZ_OVERRIDE;
|
||||
|
||||
virtual gfxASurface* LockSurface() MOZ_OVERRIDE;
|
||||
virtual gfx::DrawTarget* LockDrawTarget() MOZ_OVERRIDE;
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
|
||||
virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE { return mContentType; }
|
||||
|
||||
|
||||
private:
|
||||
void EnsureSurface();
|
||||
void EnsureDrawTarget();
|
||||
void LockTexture();
|
||||
void ReleaseTexture();
|
||||
void ClearDT();
|
||||
|
||||
RefPtr<ID3D10Texture2D> mTexture;
|
||||
nsRefPtr<gfxD2DSurface> mSurface;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
bool mIsLocked;
|
||||
gfxContentType mContentType;
|
||||
};
|
||||
|
||||
class TextureHostShmemD3D11 : public TextureHost
|
||||
, public TextureSourceD3D11
|
||||
, public TileIterator
|
||||
{
|
||||
public:
|
||||
TextureHostShmemD3D11()
|
||||
: mDevice(nullptr)
|
||||
, mIsTiled(false)
|
||||
, mCurrentTile(0)
|
||||
, mIterating(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual ID3D11Texture2D *GetD3D11Texture() MOZ_OVERRIDE {
|
||||
return mIsTiled ? mTileTextures[mCurrentTile] : TextureSourceD3D11::GetD3D11Texture();
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
|
||||
|
||||
virtual bool Lock() MOZ_OVERRIDE { return true; }
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "TextureHostShmemD3D11"; }
|
||||
#endif
|
||||
|
||||
virtual void BeginTileIteration() MOZ_OVERRIDE {
|
||||
mIterating = true;
|
||||
mCurrentTile = 0;
|
||||
}
|
||||
virtual void EndTileIteration() MOZ_OVERRIDE {
|
||||
mIterating = false;
|
||||
}
|
||||
virtual nsIntRect GetTileRect() MOZ_OVERRIDE;
|
||||
virtual size_t GetTileCount() MOZ_OVERRIDE { return mTileTextures.size(); }
|
||||
virtual bool NextTile() MOZ_OVERRIDE {
|
||||
return (++mCurrentTile < mTileTextures.size());
|
||||
}
|
||||
|
||||
virtual TileIterator* AsTileIterator() MOZ_OVERRIDE {
|
||||
return mIsTiled ? this : nullptr;
|
||||
}
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion) MOZ_OVERRIDE;
|
||||
private:
|
||||
|
||||
gfx::IntRect GetTileRect(uint32_t aID) const;
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
bool mIsTiled;
|
||||
std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
|
||||
uint32_t mCurrentTile;
|
||||
bool mIterating;
|
||||
};
|
||||
|
||||
class TextureHostDXGID3D11 : public TextureHost
|
||||
, public TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
TextureHostDXGID3D11()
|
||||
: mDevice(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool Lock() MOZ_OVERRIDE;
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "TextureHostDXGID3D11"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion) MOZ_OVERRIDE;
|
||||
private:
|
||||
void LockTexture();
|
||||
void ReleaseTexture();
|
||||
|
||||
gfx::IntRect GetTileRect(uint32_t aID) const; // TODO[Bas] not defined anywhere?
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
};
|
||||
|
||||
class TextureHostYCbCrD3D11 : public TextureHost
|
||||
, public TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
TextureHostYCbCrD3D11()
|
||||
: mDevice(nullptr)
|
||||
{
|
||||
mFormat = gfx::FORMAT_YUV;
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsYCbCrSource() const MOZ_OVERRIDE { return true; }
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() MOZ_OVERRIDE { return "TextureImageTextureHostD3D11"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
|
||||
nsIntRegion* aRegion) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
};
|
||||
|
||||
inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
|
||||
{
|
||||
int32_t maxTextureSize;
|
||||
switch (aFeatureLevel) {
|
||||
case D3D_FEATURE_LEVEL_11_1:
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_9_3:
|
||||
maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
default:
|
||||
maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
}
|
||||
return maxTextureSize;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_GFX_TEXTURED3D11_H */
|
|
@ -0,0 +1,30 @@
|
|||
# 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/.
|
||||
|
||||
tempfile=tmpShaderHeader
|
||||
rm CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ELayerQuadVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadVS
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ESolidColorShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShader
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ERGBShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShader
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ERGBAShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShader
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -EYCbCrShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShader
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ELayerQuadMaskVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMaskVS
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ELayerQuadMask3DVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMask3DVS
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ESolidColorShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShaderMask
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ERGBShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShaderMask
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ERGBAShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -ERGBAShaderMask3D -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask3D
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
||||
fxc CompositorD3D11.fx -EYCbCrShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShaderMask
|
||||
cat $tempfile >> CompositorD3D11Shaders.h
|
|
@ -13,6 +13,9 @@
|
|||
#include "CompositorParent.h"
|
||||
#include "mozilla/layers/CompositorOGL.h"
|
||||
#include "mozilla/layers/BasicCompositor.h"
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/CompositorD3D11.h"
|
||||
#endif
|
||||
#include "LayerTransactionParent.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
@ -568,6 +571,11 @@ CompositorParent::AllocPLayerTransaction(const LayersBackend& aBackendHint,
|
|||
} else if (aBackendHint == mozilla::layers::LAYERS_BASIC) {
|
||||
mLayerManager =
|
||||
new LayerManagerComposite(new BasicCompositor(mWidget));
|
||||
#ifdef XP_WIN
|
||||
} else if (aBackendHint == mozilla::layers::LAYERS_D3D11) {
|
||||
mLayerManager =
|
||||
new LayerManagerComposite(new CompositorD3D11(mWidget));
|
||||
#endif
|
||||
} else {
|
||||
NS_ERROR("Unsupported backend selected for Async Compositor");
|
||||
return nullptr;
|
||||
|
|
|
@ -56,7 +56,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'ReadbackManagerD3D10.h',
|
||||
]
|
||||
EXPORTS.mozilla.layers += [
|
||||
'CompositorD3D11.h',
|
||||
'ShadowLayerUtilsD3D10.h',
|
||||
'TextureD3D11.h',
|
||||
]
|
||||
|
||||
EXPORTS.gfxipc += [
|
||||
|
|
Загрузка…
Ссылка в новой задаче