merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-12-30 12:00:03 +01:00
Родитель b2bd861a74 43bc87df8a
Коммит aa5ce3db49
278 изменённых файлов: 11010 добавлений и 8593 удалений

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

@ -5537,6 +5537,7 @@
canvas.width = 160 * scale;
canvas.height = 90 * scale;
let toDrag;
let dragImageOffset = -16;
if (gMultiProcessBrowser) {
var context = canvas.getContext('2d');
context.fillStyle = "white";
@ -5548,7 +5549,13 @@
this._dndCanvas = canvas;
this._dndPanel = document.createElement("panel");
this._dndPanel.setAttribute("type", "drag");
this._dndPanel.appendChild(canvas);
let wrapper = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
wrapper.style.width = "160px";
wrapper.style.height = "90px";
wrapper.appendChild(canvas);
canvas.style.width = "100%";
canvas.style.height = "100%";
this._dndPanel.appendChild(wrapper);
document.documentElement.appendChild(this._dndPanel);
}
// PageThumb is async with e10s but that's fine
@ -5561,8 +5568,9 @@
// be fine, so let's use the canvas for setDragImage.
PageThumbs.captureToCanvas(browser, canvas);
toDrag = canvas;
dragImageOffset = dragImageOffset * scale;
}
dt.setDragImage(toDrag, -16 * scale, -16 * scale);
dt.setDragImage(toDrag, dragImageOffset, dragImageOffset);
// _dragData.offsetX/Y give the coordinates that the mouse should be
// positioned relative to the corner of the new window created upon

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

@ -534,6 +534,10 @@ case "$target" in
# -Zc:sizedDealloc- disables C++14 global sized deallocation (see bug 1160146)
CXXFLAGS="$CXXFLAGS -Zc:sizedDealloc-"
# Disable C++11 thread-safe statics due to crashes on XP (bug 1204752)
# See https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics
CXXFLAGS="$CXXFLAGS -Zc:threadSafeInit-"
# https://connect.microsoft.com/VisualStudio/feedback/details/888527/warnings-on-dbghelp-h
# for dbghelp.h, imagehlp.h, and shobj.h
# C4091: 'typedef ': ignored on left of '' when no variable is declared

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

@ -100,10 +100,12 @@ static RedirEntry kRedirMap[] = {
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::ALLOW_SCRIPT
},
#ifndef ANDROID
{
"profiles", "chrome://global/content/aboutProfiles.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
#endif
// about:srcdoc is unresolvable by specification. It is included here
// because the security manager would disallow srcdoc iframes otherwise.
{

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

@ -180,7 +180,9 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "plugins", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "serviceworkers", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
#ifndef ANDROID
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "profiles", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },

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

@ -220,6 +220,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageAreaListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDevicesPromises)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -360,6 +361,8 @@ Navigator::Invalidate()
if (mDeviceStorageAreaListener) {
mDeviceStorageAreaListener = nullptr;
}
mVRGetDevicesPromises.Clear();
}
//*****************************************************************************
@ -1939,16 +1942,35 @@ Navigator::GetVRDevices(ErrorResult& aRv)
return nullptr;
}
// We pass ourself to RefreshVRDevices, so NotifyVRDevicesUpdated will
// be called asynchronously, resolving the promises in mVRGetDevicesPromises.
if (!VRDevice::RefreshVRDevices(this)) {
p->MaybeReject(NS_ERROR_FAILURE);
return p.forget();
}
mVRGetDevicesPromises.AppendElement(p);
return p.forget();
}
void
Navigator::NotifyVRDevicesUpdated()
{
// Synchronize the VR devices and resolve the promises in
// mVRGetDevicesPromises
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(mWindow.get());
nsTArray<RefPtr<VRDevice>> vrDevs;
if (!win->GetVRDevices(vrDevs)) {
p->MaybeReject(NS_ERROR_FAILURE);
if (win->UpdateVRDevices(vrDevs)) {
for (auto p: mVRGetDevicesPromises) {
p->MaybeResolve(vrDevs);
}
} else {
p->MaybeResolve(vrDevs);
for (auto p: mVRGetDevicesPromises) {
p->MaybeReject(NS_ERROR_FAILURE);
}
}
return p.forget();
mVRGetDevicesPromises.Clear();
}
//*****************************************************************************

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

@ -268,6 +268,7 @@ public:
void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
#endif // MOZ_GAMEPAD
already_AddRefed<Promise> GetVRDevices(ErrorResult& aRv);
void NotifyVRDevicesUpdated();
#ifdef MOZ_B2G_FM
FMRadio* GetMozFMRadio(ErrorResult& aRv);
#endif
@ -414,6 +415,8 @@ private:
// we'd need to figure out exactly how to trace that, and that seems to be
// rocket science. :(
nsInterfaceHashtable<nsStringHashKey, nsISupports> mCachedResolveResults;
nsTArray<RefPtr<Promise> > mVRGetDevicesPromises;
};
} // namespace dom

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

@ -2122,17 +2122,6 @@ public:
return true;
}
bool Suspend(JSContext* aCx) override
{
{
MutexAutoLock lock(mWebSocketImpl->mMutex);
mWebSocketImpl->mWorkerShuttingDown = true;
}
mWebSocketImpl->CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
return true;
}
private:
WebSocketImpl* mWebSocketImpl;
};

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

@ -11442,10 +11442,10 @@ nsresult nsDocument::RemoteFrameFullscreenReverted()
}
static void
ReleaseHMDInfoRef(void *, nsIAtom*, void *aPropertyValue, void *)
ReleaseVRDeviceProxyRef(void *, nsIAtom*, void *aPropertyValue, void *)
{
if (aPropertyValue) {
static_cast<gfx::VRHMDInfo*>(aPropertyValue)->Release();
static_cast<gfx::VRDeviceProxy*>(aPropertyValue)->Release();
}
}
@ -11764,9 +11764,9 @@ nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
// Process options -- in this case, just HMD
if (aRequest.mVRHMDDevice) {
RefPtr<gfx::VRHMDInfo> hmdRef = aRequest.mVRHMDDevice;
RefPtr<gfx::VRDeviceProxy> hmdRef = aRequest.mVRHMDDevice;
elem->SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
ReleaseHMDInfoRef, true);
ReleaseVRDeviceProxyRef, true);
}
// Set the full-screen element. This sets the full-screen style on the

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

@ -111,7 +111,7 @@ private:
RefPtr<nsDocument> mDocument;
public:
RefPtr<gfx::VRHMDInfo> mVRHMDDevice;
RefPtr<gfx::VRDeviceProxy> mVRHMDDevice;
// This value should be true if the fullscreen request is
// originated from chrome code.
bool mIsCallerChrome = false;

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

@ -1177,8 +1177,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mCleanedUp(false),
mDialogAbuseCount(0),
mAreDialogsEnabled(true),
mCanSkipCCGeneration(0),
mVRDevicesInitialized(false)
mCanSkipCCGeneration(0)
{
AssertIsOnMainThread();
@ -4282,7 +4281,7 @@ nsGlobalWindow::IsShowModalDialogEnabled(JSContext*, JSObject*)
sAddedPrefCache = true;
}
return !sIsDisabled;
return !sIsDisabled && !XRE_IsContentProcess();
}
nsIDOMOfflineResourceList*
@ -5964,7 +5963,7 @@ FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
}
static bool
MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRHMDInfo* aHMD,
MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRDeviceProxy* aHMD,
nsPIDOMWindow::FullscreenReason aReason, bool aFullscreen)
{
nsCOMPtr<nsIWidget> widget = aWindow->GetMainWidget();
@ -5997,7 +5996,7 @@ MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRHMDInfo* aHMD,
nsresult
nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason,
bool aFullScreen,
gfx::VRHMDInfo* aHMD)
gfx::VRDeviceProxy* aHMD)
{
MOZ_ASSERT(IsOuterWindow());
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
@ -8790,7 +8789,7 @@ nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl, nsIVariant* aArgumen
mDoc->WarnOnceAbout(nsIDocument::eShowModalDialog);
}
if (!IsShowModalDialogEnabled() || XRE_IsContentProcess()) {
if (!IsShowModalDialogEnabled()) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
@ -12941,19 +12940,11 @@ nsGlobalWindow::SyncGamepadState()
#endif // MOZ_GAMEPAD
bool
nsGlobalWindow::GetVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices)
nsGlobalWindow::UpdateVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices)
{
FORWARD_TO_INNER(GetVRDevices, (aDevices), false);
FORWARD_TO_INNER(UpdateVRDevices, (aDevices), false);
if (!mVRDevicesInitialized) {
bool ok = mozilla::dom::VRDevice::CreateAllKnownVRDevices(ToSupports(this), mVRDevices);
if (!ok) {
mVRDevices.Clear();
return false;
}
}
mVRDevicesInitialized = true;
VRDevice::UpdateVRDevices(mVRDevices, ToSupports(this));
aDevices = mVRDevices;
return true;
}

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

@ -129,7 +129,7 @@ class IDBFactory;
} // namespace indexedDB
} // namespace dom
namespace gfx {
class VRHMDInfo;
class VRDeviceProxy;
} // namespace gfx
} // namespace mozilla
@ -471,7 +471,7 @@ public:
// Outer windows only.
virtual nsresult SetFullscreenInternal(
FullscreenReason aReason, bool aIsFullscreen,
mozilla::gfx::VRHMDInfo *aHMD = nullptr) override final;
mozilla::gfx::VRDeviceProxy *aHMD = nullptr) override final;
virtual void FinishFullscreenChange(bool aIsFullscreen) override final;
void SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
nsIWidget* aWidget, nsIScreen* aScreen);
@ -760,8 +760,8 @@ public:
void EnableGamepadUpdates();
void DisableGamepadUpdates();
// Get the VR devices for this window, initializing if necessary
bool GetVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices);
// Update the VR devices for this window
bool UpdateVRDevices(nsTArray<RefPtr<mozilla::dom::VRDevice>>& aDevices);
#define EVENT(name_, id_, type_, struct_) \
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
@ -1848,12 +1848,8 @@ protected:
// This is the CC generation the last time we called CanSkip.
uint32_t mCanSkipCCGeneration;
// Did VR get initialized for this window?
bool mVRDevicesInitialized;
// The VRDevies for this window
nsTArray<RefPtr<mozilla::dom::VRDevice>> mVRDevices;
// Any attached HMD when fullscreen
RefPtr<mozilla::gfx::VRHMDInfo> mVRHMDInfo;
friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils;

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

@ -102,10 +102,6 @@ class ImageLoader;
class Rule;
} // namespace css
namespace gfx {
class VRHMDInfo;
} // namespace gfx
namespace dom {
class AnonymousContent;
class Attr;

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

@ -41,7 +41,7 @@ class Element;
class ServiceWorkerRegistrationMainThread;
} // namespace dom
namespace gfx {
class VRHMDInfo;
class VRDeviceProxy;
} // namespace gfx
} // namespace mozilla
@ -511,7 +511,7 @@ public:
*/
virtual nsresult SetFullscreenInternal(
FullscreenReason aReason, bool aIsFullscreen,
mozilla::gfx::VRHMDInfo *aHMD = nullptr) = 0;
mozilla::gfx::VRDeviceProxy *aHMD = nullptr) = 0;
/**
* This function should be called when the fullscreen state is flipped.

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

@ -1311,7 +1311,7 @@ public:
if (!mPixelStore_PremultiplyAlpha)
flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
gfx::DrawTarget* idealDrawTarget = nullptr; // Don't care for now.
RefPtr<gfx::DrawTarget> idealDrawTarget = nullptr; // Don't care for now.
return nsLayoutUtils::SurfaceFromElement(elem, flags, idealDrawTarget);
}

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

@ -7,7 +7,6 @@
#include "mozilla/dom/Touch.h"
#include "mozilla/dom/EventTarget.h"
#include "mozilla/dom/TouchBinding.h"
#include "mozilla/dom/TouchEvent.h"
#include "nsGlobalWindow.h"
#include "nsContentUtils.h"
@ -16,6 +15,29 @@
namespace mozilla {
namespace dom {
// static
already_AddRefed<Touch>
Touch::Constructor(const GlobalObject& aGlobal,
const TouchInit& aParam,
ErrorResult& aRv)
{
// Annoyingly many parameters, make sure the ordering is the same as in the
// Touch constructor.
RefPtr<Touch> touch = new Touch(aParam.mTarget,
aParam.mIdentifier,
aParam.mPageX,
aParam.mPageY,
aParam.mScreenX,
aParam.mScreenY,
aParam.mClientX,
aParam.mClientY,
aParam.mRadiusX,
aParam.mRadiusY,
aParam.mRotationAngle,
aParam.mForce);
return touch.forget();
}
Touch::Touch(EventTarget* aTarget,
int32_t aIdentifier,
int32_t aPageX,

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

@ -10,6 +10,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/dom/TouchBinding.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
#include "Units.h"
@ -28,6 +29,10 @@ class Touch final : public nsISupports
public:
static bool PrefEnabled(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<Touch> Constructor(const GlobalObject& aGlobal,
const TouchInit& aParam,
ErrorResult& aRv);
Touch(EventTarget* aTarget,
int32_t aIdentifier,
int32_t aPageX,

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

@ -207,6 +207,39 @@ TouchEvent::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
return prefValue;
}
// static
already_AddRefed<Event>
TouchEvent::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const TouchEventInit& aParam,
ErrorResult& aRv)
{
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<TouchEvent> e = new TouchEvent(t, nullptr, nullptr);
bool trusted = e->Init(t);
RefPtr<TouchList> touches = e->CopyTouches(aParam.mTouches);
RefPtr<TouchList> targetTouches = e->CopyTouches(aParam.mTargetTouches);
RefPtr<TouchList> changedTouches = e->CopyTouches(aParam.mChangedTouches);
e->InitTouchEvent(aType, aParam.mBubbles, aParam.mCancelable, aParam.mView,
aParam.mDetail, aParam.mCtrlKey, aParam.mAltKey,
aParam.mShiftKey, aParam.mMetaKey, touches, targetTouches,
changedTouches);
e->SetTrusted(trusted);
return e.forget();
}
already_AddRefed<TouchList>
TouchEvent::CopyTouches(const Sequence<OwningNonNull<Touch>>& aTouches)
{
RefPtr<TouchList> list = new TouchList(GetParentObject());
size_t len = aTouches.Length();
for (size_t i = 0; i < len; ++i) {
list->Append(aTouches[i]);
}
return list.forget();
}
bool
TouchEvent::AltKey()
{

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

@ -95,6 +95,9 @@ public:
return TouchEventBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<TouchList>
CopyTouches(const Sequence<OwningNonNull<Touch>>& aTouches);
TouchList* Touches();
TouchList* TargetTouches();
TouchList* ChangedTouches();
@ -120,6 +123,11 @@ public:
static bool PrefEnabled(JSContext* aCx = nullptr,
JSObject* aGlobal = nullptr);
static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const TouchEventInit& aParam,
ErrorResult& aRv);
protected:
~TouchEvent() {}

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

@ -3173,17 +3173,7 @@ void HTMLMediaElement::UpdateSrcMediaStreamPlaying(uint32_t aFlags)
stream->AddAudioOutput(this);
SetVolumeInternal();
#ifdef MOZ_WIDGET_GONK
bool bUseOverlayImage = mSrcStream->AsDOMHwMediaStream() != nullptr;
#else
bool bUseOverlayImage = false;
#endif
VideoFrameContainer* container;
if (bUseOverlayImage) {
container = GetOverlayImageVideoFrameContainer();
} else {
container = GetVideoFrameContainer();
}
VideoFrameContainer* container = GetVideoFrameContainer();
if (container) {
stream->AddVideoOutput(container);
}
@ -4030,22 +4020,6 @@ VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
return mVideoFrameContainer;
}
VideoFrameContainer* HTMLMediaElement::GetOverlayImageVideoFrameContainer()
{
if (mVideoFrameContainer)
return mVideoFrameContainer;
// Only video frames need an image container.
if (!IsVideo()) {
return nullptr;
}
mVideoFrameContainer =
new VideoFrameContainer(this, LayerManager::CreateImageContainer(ImageContainer::ASYNCHRONOUS_OVERLAY));
return mVideoFrameContainer;
}
nsresult HTMLMediaElement::DispatchEvent(const nsAString& aName)
{
LOG_EVENT(LogLevel::Debug, ("%p Dispatching event %s", this,
@ -4382,6 +4356,9 @@ void HTMLMediaElement::NotifyAddedSource()
// A load was paused in the resource selection algorithm, waiting for
// a new source child to be added, resume the resource selection algorithm.
if (mLoadWaitStatus == WAITING_FOR_SOURCE) {
// Rest the flag so we don't queue multiple LoadFromSourceTask() when
// multiple <source> are attached in an event loop.
mLoadWaitStatus = NOT_WAITING;
QueueLoadFromSourceTask();
}
}

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

@ -218,9 +218,6 @@ public:
virtual bool IsHidden() const final override;
// In order to create overlayImageContainer to support DOMHwMediaStream.
VideoFrameContainer* GetOverlayImageVideoFrameContainer();
// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
B2G_ACL_EXPORT virtual VideoFrameContainer* GetVideoFrameContainer() final override;

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

@ -602,3 +602,4 @@ skip-if = buildapp == 'b2g' # bug 1129014
[test_bug1166138.html]
[test_filepicker_default_directory.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
[test_bug1233598.html]

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1233598
-->
<head>
<title>Test for Bug 1233598</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1233598">Mozilla Bug 1233598</a>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1233598 **/
var i; // must be out here to trigger the leak
function runTest()
{
i = document.createElement("input");
i.setAttribute("type", "file");
i.getFilesAndDirectories(); // returns a promise
ok(true, "Are we leaking?");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set":[["dom.input.dirpicker", true]]}, runTest);
</script>
</pre>
</body>
</html>

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

@ -199,6 +199,7 @@
#include "GMPDecoderModule.h"
#include "gfxPlatform.h"
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
#include "VRManagerChild.h"
using namespace mozilla;
using namespace mozilla::docshell;
@ -1260,6 +1261,13 @@ ContentChild::AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
return ImageBridgeChild::StartUpInChildProcess(aTransport, aOtherProcess);
}
gfx::PVRManagerChild*
ContentChild::AllocPVRManagerChild(Transport* aTransport,
ProcessId aOtherProcess)
{
return gfx::VRManagerChild::StartUpInChildProcess(aTransport, aOtherProcess);
}
PBackgroundChild*
ContentChild::AllocPBackgroundChild(Transport* aTransport,
ProcessId aOtherProcess)

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

@ -148,6 +148,10 @@ public:
AllocPProcessHangMonitorChild(Transport* aTransport,
ProcessId aOtherProcess) override;
PVRManagerChild*
AllocPVRManagerChild(Transport* aTransport,
ProcessId aOtherProcess) override;
virtual bool RecvSetProcessSandbox(const MaybeFileDesc& aBroker) override;
PBackgroundChild*

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

