зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1400457 - Isolate VR Rendering from Compositor r=daoshengmu,jgilbert
- WebVR is no longer dependent on PTexture, TextureParent, TextureHost, and TextureChild. It continues to use TextureClient for pooling and coordinating locks with other Gecko code. - PreserveDrawingBuffer now behaving correctly for 2d display mirroring - Preparation for separating to VR process MozReview-Commit-ID: 2RGOulCInSu --HG-- extra : rebase_source : 3542b804c3def36fa74541be32d0e7cbc9698641
This commit is contained in:
Родитель
772b49aa9a
Коммит
c5a2279e20
|
@ -2333,80 +2333,27 @@ WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
|
|||
already_AddRefed<layers::SharedSurfaceTextureClient>
|
||||
WebGLContext::GetVRFrame()
|
||||
{
|
||||
if (!mLayerIsMirror) {
|
||||
/**
|
||||
* Do not allow VR frame submission until a mirroring canvas layer has
|
||||
* been returned by GetCanvasLayer
|
||||
*/
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* Swap buffers as though composition has occurred.
|
||||
* We will then share the resulting front buffer to be submitted to the VR
|
||||
* compositor.
|
||||
*/
|
||||
BeginComposition();
|
||||
EndComposition();
|
||||
|
||||
VRManagerChild* vrmc = VRManagerChild::Get();
|
||||
if (!vrmc) {
|
||||
return nullptr;
|
||||
}
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
if (!screen) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap buffers as though composition has occurred.
|
||||
* We will then share the resulting front buffer to be submitted to the VR
|
||||
* compositor.
|
||||
*/
|
||||
BeginComposition();
|
||||
EndComposition();
|
||||
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
if (!screen) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SharedSurfaceTextureClient> sharedSurface = screen->Front();
|
||||
if (!sharedSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sharedSurface && sharedSurface->GetAllocator() != vrmc) {
|
||||
RefPtr<SharedSurfaceTextureClient> dest =
|
||||
screen->Factory()->NewTexClient(sharedSurface->GetSize(), vrmc);
|
||||
if (!dest) {
|
||||
return nullptr;
|
||||
}
|
||||
gl::SharedSurface* destSurf = dest->Surf();
|
||||
destSurf->ProducerAcquire();
|
||||
SharedSurface::ProdCopy(sharedSurface->Surf(), dest->Surf(),
|
||||
screen->Factory());
|
||||
destSurf->ProducerRelease();
|
||||
|
||||
return dest.forget();
|
||||
}
|
||||
RefPtr<SharedSurfaceTextureClient> sharedSurface = screen->Front();
|
||||
if (!sharedSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sharedSurface.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::StartVRPresentation()
|
||||
{
|
||||
VRManagerChild* vrmc = VRManagerChild::Get();
|
||||
if (!vrmc) {
|
||||
return false;
|
||||
}
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
if (!screen) {
|
||||
return false;
|
||||
}
|
||||
gl::SurfaceCaps caps = screen->mCaps;
|
||||
|
||||
UniquePtr<gl::SurfaceFactory> factory =
|
||||
gl::GLScreenBuffer::CreateFactory(gl,
|
||||
caps,
|
||||
vrmc,
|
||||
TextureFlags::ORIGIN_BOTTOM_LEFT);
|
||||
|
||||
if (factory) {
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline size_t
|
||||
|
|
|
@ -642,7 +642,6 @@ public:
|
|||
void PolygonOffset(GLfloat factor, GLfloat units);
|
||||
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
|
||||
bool StartVRPresentation();
|
||||
|
||||
////
|
||||
|
||||
|
|
|
@ -378,7 +378,6 @@ NS_IMPL_ISUPPORTS(HTMLCanvasElementObserver, nsIObserver)
|
|||
HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
mResetLayer(true) ,
|
||||
mVRPresentationActive(false),
|
||||
mWriteOnly(false)
|
||||
{}
|
||||
|
||||
|
@ -1160,7 +1159,7 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
static uint8_t sOffscreenCanvasLayerUserDataDummy = 0;
|
||||
|
||||
if (mCurrentContext) {
|
||||
return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager, mVRPresentationActive);
|
||||
return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
|
||||
}
|
||||
|
||||
if (mOffscreenCanvas) {
|
||||
|
@ -1503,32 +1502,6 @@ HTMLCanvasElement::InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRende
|
|||
element->InvalidateCanvasContent(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLCanvasElement::StartVRPresentation()
|
||||
{
|
||||
if (GetCurrentContextType() != CanvasContextType::WebGL1 &&
|
||||
GetCurrentContextType() != CanvasContextType::WebGL2) {
|
||||
return;
|
||||
}
|
||||
|
||||
WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
|
||||
if (!webgl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!webgl->StartVRPresentation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVRPresentationActive = true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLCanvasElement::StopVRPresentation()
|
||||
{
|
||||
mVRPresentationActive = false;
|
||||
}
|
||||
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient>
|
||||
HTMLCanvasElement::GetVRFrame()
|
||||
{
|
||||
|
|
|
@ -341,8 +341,6 @@ public:
|
|||
static void SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
|
||||
static void InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
|
||||
|
||||
void StartVRPresentation();
|
||||
void StopVRPresentation();
|
||||
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
|
||||
|
||||
protected:
|
||||
|
@ -386,7 +384,6 @@ protected:
|
|||
RefPtr<AsyncCanvasRenderer> mAsyncCanvasRenderer;
|
||||
RefPtr<OffscreenCanvas> mOffscreenCanvas;
|
||||
RefPtr<HTMLCanvasElementObserver> mContextObserver;
|
||||
bool mVRPresentationActive;
|
||||
|
||||
public:
|
||||
// Record whether this canvas should be write-only or not.
|
||||
|
|
|
@ -255,7 +255,8 @@ VRDisplayHost::NotifyVSync()
|
|||
}
|
||||
|
||||
void
|
||||
VRDisplayHost::SubmitFrame(VRLayerParent* aLayer, PTextureParent* aTexture,
|
||||
VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
|
||||
const layers::SurfaceDescriptor &aTexture,
|
||||
uint64_t aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
|
@ -273,59 +274,75 @@ VRDisplayHost::SubmitFrame(VRLayerParent* aLayer, PTextureParent* aTexture,
|
|||
}
|
||||
mFrameStarted = false;
|
||||
|
||||
switch (aTexture.type()) {
|
||||
|
||||
#if defined(XP_WIN)
|
||||
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
|
||||
if (!CreateD3DObjects()) {
|
||||
return;
|
||||
}
|
||||
const SurfaceDescriptorD3D10& surf = aTexture.get_SurfaceDescriptorD3D10();
|
||||
RefPtr<ID3D11Texture2D> dxTexture;
|
||||
HRESULT hr = mDevice->OpenSharedResource((HANDLE)surf.handle(),
|
||||
__uuidof(ID3D11Texture2D),
|
||||
(void**)(ID3D11Texture2D**)getter_AddRefs(dxTexture));
|
||||
if (FAILED(hr) || !dxTexture) {
|
||||
NS_WARNING("Failed to open shared texture");
|
||||
return;
|
||||
}
|
||||
|
||||
TextureHost* th = TextureHost::AsTextureHost(aTexture);
|
||||
|
||||
// WebVR doesn't use the compositor to compose the frame, so use
|
||||
// AutoLockTextureHostWithoutCompositor here.
|
||||
AutoLockTextureHostWithoutCompositor autoLock(th);
|
||||
if (autoLock.Failed()) {
|
||||
NS_WARNING("Failed to lock the VR layer texture");
|
||||
return;
|
||||
}
|
||||
|
||||
CompositableTextureSourceRef source;
|
||||
if (!th->BindTextureSource(source)) {
|
||||
NS_WARNING("The TextureHost was successfully locked but can't provide a TextureSource");
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(source);
|
||||
|
||||
IntSize texSize = source->GetSize();
|
||||
|
||||
TextureSourceD3D11* sourceD3D11 = source->AsSourceD3D11();
|
||||
if (!sourceD3D11) {
|
||||
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a TextureSourceD3D11");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SubmitFrame(sourceD3D11, texSize, aLeftEyeRect, aRightEyeRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Similar to LockD3DTexture in TextureD3D11.cpp
|
||||
RefPtr<IDXGIKeyedMutex> mutex;
|
||||
dxTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
|
||||
if (mutex) {
|
||||
HRESULT hr = mutex->AcquireSync(0, 1000);
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
gfxDevCrash(LogReason::D3DLockTimeout) << "D3D lock mutex timeout";
|
||||
}
|
||||
else if (hr == WAIT_ABANDONED) {
|
||||
gfxCriticalNote << "GFX: D3D11 lock mutex abandoned";
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to lock the texture");
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool success = SubmitFrame(dxTexture, surf.size(),
|
||||
aLeftEyeRect, aRightEyeRect);
|
||||
if (mutex) {
|
||||
HRESULT hr = mutex->ReleaseSync(0);
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to unlock the texture");
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
TextureHost* th = TextureHost::AsTextureHost(aTexture);
|
||||
|
||||
MacIOSurface* surf = th->GetMacIOSurface();
|
||||
if (!surf) {
|
||||
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a MacIOSurface");
|
||||
return;
|
||||
}
|
||||
|
||||
IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(),
|
||||
surf->GetDevicePixelHeight());
|
||||
|
||||
if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
NS_WARNING("WebVR is not supported on this platform.");
|
||||
return;
|
||||
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
|
||||
const auto& desc = aTexture.get_SurfaceDescriptorMacIOSurface();
|
||||
RefPtr<MacIOSurface> surf = MacIOSurface::LookupSurface(desc.surfaceId(),
|
||||
desc.scaleFactor(),
|
||||
!desc.isOpaque());
|
||||
if (!surf) {
|
||||
NS_WARNING("VRDisplayHost::SubmitFrame failed to get a MacIOSurface");
|
||||
return;
|
||||
}
|
||||
IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(),
|
||||
surf->GetDevicePixelHeight());
|
||||
if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
|
||||
|
|
|
@ -17,20 +17,14 @@
|
|||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "mozilla/dom/GamepadPoseState.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <d3d11_1.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#elif defined(XP_MACOSX)
|
||||
class MacIOSurface;
|
||||
#endif
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class PTextureParent;
|
||||
#if defined(XP_WIN)
|
||||
class TextureSourceD3D11;
|
||||
#endif
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class VRLayerParent;
|
||||
|
||||
|
@ -50,7 +44,7 @@ public:
|
|||
|
||||
void StartFrame();
|
||||
void SubmitFrame(VRLayerParent* aLayer,
|
||||
mozilla::layers::PTextureParent* aTexture,
|
||||
const layers::SurfaceDescriptor& aTexture,
|
||||
uint64_t aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect);
|
||||
|
@ -81,7 +75,7 @@ protected:
|
|||
// Returns true if the SubmitFrame call will block as necessary
|
||||
// to control timing of the next frame and throttle the render loop
|
||||
// for the needed framerate.
|
||||
virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
|
||||
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) = 0;
|
||||
|
|
|
@ -343,20 +343,6 @@ VRManager::GetDisplay(const uint32_t& aDisplayID)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
|
||||
uint64_t aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
TextureHost* th = TextureHost::AsTextureHost(aTexture);
|
||||
mLastFrame = th;
|
||||
RefPtr<VRDisplayHost> display = GetDisplay(aLayer->GetDisplayID());
|
||||
if (display) {
|
||||
display->SubmitFrame(aLayer, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<gfx::VRControllerHost>
|
||||
VRManager::GetController(const uint32_t& aControllerID)
|
||||
{
|
||||
|
|
|
@ -43,11 +43,6 @@ public:
|
|||
template<class T> void NotifyGamepadChange(uint32_t aIndex, const T& aInfo);
|
||||
RefPtr<gfx::VRDisplayHost> GetDisplay(const uint32_t& aDisplayID);
|
||||
void GetVRDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayInfo);
|
||||
|
||||
void SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
|
||||
uint64_t aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect);
|
||||
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
|
||||
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
|
||||
void CreateVRTestSystem();
|
||||
|
@ -62,7 +57,6 @@ protected:
|
|||
~VRManager();
|
||||
|
||||
private:
|
||||
RefPtr<layers::TextureHost> mLastFrame;
|
||||
|
||||
void Init();
|
||||
void Destroy();
|
||||
|
|
|
@ -321,7 +321,7 @@ VRDisplayOSVR::GetSensorState()
|
|||
#if defined(XP_WIN)
|
||||
|
||||
bool
|
||||
VRDisplayOSVR::SubmitFrame(TextureSourceD3D11* aSource,
|
||||
VRDisplayOSVR::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
|||
virtual void StopPresentation() override;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
|
||||
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) override;
|
||||
|
|
|
@ -1032,10 +1032,10 @@ VRDisplayOculus::UpdateConstantBuffers()
|
|||
}
|
||||
|
||||
bool
|
||||
VRDisplayOculus::SubmitFrame(TextureSourceD3D11* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
VRDisplayOculus::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
if (!CreateD3DObjects()) {
|
||||
return false;
|
||||
|
@ -1105,12 +1105,15 @@ VRDisplayOculus::SubmitFrame(TextureSourceD3D11* aSource,
|
|||
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
mContext->VSSetShader(mQuadVS, nullptr, 0);
|
||||
mContext->PSSetShader(mQuadPS, nullptr, 0);
|
||||
ID3D11ShaderResourceView* srView = aSource->GetShaderResourceView();
|
||||
if (!srView) {
|
||||
NS_WARNING("Failed to get SRV for Oculus");
|
||||
return false;
|
||||
|
||||
RefPtr<ID3D11ShaderResourceView> srView;
|
||||
HRESULT hr = mDevice->CreateShaderResourceView(aSource, nullptr, getter_AddRefs(srView));
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Could not create shader resource view for Oculus: " << hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
mContext->PSSetShaderResources(0 /* 0 == TexSlot::RGB */, 1, &srView);
|
||||
ID3D11ShaderResourceView* viewPtr = srView.get();
|
||||
mContext->PSSetShaderResources(0 /* 0 == TexSlot::RGB */, 1, &viewPtr);
|
||||
// XXX Use Constant from TexSlot in CompositorD3D11.cpp?
|
||||
|
||||
ID3D11SamplerState *sampler = mLinearSamplerState;
|
||||
|
|
|
@ -89,7 +89,7 @@ protected:
|
|||
virtual VRHMDSensorState GetSensorState() override;
|
||||
virtual void StartPresentation() override;
|
||||
virtual void StopPresentation() override;
|
||||
virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
|
||||
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) override;
|
||||
|
|
|
@ -364,12 +364,12 @@ VRDisplayOpenVR::SubmitFrame(void* aTextureHandle,
|
|||
#if defined(XP_WIN)
|
||||
|
||||
bool
|
||||
VRDisplayOpenVR::SubmitFrame(TextureSourceD3D11* aSource,
|
||||
VRDisplayOpenVR::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
return SubmitFrame((void *)aSource->GetD3D11Texture(),
|
||||
return SubmitFrame((void *)aSource,
|
||||
::vr::ETextureType::TextureType_DirectX,
|
||||
aSize, aLeftEyeRect, aRightEyeRect);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
|||
virtual void StartPresentation() override;
|
||||
virtual void StopPresentation() override;
|
||||
#if defined(XP_WIN)
|
||||
virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
|
||||
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) override;
|
||||
|
|
|
@ -274,7 +274,7 @@ VRDisplayPuppet::UpdateConstantBuffers()
|
|||
}
|
||||
|
||||
bool
|
||||
VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
|
||||
VRDisplayPuppet::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
|
@ -303,14 +303,13 @@ VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
|
|||
// The frames are submitted to VR compositor are decoded
|
||||
// into a base64Image and dispatched to the DOM side.
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ID3D11Texture2D* texture = aSource->GetD3D11Texture();
|
||||
texture->GetDesc(&desc);
|
||||
aSource->GetDesc(&desc);
|
||||
MOZ_ASSERT(desc.Format == DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
"Only support B8G8R8A8_UNORM format.");
|
||||
// Map the staging resource
|
||||
ID3D11Texture2D* mappedTexture = nullptr;
|
||||
D3D11_MAPPED_SUBRESOURCE mapInfo;
|
||||
HRESULT hr = mContext->Map(texture,
|
||||
HRESULT hr = mContext->Map(aSource,
|
||||
0, // Subsource
|
||||
D3D11_MAP_READ,
|
||||
0, // MapFlags
|
||||
|
@ -338,7 +337,7 @@ VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
|
|||
return false;
|
||||
}
|
||||
// Copy the texture to a staging resource
|
||||
mContext->CopyResource(stagingTexture, texture);
|
||||
mContext->CopyResource(stagingTexture, aSource);
|
||||
// Map the staging resource
|
||||
hr = mContext->Map(stagingTexture,
|
||||
0, // Subsource
|
||||
|
@ -354,7 +353,7 @@ VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
mappedTexture = texture;
|
||||
mappedTexture = aSource;
|
||||
}
|
||||
// Ideally, we should convert the srcData to a PNG image and decode it
|
||||
// to a Base64 string here, but the GPU process does not have the privilege to
|
||||
|
@ -429,12 +428,15 @@ VRDisplayPuppet::SubmitFrame(TextureSourceD3D11* aSource,
|
|||
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
mContext->VSSetShader(mQuadVS, nullptr, 0);
|
||||
mContext->PSSetShader(mQuadPS, nullptr, 0);
|
||||
ID3D11ShaderResourceView* srView = aSource->GetShaderResourceView();
|
||||
if (!srView) {
|
||||
NS_WARNING("Failed to get SRV for Puppet");
|
||||
return false;
|
||||
|
||||
RefPtr<ID3D11ShaderResourceView> srView;
|
||||
HRESULT hr = mDevice->CreateShaderResourceView(aSource, nullptr, getter_AddRefs(srView));
|
||||
if (FAILED(hr) || !srView) {
|
||||
gfxWarning() << "Could not create shader resource view for Puppet: " << hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
mContext->PSSetShaderResources(0 /* 0 == TexSlot::RGB */, 1, &srView);
|
||||
ID3D11ShaderResourceView* viewPtr = srView.get();
|
||||
mContext->PSSetShaderResources(0 /* 0 == TexSlot::RGB */, 1, &viewPtr);
|
||||
// XXX Use Constant from TexSlot in CompositorD3D11.cpp?
|
||||
|
||||
ID3D11SamplerState *sampler = mLinearSamplerState;
|
||||
|
|
|
@ -32,7 +32,7 @@ protected:
|
|||
virtual void StartPresentation() override;
|
||||
virtual void StopPresentation() override;
|
||||
#if defined(XP_WIN)
|
||||
virtual bool SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
|
||||
virtual bool SubmitFrame(ID3D11Texture2D* aSource,
|
||||
const IntSize& aSize,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) override;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* 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 LayersSurfaces;
|
||||
include protocol PVRManager;
|
||||
include protocol PTexture;
|
||||
|
||||
using mozilla::gfx::Rect from "mozilla/gfx/Rect.h";
|
||||
|
||||
|
@ -18,7 +18,7 @@ async protocol PVRLayer
|
|||
manager PVRManager;
|
||||
|
||||
parent:
|
||||
async SubmitFrame(PTexture aTexture, uint64_t aFrameId,
|
||||
async SubmitFrame(SurfaceDescriptor aTexture, uint64_t aFrameId,
|
||||
Rect aLeftEyeRect, Rect aRightEyeRect);
|
||||
|
||||
async Destroy();
|
||||
|
|
|
@ -11,25 +11,21 @@
|
|||
#include "mozilla/layers/LayersMessages.h" // for TimedTexture
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/layers/SyncObject.h" // for SyncObjectClient
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
VRLayerChild::VRLayerChild()
|
||||
: mCanvasElement(nullptr)
|
||||
, mShSurfClient(nullptr)
|
||||
, mFront(nullptr)
|
||||
, mIPCOpen(false)
|
||||
, mLastSubmittedFrameId(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRLayerChild);
|
||||
}
|
||||
|
||||
VRLayerChild::~VRLayerChild()
|
||||
{
|
||||
if (mCanvasElement) {
|
||||
mCanvasElement->StopVRPresentation();
|
||||
}
|
||||
|
||||
ClearSurfaces();
|
||||
|
||||
MOZ_COUNT_DTOR(VRLayerChild);
|
||||
|
@ -40,7 +36,6 @@ VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement,
|
|||
const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
MOZ_ASSERT(aCanvasElement);
|
||||
aCanvasElement->StartVRPresentation();
|
||||
mLeftEyeRect = aLeftEyeRect;
|
||||
mRightEyeRect = aRightEyeRect;
|
||||
if (mCanvasElement == nullptr) {
|
||||
|
@ -55,31 +50,45 @@ VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement,
|
|||
void
|
||||
VRLayerChild::SubmitFrame(uint64_t aFrameId)
|
||||
{
|
||||
if (!mCanvasElement) {
|
||||
// aFrameId will not increment unless the previuosly submitted
|
||||
// frame was received by the VR thread and submitted to the VR
|
||||
// compositor. We early-exit here in the event that SubmitFrame
|
||||
// was called twice for the same aFrameId.
|
||||
if (!mCanvasElement || aFrameId == mLastSubmittedFrameId) {
|
||||
return;
|
||||
}
|
||||
mLastSubmittedFrameId = aFrameId;
|
||||
|
||||
mShSurfClient = mCanvasElement->GetVRFrame();
|
||||
if (!mShSurfClient) {
|
||||
// Keep the SharedSurfaceTextureClient alive long enough for
|
||||
// 1 extra frame, accomodating overlapped asynchronous rendering.
|
||||
mLastFrameTexture = mThisFrameTexture;
|
||||
|
||||
mThisFrameTexture = mCanvasElement->GetVRFrame();
|
||||
if (!mThisFrameTexture) {
|
||||
return;
|
||||
}
|
||||
VRManagerChild* vrmc = VRManagerChild::Get();
|
||||
layers::SyncObjectClient* syncObject = vrmc->GetSyncObject();
|
||||
mThisFrameTexture->SyncWithObject(syncObject);
|
||||
if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
if (syncObject && syncObject->IsSyncObjectValid()) {
|
||||
syncObject->Synchronize();
|
||||
}
|
||||
}
|
||||
|
||||
gl::SharedSurface* surf = mShSurfClient->Surf();
|
||||
gl::SharedSurface* surf = mThisFrameTexture->Surf();
|
||||
if (surf->mType == gl::SharedSurfaceType::Basic) {
|
||||
gfxCriticalError() << "SharedSurfaceType::Basic not supported for WebVR";
|
||||
return;
|
||||
}
|
||||
|
||||
mFront = mShSurfClient;
|
||||
mShSurfClient = nullptr;
|
||||
layers::SurfaceDescriptor desc;
|
||||
if (!surf->ToSurfaceDescriptor(&desc)) {
|
||||
gfxCriticalError() << "SharedSurface::ToSurfaceDescriptor failed in VRLayerChild::SubmitFrame";
|
||||
return;
|
||||
}
|
||||
|
||||
mFront->SetAddedToCompositableClient();
|
||||
VRManagerChild* vrmc = VRManagerChild::Get();
|
||||
mFront->SyncWithObject(vrmc->GetSyncObject());
|
||||
MOZ_ALWAYS_TRUE(mFront->InitIPDLActor(vrmc));
|
||||
|
||||
SendSubmitFrame(mFront->GetIPDLActor(), aFrameId,
|
||||
mLeftEyeRect, mRightEyeRect);
|
||||
SendSubmitFrame(desc, aFrameId, mLeftEyeRect, mRightEyeRect);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -91,8 +100,8 @@ VRLayerChild::IsIPCOpen()
|
|||
void
|
||||
VRLayerChild::ClearSurfaces()
|
||||
{
|
||||
mFront = nullptr;
|
||||
mShSurfClient = nullptr;
|
||||
mThisFrameTexture = nullptr;
|
||||
mLastFrameTexture = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,8 +47,6 @@ private:
|
|||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
RefPtr<dom::HTMLCanvasElement> mCanvasElement;
|
||||
RefPtr<layers::SharedSurfaceTextureClient> mShSurfClient;
|
||||
RefPtr<layers::TextureClient> mFront;
|
||||
bool mIPCOpen;
|
||||
|
||||
// AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
|
||||
|
@ -60,6 +58,11 @@ private:
|
|||
|
||||
gfx::Rect mLeftEyeRect;
|
||||
gfx::Rect mRightEyeRect;
|
||||
|
||||
RefPtr<layers::SharedSurfaceTextureClient> mThisFrameTexture;
|
||||
RefPtr<layers::SharedSurfaceTextureClient> mLastFrameTexture;
|
||||
|
||||
uint64_t mLastSubmittedFrameId;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "VRLayerParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "VRDisplayHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -55,14 +56,18 @@ VRLayerParent::Destroy()
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
VRLayerParent::RecvSubmitFrame(PTextureParent* texture,
|
||||
VRLayerParent::RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
|
||||
const uint64_t& aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
if (mVRDisplayID) {
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->SubmitFrame(this, texture, aFrameId, aLeftEyeRect, aRightEyeRect);
|
||||
RefPtr<VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
|
||||
if (display) {
|
||||
display->SubmitFrame(this, aTexture, aFrameId,
|
||||
aLeftEyeRect, aRightEyeRect);
|
||||
}
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
|
|
|
@ -20,7 +20,7 @@ class VRLayerParent : public PVRLayerParent {
|
|||
|
||||
public:
|
||||
VRLayerParent(uint32_t aVRDisplayID, const uint32_t aGroup);
|
||||
virtual mozilla::ipc::IPCResult RecvSubmitFrame(PTextureParent* texture,
|
||||
virtual mozilla::ipc::IPCResult RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
|
||||
const uint64_t& aFrameId,
|
||||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect) override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче