Bug 1383907 - Enable WebVR reftests on macOS; r?kip, jgilbert
MozReview-Commit-ID: 2OpA95QWI4d
--- a/dom/vr/test/reftest/reftest.list
+++ b/dom/vr/test/reftest/reftest.list
@@ -1,8 +1,10 @@
# WebVR Reftests
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)
-# VR SubmitFrame is only implemented for D3D11 now.
+# VR SubmitFrame is only implemented for D3D11 and MacOSX now.
# We need to continue to investigate why these reftests can be run well in local,
-# but will be suspended until terminating on reftest debug build.
-skip-if(!winWidget||!layersGPUAccelerated||isDebugBuild) == draw_rect.html wrapper.html?draw_rect.png
-skip-if(!winWidget||!layersGPUAccelerated||isDebugBuild) == change_size.html wrapper.html?change_size.png
+# but will be suspended until terminating on reftest D3D11 debug build.
+skip-if(Android||gtkWidget||(winWidget&&isDebugBuild)||!layersGPUAccelerated) == 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(Android||gtkWidget||(winWidget&&isDebugBuild)||!layersGPUAccelerated) == change_size.html wrapper.html?change_size.png
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -2,22 +2,26 @@
* 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/. */
#if defined(XP_WIN)
#include "CompositorD3D11.h"
#include "TextureD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
-#endif // XP_WIN
+#elif defined(XP_MACOSX)
+#include "mozilla/gfx/MacIOSurface.h"
+#endif
#include "mozilla/Base64.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
+#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "gfxVRPuppet.h"
+#include "VRManager.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
// See CompositorD3D11Shaders.h
namespace mozilla {
namespace layers {
struct ShaderBytes { const void* mData; size_t mLength; };
@@ -33,29 +37,19 @@ using namespace mozilla::layers;
// Reminder: changing the order of these buttons may break web content
static const uint64_t kPuppetButtonMask[] = {
1,
2,
4,
8
};
-
static const uint32_t kNumPuppetButtonMask = sizeof(kPuppetButtonMask) /
sizeof(uint64_t);
-
-static const uint32_t kPuppetAxes[] = {
- 0,
- 1,
- 2
-};
-
-static const uint32_t kNumPuppetAxis = sizeof(kPuppetAxes) /
- sizeof(uint32_t);
-
+static const uint32_t kNumPuppetAxis = 3;
static const uint32_t kNumPuppetHaptcs = 1;
VRDisplayPuppet::VRDisplayPuppet()
: VRDisplayHost(VRDeviceType::Puppet)
, mIsPresenting(false)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayPuppet, VRDisplayHost);
@@ -373,17 +367,17 @@ VRDisplayPuppet::SubmitFrame(TextureSour
VRSubmitFrameResultInfo result;
result.mFormat = SurfaceFormat::B8G8R8A8;
// If the original texture size is not pow of 2, CopyResource() will add padding,
// so the size is adjusted. We have to get the correct size by (mapInfo.RowPitch /
// the format size).
result.mWidth = mapInfo.RowPitch / 4;
result.mHeight = desc.Height;
result.mFrameNum = mDisplayInfo.mFrameId;
- nsCString rawString(Substring((char*)srcData, mapInfo.RowPitch * desc.Height));
+ nsCString rawString(Substring(srcData, mapInfo.RowPitch * desc.Height));
if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
MOZ_ASSERT(false, "Failed to encode base64 images.");
}
mContext->Unmap(mappedTexture, 0);
// Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
// and convert to a PNG image there.
vm->DispatchSubmitFrameResult(mDisplayInfo.mDisplayID, result);
@@ -469,22 +463,76 @@ VRDisplayPuppet::SubmitFrame(TextureSour
#elif defined(XP_MACOSX)
bool
VRDisplayPuppet::SubmitFrame(MacIOSurface* aMacIOSurface,
const IntSize& aSize,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
- if (!mIsPresenting) {
+ if (!mIsPresenting || !aMacIOSurface) {
return false;
}
- // TODO: Bug 1343730, Need to block until the next simulated
- // vblank interval and capture frames for use in reftests.
+ VRManager* vm = VRManager::Get();
+ MOZ_ASSERT(vm);
+
+ switch (gfxPrefs::VRPuppetSubmitFrame()) {
+ case 0:
+ // The VR frame is not displayed.
+ break;
+ case 1:
+ {
+ // The frames are submitted to VR compositor are decoded
+ // into a base64Image and dispatched to the DOM side.
+ RefPtr<SourceSurface> surf = aMacIOSurface->GetAsSurface();
+ RefPtr<DataSourceSurface> dataSurf = surf ? surf->GetDataSurface() :
+ nullptr;
+ if (dataSurf) {
+ // 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
+ // access the image library. So, we have to convert the RAW image data
+ // to a base64 string and forward it to let the content process to
+ // do the image conversion.
+ DataSourceSurface::MappedSurface map;
+ if (!dataSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
+ MOZ_ASSERT(false, "Read DataSourceSurface fail.");
+ return false;
+ }
+ const uint8_t* srcData = map.mData;
+ const auto& surfSize = dataSurf->GetSize();
+ VRSubmitFrameResultInfo result;
+ result.mFormat = SurfaceFormat::B8G8R8A8;
+ result.mWidth = surfSize.width;
+ result.mHeight = surfSize.height;
+ result.mFrameNum = mDisplayInfo.mFrameId;
+ // If the original texture size is not pow of 2, the data will not be tightly strided.
+ // We have to copy the pixels by rows.
+ nsCString rawString;
+ for (int32_t i = 0; i < surfSize.height; i++) {
+ rawString += Substring((const char*)(srcData) + i * map.mStride,
+ surfSize.width * 4);
+ }
+ dataSurf->Unmap();
+
+ if (Base64Encode(rawString, result.mBase64Image) != NS_OK) {
+ MOZ_ASSERT(false, "Failed to encode base64 images.");
+ }
+ // Dispatch the base64 encoded string to the DOM side. Then, it will be decoded
+ // and convert to a PNG image there.
+ vm->DispatchSubmitFrameResult(mDisplayInfo.mDisplayID, result);
+ }
+ break;
+ }
+ case 2:
+ {
+ MOZ_ASSERT(false, "No support for showing VR frames on MacOSX yet.");
+ break;
+ }
+ }
return false;
}
#endif
void
VRDisplayPuppet::NotifyVSync()
@@ -702,17 +750,17 @@ VRSystemManagerPuppet::HandleAxisMove(ui
if (controller->GetAxisMove(aAxis) != aValue) {
NewAxisMove(aControllerIdx, aAxis, aValue);
controller->SetAxisMove(aAxis, aValue);
}
}
void
VRSystemManagerPuppet::HandlePoseTracking(uint32_t aControllerIdx,
- const GamepadPoseState& aPose,
+ const dom::GamepadPoseState& aPose,
VRControllerHost* aController)
{
MOZ_ASSERT(aController);
if (aPose != aController->GetPose()) {
aController->SetPose(aPose);
NewPoseState(aControllerIdx, aPose);
}
}
--- a/gfx/vr/moz.build
+++ b/gfx/vr/moz.build
@@ -19,30 +19,30 @@ LOCAL_INCLUDES += [
'/dom/base',
'/gfx/layers/d3d11',
'/gfx/thebes',
]
UNIFIED_SOURCES += [
'gfxVR.cpp',
'gfxVROSVR.cpp',
- 'gfxVRPuppet.cpp',
'ipc/VRLayerChild.cpp',
'ipc/VRLayerParent.cpp',
'ipc/VRManagerChild.cpp',
'ipc/VRManagerParent.cpp',
'VRDisplayClient.cpp',
'VRDisplayPresentation.cpp',
'VRManager.cpp',
]
# VRDisplayHost includes MacIOSurface.h which includes Mac headers
# which define Size and Points types in the root namespace that
# often conflict with our own types.
SOURCES += [
+ 'gfxVRPuppet.cpp',
'VRDisplayHost.cpp',
]
# Build OpenVR on Windows, Linux, and macOS desktop targets
if CONFIG['OS_TARGET'] in ('WINNT', 'Linux', 'Darwin'):
DIRS += [
'openvr',
]