@ -268,6 +268,8 @@ using namespace mozilla::system;
#include "mozilla/dom/GamepadMonitoring.h"
#endif
#include "VRManagerParent.h" // for VRManagerParent
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
#if defined(XP_WIN)
@ -2639,6 +2641,9 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
opened = PImageBridge::Open(this);
MOZ_ASSERT(opened);
opened = gfx::PVRManager::Open(this);
MOZ_ASSERT(opened);
}
#ifdef MOZ_WIDGET_GONK
DebugOnly<bool> opened = PSharedBufferManager::Open(this);
@ -3411,6 +3416,13 @@ ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
return CompositorParent::Create(aTransport, aOtherProcess);
}
gfx::PVRManagerParent*
ContentParent::AllocPVRManagerParent(Transport* aTransport,
ProcessId aOtherProcess)
{
return gfx::VRManagerParent::CreateCrossProcess(aTransport, aOtherProcess);
}
PImageBridgeParent*
ContentParent::AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess)

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

@ -612,6 +612,10 @@ private:
AllocPProcessHangMonitorParent(Transport* aTransport,
ProcessId aOtherProcess) override;
PVRManagerParent*
AllocPVRManagerParent(Transport* aTransport,
ProcessId aOtherProcess) override;
virtual bool RecvGetProcessAttributes(ContentParentId* aCpId,
bool* aIsForApp,
bool* aIsForBrowser) override;

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

@ -54,6 +54,7 @@ include protocol PRemoteSpellcheckEngine;
include protocol PWebBrowserPersistDocument;
include protocol PWebrtcGlobal;
include protocol PPresentation;
include protocol PVRManager;
include DOMTypes;
include JavaScriptTypes;
include InputStreamParams;
@ -451,6 +452,7 @@ prio(normal upto urgent) sync protocol PContent
parent opens PSharedBufferManager;
parent opens PImageBridge;
parent opens PGMPService;
parent opens PVRManager;
child opens PBackground;
manages PBlob;

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

@ -1043,7 +1043,7 @@ DOMAudioNodeMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow,
DOMHwMediaStream::DOMHwMediaStream()
{
#ifdef MOZ_WIDGET_GONK
mImageContainer = LayerManager::CreateImageContainer(ImageContainer::ASYNCHRONOUS_OVERLAY);
mImageContainer = LayerManager::CreateImageContainer(ImageContainer::ASYNCHRONOUS);
mOverlayImage = mImageContainer->CreateOverlayImage();
nsAutoTArray<ImageContainer::NonOwningImage,1> images;
images.AppendElement(ImageContainer::NonOwningImage(mOverlayImage));

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

@ -2572,6 +2572,7 @@ ProcessedMediaStream::AllocateInputPort(MediaStream* aStream, TrackID aTrackID,
RefPtr<MediaInputPort> mPort;
};
MOZ_ASSERT(aStream->GraphImpl() == GraphImpl());
MOZ_ASSERT(aTrackID != TRACK_NONE && aTrackID != TRACK_INVALID,
"Only TRACK_ANY and explicit ID are allowed");
RefPtr<MediaInputPort> port = new MediaInputPort(aStream, aTrackID, this,

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

@ -365,9 +365,7 @@ AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement,
if (aRv.Failed()) {
return nullptr;
}
RefPtr<MediaElementAudioSourceNode> mediaElementAudioSourceNode =
new MediaElementAudioSourceNode(this, stream);
return mediaElementAudioSourceNode.forget();
return MediaElementAudioSourceNode::Create(this, stream, aRv);
}
already_AddRefed<MediaStreamAudioSourceNode>
@ -383,9 +381,7 @@ AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream,
return nullptr;
}
RefPtr<MediaStreamAudioSourceNode> mediaStreamAudioSourceNode =
new MediaStreamAudioSourceNode(this, &aMediaStream);
return mediaStreamAudioSourceNode.forget();
return MediaStreamAudioSourceNode::Create(this, &aMediaStream, aRv);
}
already_AddRefed<GainNode>

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

@ -61,7 +61,6 @@ public:
void OfflineShutdown();
AudioChannel MozAudioChannelType() const;
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
virtual void NotifyMainThreadStreamFinished() override;
void FireOfflineCompletionEvent();
@ -91,6 +90,7 @@ protected:
virtual ~AudioDestinationNode();
private:
void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv);
bool CheckAudioChannelPermissions(AudioChannel aValue);
void SetCanPlay(float aVolume, bool aMuted);

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

@ -54,9 +54,6 @@ AudioNode::AudioNode(AudioContext* aContext,
, mChannelInterpretation(aChannelInterpretation)
, mId(gId++)
, mPassThrough(false)
#ifdef DEBUG
, mDemiseNotified(false)
#endif
{
MOZ_ASSERT(aContext);
DOMEventTargetHelper::BindToOwner(aContext->GetParentObject());
@ -68,10 +65,8 @@ AudioNode::~AudioNode()
MOZ_ASSERT(mInputNodes.IsEmpty());
MOZ_ASSERT(mOutputNodes.IsEmpty());
MOZ_ASSERT(mOutputParams.IsEmpty());
#ifdef DEBUG
MOZ_ASSERT(mDemiseNotified,
MOZ_ASSERT(!mStream,
"The webaudio-node-demise notification must have been sent");
#endif
if (mContext) {
mContext->UnregisterNode(this);
}
@ -390,9 +385,6 @@ AudioNode::DestroyMediaStream()
id.AppendPrintf("%u", mId);
obs->NotifyObservers(nullptr, "webaudio-node-demise", id.get());
}
#ifdef DEBUG
mDemiseNotified = true;
#endif
}
}

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

@ -256,11 +256,6 @@ private:
// Whether the node just passes through its input. This is a devtools API that
// only works for some node types.
bool mPassThrough;
#ifdef DEBUG
// In debug builds, check to make sure that the node demise notification has
// been properly sent before the node is destroyed.
bool mDemiseNotified;
#endif
};
} // namespace dom

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

@ -10,12 +10,26 @@
namespace mozilla {
namespace dom {
MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext,
DOMMediaStream* aStream)
: MediaStreamAudioSourceNode(aContext, aStream)
MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext)
: MediaStreamAudioSourceNode(aContext)
{
}
/* static */ already_AddRefed<MediaElementAudioSourceNode>
MediaElementAudioSourceNode::Create(AudioContext* aContext,
DOMMediaStream* aStream, ErrorResult& aRv)
{
RefPtr<MediaElementAudioSourceNode> node =
new MediaElementAudioSourceNode(aContext);
node->Init(aStream, aRv);
if (aRv.Failed()) {
return nullptr;
}
return node.forget();
}
JSObject*
MediaElementAudioSourceNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{

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

@ -15,8 +15,8 @@ namespace dom {
class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode
{
public:
MediaElementAudioSourceNode(AudioContext* aContext,
DOMMediaStream* aStream);
static already_AddRefed<MediaElementAudioSourceNode>
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@ -29,6 +29,8 @@ public:
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
explicit MediaElementAudioSourceNode(AudioContext* aContext);
};
} // namespace dom

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

@ -31,18 +31,45 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(MediaStreamAudioSourceNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(MediaStreamAudioSourceNode, AudioNode)
MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext,
DOMMediaStream* aMediaStream)
MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext)
: AudioNode(aContext,
2,
ChannelCountMode::Max,
ChannelInterpretation::Speakers),
mInputStream(aMediaStream)
ChannelInterpretation::Speakers)
{
}
/* static */ already_AddRefed<MediaStreamAudioSourceNode>
MediaStreamAudioSourceNode::Create(AudioContext* aContext,
DOMMediaStream* aStream, ErrorResult& aRv)
{
RefPtr<MediaStreamAudioSourceNode> node =
new MediaStreamAudioSourceNode(aContext);
node->Init(aStream, aRv);
if (aRv.Failed()) {
return nullptr;
}
return node.forget();
}
void
MediaStreamAudioSourceNode::Init(DOMMediaStream* aMediaStream, ErrorResult& aRv)
{
MOZ_ASSERT(aMediaStream);
MediaStream* inputStream = aMediaStream->GetPlaybackStream();
MediaStreamGraph* graph = Context()->Graph();
if (NS_WARN_IF(graph != inputStream->Graph())) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
mInputStream = aMediaStream;
AudioNodeEngine* engine = new MediaStreamAudioSourceNodeEngine(this);
mStream = AudioNodeExternalInputStream::Create(aContext->Graph(), engine);
mStream = AudioNodeExternalInputStream::Create(graph, engine);
ProcessedMediaStream* outputStream = static_cast<ProcessedMediaStream*>(mStream.get());
mInputPort = outputStream->AllocateInputPort(aMediaStream->GetPlaybackStream());
mInputPort = outputStream->AllocateInputPort(inputStream);
mInputStream->AddConsumerToKeepAlive(static_cast<nsIDOMEventTarget*>(this));
PrincipalChanged(mInputStream); // trigger enabling/disabling of the connector

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

@ -44,8 +44,8 @@ class MediaStreamAudioSourceNode : public AudioNode,
public DOMMediaStream::PrincipalChangeObserver
{
public:
MediaStreamAudioSourceNode(AudioContext* aContext,
DOMMediaStream* aMediaStream);
static already_AddRefed<MediaStreamAudioSourceNode>
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioSourceNode, AudioNode)
@ -67,6 +67,8 @@ public:
virtual void PrincipalChanged(DOMMediaStream* aMediaStream) override;
protected:
explicit MediaStreamAudioSourceNode(AudioContext* aContext);
void Init(DOMMediaStream* aMediaStream, ErrorResult& aRv);
virtual ~MediaStreamAudioSourceNode();
private:

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

@ -2426,17 +2426,21 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
}
if (parentEpoch != ChromeEpochForContent()) {
SetChromeEpochForContent(parentEpoch);
*aPluginsChanged = true;
if (!aCreatePluginList) {
return NS_OK;
}
// Don't do this if aCreatePluginList is false. Otherwise, when we actually
// want to create the list, we'll come back here and do nothing.
SetChromeEpochForContent(parentEpoch);
for (size_t i = 0; i < plugins.Length(); i++) {
PluginTag& tag = plugins[i];
// Don't add the same plugin again.
if (PluginWithId(tag.id())) {
if (nsPluginTag* existing = PluginWithId(tag.id())) {
UpdateInMemoryPluginInfo(existing);
continue;
}
@ -2699,14 +2703,9 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
return NS_OK;
}
// This function is not relevant for fake plugins.
void
nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
nsPluginHost::UpdateInMemoryPluginInfo(nsPluginTag* aPluginTag)
{
MOZ_ASSERT(XRE_IsParentProcess());
ReadPluginInfo();
WritePluginInfo();
NS_ITERATIVE_UNREF_LIST(RefPtr<nsPluginTag>, mCachedPlugins, mNext);
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
@ -2737,6 +2736,20 @@ nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
obsService->NotifyObservers(nullptr, "plugin-info-updated", nullptr);
}
// This function is not relevant for fake plugins.
void
nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
{
MOZ_ASSERT(XRE_IsParentProcess());
ReadPluginInfo();
WritePluginInfo();
IncrementChromeEpoch();
UpdateInMemoryPluginInfo(aPluginTag);
}
/* static */ bool
nsPluginHost::IsTypeWhitelisted(const char *aMimeType)
{

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

@ -363,6 +363,8 @@ private:
uint32_t ChromeEpochForContent();
void SetChromeEpochForContent(uint32_t aEpoch);
void UpdateInMemoryPluginInfo(nsPluginTag* aPluginTag);
// On certain platforms, we only want to load certain plugins. This function
// centralizes loading rules.
bool ShouldAddPlugin(nsPluginTag* aPluginTag);

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

@ -576,7 +576,8 @@ nsPluginTag::GetClicktoplay(bool *aClicktoplay)
}
NS_IMETHODIMP
nsPluginTag::GetEnabledState(uint32_t *aEnabledState) {
nsPluginTag::GetEnabledState(uint32_t *aEnabledState)
{
int32_t enabledState;
nsresult rv = Preferences::GetInt(GetStatePrefNameForPlugin(this).get(),
&enabledState);
@ -601,7 +602,8 @@ nsPluginTag::GetEnabledState(uint32_t *aEnabledState) {
}
NS_IMETHODIMP
nsPluginTag::SetEnabledState(uint32_t aEnabledState) {
nsPluginTag::SetEnabledState(uint32_t aEnabledState)
{
if (aEnabledState >= ePluginState_MaxValue)
return NS_ERROR_ILLEGAL_VALUE;
uint32_t oldState = nsIPluginTag::STATE_DISABLED;

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

@ -56,8 +56,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug653364.html]
[test_bug861217.html]
[test_bug1077002.html]
run-if = e10s
[test_clientRects.html]
[test_clipboard_events.html]
skip-if = e10s || buildapp == 'b2g' # b2g(clipboard undefined) b2g-debug(clipboard undefined) b2g-desktop(clipboard undefined)
@ -101,6 +99,8 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_srcset_pref.html]
[test_showModalDialog.html]
skip-if = e10s || buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #Don't run modal tests on Android # b2g(showmodaldialog) b2g-debug(showmodaldialog) b2g-desktop(showmodaldialog)
[test_showModalDialog_e10s.html]
run-if = e10s
[test_stylesheetPI.html]
[test_vibrator.html]
skip-if = toolkit == 'android' #CRASH_SUTAGENT

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

@ -4,7 +4,7 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=1077002
-->
<head>
<title>Test for Bug 1077002</title>
<title>Test for showModalDialog unavailability in e10s</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
@ -20,15 +20,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1077002
<pre id="test">
<script type="application/javascript;version=1.7">
/** Test for Bug 1077002 **/
/** Test for showModalDialog unavailability in e10s **/
try {
// NB: This test runs in e10s only. In e10s showModalDialog should only
// ever throw NS_ERROR_NOT_AVAILABLE.
window.showModalDialog("http://example.org");
} catch (e) {
is(e.name, "NS_ERROR_NOT_AVAILABLE", "throw the correct error message");
}
// NB: This test runs in e10s only. In e10s showModalDialog should not
// exist.
ok(!window.showModalDialog, "showModalDialog should not exist");
</script>
</pre>

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

@ -10,7 +10,10 @@
#include "mozilla/dom/VRDeviceBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/VRDevice.h"
#include "Navigator.h"
#include "gfxVR.h"
#include "VRDeviceProxy.h"
#include "VRManagerChild.h"
#include "nsIFrame.h"
using namespace mozilla::gfx;
@ -18,6 +21,46 @@ using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
/*static*/ bool
VRDevice::RefreshVRDevices(dom::Navigator* aNavigator)
{
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
return vm && vm->RefreshVRDevicesWithCallback(aNavigator);
}
/*static*/ void
VRDevice::UpdateVRDevices(nsTArray<RefPtr<VRDevice>>& aDevices, nsISupports* aParent)
{
nsTArray<RefPtr<VRDevice>> devices;
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
nsTArray<RefPtr<gfx::VRDeviceProxy>> proxyDevices;
if (vm && vm->GetVRDevices(proxyDevices)) {
for (size_t i = 0; i < proxyDevices.Length(); i++) {
RefPtr<gfx::VRDeviceProxy> proxyDevice = proxyDevices[i];
bool isNewDevice = true;
for (size_t j = 0; j < aDevices.Length(); j++) {
if (aDevices[j]->GetHMD()->GetDeviceInfo() == proxyDevice->GetDeviceInfo()) {
devices.AppendElement(aDevices[j]);
isNewDevice = false;
}
}
if (isNewDevice) {
gfx::VRStateValidFlags sensorBits = proxyDevice->GetDeviceInfo().GetSupportedSensorStateBits();
devices.AppendElement(new HMDInfoVRDevice(aParent, proxyDevice));
if (sensorBits & (gfx::VRStateValidFlags::State_Position |
gfx::VRStateValidFlags::State_Orientation))
{
devices.AppendElement(new HMDPositionVRDevice(aParent, proxyDevice));
}
}
}
}
aDevices = devices;
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfViewReadOnly, mParent)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfViewReadOnly, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfViewReadOnly, Release)
@ -133,11 +176,11 @@ VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorSta
{
mTimeStamp = aState.timestamp;
if (aState.flags & gfx::VRHMDInfo::State_Position) {
if (aState.flags & gfx::VRStateValidFlags::State_Position) {
mPosition = new DOMPoint(mParent, aState.position[0], aState.position[1], aState.position[2], 0.0);
}
if (aState.flags & gfx::VRHMDInfo::State_Orientation) {
if (aState.flags & gfx::VRStateValidFlags::State_Orientation) {
mOrientation = new DOMPoint(mParent, aState.orientation[0], aState.orientation[1], aState.orientation[2], aState.orientation[3]);
}
}
@ -206,158 +249,118 @@ PositionSensorVRDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenP
return PositionSensorVRDeviceBinding::Wrap(aCx, this, aGivenProto);
}
namespace {
class HMDInfoVRDevice : public HMDVRDevice
HMDInfoVRDevice::HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
: HMDVRDevice(aParent, aHMD)
{
public:
HMDInfoVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
: HMDVRDevice(aParent, aHMD)
{
uint64_t hmdid = aHMD->GetDeviceIndex() << 8;
uint64_t devid = hmdid | 0x00; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
MOZ_COUNT_CTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice);
uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8;
uint64_t devid = hmdid | 0x00; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
mHWID.Truncate();
mHWID.AppendPrintf("0x%llx", hmdid);
mHWID.Truncate();
mHWID.AppendPrintf("0x%llx", hmdid);
mDeviceId.Truncate();
mDeviceId.AppendPrintf("0x%llx", devid);
mDeviceId.Truncate();
mDeviceId.AppendPrintf("0x%llx", devid);
mDeviceName.Truncate();
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceName()));
mDeviceName.AppendLiteral(" (HMD)");
mDeviceName.Truncate();
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName()));
mDeviceName.AppendLiteral(" (HMD)");
mValid = true;
}
mValid = true;
}
virtual ~HMDInfoVRDevice() { }
/* If a field of view that is set to all 0's is passed in,
* the recommended field of view for that eye is used.
*/
virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
const VRFieldOfViewInit& aRightFOV,
double zNear, double zFar) override
{
gfx::VRFieldOfView left = gfx::VRFieldOfView(aLeftFOV.mUpDegrees, aLeftFOV.mRightDegrees,
aLeftFOV.mDownDegrees, aLeftFOV.mLeftDegrees);
gfx::VRFieldOfView right = gfx::VRFieldOfView(aRightFOV.mUpDegrees, aRightFOV.mRightDegrees,
aRightFOV.mDownDegrees, aRightFOV.mLeftDegrees);
if (left.IsZero())
left = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Left);
if (right.IsZero())
right = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Right);
mHMD->SetFOV(left, right, zNear, zFar);
}
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) override
{
gfx::IntSize sz(mHMD->SuggestedEyeResolution());
gfx::VRHMDInfo::Eye eye = aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right;
RefPtr<VREyeParameters> params =
new VREyeParameters(mParent,
gfx::VRFieldOfView(15, 15, 15, 15), // XXX min?
mHMD->GetMaximumEyeFOV(eye),
mHMD->GetRecommendedEyeFOV(eye),
mHMD->GetEyeTranslation(eye),
mHMD->GetEyeFOV(eye),
gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height));
return params.forget();
}
protected:
};
class HMDPositionVRDevice : public PositionSensorVRDevice
HMDInfoVRDevice::~HMDInfoVRDevice()
{
public:
HMDPositionVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
: PositionSensorVRDevice(aParent)
, mHMD(aHMD)
, mTracking(false)
{
MOZ_COUNT_DTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice);
}
uint64_t hmdid = aHMD->GetDeviceIndex() << 8;
uint64_t devid = hmdid | 0x01; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
mHWID.Truncate();
mHWID.AppendPrintf("0x%llx", hmdid);
mDeviceId.Truncate();
mDeviceId.AppendPrintf("0x%llx", devid);
mDeviceName.Truncate();
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceName()));
mDeviceName.AppendLiteral(" (Sensor)");
mValid = true;
}
~HMDPositionVRDevice()
{
if (mTracking) {
mHMD->StopSensorTracking();
}
}
virtual already_AddRefed<VRPositionState> GetState() override
{
if (!mTracking) {
mHMD->StartSensorTracking();
mTracking = true;
}
gfx::VRHMDSensorState state = mHMD->GetSensorState();
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
virtual already_AddRefed<VRPositionState> GetImmediateState() override
{
if (!mTracking) {
mHMD->StartSensorTracking();
mTracking = true;
}
gfx::VRHMDSensorState state = mHMD->GetSensorState();
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
virtual void ResetSensor() override
{
mHMD->ZeroSensor();
}
protected:
RefPtr<gfx::VRHMDInfo> mHMD;
bool mTracking;
};
} // namespace
bool
VRDevice::CreateAllKnownVRDevices(nsISupports *aParent, nsTArray<RefPtr<VRDevice>>& aDevices)
/* If a field of view that is set to all 0's is passed in,
* the recommended field of view for that eye is used.
*/
void
HMDInfoVRDevice::SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
const VRFieldOfViewInit& aRightFOV,
double zNear, double zFar)
{
nsTArray<RefPtr<gfx::VRHMDInfo>> hmds;
gfx::VRHMDManager::GetAllHMDs(hmds);
gfx::VRFieldOfView left = gfx::VRFieldOfView(aLeftFOV.mUpDegrees, aLeftFOV.mRightDegrees,
aLeftFOV.mDownDegrees, aLeftFOV.mLeftDegrees);
gfx::VRFieldOfView right = gfx::VRFieldOfView(aRightFOV.mUpDegrees, aRightFOV.mRightDegrees,
aRightFOV.mDownDegrees, aRightFOV.mLeftDegrees);
for (size_t i = 0; i < hmds.Length(); ++i) {
uint32_t sensorBits = hmds[i]->GetSupportedSensorStateBits();
aDevices.AppendElement(new HMDInfoVRDevice(aParent, hmds[i]));
if (sensorBits &
(gfx::VRHMDInfo::State_Position | gfx::VRHMDInfo::State_Orientation))
{
aDevices.AppendElement(new HMDPositionVRDevice(aParent, hmds[i]));
}
if (left.IsZero()) {
left = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Left);
}
return true;
if (right.IsZero()) {
right = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Right);
}
mHMD->SetFOV(left, right, zNear, zFar);
}
already_AddRefed<VREyeParameters> HMDInfoVRDevice::GetEyeParameters(VREye aEye)
{
gfx::IntSize sz(mHMD->GetDeviceInfo().SuggestedEyeResolution());
gfx::VRDeviceInfo::Eye eye = aEye == VREye::Left ? gfx::VRDeviceInfo::Eye_Left : gfx::VRDeviceInfo::Eye_Right;
RefPtr<VREyeParameters> params =
new VREyeParameters(mParent,
gfx::VRFieldOfView(15, 15, 15, 15), // XXX min?
mHMD->GetDeviceInfo().GetMaximumEyeFOV(eye),
mHMD->GetDeviceInfo().GetRecommendedEyeFOV(eye),
mHMD->GetDeviceInfo().GetEyeTranslation(eye),
mHMD->GetDeviceInfo().GetEyeFOV(eye),
gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height));
return params.forget();
}
HMDPositionVRDevice::HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
: PositionSensorVRDevice(aParent, aHMD)
{
MOZ_COUNT_CTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice);
uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8;
uint64_t devid = hmdid | 0x01; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor
mHWID.Truncate();
mHWID.AppendPrintf("0x%llx", hmdid);
mDeviceId.Truncate();
mDeviceId.AppendPrintf("0x%llx", devid);
mDeviceName.Truncate();
mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName()));
mDeviceName.AppendLiteral(" (Sensor)");
mValid = true;
}
HMDPositionVRDevice::~HMDPositionVRDevice()
{
MOZ_COUNT_DTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice);
}
already_AddRefed<VRPositionState>
HMDPositionVRDevice::GetState()
{
gfx::VRHMDSensorState state = mHMD->GetSensorState();
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
already_AddRefed<VRPositionState>
HMDPositionVRDevice::GetImmediateState()
{
gfx::VRHMDSensorState state = mHMD->GetSensorState();
RefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
return obj.forget();
}
void
HMDPositionVRDevice::ResetSensor()
{
mHMD->ZeroSensor();
}
} // namespace dom

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

@ -21,9 +21,11 @@
#include "nsWrapperCache.h"
#include "gfxVR.h"
#include "VRDeviceProxy.h"
namespace mozilla {
namespace dom {
class Navigator;
class VRFieldOfViewReadOnly : public nsWrapperCache
{
@ -177,10 +179,7 @@ class VRDevice : public nsISupports,
public nsWrapperCache
{
public:
// create new VRDevice objects for all known underlying gfx::vr devices
static bool CreateAllKnownVRDevices(nsISupports *aParent, nsTArray<RefPtr<VRDevice>>& aDevices);
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(VRDevice)
@ -190,8 +189,6 @@ public:
bool IsValid() { return mValid; }
virtual void Shutdown() { }
nsISupports* GetParentObject() const
{
return mParent;
@ -204,22 +201,36 @@ public:
VRDeviceType GetType() const { return mType; }
static bool RefreshVRDevices(dom::Navigator* aNavigator);
static void UpdateVRDevices(nsTArray<RefPtr<VRDevice> >& aDevices,
nsISupports* aParent);
gfx::VRDeviceProxy *GetHMD() {
return mHMD;
}
protected:
VRDevice(nsISupports* aParent, VRDeviceType aType)
VRDevice(nsISupports* aParent,
gfx::VRDeviceProxy* aHMD,
VRDeviceType aType)
: mParent(aParent)
, mHMD(aHMD)
, mType(aType)
, mValid(false)
{
MOZ_COUNT_CTOR(VRDevice);
mHWID.AssignLiteral("uknown");
mDeviceId.AssignLiteral("unknown");
mDeviceName.AssignLiteral("unknown");
}
virtual ~VRDevice() {
Shutdown();
virtual ~VRDevice()
{
MOZ_COUNT_DTOR(VRDevice);
}
nsCOMPtr<nsISupports> mParent;
RefPtr<gfx::VRDeviceProxy> mHMD;
nsString mHWID;
nsString mDeviceId;
nsString mDeviceName;
@ -240,36 +251,64 @@ public:
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
gfx::VRHMDInfo *GetHMD() { return mHMD.get(); }
protected:
HMDVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
: VRDevice(aParent, VRDevice::HMD)
, mHMD(aHMD)
{ }
HMDVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
: VRDevice(aParent, aHMD, VRDevice::HMD)
{
MOZ_COUNT_CTOR_INHERITED(HMDVRDevice, VRDevice);
}
virtual ~HMDVRDevice() { }
virtual ~HMDVRDevice()
{
MOZ_COUNT_DTOR_INHERITED(HMDVRDevice, VRDevice);
}
};
RefPtr<gfx::VRHMDInfo> mHMD;
class HMDInfoVRDevice : public HMDVRDevice
{
public:
HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD);
virtual ~HMDInfoVRDevice();
/* If a field of view that is set to all 0's is passed in,
* the recommended field of view for that eye is used.
*/
virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
const VRFieldOfViewInit& aRightFOV,
double zNear, double zFar) override;
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) override;
};
class PositionSensorVRDevice : public VRDevice
{
public:
virtual already_AddRefed<VRPositionState> GetState() = 0;
virtual already_AddRefed<VRPositionState> GetImmediateState() = 0;
virtual void ResetSensor() = 0;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
explicit PositionSensorVRDevice(nsISupports* aParent)
: VRDevice(aParent, VRDevice::PositionSensor)
{ }
explicit PositionSensorVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD)
: VRDevice(aParent, aHMD, VRDevice::PositionSensor)
{
MOZ_COUNT_CTOR_INHERITED(PositionSensorVRDevice, VRDevice);
}
virtual ~PositionSensorVRDevice() { }
virtual ~PositionSensorVRDevice()
{
MOZ_COUNT_DTOR_INHERITED(PositionSensorVRDevice, VRDevice);
}
};
class HMDPositionVRDevice : public PositionSensorVRDevice
{
public:
HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD);
~HMDPositionVRDevice();
virtual already_AddRefed<VRPositionState> GetState() override;
virtual already_AddRefed<VRPositionState> GetImmediateState() override;
virtual void ResetSensor() override;
};
} // namespace dom

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

@ -10,7 +10,23 @@
* liability, trademark and document use rules apply.
*/
[Func="mozilla::dom::Touch::PrefEnabled"]
dictionary TouchInit {
required long identifier;
required EventTarget target;
long clientX = 0;
long clientY = 0;
long screenX = 0;
long screenY = 0;
long pageX = 0;
long pageY = 0;
float radiusX = 0;
float radiusY = 0;
float rotationAngle = 0;
float force = 0;
};
[Constructor(TouchInit touchInitDict),
Func="mozilla::dom::Touch::PrefEnabled"]
interface Touch {
readonly attribute long identifier;
readonly attribute EventTarget? target;

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

@ -4,7 +4,14 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="mozilla::dom::TouchEvent::PrefEnabled"]
dictionary TouchEventInit : EventModifierInit {
sequence<Touch> touches = [];
sequence<Touch> targetTouches = [];
sequence<Touch> changedTouches = [];
};
[Constructor(DOMString type, optional TouchEventInit eventInitDict),
Func="mozilla::dom::TouchEvent::PrefEnabled"]
interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;

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

@ -74,9 +74,6 @@ class WorkerFeature
public:
virtual ~WorkerFeature() { }
virtual bool Suspend(JSContext* aCx) { return true; }
virtual bool Resume(JSContext* aCx) { return true; }
virtual bool Notify(JSContext* aCx, Status aStatus) = 0;
};

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

@ -17,6 +17,10 @@
#include <OpenGL/OpenGL.h>
// When running inside a VM, creating an accelerated OpenGL context usually
// fails. Uncomment this line to emulate that behavior.
// #define EMULATE_VM
namespace mozilla {
namespace gl {
@ -174,12 +178,23 @@ GLContextProviderCGL::CreateWrappingExisting(void*, void*)
}
static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
NSOpenGLPFAAllowOfflineRenderers,
0
};
static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered_accel[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllowOfflineRenderers,
0
};
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
NSOpenGLPFAAllowOfflineRenderers,
NSOpenGLPFADoubleBuffer,
0
};
static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFAAllowOfflineRenderers,
NSOpenGLPFADoubleBuffer,
@ -225,17 +240,23 @@ CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
#ifdef EMULATE_VM
if (aForceAccelerated) {
return nullptr;
}
#endif
const NSOpenGLPixelFormatAttribute* attribs;
if (sCGLLibrary.UseDoubleBufferedWindows()) {
attribs = kAttribs_doubleBuffered;
attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel : kAttribs_doubleBuffered;
} else {
attribs = kAttribs_singleBuffered;
attribs = aForceAccelerated ? kAttribs_singleBuffered_accel : kAttribs_singleBuffered;
}
NSOpenGLContext* context = CreateWithFormat(attribs);
if (!context) {

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

@ -211,7 +211,7 @@ CreateEAGLContext(bool aOffscreen, GLContextEAGL* sharedContext)
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget)
GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
{
RefPtr<GLContext> glContext = CreateEAGLContext(false, GetGlobalContextEAGL());
if (!glContext) {

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

@ -749,7 +749,7 @@ GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
}
already_AddRefed<GLContext>
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
{
if (!sEGLLibrary.EnsureInitialized()) {
MOZ_CRASH("GFX: Failed to load EGL library 3!\n");

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

@ -1052,7 +1052,7 @@ GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface)
}
already_AddRefed<GLContext>
GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
{
if (!sGLXLibrary.EnsureInitialized()) {
return nullptr;

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

@ -35,11 +35,12 @@ public:
* a GL layer manager.
*
* @param aWidget Widget whose surface to create a context for
* @param aForceAccelerated true if only accelerated contexts are allowed
*
* @return Context to use for the window
*/
static already_AddRefed<GLContext>
CreateForWindow(nsIWidget* widget);
CreateForWindow(nsIWidget* widget, bool aForceAccelerated);
/**
* Create a context for offscreen rendering. The target of this

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

@ -9,7 +9,7 @@ namespace mozilla {
namespace gl {
already_AddRefed<GLContext>
GLContextProviderNull::CreateForWindow(nsIWidget*)
GLContextProviderNull::CreateForWindow(nsIWidget*, bool aForceAccelerated)
{
return nullptr;
}

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

@ -438,7 +438,7 @@ GLContextProviderWGL::CreateWrappingExisting(void*, void*)
}
already_AddRefed<GLContext>
GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
{
if (!sWGLLib.EnsureInitialized()) {
return nullptr;

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

@ -140,7 +140,6 @@ enum class CompositableType : uint8_t {
UNKNOWN,
CONTENT_TILED, // tiled painted layer
IMAGE, // image with single buffering
IMAGE_OVERLAY, // image without buffer
IMAGE_BRIDGE, // ImageBridge protocol
CONTENT_SINGLE, // painted layer interface, single buffering
CONTENT_DOUBLE, // painted layer interface, double buffering

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

@ -134,11 +134,6 @@ ImageContainer::ImageContainer(Mode flag)
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE, this).take();
MOZ_ASSERT(mImageClient);
break;
case ASYNCHRONOUS_OVERLAY:
mIPDLChild = new ImageContainerChild(this);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE_OVERLAY, this).take();
MOZ_ASSERT(mImageClient);
break;
default:
MOZ_ASSERT(false, "This flag is invalid.");
break;
@ -179,13 +174,8 @@ RefPtr<OverlayImage>
ImageContainer::CreateOverlayImage()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mImageClient && mImageClient->GetTextureInfo().mCompositableType != CompositableType::IMAGE_OVERLAY) {
// If this ImageContainer is async but the image type mismatch, fix it here
if (ImageBridgeChild::IsCreated()) {
ImageBridgeChild::DispatchReleaseImageClient(mImageClient);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(
CompositableType::IMAGE_OVERLAY, this).take();
}
if (!mImageClient || !mImageClient->AsImageClientSingle()) {
return nullptr;
}
return new OverlayImage();
}

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

@ -350,7 +350,7 @@ class ImageContainer final : public SupportsWeakPtr<ImageContainer> {
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ImageContainer)
enum Mode { SYNCHRONOUS = 0x0, ASYNCHRONOUS = 0x01, ASYNCHRONOUS_OVERLAY = 0x02 };
enum Mode { SYNCHRONOUS = 0x0, ASYNCHRONOUS = 0x01 };
explicit ImageContainer(ImageContainer::Mode flag = SYNCHRONOUS);

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

@ -1117,7 +1117,8 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
mSupportsComponentAlphaChildren(false),
mMayHaveReadbackChild(false),
mChildrenChanged(false),
mEventRegionsOverride(EventRegionsOverride::NoOverride)
mEventRegionsOverride(EventRegionsOverride::NoOverride),
mVRDeviceID(0)
{
MOZ_COUNT_CTOR(ContainerLayer);
mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
@ -1279,7 +1280,7 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
mInheritedXScale, mInheritedYScale,
mPresShellResolution, mScaleToResolution,
mEventRegionsOverride,
reinterpret_cast<uint64_t>(mHMDInfo.get()));
mVRDeviceID);
}
bool
@ -2143,8 +2144,8 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
aStream << " [force-ehr]";
}
if (mHMDInfo) {
aStream << nsPrintfCString(" [hmd=%p]", mHMDInfo.get()).get();
if (mVRDeviceID) {
aStream << nsPrintfCString(" [hmd=%lu]", mVRDeviceID).get();
}
}

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

@ -2129,8 +2129,12 @@ public:
/**
* VR
*/
void SetVRHMDInfo(gfx::VRHMDInfo* aHMD) { mHMDInfo = aHMD; }
gfx::VRHMDInfo* GetVRHMDInfo() { return mHMDInfo; }
void SetVRDeviceID(uint32_t aVRDeviceID) {
mVRDeviceID = aVRDeviceID;
}
uint32_t GetVRDeviceID() {
return mVRDeviceID;
}
/**
* Replace the current effective transform with the given one,
@ -2206,7 +2210,7 @@ protected:
// the intermediate surface.
bool mChildrenChanged;
EventRegionsOverride mEventRegionsOverride;
RefPtr<gfx::VRHMDInfo> mHMDInfo;
uint32_t mVRDeviceID;
};
/**

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

@ -107,14 +107,6 @@ protected:
AutoLockImage autoLock(mContainer);
#ifdef MOZ_WIDGET_GONK
if (autoLock.HasImage() &&
autoLock.GetImage()->GetFormat() == ImageFormat::OVERLAY_IMAGE) {
mImageClientTypeContainer = CompositableType::IMAGE_OVERLAY;
return mImageClientTypeContainer;
}
#endif
mImageClientTypeContainer = autoLock.HasImage()
? CompositableType::IMAGE : CompositableType::UNKNOWN;
return mImageClientTypeContainer;

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

@ -55,11 +55,6 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
case CompositableType::UNKNOWN:
result = nullptr;
break;
#ifdef MOZ_WIDGET_GONK
case CompositableType::IMAGE_OVERLAY:
result = new ImageClientOverlay(aForwarder, aFlags);
break;
#endif
default:
MOZ_CRASH("GFX: unhandled program type image");
}
@ -154,6 +149,21 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
for (auto& img : images) {
Image* image = img.mImage;
#ifdef MOZ_WIDGET_GONK
if (image->GetFormat() == ImageFormat::OVERLAY_IMAGE) {
OverlayImage* overlayImage = static_cast<OverlayImage*>(image);
uint32_t overlayId = overlayImage->GetOverlayId();
gfx::IntSize size = overlayImage->GetSize();
OverlaySource source;
source.handle() = OverlayHandle(overlayId);
source.size() = size;
GetForwarder()->UseOverlaySource(this, source, image->GetPictureRect());
continue;
}
#endif
RefPtr<TextureClient> texture = image->GetTextureClient(this);
for (int32_t i = mBuffers.Length() - 1; i >= 0; --i) {
@ -316,40 +326,5 @@ ImageClientBridge::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
return true;
}
#ifdef MOZ_WIDGET_GONK
ImageClientOverlay::ImageClientOverlay(CompositableForwarder* aFwd,
TextureFlags aFlags)
: ImageClient(aFwd, aFlags, CompositableType::IMAGE_OVERLAY)
{
}
bool
ImageClientOverlay::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
{
AutoLockImage autoLock(aContainer);
Image *image = autoLock.GetImage();
if (!image) {
return false;
}
if (mLastUpdateGenerationCounter == (uint32_t)image->GetSerial()) {
return true;
}
mLastUpdateGenerationCounter = (uint32_t)image->GetSerial();
if (image->GetFormat() == ImageFormat::OVERLAY_IMAGE) {
OverlayImage* overlayImage = static_cast<OverlayImage*>(image);
uint32_t overlayId = overlayImage->GetOverlayId();
gfx::IntSize size = overlayImage->GetSize();
OverlaySource source;
source.handle() = OverlayHandle(overlayId);
source.size() = size;
GetForwarder()->UseOverlaySource(this, source, image->GetPictureRect());
}
return true;
}
#endif
} // namespace layers
} // namespace mozilla

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

@ -140,28 +140,6 @@ protected:
uint64_t mAsyncContainerID;
};
#ifdef MOZ_WIDGET_GONK
/**
* And ImageClient to handle opaque video stream.
* Such video stream does not upload new Image for each frame.
* Gecko have no way to get the buffer content from the Image, since the Image
* does not contain the real buffer.
* It need special hardware to display the Image
*/
class ImageClientOverlay : public ImageClient
{
public:
ImageClientOverlay(CompositableForwarder* aFwd,
TextureFlags aFlags);
virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags);
TextureInfo GetTextureInfo() const override
{
return TextureInfo(CompositableType::IMAGE_OVERLAY);
}
};
#endif
} // namespace layers
} // namespace mozilla

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

@ -202,11 +202,6 @@ CompositableHost::Create(const TextureInfo& aTextureInfo)
case CompositableType::IMAGE:
result = new ImageHost(aTextureInfo);
break;
#ifdef MOZ_WIDGET_GONK
case CompositableType::IMAGE_OVERLAY:
result = new ImageHostOverlay(aTextureInfo);
break;
#endif
case CompositableType::CONTENT_SINGLE:
result = new ContentHostSingleBuffered(aTextureInfo);
break;

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

@ -32,6 +32,7 @@
#include "nsTArray.h" // for nsAutoTArray
#include "TextRenderer.h" // for TextRenderer
#include <vector>
#include "VRManager.h" // for VRManager
#include "GeckoProfiler.h" // for GeckoProfiler
#ifdef MOZ_ENABLE_PROFILER_SPS
#include "ProfilerMarkers.h" // for ProfilerMarkers
@ -138,7 +139,7 @@ template<class ContainerT> void
ContainerRenderVR(ContainerT* aContainer,
LayerManagerComposite* aManager,
const gfx::IntRect& aClipRect,
gfx::VRHMDInfo* aHMD)
RefPtr<gfx::VRHMDInfo> aHMD)
{
RefPtr<CompositingRenderTarget> surface;
@ -149,7 +150,7 @@ ContainerRenderVR(ContainerT* aContainer,
float opacity = aContainer->GetEffectiveOpacity();
// The size of each individual eye surface
gfx::IntSize eyeResolution = aHMD->SuggestedEyeResolution();
gfx::IntSize eyeResolution = aHMD->GetDeviceInfo().SuggestedEyeResolution();
gfx::IntRect eyeRect[2];
eyeRect[0] = gfx::IntRect(0, 0, eyeResolution.width, eyeResolution.height);
eyeRect[1] = gfx::IntRect(eyeResolution.width, 0, eyeResolution.width, eyeResolution.height);
@ -348,7 +349,7 @@ ContainerPrepare(ContainerT* aContainer,
aContainer->mPrepared = MakeUnique<PreparedData>();
aContainer->mPrepared->mNeedsSurfaceCopy = false;
gfx::VRHMDInfo *hmdInfo = aContainer->GetVRHMDInfo();
RefPtr<gfx::VRHMDInfo> hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID());
if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) {
// we're not going to do anything here; instead, we'll do it all in ContainerRender.
// XXX fix this; we can win with the same optimizations. Specifically, we
@ -693,7 +694,7 @@ ContainerRender(ContainerT* aContainer,
{
MOZ_ASSERT(aContainer->mPrepared);
gfx::VRHMDInfo *hmdInfo = aContainer->GetVRHMDInfo();
RefPtr<gfx::VRHMDInfo> hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID());
if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) {
ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo);
aContainer->mPrepared = nullptr;

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

@ -132,6 +132,21 @@ ImageHost::RemoveTextureHost(TextureHost* aTexture)
}
}
void
ImageHost::UseOverlaySource(OverlaySource aOverlay,
const gfx::IntRect& aPictureRect)
{
if ((aOverlay.handle().type() == OverlayHandle::Tint32_t) &&
aOverlay.handle().get_int32_t() != INVALID_OVERLAY) {
if (!mImageHostOverlay) {
mImageHostOverlay = new ImageHostOverlay();
}
mImageHostOverlay->UseOverlaySource(aOverlay, aPictureRect);
} else {
mImageHostOverlay = nullptr;
}
}
static TimeStamp
GetBiasedTime(const TimeStamp& aInput, ImageHost::Bias aBias)
{
@ -264,6 +279,21 @@ ImageHost::Composite(LayerComposite* aLayer,
// set the new compositor yet.
return;
}
if (mImageHostOverlay) {
mImageHostOverlay->Composite(GetCompositor(),
mFlashCounter,
aLayer,
aEffectChain,
aOpacity,
aTransform,
aFilter,
aClipRect,
aVisibleRegion);
mBias = BIAS_NONE;
return;
}
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
return;
@ -428,6 +458,10 @@ ImageHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
img.mFrontBuffer->PrintInfo(aStream, pfx.get());
AppendToString(aStream, img.mPictureRect, " [picture-rect=", "]");
}
if (mImageHostOverlay) {
mImageHostOverlay->PrintInfo(aStream, aPrefix);
}
}
void
@ -447,6 +481,10 @@ ImageHost::Dump(std::stringstream& aStream,
LayerRenderState
ImageHost::GetRenderState()
{
if (mImageHostOverlay) {
return mImageHostOverlay->GetRenderState();
}
TimedImage* img = ChooseImage();
if (img) {
return img->mFrontBuffer->GetRenderState();
@ -457,6 +495,10 @@ ImageHost::GetRenderState()
already_AddRefed<gfx::DataSourceSurface>
ImageHost::GetAsSurface()
{
if (mImageHostOverlay) {
return nullptr;
}
TimedImage* img = ChooseImage();
if (img) {
return img->mFrontBuffer->GetAsSurface();
@ -493,6 +535,10 @@ ImageHost::Unlock()
IntSize
ImageHost::GetImageSize() const
{
if (mImageHostOverlay) {
return mImageHostOverlay->GetImageSize();
}
const TimedImage* img = ChooseImage();
if (img) {
return IntSize(img->mPictureRect.width, img->mPictureRect.height);
@ -534,18 +580,20 @@ ImageHost::SetImageContainer(ImageContainerParent* aImageContainer)
}
}
#ifdef MOZ_WIDGET_GONK
ImageHostOverlay::ImageHostOverlay(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
ImageHostOverlay::ImageHostOverlay()
{
MOZ_COUNT_CTOR(ImageHostOverlay);
}
ImageHostOverlay::~ImageHostOverlay()
{
MOZ_COUNT_DTOR(ImageHostOverlay);
}
void
ImageHostOverlay::Composite(LayerComposite* aLayer,
ImageHostOverlay::Composite(Compositor* aCompositor,
uint32_t aFlashCounter,
LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
@ -553,12 +601,10 @@ ImageHostOverlay::Composite(LayerComposite* aLayer,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion)
{
if (!GetCompositor()) {
if (mOverlay.handle().type() == OverlayHandle::Tnull_t) {
return;
}
if (mOverlay.handle().type() == OverlayHandle::Tnull_t)
return;
Color hollow(0.0f, 0.0f, 0.0f, 0.0f);
aEffectChain.mPrimaryEffect = new EffectSolidColor(hollow);
aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE] = new EffectBlendMode(CompositionOp::OP_SOURCE);
@ -569,18 +615,20 @@ ImageHostOverlay::Composite(LayerComposite* aLayer,
rect.SetRect(mPictureRect.x, mPictureRect.y,
mPictureRect.width, mPictureRect.height);
mCompositor->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform);
mCompositor->DrawDiagnostics(DiagnosticFlags::IMAGE | DiagnosticFlags::BIGIMAGE,
rect, aClipRect, aTransform, mFlashCounter);
aCompositor->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform);
aCompositor->DrawDiagnostics(DiagnosticFlags::IMAGE | DiagnosticFlags::BIGIMAGE,
rect, aClipRect, aTransform, aFlashCounter);
}
LayerRenderState
ImageHostOverlay::GetRenderState()
{
LayerRenderState state;
#ifdef MOZ_WIDGET_GONK
if (mOverlay.handle().type() == OverlayHandle::Tint32_t) {
state.SetOverlayId(mOverlay.handle().get_int32_t());
}
#endif
return state;
}
@ -602,7 +650,7 @@ void
ImageHostOverlay::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
aStream << aPrefix;
aStream << nsPrintfCString("ImageHost (0x%p)", this).get();
aStream << nsPrintfCString("ImageHostOverlay (0x%p)", this).get();
AppendToString(aStream, mPictureRect, " [picture-rect=", "]");
@ -613,6 +661,5 @@ ImageHostOverlay::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
#endif
} // namespace layers
} // namespace mozilla

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

@ -30,6 +30,7 @@ namespace layers {
class Compositor;
struct EffectChain;
class ImageContainerParent;
class ImageHostOverlay;
/**
* ImageHost. Works with ImageClientSingle and ImageClientBuffered
@ -54,6 +55,9 @@ public:
virtual void RemoveTextureHost(TextureHost* aTexture) override;
virtual void UseOverlaySource(OverlaySource aOverlay,
const gfx::IntRect& aPictureRect) override;
virtual TextureHost* GetAsTextureHost(gfx::IntRect* aPictureRect = nullptr) override;
virtual void Attach(Layer* aLayer,
@ -137,39 +141,40 @@ protected:
Bias mBias;
bool mLocked;
RefPtr<ImageHostOverlay> mImageHostOverlay;
};
#ifdef MOZ_WIDGET_GONK
/**
* ImageHostOverlay works with ImageClientOverlay
* ImageHostOverlay handles OverlaySource compositing
*/
class ImageHostOverlay : public CompositableHost {
class ImageHostOverlay {
protected:
virtual ~ImageHostOverlay();
public:
ImageHostOverlay(const TextureInfo& aTextureInfo);
~ImageHostOverlay();
NS_INLINE_DECL_REFCOUNTING(ImageHostOverlay)
ImageHostOverlay();
virtual CompositableType GetType() { return mTextureInfo.mCompositableType; }
virtual void Composite(LayerComposite* aLayer,
virtual void Composite(Compositor* aCompositor,
uint32_t aFlashCounter,
LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr) override;
virtual LayerRenderState GetRenderState() override;
const nsIntRegion* aVisibleRegion);
virtual LayerRenderState GetRenderState();
virtual void UseOverlaySource(OverlaySource aOverlay,
const gfx::IntRect& aPictureRect) override;
virtual gfx::IntSize GetImageSize() const override;
const gfx::IntRect& aPictureRect);
virtual gfx::IntSize GetImageSize() const;
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
protected:
gfx::IntRect mPictureRect;
OverlaySource mOverlay;
};
#endif
} // namespace layers
} // namespace mozilla

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

@ -50,7 +50,6 @@ ImageLayerComposite::SetCompositableHost(CompositableHost* aHost)
{
switch (aHost->GetType()) {
case CompositableType::IMAGE:
case CompositableType::IMAGE_OVERLAY:
mImageHost = aHost;
return true;
default:

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

@ -1042,7 +1042,7 @@ LayerManagerComposite::RenderToPresentationSurface()
EGLSurface surface = mirrorScreen->GetEGLSurface();
if (surface == LOCAL_EGL_NO_SURFACE) {
// Create GLContext
RefPtr<GLContext> gl = gl::GLContextProvider::CreateForWindow(mirrorScreenWidget);
RefPtr<GLContext> gl = gl::GLContextProvider::CreateForWindow(mirrorScreenWidget, false);
mirrorScreenWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT,
reinterpret_cast<uintptr_t>(gl.get()));
surface = mirrorScreen->GetEGLSurface();

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

@ -676,7 +676,7 @@ CompositorD3D11::DrawVRDistortion(const gfx::Rect& aRect,
TextureSourceD3D11* source = vrEffect->mTexture->AsSourceD3D11();
VRHMDInfo* hmdInfo = vrEffect->mHMD;
VRHMDType hmdType = hmdInfo->GetType();
VRHMDType hmdType = hmdInfo->GetDeviceInfo().GetType();
if (!mAttachments->mVRDistortionVS[hmdType] ||
!mAttachments->mVRDistortionPS[hmdType])

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

@ -842,6 +842,7 @@ DXGITextureHostD3D11::Lock()
}
if (!mTextureSource) {
if (!mTexture && !OpenSharedHandle()) {
gfxWindowsPlatform::GetPlatform()->ForceDeviceReset(ForcedDeviceResetReason::OPENSHAREDHANDLE);
return false;
}

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

@ -217,7 +217,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
case CompositableOperation::TOpUseOverlaySource: {
const OpUseOverlaySource& op = aEdit.get_OpUseOverlaySource();
CompositableHost* compositable = AsCompositable(op);
MOZ_ASSERT(compositable->GetType() == CompositableType::IMAGE_OVERLAY, "Invalid operation!");
if (!ValidatePictureRect(op.overlay().size(), op.picture())) {
return false;
}

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

@ -28,6 +28,7 @@
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Rect.h" // for IntSize
#include "VRManager.h" // for VRManager
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
#include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager
@ -79,6 +80,12 @@
#include "LayerScope.h"
namespace mozilla {
namespace gfx {
// See VRManagerChild.cpp
void ReleaseVRManagerParentSingleton();
} // namespace gfx
namespace layers {
using namespace mozilla::ipc;
@ -426,6 +433,7 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
}
DispatchTouchEvents(aVsyncTimestamp);
DispatchVREvents(aVsyncTimestamp);
if (mNeedsComposite || mAsapScheduling) {
mNeedsComposite = 0;
@ -497,6 +505,15 @@ CompositorVsyncScheduler::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
#endif
}
void
CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
VRManager* vm = VRManager::Get();
vm->NotifyVsync(aVsyncTimestamp);
}
void CompositorParent::StartUp()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
@ -511,6 +528,7 @@ void CompositorParent::ShutDown()
MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
ReleaseImageBridgeParentSingleton();
ReleaseVRManagerParentSingleton();
MediaSystemResourceService::Shutdown();
sCompositorThreadHolder = nullptr;

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

@ -134,6 +134,7 @@ private:
void ObserveVsync();
void UnobserveVsync();
void DispatchTouchEvents(TimeStamp aVsyncTimestamp);
void DispatchVREvents(TimeStamp aVsyncTimestamp);
void CancelCurrentSetNeedsCompositeTask();
class Observer final : public VsyncObserver
@ -295,7 +296,8 @@ public:
/**
* Returns the compositor thread's message loop.
*
* This message loop is used by CompositorParent and ImageBridgeParent.
* This message loop is used by CompositorParent, ImageBridgeParent,
* and VRManagerParent
*/
static MessageLoop* CompositorLoop();

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

@ -49,10 +49,6 @@ typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
using mozilla::layout::RenderFrameParent;
namespace mozilla {
namespace gfx {
class VRHMDInfo;
} // namespace gfx
namespace layers {
class PGrallocBufferParent;
@ -402,12 +398,8 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
attrs.presShellResolution());
containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride());
if (attrs.hmdInfo()) {
if (!IsSameProcess()) {
NS_WARNING("VR layers currently not supported with cross-process compositing");
return false;
}
containerLayer->SetVRHMDInfo(reinterpret_cast<mozilla::gfx::VRHMDInfo*>(attrs.hmdInfo()));
if (attrs.hmdDeviceID()) {
containerLayer->SetVRDeviceID(attrs.hmdDeviceID());
}
break;

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

@ -248,10 +248,7 @@ struct ContainerLayerAttributes {
float presShellResolution;
bool scaleToResolution;
EventRegionsOverride eventRegionsOverride;
// This is a bare pointer; LayerTransactionParent::RecvUpdate prevents this
// from being used when !IsSameProcess(), but we should make this truly
// cross process at some point by passing the HMDConfig
uint64_t hmdInfo;
uint32_t hmdDeviceID;
};
struct ColorLayerAttributes { LayerColor color; IntRect bounds; };
struct CanvasLayerAttributes { Filter filter; IntRect bounds; };

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

@ -107,7 +107,7 @@ CompositorOGL::CreateContext()
#ifdef XP_WIN
if (gfxEnv::LayersPreferEGL()) {
printf_stderr("Trying GL layers...\n");
context = gl::GLContextProviderEGL::CreateForWindow(mWidget);
context = gl::GLContextProviderEGL::CreateForWindow(mWidget, false);
}
#endif
@ -122,7 +122,8 @@ CompositorOGL::CreateContext()
}
if (!context) {
context = gl::GLContextProvider::CreateForWindow(mWidget);
context = gl::GLContextProvider::CreateForWindow(mWidget,
gfxPlatform::GetPlatform()->RequiresAcceleratedGLContextForCompositorOGL());
}
if (!context) {

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

@ -116,8 +116,6 @@ if CONFIG['GNU_CXX']:
'-Wno-macro-redefined',
'-Wno-unused-private-field',
]
# work around inline function linking bug with template arguments
SOURCES['skia/src/gpu/GrResourceCache.cpp'].flags += ['-fkeep-inline-functions']
else:
CXXFLAGS += [
'-Wno-logical-op',

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

@ -727,8 +727,6 @@ if CONFIG['GNU_CXX']:
'-Wno-macro-redefined',
'-Wno-unused-private-field',
]
# work around inline function linking bug with template arguments
SOURCES['skia/src/gpu/GrResourceCache.cpp'].flags += ['-fkeep-inline-functions']
else:
CXXFLAGS += [
'-Wno-logical-op',

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

@ -1,22 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
Testcase bug 358732 - Crash in _moz_cairo_win32_scaled_font_select_font, part 2
</title>
<style>
svg, #div{border: 10px solid black;}
</style>
</head>
<body>
This should not crash Mozilla within 5 seconds
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;left:0px;top:50px;"><g id="g">
<foreignObject id="rotate" x="0" y="0" width="800" height="800">
<iframe xmlns="http://www.w3.org/1999/xhtml" style="width:800px; height: 800px;" src="358732-iframe.html"></iframe>
</foreignObject>
</g></svg>
</body>
</html>

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

@ -1,94 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mathml="http://www.w3.org/1998/Math/MathML"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xforms="http://www.w3.org/2002/xforms">&#1593;<svg:foreignObject x="0" y="0" width="100%" height="100%"></svg:foreignObject>
<html:script><![CDATA[
/*template*/
var doc = document;
if (document.getElementById('content'))
doc = document.getElementById('content').contentDocument;
function addfirstletter(){
var x=doc.createElementNS('http://www.w3.org/1999/xhtml','style');
x.innerHTML='\
*::first-letter {float: right; text-transform: uppercase; background-color:red; font-size:600%;}\
';
doc.documentElement.appendChild(x);
}
setTimeout(addfirstletter,200);
/*template*/
/*template*/
var doc = document;
if (document.getElementById('content'))
doc = document.getElementById('content').contentDocument;
function addfirstline(){
var x=doc.createElementNS('http://www.w3.org/1999/xhtml','style');
x.innerHTML='\
*::first-line { text-transform: uppercase; background-color:green; font-size:110%; height: 110%;}\
*::after { content:"anonymous text"; float:right;border:3px solid black;text-transform: uppercase;height: 90%;}\
*::before { content:"before text"; float:right;border:3px solid black;font-size: 10px;width:80%;}\
';
doc.documentElement.appendChild(x);
}
setTimeout(addfirstline,200);
/*template*/
/*template*/
var doc = document;
if (document.getElementById('content'))
doc = document.getElementById('content').contentDocument;
var timers=0;
function doe(aObj, aNested, aCurrentTimer){
var temp =0;
for (var i in aObj) {
try {
if (i == 'ordinal')
continue;
if (typeof aObj[i] == 'object') {
if (aNested >= 1000 || aObj[i] == window.location || aOb[i] == doc.documentElement.boxObject)
continue;
setTimeout(doe,500, aObj[i], ++aNested, timers);
timers++;
if (aOb[i] == doc.documentElement.boxObject.firstChild) {
alert(i);
continue;
};
}
if (i == 'textContent' || i == 'innerHTML')
continue;
}
catch(e){}
try {
//if (temp == 68 && aNested == 21 && aCurrentTimer >= 116) {
// alert(i + '-'+ aObj[i]);
// return;
// }
if (typeof aObj[i] == 'function') {
if (i =='removeChild' || i == 'getBoxObjectFor' || i == 'enableRollup')
aObj[i](doc.documentElement);
}
else {
aObj[i]= 'on';
}
temp+=1;
}
catch (e) {
}
}
}
setTimeout(doe,0, doc.documentElement, 300);
/*template*/
]]></html:script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 2.4 KiB

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

@ -1,23 +0,0 @@
<html>
<head>
<title>Testcase 3 - Bug 358732 – Crash in _moz_cairo_win32_scaled_font_select_font, part 2</title>
<script id="script">
var i=0;
function doe() {
var navigator1 = SpecialPowers.wrap(top).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).getInterface(SpecialPowers.Ci.nsIWebNavigation);
var docShell = navigator1.QueryInterface(SpecialPowers.Ci.nsIDocShell);
var docviewer = docShell.contentViewer.QueryInterface(SpecialPowers.Ci.nsIMarkupDocumentViewer);
docviewer.textZoom=i;
i=i+0.2;
if (i>10)
i = 0;
}
setInterval(doe, 50);
</script>
</head>
<body>
text&#8889;&#74746;&#48236;&#79202;&#67671;&#9251;&#14635;<sup>&#8889;&#74746;&#48236;&#79202;&#67671;&#9251;&#14635;
text
</body>
</html>

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

@ -1,37 +0,0 @@
<object>&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;
&#5787;&#5787;&#5787;&#5787;&#5787;
&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;
&#5787;&#5787;&#5787;&#5787;
<i>&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;&#5787;
<script>
var doc = document;
if (document.getElementById('content')) {
doc = document.getElementById('content').contentDocument;
}
var docviewer;
function do_onload() {
var navigator1 = SpecialPowers.wrap(parent).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).getInterface(SpecialPowers.Ci.nsIWebNavigation);
var docShell = navigator1.QueryInterface(SpecialPowers.Ci.nsIDocShell);
docviewer = docShell.contentViewer;
setTimeout(doe,500, 0.2);
}
do_onload();
function doe(i) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
docviewer.textZoom += i;
if (docviewer.textZoom >=4)
i = -0.2;
if (docviewer.textZoom <=0)
i = 0.2;
window.status = docviewer.textZoom;
setTimeout(doe, 100, i);
}
</script>

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

@ -12,9 +12,6 @@ load 345576-1.html
load 345629-1.html
load 348462-1.html
load 348462-2.html
skip load 358732-1.xhtml # Bug 1226751
load 358732-2.svg
load 358732-3.html
load 366643.html
load 369688-1.html
load 369947-1.html

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

@ -19,7 +19,6 @@
#include "gfxPrefs.h"
#include "gfxEnv.h"
#include "gfxTextRun.h"
#include "gfxVR.h"
#ifdef XP_WIN
#include <process.h>
@ -127,6 +126,8 @@ class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted {
#include "SoftwareVsyncSource.h"
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
#include "mozilla/dom/ContentChild.h"
#include "gfxVR.h"
#include "VRManagerChild.h"
namespace mozilla {
namespace layers {
@ -445,8 +446,7 @@ gfxPlatform::gfxPlatform()
contentMask, BackendType::CAIRO);
mTotalSystemMemory = mozilla::hal::GetTotalSystemMemory();
// give HMDs a chance to be initialized very early on
VRHMDManager::ManagerInit();
VRManager::ManagerInit();
}
gfxPlatform*
@ -735,6 +735,7 @@ gfxPlatform::InitLayersIPC()
SharedBufferManagerChild::StartUp();
#endif
mozilla::layers::ImageBridgeChild::StartUp();
gfx::VRManagerChild::StartUpSameProcess();
}
}
@ -750,13 +751,16 @@ gfxPlatform::ShutdownLayersIPC()
{
// This must happen after the shutdown of media and widgets, which
// are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
gfx::VRManagerChild::ShutDown();
layers::ImageBridgeChild::ShutDown();
#ifdef MOZ_WIDGET_GONK
layers::SharedBufferManagerChild::ShutDown();
#endif
layers::CompositorParent::ShutDown();
}
} else if (XRE_GetProcessType() == GeckoProcessType_Content) {
gfx::VRManagerChild::ShutDown();
}
}
gfxPlatform::~gfxPlatform()
@ -764,9 +768,6 @@ gfxPlatform::~gfxPlatform()
mScreenReferenceSurface = nullptr;
mScreenReferenceDrawTarget = nullptr;
// Clean up any VR stuff
VRHMDManager::ManagerDestroy();
// The cairo folks think we should only clean up in debug builds,
// but we're generally in the habit of trying to shut down as
// cleanly as possible even in production code, so call this
@ -2246,9 +2247,7 @@ gfxPlatform::GetCompositorBackends(bool useAcceleration, nsTArray<mozilla::layer
if (useAcceleration) {
GetAcceleratedCompositorBackends(aBackends);
}
if (SupportsBasicCompositor()) {
aBackends.AppendElement(LayersBackend::LAYERS_BASIC);
}
aBackends.AppendElement(LayersBackend::LAYERS_BASIC);
}
void

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

@ -132,9 +132,15 @@ enum class DeviceResetReason
DRIVER_ERROR,
INVALID_CALL,
OUT_OF_MEMORY,
FORCED_RESET,
UNKNOWN
};
enum class ForcedDeviceResetReason
{
OPENSHAREDHANDLE = 0
};
class gfxPlatform {
friend class SRGBOverrideObserver;
@ -644,6 +650,12 @@ public:
return false;
}
// Some platforms don't support CompositorOGL in an unaccelerated OpenGL
// context. These platforms should return true here.
virtual bool RequiresAcceleratedGLContextForCompositorOGL() const {
return false;
}
protected:
gfxPlatform();
virtual ~gfxPlatform();
@ -659,11 +671,6 @@ protected:
// Returns a prioritized list of available compositor backends for acceleration.
virtual void GetAcceleratedCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aBackends);
// Returns whether or not the basic compositor is supported.
virtual bool SupportsBasicCompositor() const {
return true;
}
/**
* Initialise the preferred and fallback canvas backends
* aBackendBitmask specifies the backends which are acceptable to the caller.

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

@ -83,9 +83,11 @@ public:
return true;
}
bool SupportsBasicCompositor() const override {
// At the moment, BasicCompositor is broken on mac.
return false;
bool RequiresAcceleratedGLContextForCompositorOGL() const override {
// On OS X in a VM, unaccelerated CompositorOGL shows black flashes, so we
// require accelerated GL for CompositorOGL but allow unaccelerated GL for
// BasicCompositor.
return true;
}
bool UseAcceleratedCanvas();

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

@ -555,6 +555,15 @@ gfxWindowsPlatform::UpdateRenderMode()
}
}
void
gfxWindowsPlatform::ForceDeviceReset(ForcedDeviceResetReason aReason)
{
Telemetry::Accumulate(Telemetry::FORCED_DEVICE_RESET_REASON, uint32_t(aReason));
mDeviceResetReason = DeviceResetReason::FORCED_RESET;
mHasDeviceReset = true;
}
mozilla::gfx::BackendType
gfxWindowsPlatform::GetContentBackendFor(mozilla::layers::LayersBackend aLayers)
{

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

@ -149,6 +149,11 @@ public:
*/
void UpdateRenderMode();
/**
* Forces all GPU resources to be recreated on the next frame.
*/
void ForceDeviceReset(ForcedDeviceResetReason aReason);
/**
* Verifies a D2D device is present and working, will attempt to create one
* it is non-functional or non-existant.

153
gfx/vr/VRDeviceProxy.cpp Normal file
Просмотреть файл

@ -0,0 +1,153 @@
/* -*- 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/. */
#include <math.h>
#include "prlink.h"
#include "prmem.h"
#include "prenv.h"
#include "gfxPrefs.h"
#include "nsString.h"
#include "mozilla/Preferences.h"
#include "mozilla/unused.h"
#include "nsServiceManagerUtils.h"
#include "nsIScreenManager.h"
#ifdef XP_WIN
#include "../layers/d3d11/CompositorD3D11.h"
#endif
#include "VRDeviceProxy.h"
#include "VRManagerChild.h"
using namespace mozilla;
using namespace mozilla::gfx;
VRDeviceProxy::VRDeviceProxy(const VRDeviceUpdate& aDeviceUpdate)
: mDeviceInfo(aDeviceUpdate.mDeviceInfo)
, mSensorState(aDeviceUpdate.mSensorState)
{
MOZ_COUNT_CTOR(VRDeviceProxy);
if (mDeviceInfo.mScreenRect.width && mDeviceInfo.mScreenRect.height) {
if (mDeviceInfo.mIsFakeScreen) {
mScreen = MakeFakeScreen(mDeviceInfo.mScreenRect);
} else {
nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
if (screenmgr) {
screenmgr->ScreenForRect(mDeviceInfo.mScreenRect.x, mDeviceInfo.mScreenRect.y,
mDeviceInfo.mScreenRect.width, mDeviceInfo.mScreenRect.height,
getter_AddRefs(mScreen));
}
}
#ifdef DEBUG
printf_stderr("VR DEVICE SCREEN: %d %d %d %d\n",
mDeviceInfo.mScreenRect.x, mDeviceInfo.mScreenRect.y,
mDeviceInfo.mScreenRect.width, mDeviceInfo.mScreenRect.height);
#endif
}
}
VRDeviceProxy::~VRDeviceProxy() {
MOZ_COUNT_DTOR(VRDeviceProxy);
}
void
VRDeviceProxy::UpdateDeviceInfo(const VRDeviceUpdate& aDeviceUpdate)
{
mDeviceInfo = aDeviceUpdate.mDeviceInfo;
mSensorState = aDeviceUpdate.mSensorState;
}
bool
VRDeviceProxy::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
double zNear, double zFar)
{
VRManagerChild *vm = VRManagerChild::Get();
vm->SendSetFOV(mDeviceInfo.mDeviceID, aFOVLeft, aFOVRight, zNear, zFar);
return true;
}
void
VRDeviceProxy::ZeroSensor()
{
VRManagerChild *vm = VRManagerChild::Get();
vm->SendResetSensor(mDeviceInfo.mDeviceID);
}
VRHMDSensorState
VRDeviceProxy::GetSensorState(double timeOffset)
{
VRManagerChild *vm = VRManagerChild::Get();
Unused << vm->SendKeepSensorTracking(mDeviceInfo.mDeviceID);
return mSensorState;
}
void
VRDeviceProxy::UpdateSensorState(const VRHMDSensorState& aSensorState)
{
mSensorState = aSensorState;
}
// Dummy nsIScreen implementation, for when we just need to specify a size
class FakeScreen : public nsIScreen
{
public:
explicit FakeScreen(const IntRect& aScreenRect)
: mScreenRect(aScreenRect)
{ }
NS_DECL_ISUPPORTS
NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
*l = mScreenRect.x;
*t = mScreenRect.y;
*w = mScreenRect.width;
*h = mScreenRect.height;
return NS_OK;
}
NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetRect(l, t, w, h);
}
NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetRect(l, t, w, h);
}
NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetAvailRect(l, t, w, h);
}
NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD GetRotation(uint32_t* aRotation) override {
*aRotation = nsIScreen::ROTATION_0_DEG;
return NS_OK;
}
NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
*aContentsScaleFactor = 1.0;
return NS_OK;
}
protected:
virtual ~FakeScreen() {}
IntRect mScreenRect;
};
NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
/* static */ already_AddRefed<nsIScreen>
VRDeviceProxy::MakeFakeScreen(const IntRect& aScreenRect)
{
nsCOMPtr<nsIScreen> screen = new FakeScreen(aScreenRect);
return screen.forget();
}

57
gfx/vr/VRDeviceProxy.h Normal file
Просмотреть файл

@ -0,0 +1,57 @@
/* -*- 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 GFX_VR_PROXY_H
#define GFX_VR_PROXY_H
#include "nsIScreen.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "gfxVR.h"
namespace mozilla {
namespace gfx {
class VRManagerChild;
class VRDeviceProxy
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRDeviceProxy)
explicit VRDeviceProxy(const VRDeviceUpdate& aDeviceUpdate);
void UpdateDeviceInfo(const VRDeviceUpdate& aDeviceUpdate);
void UpdateSensorState(const VRHMDSensorState& aSensorState);
const VRDeviceInfo& GetDeviceInfo() const { return mDeviceInfo; }
virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0);
bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
double zNear, double zFar);
virtual void ZeroSensor();
// The nsIScreen that represents this device
nsIScreen* GetScreen() { return mScreen; }
protected:
virtual ~VRDeviceProxy();
VRDeviceInfo mDeviceInfo;
VRHMDSensorState mSensorState;
nsCOMPtr<nsIScreen> mScreen;
static already_AddRefed<nsIScreen> MakeFakeScreen(const IntRect& aScreenRect);
};
} // namespace gfx
} // namespace mozilla
#endif /* GFX_VR_PROXY_H */

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

@ -0,0 +1,199 @@
/* -*- 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/. */
#include <math.h>
#include "VRDeviceProxyOrientationFallBack.h"
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientationInternal
#include "mozilla/Hal.h"
using namespace mozilla;
using namespace mozilla::gfx;
// 1/sqrt(2) (aka sqrt(2)/2)
#ifndef M_SQRT1_2
# define M_SQRT1_2 0.70710678118654752440
#endif
#ifdef ANDROID
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoVR" , ## args)
#else
#define LOG(...) do { } while(0)
#endif
namespace {
// some utility functions
// This remaps axes in the given matrix to a new configuration based on the
// screen orientation. Similar to what Android SensorManager.remapCoordinateSystem
// does, except only for a fixed number of transforms that we need.
Matrix4x4
RemapMatrixForOrientation(dom::ScreenOrientationInternal screenConfig, const Matrix4x4& aMatrix)
{
Matrix4x4 out;
const float *in = &aMatrix._11;
float *o = &out._11;
if (screenConfig == dom::eScreenOrientation_LandscapePrimary) {
// remap X,Y -> Y,-X
o[0] = -in[1]; o[1] = in[0]; o[2] = in[2];
o[4] = -in[5]; o[5] = in[4]; o[6] = in[6];
o[8] = -in[9]; o[9] = in[8]; o[10] = in[10];
} else if (screenConfig == dom::eScreenOrientation_LandscapeSecondary) {
// remap X,Y -> -Y,X
o[0] = in[1]; o[1] = -in[0]; o[2] = in[2];
o[4] = in[5]; o[5] = -in[4]; o[6] = in[6];
o[8] = in[9]; o[9] = -in[8]; o[10] = in[10];
} else if (screenConfig == dom::eScreenOrientation_PortraitPrimary) {
out = aMatrix;
} else if (screenConfig == dom::eScreenOrientation_PortraitSecondary) {
// remap X,Y -> X,-Z
o[0] = in[0]; o[1] = in[2]; o[2] = -in[1];
o[4] = in[4]; o[5] = in[6]; o[6] = -in[5];
o[8] = in[8]; o[9] = in[10]; o[10] = -in[9];
} else {
MOZ_ASSERT(0, "gfxVRCardboard::RemapMatrixForOrientation invalid screenConfig");
}
return out;
}
} // namespace
namespace mozilla {
namespace gfx {
VRDeviceProxyOrientationFallBack::VRDeviceProxyOrientationFallBack(const VRDeviceUpdate& aDeviceUpdate)
: VRDeviceProxy(aDeviceUpdate)
, mOrient(dom::eScreenOrientation_PortraitPrimary)
, mTracking(false)
{
MOZ_COUNT_CTOR_INHERITED(VRDeviceProxyOrientationFallBack, VRDeviceProxy);
}
VRDeviceProxyOrientationFallBack::~VRDeviceProxyOrientationFallBack()
{
StopSensorTracking();
MOZ_COUNT_DTOR_INHERITED(VRDeviceProxyOrientationFallBack, VRDeviceProxy);
}
void
VRDeviceProxyOrientationFallBack::StartSensorTracking()
{
if (!mTracking) {
// it's never been started before; initialize observers and
// initial state.
hal::ScreenConfiguration sconfig;
hal::GetCurrentScreenConfiguration(&sconfig);
this->Notify(sconfig);
hal::RegisterSensorObserver(hal::SENSOR_GAME_ROTATION_VECTOR, this);
hal::RegisterScreenConfigurationObserver(this);
mSensorState.Clear();
mTracking = true;
}
}
void
VRDeviceProxyOrientationFallBack::StopSensorTracking()
{
if (mTracking) {
hal::UnregisterScreenConfigurationObserver(this);
hal::UnregisterSensorObserver(hal::SENSOR_GAME_ROTATION_VECTOR, this);
mTracking = false;
}
}
// Android sends us events that have a 90-degree rotation about
// the x axis compared to what we want (phone flat vs. phone held in front of the eyes).
// Correct for this by applying a transform to undo this rotation.
void
VRDeviceProxyOrientationFallBack::Notify(const hal::ScreenConfiguration& config)
{
mOrient = config.orientation();
if (mOrient == dom::eScreenOrientation_LandscapePrimary) {
mScreenTransform = Quaternion(-0.5f, 0.5f, 0.5f, 0.5f);
} else if (mOrient == dom::eScreenOrientation_LandscapeSecondary) {
mScreenTransform = Quaternion(-0.5f, -0.5f, -0.5f, 0.5f);
} else if (mOrient == dom::eScreenOrientation_PortraitPrimary) {
mScreenTransform = Quaternion((float) -M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2);
} else if (mOrient == dom::eScreenOrientation_PortraitSecondary) {
// Currently, PortraitSecondary event doesn't be triggered.
mScreenTransform = Quaternion((float) M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2);
}
}
void
VRDeviceProxyOrientationFallBack::Notify(const hal::SensorData& data)
{
if (data.sensor() != hal::SENSOR_GAME_ROTATION_VECTOR)
return;
const nsTArray<float>& sensorValues = data.values();
// This is super chatty
//LOG("HMDInfoCardboard::Notify %f %f %f %f\n", sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
mSavedLastSensor.Set(sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
mSavedLastSensorTime = data.timestamp();
mNeedsSensorCompute = true;
}
void
VRDeviceProxyOrientationFallBack::ZeroSensor()
{
mSensorZeroInverse = mSavedLastSensor;
mSensorZeroInverse.Invert();
}
void
VRDeviceProxyOrientationFallBack::ComputeStateFromLastSensor()
{
if (!mNeedsSensorCompute)
return;
// apply the zero orientation
Quaternion q = mSensorZeroInverse * mSavedLastSensor;
// make a matrix from the quat
Matrix4x4 qm;
qm.SetRotationFromQuaternion(q);
// remap the coordinate space, based on the orientation
Matrix4x4 qmRemapped = RemapMatrixForOrientation(mOrient, qm);
// turn it back into a quat
q.SetFromRotationMatrix(qmRemapped);
// apply adjustment based on what's been done to the screen and the original zero
// position of the base coordinate space
q = mScreenTransform * q;
mSensorState.flags |= VRStateValidFlags::State_Orientation;
mSensorState.orientation[0] = q.x;
mSensorState.orientation[1] = q.y;
mSensorState.orientation[2] = q.z;
mSensorState.orientation[3] = q.w;
mSensorState.timestamp = mSavedLastSensorTime / 1000000.0;
mNeedsSensorCompute = false;
}
VRHMDSensorState
VRDeviceProxyOrientationFallBack::GetSensorState(double timeOffset)
{
StartSensorTracking();
ComputeStateFromLastSensor();
return mSensorState;
}
} // namespace gfx
} // namespace mozilla

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

@ -0,0 +1,54 @@
/* -*- 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 GFX_VR_PROXY_ORIENTATION_FALLBACK_H
#define GFX_VR_PROXY_ORIENTATION_FALLBACK_H
#include "VRDeviceProxy.h"
#include "mozilla/HalSensor.h"
#include "mozilla/HalScreenConfiguration.h"
namespace mozilla {
namespace gfx {
class VRDeviceProxyOrientationFallBack : public VRDeviceProxy
, public hal::ISensorObserver
, public hal::ScreenConfigurationObserver
{
public:
explicit VRDeviceProxyOrientationFallBack(const VRDeviceUpdate& aDeviceUpdate);
virtual void ZeroSensor() override;
virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) override;
// ISensorObserver interface
void Notify(const hal::SensorData& SensorData) override;
// ScreenConfigurationObserver interface
void Notify(const hal::ScreenConfiguration& ScreenConfiguration) override;
protected:
virtual ~VRDeviceProxyOrientationFallBack();
void StartSensorTracking();
void StopSensorTracking();
void ComputeStateFromLastSensor();
uint32_t mOrient;
Quaternion mScreenTransform;
Quaternion mSensorZeroInverse;
Quaternion mSavedLastSensor;
double mSavedLastSensorTime;
bool mNeedsSensorCompute; // if we need to compute the state from mSavedLastSensor
bool mTracking;
};
} // namespace gfx
} // namespace mozilla
#endif /* GFX_VR_PROXY_ORIENTATION_FALLBACK_H */

221
gfx/vr/VRManager.cpp Normal file
Просмотреть файл

@ -0,0 +1,221 @@
/* -*- 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/. */
#include "VRManager.h"
#include "VRManagerParent.h"
#include "gfxVR.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/VRDevice.h"
#include "mozilla/unused.h"
#include "gfxPrefs.h"
#include "gfxVR.h"
#if defined(XP_WIN)
#include "gfxVROculus.h"
#endif
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
#include "gfxVROculus050.h"
#endif
#include "gfxVRCardboard.h"
namespace mozilla {
namespace gfx {
static StaticRefPtr<VRManager> sVRManagerSingleton;
/*static*/ void
VRManager::ManagerInit()
{
MOZ_ASSERT(NS_IsMainThread());
if (sVRManagerSingleton == nullptr) {
sVRManagerSingleton = new VRManager();
ClearOnShutdown(&sVRManagerSingleton);
}
}
VRManager::VRManager()
: mInitialized(false)
{
MOZ_COUNT_CTOR(VRManager);
MOZ_ASSERT(sVRManagerSingleton == nullptr);
RefPtr<VRHMDManager> mgr;
// we'll only load the 0.5.0 oculus runtime if
// the >= 0.6.0 one failed to load; otherwise
// we might initialize oculus twice
bool useOculus050 = true;
Unused << useOculus050;
#if defined(XP_WIN)
mgr = VRHMDManagerOculus::Create();
if (mgr) {
useOculus050 = false;
mManagers.AppendElement(mgr);
}
#endif
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
if (useOculus050) {
mgr = VRHMDManagerOculus050::Create();
if (mgr) {
mManagers.AppendElement(mgr);
}
}
#endif
mgr = VRHMDManagerCardboard::Create();
if (mgr) {
mManagers.AppendElement(mgr);
}
}
VRManager::~VRManager()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mInitialized);
MOZ_COUNT_DTOR(VRManager);
}
void
VRManager::Destroy()
{
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->Destroy();
}
mInitialized = false;
}
void
VRManager::Init()
{
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->Init();
}
mInitialized = true;
}
/* static */VRManager*
VRManager::Get()
{
MOZ_ASSERT(sVRManagerSingleton != nullptr);
return sVRManagerSingleton;
}
void
VRManager::AddVRManagerParent(VRManagerParent* aVRManagerParent)
{
if (mVRManagerParents.IsEmpty()) {
Init();
}
mVRManagerParents.PutEntry(aVRManagerParent);
}
void
VRManager::RemoveVRManagerParent(VRManagerParent* aVRManagerParent)
{
mVRManagerParents.RemoveEntry(aVRManagerParent);
if (mVRManagerParents.IsEmpty()) {
Destroy();
}
}
void
VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp)
{
for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) {
gfx::VRHMDInfo* device = iter.UserData();
device->NotifyVsync(aVsyncTimestamp);
}
DispatchVRDeviceSensorUpdate();
}
void
VRManager::RefreshVRDevices()
{
nsTArray<RefPtr<gfx::VRHMDInfo> > devices;
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
mManagers[i]->GetHMDs(devices);
}
bool deviceInfoChanged = false;
if (devices.Length() != mVRDevices.Count()) {
deviceInfoChanged = true;
}
for (const auto& device: devices) {
RefPtr<VRHMDInfo> oldDevice = GetDevice(device->GetDeviceInfo().GetDeviceID());
if (oldDevice == nullptr) {
deviceInfoChanged = true;
break;
}
if (oldDevice->GetDeviceInfo() != device->GetDeviceInfo()) {
deviceInfoChanged = true;
break;
}
}
if (deviceInfoChanged) {
mVRDevices.Clear();
for (const auto& device: devices) {
mVRDevices.Put(device->GetDeviceInfo().GetDeviceID(), device);
}
}
DispatchVRDeviceInfoUpdate();
}
void
VRManager::DispatchVRDeviceInfoUpdate()
{
nsTArray<VRDeviceUpdate> update;
for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) {
gfx::VRHMDInfo* device = iter.UserData();
update.AppendElement(VRDeviceUpdate(device->GetDeviceInfo(),
device->GetSensorState()));
}
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendUpdateDeviceInfo(update);
}
}
void
VRManager::DispatchVRDeviceSensorUpdate()
{
nsTArray<VRSensorUpdate> update;
for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) {
gfx::VRHMDInfo* device = iter.UserData();
if (!device->GetDeviceInfo().GetUseMainThreadOrientation()) {
update.AppendElement(VRSensorUpdate(device->GetDeviceInfo().GetDeviceID(),
device->GetSensorState()));
}
}
if (update.Length() > 0) {
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendUpdateDeviceSensors(update);
}
}
}
RefPtr<gfx::VRHMDInfo>
VRManager::GetDevice(const uint32_t& aDeviceID)
{
RefPtr<gfx::VRHMDInfo> device;
if (mVRDevices.Get(aDeviceID, getter_AddRefs(device))) {
return device;
}
return nullptr;
}
} // namespace gfx
} // namespace mozilla

65
gfx/vr/VRManager.h Normal file
Просмотреть файл

@ -0,0 +1,65 @@
/* -*- 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 GFX_VR_MANAGER_H
#define GFX_VR_MANAGER_H
#include "nsAutoPtr.h"
#include "nsRefPtrHashtable.h"
#include "nsTArray.h"
#include "nsTHashtable.h"
#include "mozilla/TimeStamp.h"
#include "gfxVR.h"
namespace mozilla {
namespace gfx {
class VRManagerParent;
class VRHMDInfo;
class VRManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRManager)
public:
static void ManagerInit();
static VRManager* Get();
void AddVRManagerParent(VRManagerParent* aVRManagerParent);
void RemoveVRManagerParent(VRManagerParent* aVRManagerParent);
void NotifyVsync(const TimeStamp& aVsyncTimestamp);
void RefreshVRDevices();
RefPtr<gfx::VRHMDInfo> GetDevice(const uint32_t& aDeviceID);
protected:
VRManager();
~VRManager();
private:
void Init();
void Destroy();
void DispatchVRDeviceInfoUpdate();
void DispatchVRDeviceSensorUpdate();
typedef nsTHashtable<nsRefPtrHashKey<VRManagerParent>> VRManagerParentSet;
VRManagerParentSet mVRManagerParents;
typedef nsTArray<RefPtr<VRHMDManager>> VRHMDManagerArray;
VRHMDManagerArray mManagers;
typedef nsRefPtrHashtable<nsUint32HashKey, gfx::VRHMDInfo> VRHMDInfoHashMap;
VRHMDInfoHashMap mVRDevices;
Atomic<bool> mInitialized;
};
} // namespace gfx
} // namespace mozilla
#endif // GFX_VR_MANAGER_H

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

@ -20,9 +20,6 @@
#endif
#include "gfxVRCardboard.h"
#include "nsServiceManagerUtils.h"
#include "nsIScreenManager.h"
#include "mozilla/unused.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
@ -34,145 +31,27 @@
using namespace mozilla;
using namespace mozilla::gfx;
// Dummy nsIScreen implementation, for when we just need to specify a size
class FakeScreen : public nsIScreen
{
public:
explicit FakeScreen(const IntRect& aScreenRect)
: mScreenRect(aScreenRect)
{ }
NS_DECL_ISUPPORTS
NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
*l = mScreenRect.x;
*t = mScreenRect.y;
*w = mScreenRect.width;
*h = mScreenRect.height;
return NS_OK;
}
NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetRect(l, t, w, h);
}
NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetRect(l, t, w, h);
}
NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
return GetAvailRect(l, t, w, h);
}
NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD GetRotation(uint32_t* aRotation) override {
*aRotation = nsIScreen::ROTATION_0_DEG;
return NS_OK;
}
NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
*aContentsScaleFactor = 1.0;
return NS_OK;
}
protected:
virtual ~FakeScreen() {}
IntRect mScreenRect;
};
NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
VRHMDInfo::VRHMDInfo(VRHMDType aType)
: mType(aType)
{
MOZ_COUNT_CTOR(VRHMDInfo);
mDeviceIndex = VRHMDManager::AllocateDeviceIndex();
mDeviceName.AssignLiteral("Unknown Device");
}
VRHMDManager::VRHMDManagerArray *VRHMDManager::sManagers = nullptr;
Atomic<uint32_t> VRHMDManager::sDeviceBase(0);
/* static */ void
VRHMDManager::ManagerInit()
VRHMDInfo::VRHMDInfo(VRHMDType aType, bool aUseMainThreadOrientation)
{
if (sManagers)
return;
sManagers = new VRHMDManagerArray();
RefPtr<VRHMDManager> mgr;
// we'll only load the 0.5.0 oculus runtime if
// the >= 0.6.0 one failed to load; otherwise
// we might initialize oculus twice
bool useOculus050 = true;
Unused << useOculus050;
#if defined(XP_WIN)
mgr = new VRHMDManagerOculus();
if (mgr->PlatformInit()) {
useOculus050 = false;
sManagers->AppendElement(mgr);
}
#endif
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
if (useOculus050) {
mgr = new VRHMDManagerOculus050();
if (mgr->PlatformInit())
sManagers->AppendElement(mgr);
}
#endif
mgr = new VRHMDManagerCardboard();
if (mgr->PlatformInit())
sManagers->AppendElement(mgr);
MOZ_COUNT_CTOR(VRHMDInfo);
mDeviceInfo.mType = aType;
mDeviceInfo.mDeviceID = VRHMDManager::AllocateDeviceID();
mDeviceInfo.mUseMainThreadOrientation = aUseMainThreadOrientation;
}
/* static */ void
VRHMDManager::ManagerDestroy()
VRHMDInfo::~VRHMDInfo()
{
if (!sManagers)
return;
for (uint32_t i = 0; i < sManagers->Length(); ++i) {
(*sManagers)[i]->Destroy();
}
delete sManagers;
sManagers = nullptr;
}
/* static */ void
VRHMDManager::GetAllHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult)
{
if (!sManagers)
return;
for (uint32_t i = 0; i < sManagers->Length(); ++i) {
(*sManagers)[i]->GetHMDs(aHMDResult);
}
MOZ_COUNT_DTOR(VRHMDInfo);
}
/* static */ uint32_t
VRHMDManager::AllocateDeviceIndex()
VRHMDManager::AllocateDeviceID()
{
return ++sDeviceBase;
}
/* static */ already_AddRefed<nsIScreen>
VRHMDManager::MakeFakeScreen(int32_t x, int32_t y, uint32_t width, uint32_t height)
{
nsCOMPtr<nsIScreen> screen = new FakeScreen(IntRect(x, y, width, height));
return screen.forget();
}
VRHMDRenderingSupport::RenderTargetSet::RenderTargetSet()
: currentRenderTarget(0)
{

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

@ -7,14 +7,15 @@
#define GFX_VR_H
#include "nsTArray.h"
#include "nsIScreen.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/Atomics.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TypedEnumBits.h"
namespace mozilla {
namespace layers {
@ -31,6 +32,15 @@ enum class VRHMDType : uint16_t {
NumHMDTypes
};
enum class VRStateValidFlags : uint16_t {
State_None = 0,
State_Position = 1 << 1,
State_Orientation = 1 << 2,
// State_All used for validity checking during IPC serialization
State_All = (1 << 3) - 1
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRStateValidFlags)
struct VRFieldOfView {
VRFieldOfView() {}
VRFieldOfView(double up, double right, double down, double left)
@ -63,13 +73,6 @@ struct VRFieldOfView {
double leftDegrees;
};
// 12 floats per vertex. Position, tex coordinates
// for each channel, and 4 generic attributes
struct VRDistortionConstants {
float eyeToSourceScaleAndOffset[4];
float destinationScaleAndOffset[4];
};
struct VRDistortionVertex {
float values[12];
};
@ -79,9 +82,86 @@ struct VRDistortionMesh {
nsTArray<uint16_t> mIndices;
};
// 12 floats per vertex. Position, tex coordinates
// for each channel, and 4 generic attributes
struct VRDistortionConstants {
float eyeToSourceScaleAndOffset[4];
float destinationScaleAndOffset[4];
};
struct VRDeviceInfo
{
VRHMDType GetType() const { return mType; }
uint32_t GetDeviceID() const { return mDeviceID; }
const nsCString& GetDeviceName() const { return mDeviceName; }
VRStateValidFlags GetSupportedSensorStateBits() const { return mSupportedSensorBits; }
const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) const { return mRecommendedEyeFOV[whichEye]; }
const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) const { return mMaximumEyeFOV[whichEye]; }
const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const { return mEyeFOV[whichEye]; }
bool GetUseMainThreadOrientation() const { return mUseMainThreadOrientation; }
enum Eye {
Eye_Left,
Eye_Right,
NumEyes
};
uint32_t mDeviceID;
VRHMDType mType;
nsCString mDeviceName;
VRStateValidFlags mSupportedSensorBits;
VRFieldOfView mMaximumEyeFOV[VRDeviceInfo::NumEyes];
VRFieldOfView mRecommendedEyeFOV[VRDeviceInfo::NumEyes];
VRFieldOfView mEyeFOV[VRDeviceInfo::NumEyes];
Point3D mEyeTranslation[VRDeviceInfo::NumEyes];
Matrix4x4 mEyeProjectionMatrix[VRDeviceInfo::NumEyes];
/* Suggested resolution for rendering a single eye.
* Assumption is that left/right rendering will be 2x of this size.
* XXX fix this for vertical displays
*/
IntSize mEyeResolution;
IntRect mScreenRect;
bool mIsFakeScreen;
bool mUseMainThreadOrientation;
bool operator==(const VRDeviceInfo& other) const {
return mType == other.mType &&
mDeviceID == other.mDeviceID &&
mDeviceName == other.mDeviceName &&
mSupportedSensorBits == other.mSupportedSensorBits &&
mEyeResolution == other.mEyeResolution &&
mScreenRect == other.mScreenRect &&
mIsFakeScreen == other.mIsFakeScreen &&
mUseMainThreadOrientation == other.mUseMainThreadOrientation &&
mMaximumEyeFOV[0] == other.mMaximumEyeFOV[0] &&
mMaximumEyeFOV[1] == other.mMaximumEyeFOV[1] &&
mRecommendedEyeFOV[0] == other.mRecommendedEyeFOV[0] &&
mRecommendedEyeFOV[1] == other.mRecommendedEyeFOV[1] &&
mEyeFOV[0] == other.mEyeFOV[0] &&
mEyeFOV[1] == other.mEyeFOV[1] &&
mEyeTranslation[0] == other.mEyeTranslation[0] &&
mEyeTranslation[1] == other.mEyeTranslation[1] &&
mEyeProjectionMatrix[0] == other.mEyeProjectionMatrix[0] &&
mEyeProjectionMatrix[1] == other.mEyeProjectionMatrix[1];
}
bool operator!=(const VRDeviceInfo& other) const {
return !(*this == other);
}
};
struct VRHMDSensorState {
double timestamp;
uint32_t flags;
VRStateValidFlags flags;
float orientation[4];
float position[3];
float angularVelocity[3];
@ -94,6 +174,27 @@ struct VRHMDSensorState {
}
};
struct VRSensorUpdate {
VRSensorUpdate() { }; // Required for ipdl binding
VRSensorUpdate(uint32_t aDeviceID, const VRHMDSensorState& aSensorState)
: mDeviceID(aDeviceID)
, mSensorState(aSensorState) { };
uint32_t mDeviceID;
VRHMDSensorState mSensorState;
};
struct VRDeviceUpdate {
VRDeviceUpdate() { }; // Required for ipdl binding
VRDeviceUpdate(const VRDeviceInfo& aDeviceInfo,
const VRHMDSensorState& aSensorState)
: mDeviceInfo(aDeviceInfo)
, mSensorState(aSensorState) { };
VRDeviceInfo mDeviceInfo;
VRHMDSensorState mSensorState;
};
/* A pure data struct that can be used to see if
* the configuration of one HMDInfo matches another; for rendering purposes,
* really asking "can the rendering details of this one be used for the other"
@ -149,51 +250,23 @@ protected:
};
class VRHMDInfo {
public:
enum Eye {
Eye_Left,
Eye_Right,
NumEyes
};
enum StateValidFlags {
State_Position = 1 << 1,
State_Orientation = 1 << 2
};
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo)
VRHMDType GetType() const { return mType; }
uint32_t GetDeviceIndex() const { return mDeviceIndex; }
const nsCString& GetDeviceName() const { return mDeviceName; }
virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; }
virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; }
const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; }
const VRDeviceInfo& GetDeviceInfo() const { return mDeviceInfo; }
/* set the FOV for this HMD unit; this triggers a computation of all the remaining bits. Returns false if it fails */
virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
double zNear, double zFar) = 0;
const VRFieldOfView& GetEyeFOV(uint32_t whichEye) { return mEyeFOV[whichEye]; }
/* Suggested resolution for rendering a single eye.
* Assumption is that left/right rendering will be 2x of this size.
* XXX fix this for vertical displays
*/
const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; }
virtual bool StartSensorTracking() = 0;
virtual bool KeepSensorTracking() = 0;
virtual void NotifyVsync(const TimeStamp& aVsyncTimestamp) = 0;
virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0;
virtual void StopSensorTracking() = 0;
virtual void ZeroSensor() = 0;
// if rendering is offloaded
virtual VRHMDRenderingSupport *GetRenderingSupport() { return nullptr; }
@ -205,50 +278,27 @@ public:
const Rect& destRect, // the rectangle within the dest viewport that this should be rendered
VRDistortionConstants& values) = 0;
virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
// The nsIScreen that represents this device
virtual nsIScreen* GetScreen() { return mScreen; }
const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
protected:
explicit VRHMDInfo(VRHMDType aType);
virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); }
explicit VRHMDInfo(VRHMDType aType, bool aUseMainThreadOrientation);
virtual ~VRHMDInfo();
VRHMDType mType;
VRHMDConfiguration mConfiguration;
uint32_t mDeviceIndex;
nsCString mDeviceName;
VRFieldOfView mEyeFOV[NumEyes];
IntSize mEyeResolution;
Point3D mEyeTranslation[NumEyes];
Matrix4x4 mEyeProjectionMatrix[NumEyes];
VRDistortionMesh mDistortionMesh[NumEyes];
uint32_t mSupportedSensorBits;
VRFieldOfView mRecommendedEyeFOV[NumEyes];
VRFieldOfView mMaximumEyeFOV[NumEyes];
nsCOMPtr<nsIScreen> mScreen;
VRDeviceInfo mDeviceInfo;
VRDistortionMesh mDistortionMesh[VRDeviceInfo::NumEyes];
};
class VRHMDManager {
public:
static void ManagerInit();
static void ManagerDestroy();
static void GetAllHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult);
static uint32_t AllocateDeviceIndex();
static already_AddRefed<nsIScreen> MakeFakeScreen(int32_t x, int32_t y, uint32_t width, uint32_t height);
static uint32_t AllocateDeviceID();
protected:
typedef nsTArray<RefPtr<VRHMDManager>> VRHMDManagerArray;
static VRHMDManagerArray *sManagers;
static Atomic<uint32_t> sDeviceBase;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDManager)
virtual bool PlatformInit() = 0;
virtual bool Init() = 0;
virtual void Destroy() = 0;
virtual void GetHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult) = 0;

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

@ -10,7 +10,6 @@
#include "prenv.h"
#include "gfxPrefs.h"
#include "nsString.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "mozilla/Preferences.h"
#include "mozilla/Hal.h"
@ -19,232 +18,87 @@
#include "nsServiceManagerUtils.h"
#include "nsIScreenManager.h"
#ifdef ANDROID
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoVR" , ## args)
#else
#define LOG(...) do { } while(0)
#endif
// 1/sqrt(2) (aka sqrt(2)/2)
#ifndef M_SQRT1_2
# define M_SQRT1_2 0.70710678118654752440
#endif
using namespace mozilla::dom;
using namespace mozilla::gfx;
using namespace mozilla::gfx::impl;
namespace {
// some utility functions
// This remaps axes in the given matrix to a new configuration based on the
// screen orientation. Similar to what Android SensorManager.remapCoordinateSystem
// does, except only for a fixed number of transforms that we need.
Matrix4x4
RemapMatrixForOrientation(ScreenOrientationInternal screenConfig, const Matrix4x4& aMatrix)
{
Matrix4x4 out;
const float *in = &aMatrix._11;
float *o = &out._11;
if (screenConfig == eScreenOrientation_LandscapePrimary) {
// remap X,Y -> Y,-X
o[0] = -in[1]; o[1] = in[0]; o[2] = in[2];
o[4] = -in[5]; o[5] = in[4]; o[6] = in[6];
o[8] = -in[9]; o[9] = in[8]; o[10] = in[10];
} else if (screenConfig == eScreenOrientation_LandscapeSecondary) {
// remap X,Y -> -Y,X
o[0] = in[1]; o[1] = -in[0]; o[2] = in[2];
o[4] = in[5]; o[5] = -in[4]; o[6] = in[6];
o[8] = in[9]; o[9] = -in[8]; o[10] = in[10];
} else if (screenConfig == eScreenOrientation_PortraitPrimary) {
out = aMatrix;
} else if (screenConfig == eScreenOrientation_PortraitSecondary) {
// remap X,Y -> X,-Z
o[0] = in[0]; o[1] = in[2]; o[2] = -in[1];
o[4] = in[4]; o[5] = in[6]; o[6] = -in[5];
o[8] = in[8]; o[9] = in[10]; o[10] = -in[9];
} else {
MOZ_ASSERT(0, "gfxVRCardboard::RemapMatrixForOrientation invalid screenConfig");
}
return out;
}
} // namespace
HMDInfoCardboard::HMDInfoCardboard()
: VRHMDInfo(VRHMDType::Cardboard)
, mStartCount(0)
, mOrient(eScreenOrientation_PortraitPrimary)
: VRHMDInfo(VRHMDType::Cardboard, true)
{
MOZ_ASSERT(sizeof(HMDInfoCardboard::DistortionVertex) == sizeof(VRDistortionVertex),
"HMDInfoCardboard::DistortionVertex must match the size of VRDistortionVertex");
MOZ_COUNT_CTOR_INHERITED(HMDInfoCardboard, VRHMDInfo);
mDeviceName.AssignLiteral("Phone Sensor (Cardboard) HMD");
mDeviceInfo.mDeviceName.AssignLiteral("Phone Sensor (Cardboard) HMD");
mSupportedSensorBits = State_Orientation;
mDeviceInfo.mSupportedSensorBits = VRStateValidFlags::State_Orientation;
mRecommendedEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mRecommendedEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mMaximumEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mMaximumEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Left] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Right] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
#if 1
int32_t xcoord = 0;
if (PR_GetEnv("FAKE_CARDBOARD_SCREEN")) {
const char *env = PR_GetEnv("FAKE_CARDBOARD_SCREEN");
nsresult err;
xcoord = nsCString(env).ToInteger(&err);
if (err != NS_OK) xcoord = 0;
}
mScreen = VRHMDManager::MakeFakeScreen(xcoord, 0, 1920, 1080);
#endif
SetFOV(mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left], mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right], 0.01, 10000.0);
mDeviceInfo.mScreenRect.x = 0;
mDeviceInfo.mScreenRect.y = 0;
mDeviceInfo.mScreenRect.width = 1920;
mDeviceInfo.mScreenRect.height = 1080;
mDeviceInfo.mIsFakeScreen = true;
}
bool
HMDInfoCardboard::StartSensorTracking()
{
LOG("HMDInfoCardboard::StartSensorTracking %d\n", mStartCount);
if (mStartCount == 0) {
// it's never been started before; initialize observers and
// initial state.
mozilla::hal::ScreenConfiguration sconfig;
mozilla::hal::GetCurrentScreenConfiguration(&sconfig);
this->Notify(sconfig);
mozilla::hal::RegisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this);
mozilla::hal::RegisterScreenConfigurationObserver(this);
mLastSensorState.Clear();
}
mStartCount++;
return true;
}
// Android sends us events that have a 90-degree rotation about
// the x axis compared to what we want (phone flat vs. phone held in front of the eyes).
// Correct for this by applying a transform to undo this rotation.
void
HMDInfoCardboard::Notify(const mozilla::hal::ScreenConfiguration& config)
{
mOrient = config.orientation();
if (mOrient == eScreenOrientation_LandscapePrimary) {
mScreenTransform = Quaternion(-0.5f, 0.5f, 0.5f, 0.5f);
} else if (mOrient == eScreenOrientation_LandscapeSecondary) {
mScreenTransform = Quaternion(-0.5f, -0.5f, -0.5f, 0.5f);
} else if (mOrient == eScreenOrientation_PortraitPrimary) {
mScreenTransform = Quaternion((float) -M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2);
} else if (mOrient == eScreenOrientation_PortraitSecondary) {
// Currently, PortraitSecondary event doesn't be triggered.
mScreenTransform = Quaternion((float) M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2);
}
}
void
HMDInfoCardboard::Notify(const mozilla::hal::SensorData& data)
{
if (data.sensor() != mozilla::hal::SENSOR_GAME_ROTATION_VECTOR)
return;
const nsTArray<float>& sensorValues = data.values();
// This is super chatty
//LOG("HMDInfoCardboard::Notify %f %f %f %f\n", sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
mSavedLastSensor.Set(sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
mSavedLastSensorTime = data.timestamp();
mNeedsSensorCompute = true;
}
void
HMDInfoCardboard::ComputeStateFromLastSensor()
{
if (!mNeedsSensorCompute)
return;
// apply the zero orientation
Quaternion q = mSensorZeroInverse * mSavedLastSensor;
// make a matrix from the quat
Matrix4x4 qm;
qm.SetRotationFromQuaternion(q);
// remap the coordinate space, based on the orientation
Matrix4x4 qmRemapped = RemapMatrixForOrientation(mOrient, qm);
// turn it back into a quat
q.SetFromRotationMatrix(qmRemapped);
// apply adjustment based on what's been done to the screen and the original zero
// position of the base coordinate space
q = mScreenTransform * q;
VRHMDSensorState& state = mLastSensorState;
state.flags |= State_Orientation;
state.orientation[0] = q.x;
state.orientation[1] = q.y;
state.orientation[2] = q.z;
state.orientation[3] = q.w;
state.timestamp = mSavedLastSensorTime / 1000000.0;
mNeedsSensorCompute = false;
}
VRHMDSensorState
HMDInfoCardboard::GetSensorState(double timeOffset)
{
ComputeStateFromLastSensor();
return mLastSensorState;
}
void
HMDInfoCardboard::StopSensorTracking()
{
LOG("HMDInfoCardboard::StopSensorTracking, count %d\n", mStartCount);
if (--mStartCount == 0) {
mozilla::hal::UnregisterScreenConfigurationObserver(this);
mozilla::hal::UnregisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this);
}
// Actual sensor state is calculated on the main thread,
// within VRDeviceProxyOrientationFallBack
VRHMDSensorState result;
result.Clear();
return result;
}
void
HMDInfoCardboard::ZeroSensor()
{
mSensorZeroInverse = mSavedLastSensor;
mSensorZeroInverse.Invert();
MOZ_ASSERT(0, "HMDInfoCardboard::ZeroSensor not implemented. "
"Should use VRDeviceProxyOrientationFallBack on main thread");
}
void
HMDInfoCardboard::NotifyVsync(const TimeStamp& aVsyncTimestamp)
{
// Nothing to do here for Cardboard VR
}
bool
HMDInfoCardboard::SetFOV(const VRFieldOfView& aFOVLeft,
const VRFieldOfView& aFOVRight,
HMDInfoCardboard::KeepSensorTracking()
{
// Nothing to do here for Cardboard VR
return true;
}
bool
HMDInfoCardboard::SetFOV(const gfx::VRFieldOfView& aFOVLeft,
const gfx::VRFieldOfView& aFOVRight,
double zNear, double zFar)
{
const float standardIPD = 0.064f;
for (uint32_t eye = 0; eye < NumEyes; eye++) {
mEyeFOV[eye] = eye == Eye_Left ? aFOVLeft : aFOVRight;
mEyeTranslation[eye] = Point3D(standardIPD * (eye == Eye_Left ? -1.0 : 1.0), 0.0, 0.0);
mEyeProjectionMatrix[eye] = mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true);
for (uint32_t eye = 0; eye < VRDeviceInfo::NumEyes; eye++) {
mDeviceInfo.mEyeFOV[eye] = eye == VRDeviceInfo::Eye_Left ? aFOVLeft : aFOVRight;
mDeviceInfo.mEyeTranslation[eye] = Point3D(standardIPD * (eye == VRDeviceInfo::Eye_Left ? -1.0 : 1.0), 0.0, 0.0);
mDeviceInfo.mEyeProjectionMatrix[eye] = mDeviceInfo.mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true);
mDistortionMesh[eye].mVertices.SetLength(4);
mDistortionMesh[eye].mIndices.SetLength(6);
HMDInfoCardboard::DistortionVertex *destv = reinterpret_cast<HMDInfoCardboard::DistortionVertex*>(mDistortionMesh[eye].mVertices.Elements());
float xoffs = eye == Eye_Left ? 0.0f : 1.0f;
float txoffs = eye == Eye_Left ? 0.0f : 0.5f;
float xoffs = eye == VRDeviceInfo::Eye_Left ? 0.0f : 1.0f;
float txoffs = eye == VRDeviceInfo::Eye_Left ? 0.0f : 0.5f;
destv[0].pos[0] = -1.0 + xoffs;
destv[0].pos[1] = -1.0;
destv[0].texR[0] = destv[0].texG[0] = destv[0].texB[0] = 0.0 + txoffs;
@ -275,16 +129,16 @@ HMDInfoCardboard::SetFOV(const VRFieldOfView& aFOVLeft,
}
// XXX find out the default screen size and use that
mEyeResolution.width = 1920 / 2;
mEyeResolution.height = 1080;
mDeviceInfo.mEyeResolution.width = 1920 / 2;
mDeviceInfo.mEyeResolution.height = 1080;
if (PR_GetEnv("FAKE_CARDBOARD_SCREEN")) {
// for testing, make the eye resolution 2x of the screen
mEyeResolution.width *= 2;
mEyeResolution.height *= 2;
mDeviceInfo.mEyeResolution.width *= 2;
mDeviceInfo.mEyeResolution.height *= 2;
}
mConfiguration.hmdType = mType;
mConfiguration.hmdType = mDeviceInfo.mType;
mConfiguration.value = 0;
mConfiguration.fov[0] = aFOVLeft;
mConfiguration.fov[1] = aFOVRight;
@ -332,19 +186,26 @@ HMDInfoCardboard::Destroy()
{
}
bool
VRHMDManagerCardboard::PlatformInit()
/*static*/ already_AddRefed<VRHMDManagerCardboard>
VRHMDManagerCardboard::Create()
{
return gfxPrefs::VREnabled() && gfxPrefs::VRCardboardEnabled();
MOZ_ASSERT(NS_IsMainThread());
if (!gfxPrefs::VREnabled() || !gfxPrefs::VRCardboardEnabled())
{
return nullptr;
}
RefPtr<VRHMDManagerCardboard> manager = new VRHMDManagerCardboard();
return manager.forget();
}
bool
VRHMDManagerCardboard::Init()
{
if (mCardboardInitialized)
if (mCardboardInitialized) {
return true;
}
RefPtr<HMDInfoCardboard> hmd = new HMDInfoCardboard();
mCardboardHMDs.AppendElement(hmd);
@ -370,7 +231,10 @@ VRHMDManagerCardboard::Destroy()
void
VRHMDManagerCardboard::GetHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult)
{
Init();
if (!mCardboardInitialized) {
return;
}
for (size_t i = 0; i < mCardboardHMDs.Length(); ++i) {
aHMDResult.AppendElement(mCardboardHMDs[i]);
}

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

@ -9,8 +9,6 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Quaternion.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/HalSensor.h"
#include "mozilla/HalScreenConfiguration.h"
#include "gfxVR.h"
@ -19,9 +17,7 @@ namespace gfx {
namespace impl {
class HMDInfoCardboard :
public VRHMDInfo,
public hal::ISensorObserver,
public hal::ScreenConfigurationObserver
public VRHMDInfo
{
public:
explicit HMDInfoCardboard();
@ -29,10 +25,10 @@ public:
bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
double zNear, double zFar) override;
bool StartSensorTracking() override;
VRHMDSensorState GetSensorState(double timeOffset) override;
void StopSensorTracking() override;
void ZeroSensor() override;
bool KeepSensorTracking() override;
void NotifyVsync(const TimeStamp& aVsyncTimestamp) override;
void FillDistortionConstants(uint32_t whichEye,
const IntSize& textureSize, const IntRect& eyeViewport,
@ -41,12 +37,12 @@ public:
void Destroy();
// ISensorObserver interface
void Notify(const hal::SensorData& SensorData) override;
// ScreenConfigurationObserver interface
void Notify(const hal::ScreenConfiguration& ScreenConfiguration) override;
protected:
virtual ~HMDInfoCardboard() {
MOZ_COUNT_DTOR_INHERITED(HMDInfoCardboard, VRHMDInfo);
Destroy();
}
// must match the size of VRDistortionVertex
struct DistortionVertex {
float pos[2];
@ -56,21 +52,6 @@ protected:
float padding[4];
};
virtual ~HMDInfoCardboard() {
Destroy();
}
void ComputeStateFromLastSensor();
uint32_t mStartCount;
VRHMDSensorState mLastSensorState;
uint32_t mOrient;
Quaternion mScreenTransform;
Quaternion mSensorZeroInverse;
Quaternion mSavedLastSensor;
double mSavedLastSensorTime;
bool mNeedsSensorCompute; // if we need to compute the state from mSavedLastSensor
};
} // namespace impl
@ -78,15 +59,14 @@ protected:
class VRHMDManagerCardboard : public VRHMDManager
{
public:
VRHMDManagerCardboard()
: mCardboardInitialized(false)
{ }
virtual bool PlatformInit() override;
static already_AddRefed<VRHMDManagerCardboard> Create();
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRHMDInfo> >& aHMDResult) override;
protected:
VRHMDManagerCardboard()
: mCardboardInitialized(false)
{ }
nsTArray<RefPtr<impl::HMDInfoCardboard>> mCardboardHMDs;
bool mCardboardInitialized;
};

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

@ -11,6 +11,7 @@
#include "gfxPrefs.h"
#include "nsString.h"
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/gfx/Quaternion.h"
@ -20,9 +21,6 @@
#include "gfxVROculus.h"
#include "nsServiceManagerUtils.h"
#include "nsIScreenManager.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
@ -111,7 +109,7 @@ InitializeOculusCAPI()
libSearchPaths.AppendElement(nsCString("/usr/lib"));
libName.AppendPrintf("libOVRRT%d_%d.so.%d", BUILD_BITS, OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION);
#endif
// If the pref is present, we override libName
nsAdoptingCString prefLibPath = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path");
if (prefLibPath && prefLibPath.get()) {
@ -227,7 +225,7 @@ do_CalcEyePoses(ovrPosef headPose,
}
ovrFovPort
ToFovPort(const VRFieldOfView& aFOV)
ToFovPort(const gfx::VRFieldOfView& aFOV)
{
ovrFovPort fovPort;
fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0);
@ -237,10 +235,10 @@ ToFovPort(const VRFieldOfView& aFOV)
return fovPort;
}
VRFieldOfView
gfx::VRFieldOfView
FromFovPort(const ovrFovPort& aFOV)
{
VRFieldOfView fovInfo;
gfx::VRFieldOfView fovInfo;
fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI;
fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI;
fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI;
@ -250,53 +248,66 @@ FromFovPort(const ovrFovPort& aFOV)
} // namespace
HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD)
: VRHMDInfo(VRHMDType::Oculus)
HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD, bool aDebug, int aDeviceID)
: VRHMDInfo(VRHMDType::Oculus, false)
, mHMD(aHMD)
, mStartCount(0)
, mTracking(false)
, mDebug(aDebug)
, mDeviceID(aDeviceID)
, mSensorTrackingFramesRemaining(0)
{
MOZ_ASSERT(sizeof(HMDInfoOculus::DistortionVertex) == sizeof(VRDistortionVertex),
"HMDInfoOculus::DistortionVertex must match the size of VRDistortionVertex");
MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
mDeviceName.AssignLiteral("Oculus VR HMD");
mSupportedSensorBits = 0;
if (mHMD->TrackingCaps & ovrTrackingCap_Orientation)
mSupportedSensorBits |= State_Orientation;
if (mHMD->TrackingCaps & ovrTrackingCap_Position)
mSupportedSensorBits |= State_Position;
mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
#if 1
int32_t xcoord = 0;
if (getenv("FAKE_OCULUS_SCREEN")) {
const char *env = getenv("FAKE_OCULUS_SCREEN");
nsresult err;
xcoord = nsCString(env).ToInteger(&err);
if (err != NS_OK) xcoord = 0;
if (aDebug) {
mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD Debug)");
} else {
mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD");
}
mDeviceInfo.mSupportedSensorBits = VRStateValidFlags::State_None;
if (mHMD->TrackingCaps & ovrTrackingCap_Orientation) {
mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Orientation;
}
if (mHMD->TrackingCaps & ovrTrackingCap_Position) {
mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Position;
}
mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
uint32_t w = mHMD->Resolution.w;
uint32_t h = mHMD->Resolution.h;
mScreen = VRHMDManager::MakeFakeScreen(xcoord, 0, std::max(w, h), std::min(w, h));
mDeviceInfo.mScreenRect.x = 0;
mDeviceInfo.mScreenRect.y = 0;
mDeviceInfo.mScreenRect.width = std::max(w, h);
mDeviceInfo.mScreenRect.height = std::min(w, h);
mDeviceInfo.mIsFakeScreen = true;
#ifdef DEBUG
printf_stderr("OCULUS SCREEN: %d %d %d %d\n", xcoord, 0, std::max(w, h), std::min(w, h));
#endif
#endif
SetFOV(mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left], mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right], 0.01, 10000.0);
}
bool
HMDInfoOculus::GetIsDebug() const
{
return mDebug;
}
int
HMDInfoOculus::GetDeviceID() const
{
return mDeviceID;
}
void
HMDInfoOculus::Destroy()
{
StopSensorTracking();
if (mHMD) {
ovrHmd_Destroy(mHMD);
mHMD = nullptr;
@ -304,33 +315,33 @@ HMDInfoOculus::Destroy()
}
bool
HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
HMDInfoOculus::SetFOV(const gfx::VRFieldOfView& aFOVLeft, const gfx::VRFieldOfView& aFOVRight,
double zNear, double zFar)
{
float pixelsPerDisplayPixel = 1.0;
ovrSizei texSize[2];
// get eye parameters and create the mesh
for (uint32_t eye = 0; eye < NumEyes; eye++) {
mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
mFOVPort[eye] = ToFovPort(mEyeFOV[eye]);
for (uint32_t eye = 0; eye < VRDeviceInfo::NumEyes; eye++) {
mDeviceInfo.mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
mFOVPort[eye] = ToFovPort(mDeviceInfo.mEyeFOV[eye]);
ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]);
// As of Oculus 0.6.0, the HmdToEyeViewOffset values are correct and don't need to be negated.
mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeViewOffset.x, renderDesc.HmdToEyeViewOffset.y, renderDesc.HmdToEyeViewOffset.z);
mDeviceInfo.mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeViewOffset.x, renderDesc.HmdToEyeViewOffset.y, renderDesc.HmdToEyeViewOffset.z);
// note that we are using a right-handed coordinate system here, to match CSS
mEyeProjectionMatrix[eye] = mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true);
mDeviceInfo.mEyeProjectionMatrix[eye] = mDeviceInfo.mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true);
texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel);
}
// take the max of both for eye resolution
mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w);
mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h);
mDeviceInfo.mEyeResolution.width = std::max(texSize[VRDeviceInfo::Eye_Left].w, texSize[VRDeviceInfo::Eye_Right].w);
mDeviceInfo.mEyeResolution.height = std::max(texSize[VRDeviceInfo::Eye_Left].h, texSize[VRDeviceInfo::Eye_Right].h);
mConfiguration.hmdType = mType;
mConfiguration.hmdType = mDeviceInfo.mType;
mConfiguration.value = 0;
mConfiguration.fov[0] = aFOVLeft;
mConfiguration.fov[1] = aFOVRight;
@ -349,23 +360,51 @@ HMDInfoOculus::FillDistortionConstants(uint32_t whichEye,
}
bool
HMDInfoOculus::StartSensorTracking()
HMDInfoOculus::KeepSensorTracking()
{
if (mStartCount == 0) {
bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
if (!ok)
return false;
// Keep sensor tracking alive for short time after the last request for
// tracking state by content. Value conservatively high to accomodate
// potentially high frame rates.
const uint32_t kKeepAliveFrames = 200;
bool success = true;
if (mSensorTrackingFramesRemaining == 0) {
success = StartSensorTracking();
}
if (success) {
mSensorTrackingFramesRemaining = kKeepAliveFrames;
}
mStartCount++;
return true;
return success;
}
void
HMDInfoOculus::NotifyVsync(const mozilla::TimeStamp& aVsyncTimestamp)
{
if (mSensorTrackingFramesRemaining == 1) {
StopSensorTracking();
}
if (mSensorTrackingFramesRemaining) {
--mSensorTrackingFramesRemaining;
}
}
bool
HMDInfoOculus::StartSensorTracking()
{
if (!mTracking) {
mTracking = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
}
return mTracking;
}
void
HMDInfoOculus::StopSensorTracking()
{
if (--mStartCount == 0) {
if (mTracking) {
ovrHmd_ConfigureTracking(mHMD, 0, 0);
mTracking = false;
}
}
@ -389,7 +428,7 @@ HMDInfoOculus::GetSensorState(double timeOffset)
result.timestamp = pose.TimeInSeconds;
if (state.StatusFlags & ovrStatus_OrientationTracked) {
result.flags |= State_Orientation;
result.flags |= VRStateValidFlags::State_Orientation;
result.orientation[0] = pose.ThePose.Orientation.x;
result.orientation[1] = pose.ThePose.Orientation.y;
@ -406,7 +445,7 @@ HMDInfoOculus::GetSensorState(double timeOffset)
}
if (state.StatusFlags & ovrStatus_PositionTracked) {
result.flags |= State_Position;
result.flags |= VRStateValidFlags::State_Position;
result.position[0] = pose.ThePose.Position.x;
result.position[1] = pose.ThePose.Position.y;
@ -561,8 +600,8 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet)
layer.Viewport[1].Size.w = rts->size.width / 2;
layer.Viewport[1].Size.h = rts->size.height;
const Point3D& l = rts->hmd->mEyeTranslation[0];
const Point3D& r = rts->hmd->mEyeTranslation[1];
const Point3D& l = rts->hmd->mDeviceInfo.mEyeTranslation[0];
const Point3D& r = rts->hmd->mDeviceInfo.mEyeTranslation[1];
const ovrVector3f hmdToEyeViewOffset[2] = { { l.x, l.y, l.z },
{ r.x, r.y, r.z } };
do_CalcEyePoses(rts->hmd->mLastTrackingState.HeadPose.ThePose, hmdToEyeViewOffset, layer.RenderPose);
@ -575,95 +614,127 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet)
}
}
bool
VRHMDManagerOculus::PlatformInit()
/*static*/ already_AddRefed<VRHMDManagerOculus>
VRHMDManagerOculus::Create()
{
if (mOculusPlatformInitialized)
return true;
MOZ_ASSERT(NS_IsMainThread());
if (!gfxPrefs::VREnabled() ||
!gfxPrefs::VROculusEnabled())
if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled())
{
return false;
return nullptr;
}
if (!InitializeOculusCAPI())
return false;
if (!InitializeOculusCAPI()) {
return nullptr;
}
ovrInitParams params;
params.Flags = ovrInit_RequestVersion;
params.RequestedMinorVersion = OVR_MINOR_VERSION;
params.LogCallback = nullptr;
params.ConnectionTimeoutMS = 0;
ovrResult orv = ovr_Initialize(&params);
if (orv != ovrSuccess)
return false;
mOculusPlatformInitialized = true;
return true;
RefPtr<VRHMDManagerOculus> manager = new VRHMDManagerOculus();
return manager.forget();
}
bool
VRHMDManagerOculus::Init()
{
if (mOculusInitialized)
return true;
if (!mOculusInitialized) {
nsIThread* thread = nullptr;
NS_GetCurrentThread(&thread);
mOculusThread = already_AddRefed<nsIThread>(thread);
if (!PlatformInit())
return false;
ovrInitParams params;
params.Flags = ovrInit_RequestVersion;
params.RequestedMinorVersion = OVR_MINOR_VERSION;
params.LogCallback = nullptr;
params.ConnectionTimeoutMS = 0;
ovrResult orv = ovr_Initialize(&params);
if (orv == ovrSuccess) {
mOculusInitialized = true;
}
}
return mOculusInitialized;
}
void
VRHMDManagerOculus::Destroy()
{
if(mOculusInitialized) {
MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread);
mOculusThread = nullptr;
for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
mOculusHMDs[i]->Destroy();
}
mOculusHMDs.Clear();
ovr_Shutdown();
mOculusInitialized = false;
}
}
void
VRHMDManagerOculus::GetHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult)
{
if (!mOculusInitialized) {
return;
}
nsTArray<RefPtr<impl::HMDInfoOculus> > newHMDs;
ovrResult orv;
int count = ovrHmd_Detect();
for (int i = 0; i < count; ++i) {
ovrHmd hmd;
orv = ovrHmd_Create(i, &hmd);
if (orv == ovrSuccess) {
RefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
mOculusHMDs.AppendElement(oc);
for (int j = 0; j < count; ++j) {
bool is_new = true;
for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
if (mOculusHMDs[i]->GetDeviceID() == j) {
newHMDs.AppendElement(mOculusHMDs[i]);
is_new = false;
break;
}
}
if (is_new) {
ovrHmd hmd;
orv = ovrHmd_Create(j, &hmd);
if (orv == ovrSuccess) {
RefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd, false, j);
newHMDs.AppendElement(oc);
}
}
}
// VRAddTestDevices == 1: add test device only if no real devices present
// VRAddTestDevices == 2: add test device always
if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) ||
(gfxPrefs::VRAddTestDevices() == 2))
(gfxPrefs::VRAddTestDevices() == 2))
{
ovrHmd hmd;
orv = ovrHmd_CreateDebug(ovrHmd_DK2, &hmd);
if (orv == ovrSuccess) {
RefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
mOculusHMDs.AppendElement(oc);
// Keep existing debug HMD if possible
bool foundDebug = false;
for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
if (mOculusHMDs[i]->GetIsDebug()) {
newHMDs.AppendElement(mOculusHMDs[i]);
foundDebug = true;
}
}
// If there isn't already a debug HMD, create one
if (!foundDebug) {
ovrHmd hmd;
orv = ovrHmd_CreateDebug(ovrHmd_DK2, &hmd);
if (orv == ovrSuccess) {
RefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd, true, -1);
newHMDs.AppendElement(oc);
}
}
}
mOculusInitialized = true;
return true;
}
mOculusHMDs = newHMDs;
void
VRHMDManagerOculus::Destroy()
{
if (!mOculusInitialized)
return;
for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
mOculusHMDs[i]->Destroy();
}
mOculusHMDs.Clear();
ovr_Shutdown();
mOculusInitialized = false;
}
void
VRHMDManagerOculus::GetHMDs(nsTArray<RefPtr<VRHMDInfo>>& aHMDResult)
{
Init();
for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
aHMDResult.AppendElement(mOculusHMDs[i]);
for (size_t j = 0; j < mOculusHMDs.Length(); ++j) {
aHMDResult.AppendElement(mOculusHMDs[j]);
}
}

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

@ -7,8 +7,6 @@
#define GFX_VR_OCULUS_H
#include "nsTArray.h"
#include "nsIScreen.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/2D.h"
@ -25,15 +23,15 @@ namespace impl {
class HMDInfoOculus : public VRHMDInfo, public VRHMDRenderingSupport {
public:
explicit HMDInfoOculus(ovrHmd aHMD);
explicit HMDInfoOculus(ovrHmd aHMD, bool aDebug, int aDeviceID);
bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
double zNear, double zFar) override;
bool StartSensorTracking() override;
VRHMDSensorState GetSensorState(double timeOffset) override;
void StopSensorTracking() override;
void ZeroSensor() override;
bool KeepSensorTracking() override;
void NotifyVsync(const TimeStamp& aVsyncTimestamp) override;
void FillDistortionConstants(uint32_t whichEye,
const IntSize& textureSize, const IntRect& eyeViewport,
@ -50,8 +48,18 @@ public:
void SubmitFrame(RenderTargetSet *aRTSet) override;
ovrHmd GetOculusHMD() const { return mHMD; }
bool GetIsDebug() const;
int GetDeviceID() const;
protected:
virtual ~HMDInfoOculus() {
Destroy();
MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
}
bool StartSensorTracking();
void StopSensorTracking();
// must match the size of VRDistortionVertex
struct DistortionVertex {
float pos[2];
@ -61,15 +69,15 @@ protected:
float genericAttribs[4];
};
virtual ~HMDInfoOculus() {
Destroy();
MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
}
ovrHmd mHMD;
ovrFovPort mFOVPort[2];
uint32_t mStartCount;
bool mTracking;
ovrTrackingState mLastTrackingState;
bool mDebug; // True if this is a debug HMD
int mDeviceID; // Index of device passed to ovrHmd_Create
uint32_t mSensorTrackingFramesRemaining;
};
} // namespace impl
@ -77,18 +85,18 @@ protected:
class VRHMDManagerOculus : public VRHMDManager
{
public:
VRHMDManagerOculus()
: mOculusInitialized(false), mOculusPlatformInitialized(false)
{ }
virtual bool PlatformInit() override;
static already_AddRefed<VRHMDManagerOculus> Create();
virtual bool Init() override;
virtual void Destroy() override;
virtual void GetHMDs(nsTArray<RefPtr<VRHMDInfo> >& aHMDResult) override;
protected:
VRHMDManagerOculus()
: mOculusInitialized(false)
{ }
nsTArray<RefPtr<impl::HMDInfoOculus>> mOculusHMDs;
bool mOculusInitialized;
bool mOculusPlatformInitialized;
RefPtr<nsIThread> mOculusThread;
};
} // namespace gfx

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше