--- a/dom/vr/test/reftest/reftest.list
+++ b/dom/vr/test/reftest/reftest.list
@@ -1,10 +1,10 @@
# WebVR Reftests
# Please confirm there is no other VR display connected. Otherwise, VRPuppetDisplay can't be attached.
default-preferences pref(dom.vr.puppet.enabled,true) pref(dom.vr.test.enabled,true) pref(dom.vr.require-gesture,false) pref(dom.vr.puppet.submitframe,1) pref(dom.vr.display.rafMaxDuration,200) pref(dom.vr.display.enumerate.interval,0) pref(dom.vr.controller.enumerate.interval,0)
# VR SubmitFrame is only implemented for D3D11.1 and MacOSX now.
# Our Windows 7 test machines don't support D3D11.1, so we run these tests on Windows 8+ only.
-skip-if((!winWidget&&release_or_beta)||Android||gtkWidget||!layersGPUAccelerated||/^Windows\x20NT\x206\.1/.test(http.oscpu)) == draw_rect.html wrapper.html?draw_rect.png
+skip-if((!winWidget&&release_or_beta)||Android||/^Windows\x20NT\x206\.1/.test(http.oscpu)) == draw_rect.html wrapper.html?draw_rect.png
# On MacOSX platform, getting different color interpolation result.
# For lower resolution Mac hardware, we need to adjust it to fuzzy-if(cocoaWidget,1,1200).
fuzzy-if(cocoaWidget,1,600) skip-if((!winWidget&&release_or_beta)||Android||gtkWidget||!layersGPUAccelerated||/^Windows\x20NT\x206\.1/.test(http.oscpu)) == change_size.html wrapper.html?change_size.png
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -491,17 +491,17 @@ private:
DECL_GFX_PREF(Live, "gfx.perf-warnings.enabled", PerfWarnings, bool, false);
DECL_GFX_PREF(Live, "gfx.testing.device-reset", DeviceResetForTesting, int32_t, 0);
DECL_GFX_PREF(Live, "gfx.testing.device-fail", DeviceFailForTesting, bool, false);
DECL_GFX_PREF(Once, "gfx.text.disable-aa", DisableAllTextAA, bool, false);
DECL_GFX_PREF(Live, "gfx.ycbcr.accurate-conversion", YCbCrAccurateConversion, bool, false);
// Disable surface sharing due to issues with compatible FBConfigs on
// NVIDIA drivers as described in bug 1193015.
- DECL_GFX_PREF(Live, "gfx.use-glx-texture-from-pixmap", UseGLXTextureFromPixmap, bool, false);
+ DECL_GFX_PREF(Live, "gfx.use-glx-texture-from-pixmap", UseGLXTextureFromPixmap, bool, true); // FINDME!!! KIP!! HACK!!
DECL_GFX_PREF(Once, "gfx.use-iosurface-textures", UseIOSurfaceTextures, bool, false);
DECL_GFX_PREF(Once, "gfx.use-mutex-on-present", UseMutexOnPresent, bool, false);
DECL_GFX_PREF(Once, "gfx.use-surfacetexture-textures", UseSurfaceTextureTextures, bool, false);
DECL_GFX_PREF(Live, "gfx.vsync.collect-scroll-transforms", CollectScrollTransforms, bool, false);
DECL_GFX_PREF(Once, "gfx.vsync.compositor.unobserve-count", CompositorUnobserveCount, int32_t, 10);
DECL_GFX_PREF(Once, "gfx.webrender.all", WebRenderAll, bool, false);
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -19,25 +19,33 @@
#include "../layers/d3d11/CompositorD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/TextureD3D11.h"
#elif defined(XP_MACOSX)
#include "mozilla/gfx/MacIOSurface.h"
+#elif defined(XP_LINUX) && !defined(MOZ_ANDROID_GOOGLE_VR)
+
+#include "GLContextProvider.h" // for GLContextProvider
+#include "GLContext.h" // for GLContext
+#include "mozilla/gfx/gfxVars.h" // for gfxVars
+#include "SurfaceTypes.h" // for SurfaceCaps
+
#endif
#if defined(MOZ_ANDROID_GOOGLE_VR)
#include "mozilla/layers/CompositorThread.h"
#endif // defined(MOZ_ANDROID_GOOGLE_VR)
using namespace mozilla;
using namespace mozilla::gfx;
+using namespace mozilla::gl;
using namespace mozilla::layers;
VRDisplayHost::AutoRestoreRenderState::AutoRestoreRenderState(VRDisplayHost* aDisplay)
: mDisplay(aDisplay)
, mSuccess(true)
{
#if defined(XP_WIN)
ID3D11DeviceContext1* context = mDisplay->GetD3DDeviceContext();
@@ -146,16 +154,46 @@ VRDisplayHost::GetD3DDeviceContext()
ID3DDeviceContextState*
VRDisplayHost::GetD3DDeviceContextState()
{
return mDeviceContextState;
}
#endif // defined(XP_WIN)
+#if defined(XP_LINUX) && !defined(MOZ_ANDROID_GOOGLE_VR)
+
+bool
+VRDisplayHost::CreateGLContext()
+{
+ if (!mGLContext) {
+ const gfx::IntSize dummySize(16, 16);
+ SurfaceCaps caps = SurfaceCaps::ForRGB();
+ caps.preserve = false;
+ caps.bpp16 = gfxVars::OffscreenFormat() == SurfaceFormat::R5G6B5_UINT16;
+
+ nsCString discardFailureId;
+ mGLContext = GLContextProvider::CreateOffscreen(dummySize,
+ caps, CreateContextFlags::REQUIRE_COMPAT_PROFILE,
+ &discardFailureId);
+ }
+ if (!mGLContext) {
+ NS_WARNING("Failed to create VRDisplayHost context");
+ }
+ return mGLContext != nullptr;
+}
+
+gl::GLContext*
+VRDisplayHost::GetGLContext()
+{
+ return mGLContext;
+}
+
+#endif // defined(XP_LINUX) && !defined(MOZ_ANDROID_GOOGLE_VR)
+
void
VRDisplayHost::SetGroupMask(uint32_t aGroupMask)
{
mDisplayInfo.mGroupMask = aGroupMask;
}
bool
VRDisplayHost::GetIsConnected()
@@ -339,24 +377,35 @@ VRDisplayHost::SubmitFrameInternal(const
#elif defined(MOZ_ANDROID_GOOGLE_VR)
case SurfaceDescriptor::TEGLImageDescriptor: {
const EGLImageDescriptor& desc = aTexture.get_EGLImageDescriptor();
if (!SubmitFrame(&desc, aLeftEyeRect, aRightEyeRect)) {
return;
}
break;
}
+#elif defined(XP_LINUX)
+ case SurfaceDescriptor::TSurfaceDescriptorX11: {
+ if (!CreateGLContext()) {
+ return;
+ }
+ const SurfaceDescriptorX11& desc = aTexture.get_SurfaceDescriptorX11();
+ if (!SubmitFrame(&desc, desc.mSize, aLeftEyeRect, aRightEyeRect)) {
+ return;
+ }
+ break;
+ }
#endif
default: {
NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture");
return;
}
}
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_ANDROID_GOOGLE_VR)
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_ANDROID_GOOGLE_VR) || defined(XP_LINUX)
/**
* Trigger the next VSync immediately after we are successfully
* submitting frames. As SubmitFrame is responsible for throttling
* the render loop, if we don't successfully call it, we shouldn't trigger
* NotifyVRVsync immediately, as it will run unbounded.
* If NotifyVRVsync is not called here due to SubmitFrame failing, the
* fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause
--- a/gfx/vr/VRDisplayHost.h
+++ b/gfx/vr/VRDisplayHost.h
@@ -21,16 +21,19 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#if defined(XP_WIN)
#include <d3d11_1.h>
#elif defined(XP_MACOSX)
class MacIOSurface;
#endif
namespace mozilla {
+namespace gl {
+class GLContext;
+}
namespace gfx {
class VRThread;
class VRLayerParent;
class VRDisplayHost {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRDisplayHost)
@@ -85,16 +88,21 @@ protected:
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
#elif defined(MOZ_ANDROID_GOOGLE_VR)
virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) = 0;
+#elif defined(XP_LINUX)
+ virtual bool SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) = 0;
#endif
VRDisplayInfo mDisplayInfo;
nsTArray<VRLayerParent *> mLayers;
// Weak reference to mLayers entries are cleared in
// VRLayerParent destructor
@@ -118,16 +126,23 @@ protected:
RefPtr<ID3D11Device1> mDevice;
RefPtr<ID3D11DeviceContext1> mContext;
ID3D11Device1* GetD3DDevice();
ID3D11DeviceContext1* GetD3DDeviceContext();
ID3DDeviceContextState* GetD3DDeviceContextState();
private:
RefPtr<ID3DDeviceContextState> mDeviceContextState;
+#elif defined(XP_LINUX) && !defined(MOZ_ANDROID_GOOGLE_VR)
+protected:
+ bool CreateGLContext();
+ gl::GLContext* GetGLContext();
+private:
+ RefPtr<gl::GLContext> mGLContext;
+
#endif
};
class VRControllerHost {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRControllerHost)
const VRControllerInfo& GetControllerInfo() const;
--- a/gfx/vr/gfxVROSVR.cpp
+++ b/gfx/vr/gfxVROSVR.cpp
@@ -365,16 +365,28 @@ VRDisplayOSVR::SubmitFrame(const mozilla
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
// XXX Add code to submit frame
MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
return false;
}
+#elif defined(XP_LINUX)
+
+bool
+VRDisplayOSVR::SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect)
+{
+ // XXX Add code to submit frame
+ return false;
+}
+
#endif
void
VRDisplayOSVR::StartPresentation()
{
// XXX Add code to start VR Presentation
}
--- a/gfx/vr/gfxVROSVR.h
+++ b/gfx/vr/gfxVROSVR.h
@@ -45,16 +45,21 @@ protected:
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
#elif defined(MOZ_ANDROID_GOOGLE_VR)
virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor*,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
+#elif defined(XP_LINUX)
+ virtual bool SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) override;
#endif
public:
explicit VRDisplayOSVR(OSVR_ClientContext* context,
OSVR_ClientInterface* iface,
OSVR_DisplayConfig* display);
protected:
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -13,16 +13,22 @@
#include "mozilla/gfx/Quaternion.h"
#ifdef XP_WIN
#include "CompositorD3D11.h"
#include "TextureD3D11.h"
#elif defined(XP_MACOSX)
#include "mozilla/gfx/MacIOSurface.h"
+#elif defined(XP_LINUX) && !defined(MOZ_ANDROID_GOOGLE_VR)
+#include "gfxXlibSurface.h"
+#include "GLContext.h" // for GLContext
+#include "GLContextProvider.h"
+#include "GLContextGLX.h"
+#include "GLXLibrary.h"
#endif
#include "gfxVROpenVR.h"
#include "VRManagerParent.h"
#include "VRManager.h"
#include "VRThread.h"
#include "nsServiceManagerUtils.h"
@@ -34,16 +40,17 @@
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::gfx::impl;
+using namespace mozilla::gl;
using namespace mozilla::layers;
using namespace mozilla::dom;
#define BTN_MASK_FROM_ID(_id) \
::vr::ButtonMaskFromId(vr::EVRButtonId::_id)
static const uint32_t kNumOpenVRHaptcs = 1;
@@ -417,16 +424,57 @@ VRDisplayOpenVR::SubmitFrame(MacIOSurfac
} else {
result = SubmitFrame((void *)ioSurface,
::vr::ETextureType::TextureType_IOSurface,
aSize, aLeftEyeRect, aRightEyeRect);
}
return result;
}
+#elif defined(XP_LINUX)
+
+bool
+VRDisplayOpenVR::SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect)
+{
+ bool result = false;
+
+ RefPtr<gfxXlibSurface> surface = aDescriptor->OpenForeign();
+ // FINDME!! KIP!! HACK!! IMPLEMENT THIS!
+ // KIP - Maybe follow this pattern:
+ // mozilla::layers::X11TextureSourceOGL::X11TextureSourceOGL
+ // Also follow mozilla::layers::CompositorOGL::CreateContext()...
+
+ GLContext* context = GetGLContext();
+
+ GLuint tex = 0;
+
+ context->fGenTextures(1, &tex);
+
+ context->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
+ gl::sGLXLibrary.BindTexImage(surface->XDisplay(), surface->GetGLXPixmap());
+
+ if (tex) {
+
+ result = SubmitFrame((void *)tex,
+ ::vr::ETextureType::TextureType_OpenGL,
+ aSize, aLeftEyeRect, aRightEyeRect);
+
+ if (context->MakeCurrent()) {
+ gl::sGLXLibrary.ReleaseTexImage(surface->XDisplay(), surface->GetGLXPixmap());
+ context->fDeleteTextures(1, &tex);
+ tex = 0;
+ }
+ }
+
+ return result;
+}
+
#endif
VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplayID,
uint32_t aNumButtons, uint32_t aNumTriggers,
uint32_t aNumAxes, const nsCString& aId)
: VRControllerHost(VRDeviceType::OpenVR, aHand, aDisplayID)
, mTrigger(aNumTriggers)
, mAxisMove(aNumAxes)
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -43,16 +43,21 @@ protected:
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
#elif defined(XP_MACOSX)
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
+#elif defined(XP_LINUX)
+ virtual bool SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) override;
#endif
public:
explicit VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
::vr::IVRChaperone *aVRChaperone,
::vr::IVRCompositor *aVRCompositor);
void Refresh();
protected:
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -561,16 +561,26 @@ bool
VRDisplayPuppet::SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread());
return false;
}
+#elif defined(XP_LINUX)
+
+bool
+VRDisplayPuppet::SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) {
+ return false;
+}
+
#endif
void
VRDisplayPuppet::Refresh()
{
// We update mIsConneced once per refresh.
mDisplayInfo.mIsConnected = true;
}
--- a/gfx/vr/gfxVRPuppet.h
+++ b/gfx/vr/gfxVRPuppet.h
@@ -41,16 +41,21 @@ protected:
virtual bool SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
#elif defined(MOZ_ANDROID_GOOGLE_VR)
virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
+#elif defined(XP_LINUX)
+ virtual bool SubmitFrame(const mozilla::layers::SurfaceDescriptorX11* aDescriptor,
+ const IntSize& aSize,
+ const gfx::Rect& aLeftEyeRect,
+ const gfx::Rect& aRightEyeRect) override;
#endif
public:
explicit VRDisplayPuppet();
void Refresh();
protected:
virtual ~VRDisplayPuppet();