зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
aa5ce3db49
|
@ -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">ع<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⊹𒏺뱬𓕢𐡗␣㤫<sup>⊹𒏺뱬𓕢𐡗␣㤫
|
||||
text
|
||||
</body>
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
<object>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛
|
||||
<i>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
|
||||
<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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
137
gfx/vr/gfxVR.cpp
137
gfx/vr/gfxVR.cpp
|
@ -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)
|
||||
{
|
||||
|
|
192
gfx/vr/gfxVR.h
192
gfx/vr/gfxVR.h
|
@ -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(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
|
||||
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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче