Bug 1381085 - Submit VR frames with a separate ID3DDeviceContextState r=daoshengmu

- Using a separate ID3DDeviceContextState ensures
  that the WebVR context does not stomp over the
  mirrored state used by the MLGPU "Advanced" Layers rendering.
MozReview-Commit-ID: 99mfdsjFrMI

--HG--
extra : rebase_source : fdcdcb55185048cfb54163f51aca70409a1aa74a
This commit is contained in:
Kearwood "Kip" Gilbert 2017-09-18 16:19:49 -07:00
Родитель 46bcf3cd76
Коммит fcc8fcf709
6 изменённых файлов: 147 добавлений и 32 удалений

Просмотреть файл

@ -14,6 +14,7 @@
#include <d3d11.h>
#include "gfxWindowsPlatform.h"
#include "../layers/d3d11/CompositorD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/TextureD3D11.h"
#elif defined(XP_MACOSX)
@ -26,6 +27,37 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::layers;
VRDisplayHost::AutoRestoreRenderState::AutoRestoreRenderState(VRDisplayHost* aDisplay)
: mDisplay(aDisplay)
, mSuccess(true)
{
#if defined(XP_WIN)
ID3D11DeviceContext1* context = mDisplay->GetD3DDeviceContext();
ID3DDeviceContextState* state = mDisplay->GetD3DDeviceContextState();
if (!context || !state) {
mSuccess = false;
return;
}
context->SwapDeviceContextState(state, getter_AddRefs(mPrevDeviceContextState));
#endif
}
VRDisplayHost::AutoRestoreRenderState::~AutoRestoreRenderState()
{
#if defined(XP_WIN)
ID3D11DeviceContext1* context = mDisplay->GetD3DDeviceContext();
if (context && mSuccess) {
context->SwapDeviceContextState(mPrevDeviceContextState, nullptr);
}
#endif
}
bool
VRDisplayHost::AutoRestoreRenderState::IsSuccess()
{
return mSuccess;
}
VRDisplayHost::VRDisplayHost(VRDeviceType aType)
: mFrameStarted(false)
{
@ -42,6 +74,69 @@ VRDisplayHost::~VRDisplayHost()
MOZ_COUNT_DTOR(VRDisplayHost);
}
#if defined(XP_WIN)
bool
VRDisplayHost::CreateD3DObjects()
{
if (!mDevice) {
RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
if (!device) {
NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get a D3D11Device");
return false;
}
if (FAILED(device->QueryInterface(__uuidof(ID3D11Device1), getter_AddRefs(mDevice)))) {
NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get a D3D11Device1");
return false;
}
}
if (!mContext) {
mDevice->GetImmediateContext1(getter_AddRefs(mContext));
if (!mContext) {
NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get an immediate context");
return false;
}
}
if (!mDeviceContextState) {
D3D_FEATURE_LEVEL featureLevels[] {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0
};
mDevice->CreateDeviceContextState(0,
featureLevels,
2,
D3D11_SDK_VERSION,
__uuidof(ID3D11Device1),
nullptr,
getter_AddRefs(mDeviceContextState));
}
if (!mDeviceContextState) {
NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get a D3D11DeviceContextState");
return false;
}
return true;
}
ID3D11Device1*
VRDisplayHost::GetD3DDevice()
{
return mDevice;
}
ID3D11DeviceContext1*
VRDisplayHost::GetD3DDeviceContext()
{
return mContext;
}
ID3DDeviceContextState*
VRDisplayHost::GetD3DDeviceContextState()
{
return mDeviceContextState;
}
#endif // defined(XP_WIN)
void
VRDisplayHost::SetGroupMask(uint32_t aGroupMask)
{

Просмотреть файл

@ -17,6 +17,9 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/dom/GamepadPoseState.h"
#if defined(XP_WIN)
#include <d3d11_1.h>
#endif
#if defined(XP_MACOSX)
class MacIOSurface;
@ -56,6 +59,19 @@ public:
void SetGroupMask(uint32_t aGroupMask);
bool GetIsConnected();
class AutoRestoreRenderState {
public:
explicit AutoRestoreRenderState(VRDisplayHost* aDisplay);
~AutoRestoreRenderState();
bool IsSuccess();
private:
RefPtr<VRDisplayHost> mDisplay;
#if defined(XP_WIN)
RefPtr<ID3DDeviceContextState> mPrevDeviceContextState;
#endif
bool mSuccess;
};
protected:
explicit VRDisplayHost(VRDeviceType aType);
virtual ~VRDisplayHost();
@ -89,6 +105,19 @@ private:
VRDisplayInfo mLastUpdateDisplayInfo;
TimeStamp mLastFrameStart;
bool mFrameStarted;
#if defined(XP_WIN)
protected:
bool CreateD3DObjects();
RefPtr<ID3D11Device1> mDevice;
RefPtr<ID3D11DeviceContext1> mContext;
ID3D11Device1* GetD3DDevice();
ID3D11DeviceContext1* GetD3DDeviceContext();
ID3DDeviceContextState* GetD3DDeviceContextState();
private:
RefPtr<ID3DDeviceContextState> mDeviceContextState;
#endif
};
class VRControllerHost {

Просмотреть файл

@ -910,27 +910,14 @@ VRDisplayOculus::GetSensorState(double absTime)
void
VRDisplayOculus::StartPresentation()
{
if (!CreateD3DObjects()) {
return;
}
mSession->StartPresentation(IntSize(mDisplayInfo.mEyeResolution.width * 2, mDisplayInfo.mEyeResolution.height));
if (!mSession->IsRenderReady()) {
return;
}
if (!mDevice) {
mDevice = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
if (!mDevice) {
NS_WARNING("Failed to get a D3D11Device for Oculus");
return;
}
}
if (!mContext) {
mDevice->GetImmediateContext(getter_AddRefs(mContext));
if (!mContext) {
NS_WARNING("Failed to get immediate context for Oculus");
return;
}
}
if (!mQuadVS) {
if (FAILED(mDevice->CreateVertexShader(sLayerQuadVS.mData, sLayerQuadVS.mLength, nullptr, &mQuadVS))) {
NS_WARNING("Failed to create vertex shader for Oculus");
@ -1048,7 +1035,16 @@ VRDisplayOculus::SubmitFrame(TextureSourceD3D11* aSource,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
if (!mSession->IsRenderReady() || !mDevice || !mContext) {
if (!CreateD3DObjects()) {
return false;
}
AutoRestoreRenderState restoreState(this);
if (!restoreState.IsSuccess()) {
return false;
}
if (!mSession->IsRenderReady()) {
return false;
}
/**

Просмотреть файл

@ -108,8 +108,6 @@ protected:
RefPtr<VROculusSession> mSession;
ovrFovPort mFOVPort[2];
RefPtr<ID3D11Device> mDevice;
RefPtr<ID3D11DeviceContext> mContext;
ID3D11VertexShader* mQuadVS;
ID3D11PixelShader* mQuadPS;
RefPtr<ID3D11SamplerState> mLinearSamplerState;

Просмотреть файл

@ -166,17 +166,7 @@ VRDisplayPuppet::StartPresentation()
mIsPresenting = true;
#if defined(XP_WIN)
if (!mDevice) {
mDevice = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
if (!mDevice) {
NS_WARNING("Failed to get a D3D11Device for Puppet");
return;
}
}
mDevice->GetImmediateContext(getter_AddRefs(mContext));
if (!mContext) {
NS_WARNING("Failed to get immediate context for Puppet");
if (!CreateD3DObjects()) {
return;
}
@ -293,6 +283,15 @@ VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
return false;
}
if (!CreateD3DObjects()) {
return false;
}
AutoRestoreRenderState restoreState(this);
if (!restoreState.IsSuccess()) {
return false;
}
VRManager *vm = VRManager::Get();
MOZ_ASSERT(vm);

Просмотреть файл

@ -56,8 +56,6 @@ private:
#if defined(XP_WIN)
bool UpdateConstantBuffers();
RefPtr<ID3D11Device> mDevice;
RefPtr<ID3D11DeviceContext> mContext;
ID3D11VertexShader* mQuadVS;
ID3D11PixelShader* mQuadPS;
RefPtr<ID3D11SamplerState> mLinearSamplerState;