author | Narcis Beleuzu <nbeleuzu@mozilla.com> |
Wed, 06 Jun 2018 12:36:55 +0300 | |
changeset 421531 | cec4a3cecc29ff97860198969b6fdff24b9e93bb |
parent 421510 | d51b920aef6953a2911aab2a9f05470803708f76 (current diff) |
parent 421530 | 633a10eff02a2ada758db8459dc9927bbce31df5 (diff) |
child 421537 | 841300ddc8ec135573453aa95a31196d84bba872 |
child 421581 | 072201279e41b15e1ff1606bfd7460e3656d13b3 |
push id | 34096 |
push user | nbeleuzu@mozilla.com |
push date | Wed, 06 Jun 2018 09:37:23 +0000 |
treeherder | mozilla-central@cec4a3cecc29 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 62.0a1 |
first release with | nightly linux32
cec4a3cecc29
/
62.0a1
/
20180606100133
/
files
nightly linux64
cec4a3cecc29
/
62.0a1
/
20180606100133
/
files
nightly mac
cec4a3cecc29
/
62.0a1
/
20180606100133
/
files
nightly win32
cec4a3cecc29
/
62.0a1
/
20180606100133
/
files
nightly win64
cec4a3cecc29
/
62.0a1
/
20180606100133
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
62.0a1
/
20180606100133
/
pushlog to previous
nightly linux64
62.0a1
/
20180606100133
/
pushlog to previous
nightly mac
62.0a1
/
20180606100133
/
pushlog to previous
nightly win32
62.0a1
/
20180606100133
/
pushlog to previous
nightly win64
62.0a1
/
20180606100133
/
pushlog to previous
|
gfx/vr/gfxVRGVR.cpp | file | annotate | diff | comparison | revisions | |
gfx/vr/gfxVRGVR.h | file | annotate | diff | comparison | revisions | |
gfx/vr/gfxVRGVRAPI.h | file | annotate | diff | comparison | revisions | |
gfx/vr/jni/gfxGVRJNI.cpp | file | annotate | diff | comparison | revisions | |
image/ImageURL.h | file | annotate | diff | comparison | revisions |
--- a/accessible/base/ARIAMap.cpp +++ b/accessible/base/ARIAMap.cpp @@ -83,27 +83,45 @@ static const nsRoleMapEntry sWAIRoleMaps roles::NOTHING, kUseNativeRole, eNoValue, eNoAction, eNoLiveAttr, eLandmark, kNoReqStates }, + { // blockquote + &nsGkAtoms::blockquote, + roles::BLOCKQUOTE, + kUseMapRole, + eNoValue, + eNoAction, + eNoLiveAttr, + kGenericAccType, + }, { // button &nsGkAtoms::button, roles::PUSHBUTTON, kUseMapRole, eNoValue, ePressAction, eNoLiveAttr, eButton, kNoReqStates // eARIAPressed is auto applied on any button }, + { // caption + &nsGkAtoms::caption, + roles::CAPTION, + kUseMapRole, + eNoValue, + eNoAction, + eNoLiveAttr, + kGenericAccType, + }, { // cell &nsGkAtoms::cell, roles::CELL, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, eTableCell, @@ -892,16 +910,25 @@ static const nsRoleMapEntry sWAIRoleMaps eNoValue, eSelectAction, eNoLiveAttr, kGenericAccType, kNoReqStates, eARIASelectable, eARIACheckedMixed }, + { // paragraph + &nsGkAtoms::paragraph, + roles::PARAGRAPH, + kUseMapRole, + eNoValue, + eNoAction, + eNoLiveAttr, + kGenericAccType, + }, { // presentation &nsGkAtoms::presentation, roles::NOTHING, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, kGenericAccType,
--- a/accessible/base/MarkupMap.h +++ b/accessible/base/MarkupMap.h @@ -23,17 +23,17 @@ MARKUPMAP(article, Attr(xmlroles, article)) MARKUPMAP(aside, New_HyperText, roles::NOTE) MARKUPMAP(blockquote, New_HyperText, - roles::SECTION) + roles::BLOCKQUOTE) MARKUPMAP(dd, New_HTMLDefinition, roles::DEFINITION) MARKUPMAP(details, New_HyperText, roles::DETAILS)
--- a/accessible/base/Role.h +++ b/accessible/base/Role.h @@ -1015,17 +1015,22 @@ enum Role { REGION = 173, /** * Represents a control with a text input and a popup with a set of predefined * choices. It is used for ARIA's combobox role. See also COMBOBOX. */ EDITCOMBOBOX = 174, - LAST_ROLE = EDITCOMBOBOX + /** + * A section of content that is quoted from another source. + */ + BLOCKQUOTE = 175, + + LAST_ROLE = BLOCKQUOTE }; } // namespace role typedef enum mozilla::a11y::roles::Role role; } // namespace a11y } // namespace mozilla
--- a/accessible/base/RoleMap.h +++ b/accessible/base/RoleMap.h @@ -1413,8 +1413,16 @@ ROLE(REGION, // See also COMBOBOX. ROLE(EDITCOMBOBOX, "editcombobox", ATK_ROLE_COMBO_BOX, NSAccessibilityComboBoxRole, ROLE_SYSTEM_COMBOBOX, ROLE_SYSTEM_COMBOBOX, eNameFromValueRule) + +ROLE(BLOCKQUOTE, + "blockquote", + ATK_ROLE_BLOCK_QUOTE, + NSAccessibilityGroupRole, + ROLE_SYSTEM_GROUPING, + IA2_ROLE_SECTION, + eNoNameRule)
--- a/accessible/interfaces/nsIAccessibleRole.idl +++ b/accessible/interfaces/nsIAccessibleRole.idl @@ -1009,9 +1009,14 @@ interface nsIAccessibleRole : nsISupport */ const unsigned long ROLE_REGION = 173; /** * Represents a control with a text input and a popup with a set of predefined * choices. It is used for ARIA's combobox role. See also ROLE_COMBOBOX. */ const unsigned long ROLE_EDITCOMBOBOX = 174; + + /** + * A section of content that is quoted from another source. + */ + const unsigned long ROLE_BLOCKQUOTE = 175; };
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html +++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html @@ -175,17 +175,17 @@ ] }; testElm("bdo_container", obj); // //////////////////////////////////////////////////////////////////////// // HTML:blockquote obj = { - role: ROLE_SECTION, + role: ROLE_BLOCKQUOTE, interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ], children: [ { role: ROLE_PARAGRAPH } ] }; testElm("blockquote", obj); // //////////////////////////////////////////////////////////////////////// // HTML:br contained by paragraph
--- a/accessible/tests/mochitest/role.js +++ b/accessible/tests/mochitest/role.js @@ -2,16 +2,17 @@ // Role constants const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT; const ROLE_ARTICLE = nsIAccessibleRole.ROLE_ARTICLE; const ROLE_ANIMATION = nsIAccessibleRole.ROLE_ANIMATION; const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION; const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT; const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE; +const ROLE_BLOCKQUOTE = nsIAccessibleRole.ROLE_BLOCKQUOTE; const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID; const ROLE_CANVAS = nsIAccessibleRole.ROLE_CANVAS; const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION; const ROLE_CELL = nsIAccessibleRole.ROLE_CELL; const ROLE_CHECKBUTTON = nsIAccessibleRole.ROLE_CHECKBUTTON; const ROLE_CHECK_MENU_ITEM = nsIAccessibleRole.ROLE_CHECK_MENU_ITEM; const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW; const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
--- a/accessible/tests/mochitest/role/test_aria.html +++ b/accessible/tests/mochitest/role/test_aria.html @@ -16,17 +16,19 @@ <script type="application/javascript"> function doTest() { // ARIA role map. testRole("aria_alert", ROLE_ALERT); testRole("aria_alertdialog", ROLE_DIALOG); testRole("aria_application", ROLE_APPLICATION); testRole("aria_article", ROLE_ARTICLE); + testRole("aria_blockquote", ROLE_BLOCKQUOTE); testRole("aria_button", ROLE_PUSHBUTTON); + testRole("aria_caption", ROLE_CAPTION); testRole("aria_checkbox", ROLE_CHECKBUTTON); testRole("aria_columnheader", ROLE_COLUMNHEADER); testRole("aria_combobox", ROLE_EDITCOMBOBOX); testRole("aria_dialog", ROLE_DIALOG); testRole("aria_directory", ROLE_LIST); testRole("aria_document", ROLE_NON_NATIVE_DOCUMENT); testRole("aria_form", ROLE_FORM); testRole("aria_feed", ROLE_GROUPING); @@ -44,16 +46,17 @@ testRole("aria_marquee", ROLE_ANIMATION); testRole("aria_math", ROLE_FLAT_EQUATION); testRole("aria_menu", ROLE_MENUPOPUP); testRole("aria_menubar", ROLE_MENUBAR); testRole("aria_menuitem", ROLE_MENUITEM); testRole("aria_menuitemcheckbox", ROLE_CHECK_MENU_ITEM); testRole("aria_menuitemradio", ROLE_RADIO_MENU_ITEM); testRole("aria_note", ROLE_NOTE); + testRole("aria_paragraph", ROLE_PARAGRAPH); testRole("aria_presentation", ROLE_TEXT); // weak role testRole("aria_progressbar", ROLE_PROGRESSBAR); testRole("aria_radio", ROLE_RADIOBUTTON); testRole("aria_radiogroup", ROLE_RADIO_GROUP); testRole("aria_region_no_name", ROLE_TEXT); testRole("aria_region_has_label", ROLE_REGION); testRole("aria_region_has_labelledby", ROLE_REGION); testRole("aria_region_has_title", ROLE_REGION); @@ -204,17 +207,19 @@ <div id="content" style="display: none"></div> <pre id="test"> </pre> <span id="aria_alert" role="alert"/> <span id="aria_alertdialog" role="alertdialog"/> <span id="aria_application" role="application"/> <span id="aria_article" role="article"/> + <span id="aria_blockquote" role="blockquote"/> <span id="aria_button" role="button"/> + <span id="aria_caption" role="caption"/> <span id="aria_checkbox" role="checkbox"/> <span id="aria_columnheader" role="columnheader"/> <span id="aria_combobox" role="combobox"/> <span id="aria_dialog" role="dialog"/> <span id="aria_directory" role="directory"/> <span id="aria_document" role="document"/> <span id="aria_form" role="form"/> <span id="aria_feed" role="feed"/> @@ -232,16 +237,17 @@ <span id="aria_marquee" role="marquee"/> <span id="aria_math" role="math"/> <span id="aria_menu" role="menu"/> <span id="aria_menubar" role="menubar"/> <span id="aria_menuitem" role="menuitem"/> <span id="aria_menuitemcheckbox" role="menuitemcheckbox"/> <span id="aria_menuitemradio" role="menuitemradio"/> <span id="aria_note" role="note"/> + <span id="aria_paragraph" role="paragraph"/> <span id="aria_presentation" role="presentation" tabindex="0"/> <span id="aria_progressbar" role="progressbar"/> <span id="aria_radio" role="radio"/> <span id="aria_radiogroup" role="radiogroup"/> <span id="aria_region_no_name" role="region"/> <span id="aria_region_has_label" role="region" aria-label="label"/> <span id="aria_region_has_labelledby" role="region" aria-labelledby="label"/><span id="label" aria-label="label"> <span id="aria_region_has_title" role="region" title="title"/>
--- a/accessible/tests/mochitest/role/test_general.html +++ b/accessible/tests/mochitest/role/test_general.html @@ -36,17 +36,17 @@ testRole("aside_overflow", ROLE_NOTE); testRole("footer_overflow", ROLE_SECTION); testRole("article_overflow", ROLE_ARTICLE); // test html:div testRole("sec", ROLE_SECTION); // Test html:blockquote - testRole("quote", ROLE_SECTION); + testRole("quote", ROLE_BLOCKQUOTE); // Test html:h, all levels testRole("head1", ROLE_HEADING); testRole("head2", ROLE_HEADING); testRole("head3", ROLE_HEADING); testRole("head4", ROLE_HEADING); testRole("head5", ROLE_HEADING); testRole("head6", ROLE_HEADING);
--- a/accessible/tests/mochitest/tree/test_txtcntr.html +++ b/accessible/tests/mochitest/tree/test_txtcntr.html @@ -90,17 +90,17 @@ testAccessibleTree("c4", accTree); // blockquote accTree = { role: ROLE_SECTION, children: [ { // block quote - role: ROLE_SECTION, + role: ROLE_BLOCKQUOTE, children: [ { // text child role: ROLE_TEXT_LEAF, name: "Hello", children: [] } ] }
--- a/devtools/client/themes/animation.css +++ b/devtools/client/themes/animation.css @@ -403,16 +403,17 @@ select.playback-rate-selector.devtools-b white-space: nowrap; } .animation-detail-close-button { margin: 0; } .animation-detail-close-button::before { + fill: var(--theme-toolbar-photon-icon-color); background-image: url(chrome://devtools/skin/images/close.svg); } /* Animated Property List Container */ .animated-property-list-container { display: flex; flex: 1; flex-direction: column;
--- a/gfx/vr/VRDisplayClient.cpp +++ b/gfx/vr/VRDisplayClient.cpp @@ -76,27 +76,27 @@ VRDisplayClient::SetGroupMask(uint32_t a { VRManagerChild *vm = VRManagerChild::Get(); vm->SendSetGroupMask(mDisplayInfo.mDisplayID, aGroupMask); } bool VRDisplayClient::IsPresentationGenerationCurrent() const { - if (mLastPresentingGeneration != mDisplayInfo.mPresentingGeneration) { + if (mLastPresentingGeneration != mDisplayInfo.mDisplayState.mPresentingGeneration) { return false; } return true; } void VRDisplayClient::MakePresentationGenerationCurrent() { - mLastPresentingGeneration = mDisplayInfo.mPresentingGeneration; + mLastPresentingGeneration = mDisplayInfo.mDisplayState.mPresentingGeneration; } void VRDisplayClient::FireEvents() { VRManagerChild *vm = VRManagerChild::Get(); // Only fire these events for non-chrome VR sessions bool isPresenting = (mDisplayInfo.mPresentingGroups & kVRGroupContent) != 0;
--- a/gfx/vr/VRDisplayHost.cpp +++ b/gfx/vr/VRDisplayHost.cpp @@ -21,19 +21,19 @@ #include "mozilla/layers/TextureD3D11.h" #elif defined(XP_MACOSX) #include "mozilla/gfx/MacIOSurface.h" #endif -#if defined(MOZ_ANDROID_GOOGLE_VR) +#if defined(MOZ_WIDGET_ANDROID) #include "mozilla/layers/CompositorThread.h" -#endif // defined(MOZ_ANDROID_GOOGLE_VR) +#endif // defined(MOZ_WIDGET_ANDROID) using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::layers; VRDisplayHost::AutoRestoreRenderState::AutoRestoreRenderState(VRDisplayHost* aDisplay) : mDisplay(aDisplay) @@ -72,17 +72,17 @@ VRDisplayHost::VRDisplayHost(VRDeviceTyp , mFrameStarted(false) { MOZ_COUNT_CTOR(VRDisplayHost); mDisplayInfo.mType = aType; mDisplayInfo.mDisplayID = VRSystemManager::AllocateDisplayID(); mDisplayInfo.mPresentingGroups = 0; mDisplayInfo.mGroupMask = kVRGroupContent; mDisplayInfo.mFrameId = 0; - mDisplayInfo.mPresentingGeneration = 0; + mDisplayInfo.mDisplayState.mPresentingGeneration = 0; mDisplayInfo.mDisplayState.mDisplayName[0] = '\0'; } VRDisplayHost::~VRDisplayHost() { if (mSubmitThread) { mSubmitThread->Shutdown(); mSubmitThread = nullptr; @@ -263,19 +263,19 @@ VRDisplayHost::NotifyVSync() } void VRDisplayHost::SubmitFrameInternal(const layers::SurfaceDescriptor &aTexture, uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) { -#if !defined(MOZ_ANDROID_GOOGLE_VR) +#if !defined(MOZ_WIDGET_ANDROID) MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread()); -#endif // !defined(MOZ_ANDROID_GOOGLE_VR) +#endif // !defined(MOZ_WIDGET_ANDROID) AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost"); mFrameStarted = false; switch (aTexture.type()) { #if defined(XP_WIN) case SurfaceDescriptor::TSurfaceDescriptorD3D10: { if (!CreateD3DObjects()) { @@ -332,32 +332,32 @@ VRDisplayHost::SubmitFrameInternal(const } IntSize texSize = gfx::IntSize(surf->GetDevicePixelWidth(), surf->GetDevicePixelHeight()); if (!SubmitFrame(surf, texSize, aLeftEyeRect, aRightEyeRect)) { return; } break; } -#elif defined(MOZ_ANDROID_GOOGLE_VR) - case SurfaceDescriptor::TEGLImageDescriptor: { - const EGLImageDescriptor& desc = aTexture.get_EGLImageDescriptor(); - if (!SubmitFrame(&desc, aLeftEyeRect, aRightEyeRect)) { +#elif defined(MOZ_WIDGET_ANDROID) + case SurfaceDescriptor::TSurfaceTextureDescriptor: { + const SurfaceTextureDescriptor& desc = aTexture.get_SurfaceTextureDescriptor(); + if (!SubmitFrame(desc, aLeftEyeRect, aRightEyeRect)) { return; } break; } #endif default: { NS_WARNING("Unsupported SurfaceDescriptor type for VR layer texture"); return; } } -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_ANDROID_GOOGLE_VR) +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) /** * Trigger the next VSync immediately after we are successfully * submitting frames. As SubmitFrame is responsible for throttling * the render loop, if we don't successfully call it, we shouldn't trigger * NotifyVRVsync immediately, as it will run unbounded. * If NotifyVRVsync is not called here due to SubmitFrame failing, the * fallback "watchdog" code in VRDisplayHost::NotifyVSync() will cause @@ -376,43 +376,43 @@ VRDisplayHost::SubmitFrameInternal(const void VRDisplayHost::SubmitFrame(VRLayerParent* aLayer, const layers::SurfaceDescriptor &aTexture, uint64_t aFrameId, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) { -#if !defined(MOZ_ANDROID_GOOGLE_VR) +#if !defined(MOZ_WIDGET_ANDROID) if (!mSubmitThread) { mSubmitThread = new VRThread(NS_LITERAL_CSTRING("VR_SubmitFrame")); } -#endif // !defined(MOZ_ANDROID_GOOGLE_VR) +#endif // !defined(MOZ_WIDGET_ANDROID) if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) { // Suppress layers hidden by the group mask return; } // Ensure that we only accept the first SubmitFrame call per RAF cycle. if (!mFrameStarted || aFrameId != mDisplayInfo.mFrameId) { return; } RefPtr<Runnable> submit = NewRunnableMethod<StoreCopyPassByConstLRef<layers::SurfaceDescriptor>, uint64_t, StoreCopyPassByConstLRef<gfx::Rect>, StoreCopyPassByConstLRef<gfx::Rect>>( "gfx::VRDisplayHost::SubmitFrameInternal", this, &VRDisplayHost::SubmitFrameInternal, aTexture, aFrameId, aLeftEyeRect, aRightEyeRect); -#if !defined(MOZ_ANDROID_GOOGLE_VR) +#if !defined(MOZ_WIDGET_ANDROID) mSubmitThread->Start(); mSubmitThread->PostTask(submit.forget()); #else CompositorThreadHolder::Loop()->PostTask(submit.forget()); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) +#endif // defined(MOZ_WIDGET_ANDROID) } bool VRDisplayHost::CheckClearDisplayInfoDirty() { if (mDisplayInfo == mLastUpdateDisplayInfo) { return false; }
--- a/gfx/vr/VRDisplayHost.h +++ b/gfx/vr/VRDisplayHost.h @@ -81,18 +81,18 @@ protected: const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) = 0; #elif defined(XP_MACOSX) virtual bool SubmitFrame(MacIOSurface* aMacIOSurface, const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) = 0; -#elif defined(MOZ_ANDROID_GOOGLE_VR) - virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor, +#elif defined(MOZ_WIDGET_ANDROID) + virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aSurface, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) = 0; #endif VRDisplayInfo mDisplayInfo; nsTArray<VRLayerParent *> mLayers; // Weak reference to mLayers entries are cleared in
--- a/gfx/vr/VRManager.cpp +++ b/gfx/vr/VRManager.cpp @@ -21,19 +21,16 @@ #include "gfxVRExternal.h" #if defined(XP_WIN) #include "gfxVROculus.h" #endif #if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID)) #include "gfxVROpenVR.h" #include "gfxVROSVR.h" #endif -#if defined(MOZ_ANDROID_GOOGLE_VR) -#include "gfxVRGVR.h" -#endif // MOZ_ANDROID_GOOGLE_VR #include "gfxVRPuppet.h" #include "ipc/VRLayerParent.h" using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::layers; using namespace mozilla::gl; @@ -99,23 +96,16 @@ VRManager::VRManager() // OSVR is cross platform compatible mgr = VRSystemManagerOSVR::Create(); if (mgr) { mManagers.AppendElement(mgr); } #endif -#if defined(MOZ_ANDROID_GOOGLE_VR) - mgr = VRSystemManagerGVR::Create(); - if (mgr) { - mManagers.AppendElement(mgr); - } -#endif // defined(MOZ_ANDROID_GOOGLE_VR) - // Enable gamepad extensions while VR is enabled. // Preference only can be set at the Parent process. if (XRE_IsParentProcess() && gfxPrefs::VREnabled()) { Preferences::SetBool("dom.gamepad.extensions.enabled", true); } } VRManager::~VRManager()
--- a/gfx/vr/external_api/moz_external_vr.h +++ b/gfx/vr/external_api/moz_external_vr.h @@ -11,24 +11,30 @@ #include <stdint.h> #include <type_traits> #ifdef MOZILLA_INTERNAL_API #include "mozilla/TypedEnumBits.h" #include "mozilla/gfx/2D.h" #endif // MOZILLA_INTERNAL_API +#if defined(__ANDROID__) +#include <pthread.h> +#endif // defined(__ANDROID__) + namespace mozilla { #ifdef MOZILLA_INTERNAL_API namespace dom { enum class GamepadHand : uint8_t; } #endif // MOZILLA_INTERNAL_API namespace gfx { +static const int32_t kVRExternalVersion = 0; + // We assign VR presentations to groups with a bitmask. // Currently, we will only display either content or chrome. // Later, we will have more groups to support VR home spaces and // multitasking environments. // These values are not exposed to regular content and only affect // chrome-only API's. They may be changed at any time. static const uint32_t kVRGroupNone = 0; static const uint32_t kVRGroupContent = 1 << 0; @@ -211,26 +217,30 @@ struct VRFieldOfView { struct VRDisplayState { enum Eye { Eye_Left, Eye_Right, NumEyes }; +#if defined(__ANDROID__) + bool shutdown; +#endif // defined(__ANDROID__) char mDisplayName[kVRDisplayNameMaxLen]; VRDisplayCapabilityFlags mCapabilityFlags; VRFieldOfView mEyeFOV[VRDisplayState::NumEyes]; Point3D_POD mEyeTranslation[VRDisplayState::NumEyes]; IntSize_POD mEyeResolution; bool mIsConnected; bool mIsMounted; FloatSize_POD mStageSize; // We can't use a Matrix4x4 here unless we ensure it's a POD type float mSittingToStandingTransform[16]; + uint32_t mPresentingGeneration; }; struct VRControllerState { char mControllerName[kVRControllerNameMaxLen]; #ifdef MOZILLA_INTERNAL_API dom::GamepadHand mHand; #else @@ -291,34 +301,49 @@ struct VRLayerState union { VRLayer_2D_Content layer_2d_content; VRLayer_Stereo_Immersive layer_stereo_immersive; }; }; struct VRBrowserState { +#if defined(__ANDROID__) + bool shutdown; +#endif // defined(__ANDROID__) VRLayerState layerState[kVRLayerMaxCount]; }; struct VRSystemState { + uint32_t presentingGeneration; VRDisplayState displayState; VRHMDSensorState sensorState; VRControllerState controllerState[kVRControllerMaxCount]; }; struct VRExternalShmem { + int32_t version; + int32_t size; +#if defined(__ANDROID__) + pthread_mutex_t systemMutex; + pthread_mutex_t browserMutex; +#else int64_t generationA; +#endif // defined(__ANDROID__) VRSystemState state; +#if !defined(__ANDROID__) int64_t generationB; int64_t browserGenerationA; +#endif // !defined(__ANDROID__) VRBrowserState browserState; +#if !defined(__ANDROID__) int64_t browserGenerationB; +#endif // !defined(__ANDROID__) }; // As we are memcpy'ing VRExternalShmem and its members around, it must be a POD type static_assert(std::is_pod<VRExternalShmem>::value, "VRExternalShmem must be a POD type."); } // namespace gfx } // namespace mozilla
--- a/gfx/vr/gfxVR.h +++ b/gfx/vr/gfxVR.h @@ -54,17 +54,16 @@ enum class VRDeviceType : uint16_t { struct VRDisplayInfo { uint32_t mDisplayID; VRDeviceType mType; uint32_t mPresentingGroups; uint32_t mGroupMask; uint64_t mFrameId; - uint32_t mPresentingGeneration; VRDisplayState mDisplayState; VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames]; const VRHMDSensorState& GetSensorState() const { return mLastSensorState[mFrameId % kVRMaxLatencyFrames]; } @@ -91,18 +90,17 @@ struct VRDisplayInfo } } // Note that mDisplayState is asserted to be a POD type, so memcmp is safe return mType == other.mType && mDisplayID == other.mDisplayID && memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 && mPresentingGroups == other.mPresentingGroups && mGroupMask == other.mGroupMask && - mFrameId == other.mFrameId && - mPresentingGeneration == other.mPresentingGeneration; + mFrameId == other.mFrameId; } bool operator!=(const VRDisplayInfo& other) const { return !(*this == other); } }; struct VRSubmitFrameResultInfo
--- a/gfx/vr/gfxVRExternal.cpp +++ b/gfx/vr/gfxVRExternal.cpp @@ -19,17 +19,21 @@ static const char* kShmemName = "moz.gecko.vr_ext.0.0.1"; #elif defined(XP_MACOSX) #include "mozilla/gfx/MacIOSurface.h" #include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ #include <errno.h> static const char* kShmemName = "/moz.gecko.vr_ext.0.0.1"; -#endif +#elif defined(MOZ_WIDGET_ANDROID) +#include <string.h> +#include <pthread.h> +#include "GeckoVRManager.h" +#endif // defined(MOZ_WIDGET_ANDROID) #include "gfxVRExternal.h" #include "VRManagerParent.h" #include "VRManager.h" #include "VRThread.h" #include "nsServiceManagerUtils.h" #include "nsIScreenManager.h" @@ -167,16 +171,26 @@ VRDisplayExternal::SubmitFrame(MacIOSurf if (ioSurface == nullptr) { NS_WARNING("VRDisplayExternal::SubmitFrame() could not get an IOSurface"); } else { // FINDME! Implement this } return result; } +#elif defined(MOZ_WIDGET_ANDROID) + +bool +VRDisplayExternal::SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface, + const gfx::Rect& aLeftEyeRect, + const gfx::Rect& aRightEyeRect) { + + return false; +} + #endif VRControllerExternal::VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID, uint32_t aNumButtons, uint32_t aNumTriggers, uint32_t aNumAxes, const nsCString& aId) : VRControllerHost(VRDeviceType::External, aHand, aDisplayID) { MOZ_COUNT_CTOR_INHERITED(VRControllerExternal, VRControllerHost); @@ -196,33 +210,39 @@ VRControllerExternal::~VRControllerExter VRSystemManagerExternal::VRSystemManagerExternal() : mExternalShmem(nullptr) { #if defined(XP_MACOSX) mShmemFD = 0; #elif defined(XP_WIN) mShmemFile = NULL; +#elif defined(MOZ_WIDGET_ANDROID) + mDoShutdown = false; + mExternalStructFailed = false; #endif } VRSystemManagerExternal::~VRSystemManagerExternal() { CloseShmem(); } void VRSystemManagerExternal::OpenShmem() { if (mExternalShmem) { return; +#if defined(MOZ_WIDGET_ANDROID) + } else if (mExternalStructFailed) { + return; +#endif // defined(MOZ_WIDGET_ANDROID) } #if defined(XP_MACOSX) - if (mShmemFD == 0) { mShmemFD = shm_open(kShmemName, O_RDWR, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); } if (mShmemFD <= 0) { mShmemFD = 0; return; } @@ -239,17 +259,16 @@ VRSystemManagerExternal::OpenShmem() if (mExternalShmem == MAP_FAILED) { // TODO - Implement logging mExternalShmem = NULL; CloseShmem(); return; } #elif defined(XP_WIN) - if (mShmemFile == NULL) { mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName); if (mShmemFile == NULL) { // TODO - Implement logging CloseShmem(); return; } } @@ -261,53 +280,74 @@ VRSystemManagerExternal::OpenShmem() 0, length.QuadPart); if (mExternalShmem == NULL) { // TODO - Implement logging CloseShmem(); return; } +#elif defined(MOZ_WIDGET_ANDROID) + mExternalShmem = (VRExternalShmem*)mozilla::GeckoVRManager::GetExternalContext(); + if (!mExternalShmem) { + return; + } + if (mExternalShmem->version != kVRExternalVersion) { + mExternalShmem = nullptr; + mExternalStructFailed = true; + return; + } + if (mExternalShmem->size != sizeof(VRExternalShmem)) { + mExternalShmem = nullptr; + mExternalStructFailed = true; + return; + } #endif CheckForShutdown(); } void VRSystemManagerExternal::CheckForShutdown() { +#if defined(MOZ_WIDGET_ANDROID) + if (mDoShutdown) { + Shutdown(); + } +#else if (mExternalShmem) { if (mExternalShmem->generationA == -1 && mExternalShmem->generationB == -1) { Shutdown(); } } +#endif // defined(MOZ_WIDGET_ANDROID) } void VRSystemManagerExternal::CloseShmem() { #if defined(XP_MACOSX) - if (mExternalShmem) { munmap((void *)mExternalShmem, sizeof(VRExternalShmem)); mExternalShmem = NULL; } if (mShmemFD) { close(mShmemFD); } mShmemFD = 0; - #elif defined(XP_WIN) if (mExternalShmem) { UnmapViewOfFile((void *)mExternalShmem); mExternalShmem = NULL; } if (mShmemFile) { CloseHandle(mShmemFile); mShmemFile = NULL; } +#elif defined(MOZ_WIDGET_ANDROID) + mExternalShmem = NULL; #endif } /*static*/ already_AddRefed<VRSystemManagerExternal> VRSystemManagerExternal::Create() { MOZ_ASSERT(NS_IsMainThread()); @@ -328,16 +368,19 @@ VRSystemManagerExternal::Destroy() void VRSystemManagerExternal::Shutdown() { if (mDisplay) { mDisplay = nullptr; } RemoveControllers(); CloseShmem(); +#if defined(MOZ_WIDGET_ANDROID) + mDoShutdown = false; +#endif } void VRSystemManagerExternal::NotifyVSync() { VRSystemManager::NotifyVSync(); CheckForShutdown(); @@ -445,19 +488,29 @@ VRSystemManagerExternal::RemoveControlle mControllerCount = 0; } void VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */) { MOZ_ASSERT(mExternalShmem); if (mExternalShmem) { - // TODO - Add locking here for non-x86 platforms +#if defined(MOZ_WIDGET_ANDROID) + if (pthread_mutex_lock((pthread_mutex_t*)&(mExternalShmem->systemMutex)) == 0) { + memcpy(aDisplayState, (void*)&(mExternalShmem->state.displayState), sizeof(VRDisplayState)); + if (aSensorState) { + memcpy(aSensorState, (void*)&(mExternalShmem->state.sensorState), sizeof(VRHMDSensorState)); + } + pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex)); + mDoShutdown = aDisplayState->shutdown; + } +#else VRExternalShmem tmp; memcpy(&tmp, (void *)mExternalShmem, sizeof(VRExternalShmem)); if (tmp.generationA == tmp.generationB && tmp.generationA != 0 && tmp.generationA != -1) { memcpy(aDisplayState, &tmp.state.displayState, sizeof(VRDisplayState)); if (aSensorState) { memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState)); } } +#endif // defined(MOZ_WIDGET_ANDROID) } }
--- a/gfx/vr/gfxVRExternal.h +++ b/gfx/vr/gfxVRExternal.h @@ -41,16 +41,20 @@ protected: const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; #elif defined(XP_MACOSX) virtual bool SubmitFrame(MacIOSurface* aMacIOSurface, const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; +#elif defined(MOZ_WIDGET_ANDROID) + bool SubmitFrame(const layers::SurfaceTextureDescriptor& aSurface, + const gfx::Rect& aLeftEyeRect, + const gfx::Rect& aRightEyeRect) override; #endif public: explicit VRDisplayExternal(const VRDisplayState& aDisplayState); void Refresh(); protected: virtual ~VRDisplayExternal(); void Destroy(); @@ -101,22 +105,25 @@ public: protected: VRSystemManagerExternal(); virtual ~VRSystemManagerExternal(); private: // there can only be one RefPtr<impl::VRDisplayExternal> mDisplay; nsTArray<RefPtr<impl::VRControllerExternal>> mExternalController; - #if defined(XP_MACOSX) int mShmemFD; #elif defined(XP_WIN) HANDLE mShmemFile; +#elif defined(MOZ_WIDGET_ANDROID) + bool mDoShutdown; + bool mExternalStructFailed; #endif + volatile VRExternalShmem* mExternalShmem; void OpenShmem(); void CloseShmem(); void CheckForShutdown(); }; } // namespace gfx
deleted file mode 100644 --- a/gfx/vr/gfxVRGVR.cpp +++ /dev/null @@ -1,816 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 "GLBlitHelper.h" -#include "GLContextEGL.h" -#include "GLContextProvider.h" -#include "GLContextTypes.h" -#include "GLImages.h" -#include "GLLibraryEGL.h" - -#include "gfxPrefs.h" -#include "gfxVRGVRAPI.h" -#include "gfxVRGVR.h" - -#include "mozilla/dom/GamepadEventTypes.h" -#include "mozilla/dom/GamepadBinding.h" -#include "mozilla/gfx/Matrix.h" -#include "mozilla/gfx/Quaternion.h" -#include "mozilla/jni/Utils.h" -#include "mozilla/layers/CompositorThread.h" -#include "mozilla/layers/TextureHostOGL.h" -#include "mozilla/Preferences.h" - -#include "GeckoVRManager.h" -#include "nsString.h" - -#include "SurfaceTypes.h" - -#include "VRManager.h" - -#define MOZ_CHECK_GVR_ERRORS - -#if defined(MOZ_CHECK_GVR_ERRORS) -#define GVR_LOGTAG "GeckoWebVR" -#include <android/log.h> -#define GVR_CHECK(X) X; \ -{ \ - gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext()); \ - if (context && (gvr_get_error(context) != GVR_ERROR_NONE)) { \ - __android_log_print(ANDROID_LOG_ERROR, GVR_LOGTAG, \ - "GVR ERROR: %s at:%s:%s:%d", \ - gvr_get_error_string(gvr_get_error(context)), \ - __FILE__, __FUNCTION__, __LINE__); \ - gvr_clear_error(context); \ - } else if (!context) { \ - __android_log_print(ANDROID_LOG_ERROR, GVR_LOGTAG, \ - "UNABLE TO CHECK GVR ERROR: NO CONTEXT"); \ - } \ -} -#define GVR_LOG(format, ...) __android_log_print(ANDROID_LOG_INFO, GVR_LOGTAG, format, ##__VA_ARGS__); -#else -#define GVR_CHECK(X) X -#define GVR_LOG(...) -#endif - -using namespace mozilla; -using namespace mozilla::gl; -using namespace mozilla::gfx; -using namespace mozilla::gfx::impl; -using namespace mozilla::layers; -using namespace mozilla::dom; - -namespace { -static VRDisplayGVR* sContextObserver; -static RefPtr<GLContextEGL> sGLContextEGL; -static gvr_context* sNonPresentingContext; - -gvr_context* -GetNonPresentingContext() { - if (!sNonPresentingContext) { - // Try and restore if it has been lost - sNonPresentingContext = (gvr_context*)GeckoVRManager::CreateGVRNonPresentingContext(); - } - return sNonPresentingContext; -} - -class SynchronousRunnable : public nsIRunnable { -public: - enum class Type { - PresentingContext, - NonPresentingContext, - Pause, - Resume - }; - SynchronousRunnable(const Type aType, void* aContext) - : mType(aType) - , mContext(aContext) - , mUpdateMonitor(new Monitor("SynchronousRunnable_for_Android")) - , mUpdated(false) - {} - NS_DECL_THREADSAFE_ISUPPORTS - nsresult Run() override - { - MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); - MonitorAutoLock lock(*mUpdateMonitor); - if (mType == Type::PresentingContext) { - SetGVRPresentingContext(mContext); - } else if (mType == Type::NonPresentingContext) { - CleanupGVRNonPresentingContext(); - } else if (mType == Type::Pause) { - SetGVRPaused(true); - } else if (mType == Type::Resume) { - SetGVRPaused(false); - } else { - GVR_LOG("UNKNOWN SynchronousRunnable::Type!"); - } - mUpdated = true; - lock.NotifyAll(); - return NS_OK; - } - void Wait() - { - MonitorAutoLock lock(*mUpdateMonitor); - while(!mUpdated) { - lock.Wait(); - } - } - - static bool Dispatch(const Type aType, void* aContext) - { - if (!CompositorThreadHolder::IsInCompositorThread()) { - RefPtr<SynchronousRunnable> runnable = new SynchronousRunnable(aType, aContext); - CompositorThreadHolder::Loop()->PostTask(do_AddRef(runnable)); - runnable->Wait(); - return true; - } - - return false; - } - -protected: - virtual ~SynchronousRunnable() - { - delete mUpdateMonitor; - } - - Type mType; - void* mContext; - Monitor* mUpdateMonitor; - bool mUpdated; -}; - -} - -NS_IMPL_ISUPPORTS(SynchronousRunnable, nsIRunnable) - -void -mozilla::gfx::SetGVRPresentingContext(void* aGVRPresentingContext) -{ - if (SynchronousRunnable::Dispatch(SynchronousRunnable::Type::PresentingContext, aGVRPresentingContext)) { - GVR_LOG("Done waiting for compositor thread to set presenting context."); - return; - } - - MOZ_ASSERT(sContextObserver); - if (!sGLContextEGL && aGVRPresentingContext) { - CreateContextFlags flags = CreateContextFlags::NONE; - SurfaceCaps caps = SurfaceCaps::ForRGBA(); - nsCString str; - sGLContextEGL = GLContextEGL::CreateEGLPBufferOffscreenContext(flags, IntSize(4, 4), caps, &str); - if (!sGLContextEGL->MakeCurrent()) { - GVR_LOG("Failed to make GL context current"); - } - } - sContextObserver->SetPresentingContext(aGVRPresentingContext); -} - -void -mozilla::gfx::CleanupGVRNonPresentingContext() -{ - if (SynchronousRunnable::Dispatch(SynchronousRunnable::Type::NonPresentingContext, nullptr)) { - GVR_LOG("Done waiting for compositor thread to set non presenting context."); - return; - } - - if (sNonPresentingContext) { - sNonPresentingContext = nullptr; - GeckoVRManager::DestroyGVRNonPresentingContext(); - } -} - -void -mozilla::gfx::SetGVRPaused(const bool aPaused) -{ - if (SynchronousRunnable::Dispatch((aPaused ? SynchronousRunnable::Type::Pause : SynchronousRunnable::Type::Resume), nullptr)) { - GVR_LOG("Done waiting for GVR in compositor to: %s",(aPaused ? "Pause" : "Resume")); - return; - } - MOZ_ASSERT(sContextObserver); - sContextObserver->SetPaused(aPaused); -} - -VRDisplayGVR::VRDisplayGVR() - : VRDisplayHost(VRDeviceType::GVR) - , mIsPresenting(false) - , mControllerAdded(false) - , mPresentingContext(nullptr) - , mControllerContext(nullptr) - , mControllerState(nullptr) - , mViewportList(nullptr) - , mLeftViewport(nullptr) - , mRightViewport(nullptr) - , mSwapChain(nullptr) - , mFrameBufferSize{0, 0} -{ - MOZ_COUNT_CTOR_INHERITED(VRDisplayGVR, VRDisplayHost); - MOZ_ASSERT(GetNonPresentingContext()); - MOZ_ASSERT(!sContextObserver); // There can be only one GVR display at a time. - sContextObserver = this; - - strncpy(mDisplayInfo.mDisplayName, "GVR HMD", kVRDisplayNameMaxLen); - mDisplayInfo.mIsConnected = true; - mDisplayInfo.mIsMounted = true; - mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None | - VRDisplayCapabilityFlags::Cap_Orientation | - VRDisplayCapabilityFlags::Cap_Position | // Not yet... - VRDisplayCapabilityFlags::Cap_Present; - - GVR_CHECK(gvr_refresh_viewer_profile(GetNonPresentingContext())); - mViewportList = GVR_CHECK(gvr_buffer_viewport_list_create(GetNonPresentingContext())); - mLeftViewport = GVR_CHECK(gvr_buffer_viewport_create(GetNonPresentingContext())); - mRightViewport = GVR_CHECK(gvr_buffer_viewport_create(GetNonPresentingContext())); - UpdateViewport(); - - dom::GamepadHand hand = dom::GamepadHand::Right; - const gvr_user_prefs* prefs = GVR_CHECK(gvr_get_user_prefs(GetNonPresentingContext())); - if (prefs) { - hand = ((gvr_user_prefs_get_controller_handedness(prefs) == GVR_CONTROLLER_RIGHT_HANDED) ? - dom::GamepadHand::Right : dom::GamepadHand::Left); - } - mController = new VRControllerGVR(hand, mDisplayInfo.mDisplayID); -} - -VRDisplayGVR::~VRDisplayGVR() -{ - MOZ_COUNT_DTOR_INHERITED(VRDisplayGVR, VRDisplayHost); -} - -void -VRDisplayGVR::ZeroSensor() -{ -} - -void -VRDisplayGVR::StartPresentation() -{ - if (mIsPresenting) { - return; - } - - mIsPresenting = true; - GeckoVRManager::EnableVRMode(); -} - -void -VRDisplayGVR::StopPresentation() -{ - if (!mIsPresenting) { - return; - } - - mIsPresenting = false; - GeckoVRManager::DisableVRMode(); -} - -bool -VRDisplayGVR::SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) -{ - if (!mPresentingContext) { - GVR_LOG("Unable to submit frame. No presenting context") - return false; - } - - if (!sGLContextEGL) { - GVR_LOG("Unable to submit frame. No GL Context"); - return false; - } - - if (!sGLContextEGL->MakeCurrent()) { - GVR_LOG("Failed to make GL context current"); - return false; - } - - EGLImage image = (EGLImage)aDescriptor->image(); - EGLSync sync = (EGLSync)aDescriptor->fence(); - gfx::IntSize size = aDescriptor->size(); - MOZ_ASSERT(mSwapChain); - GVR_CHECK(gvr_get_recommended_buffer_viewports(mPresentingContext, mViewportList)); - if ((size.width != mFrameBufferSize.width) || (size.height != mFrameBufferSize.height)) { - mFrameBufferSize.width = size.width; - mFrameBufferSize.height = size.height; - GVR_CHECK(gvr_swap_chain_resize_buffer(mSwapChain, 0, mFrameBufferSize)); - GVR_LOG("Resize Swap Chain %d,%d", mFrameBufferSize.width, mFrameBufferSize.height); - } - gvr_frame* frame = GVR_CHECK(gvr_swap_chain_acquire_frame(mSwapChain)); - if (!frame) { - // Sometimes the swap chain seems to not initialized correctly so that - // frames can not be acquired. Recreating the swap chain seems to fix the - // issue. - GVR_LOG("Unable to acquire GVR frame. Recreating swap chain."); - RecreateSwapChain(); - return false; - } - GVR_CHECK(gvr_frame_bind_buffer(frame, 0)); - - EGLint status = LOCAL_EGL_CONDITION_SATISFIED; - auto* egl = gl::GLLibraryEGL::Get(); - - if (sync) { - MOZ_ASSERT(egl->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)); - status = egl->fClientWaitSync(EGL_DISPLAY(), sync, 0, LOCAL_EGL_FOREVER); - } - - if (status != LOCAL_EGL_CONDITION_SATISFIED) { - MOZ_ASSERT(status != 0, - "ClientWaitSync generated an error. Has sync already been destroyed?"); - return false; - } - - if (image) { - GLuint tex = 0; - sGLContextEGL->fGenTextures(1, &tex); - - const ScopedSaveMultiTex saveTex(sGLContextEGL, 1, LOCAL_GL_TEXTURE_2D); - sGLContextEGL->fBindTexture(LOCAL_GL_TEXTURE_2D, tex); - sGLContextEGL->TexParams_SetClampNoMips(); - sGLContextEGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image); - sGLContextEGL->BlitHelper()->DrawBlitTextureToFramebuffer(tex, gfx::IntSize(size.width, size.height), gfx::IntSize(mFrameBufferSize.width, mFrameBufferSize.height)); - sGLContextEGL->fDeleteTextures(1, &tex); - } else { - GVR_LOG("Unable to submit frame. Unable to extract EGLImage"); - return false; - } - GVR_CHECK(gvr_frame_unbind(frame)); - GVR_CHECK(gvr_frame_submit(&frame, mViewportList, mHeadMatrix)); - return true; -} - -static void -FillMatrix(gfx::Matrix4x4 &target, const gvr_mat4f& source) -{ - target._11 = source.m[0][0]; - target._12 = source.m[0][1]; - target._13 = source.m[0][2]; - target._14 = source.m[0][3]; - target._21 = source.m[1][0]; - target._22 = source.m[1][1]; - target._23 = source.m[1][2]; - target._24 = source.m[1][3]; - target._31 = source.m[2][0]; - target._32 = source.m[2][1]; - target._33 = source.m[2][2]; - target._34 = source.m[2][3]; - target._41 = source.m[3][0]; - target._42 = source.m[3][1]; - target._43 = source.m[3][2]; - target._44 = source.m[3][3]; -} - -VRHMDSensorState -VRDisplayGVR::GetSensorState() -{ - VRHMDSensorState result{}; - - gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext()); - - if (!context) { - GVR_LOG("Unable to get sensor state. Context is null"); - return result; - } - - gvr_clock_time_point when = GVR_CHECK(gvr_get_time_point_now()); - if (mIsPresenting) { - // 50ms into the future is what GVR docs recommends using for head rotation - // prediction. - when.monotonic_system_time_nanos += 50000000; - } - mHeadMatrix = GVR_CHECK(gvr_get_head_space_from_start_space_rotation(context, when)); - gvr_mat4f neck = GVR_CHECK(gvr_apply_neck_model(context, mHeadMatrix, 1.0));; - - gfx::Matrix4x4 m; - - FillMatrix(m, neck); - m.Invert(); - gfx::Quaternion rot; - rot.SetFromRotationMatrix(m); - - result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; - result.orientation[0] = rot.x; - result.orientation[1] = rot.y; - result.orientation[2] = rot.z; - result.orientation[3] = rot.w; - result.angularVelocity[0] = 0.0f; - result.angularVelocity[1] = 0.0f; - result.angularVelocity[2] = 0.0f; - - result.flags |= VRDisplayCapabilityFlags::Cap_Position; - result.position[0] = m._14; - result.position[1] = m._24; - result.position[2] = m._34; - result.linearVelocity[0] = 0.0f; - result.linearVelocity[1] = 0.0f; - result.linearVelocity[2] = 0.0f; - - UpdateHeadToEye(context); - CalcViewMatrices(&result, mHeadToEyes); - - return result; -} - -void -VRDisplayGVR::SetPaused(const bool aPaused) -{ - if (aPaused) { - if (mPresentingContext) { - GVR_CHECK(gvr_pause_tracking(mPresentingContext)); - } else if (sNonPresentingContext) { - GVR_CHECK(gvr_pause_tracking(sNonPresentingContext)); - } - - if (mControllerContext) { - GVR_CHECK(gvr_controller_pause(mControllerContext)); - } - } else { - if (mPresentingContext) { - GVR_CHECK(gvr_refresh_viewer_profile(mPresentingContext)); - GVR_CHECK(gvr_resume_tracking(mPresentingContext)); - } else if (sNonPresentingContext) { - GVR_CHECK(gvr_resume_tracking(sNonPresentingContext)); - } - - if (mControllerContext) { - GVR_CHECK(gvr_controller_resume(mControllerContext)); - } - } -} - -void -VRDisplayGVR::SetPresentingContext(void* aGVRPresentingContext) -{ - MOZ_ASSERT(sGLContextEGL); - sGLContextEGL->MakeCurrent(); - mPresentingContext = (gvr_context*)aGVRPresentingContext; - if (mPresentingContext) { - GVR_CHECK(gvr_initialize_gl(mPresentingContext)); - RecreateSwapChain(); - } else { - - if (mSwapChain) { - // gvr_swap_chain_destroy will set the pointer to null - GVR_CHECK(gvr_swap_chain_destroy(&mSwapChain)); - MOZ_ASSERT(!mSwapChain); - } - - // The presentation context has been destroy, probably by the user so increment the presenting - // generation if we are presenting so that the DOM knows to end the current presentation. - if (mIsPresenting) { - mDisplayInfo.mPresentingGeneration++; - } - } -} - -void -VRDisplayGVR::UpdateHeadToEye(gvr_context* aContext) -{ - if (!aContext) { - return; - } - - for (uint32_t eyeIndex = 0; eyeIndex < 2; eyeIndex++) { - gvr_mat4f eye = GVR_CHECK(gvr_get_eye_from_head_matrix(aContext, eyeIndex)); - mDisplayInfo.mEyeTranslation[eyeIndex].x = -eye.m[0][3]; - mDisplayInfo.mEyeTranslation[eyeIndex].y = -eye.m[1][3]; - mDisplayInfo.mEyeTranslation[eyeIndex].z = -eye.m[2][3]; - mHeadToEyes[eyeIndex] = gfx::Matrix4x4(); - mHeadToEyes[eyeIndex].PreTranslate(eye.m[0][3], eye.m[1][3], eye.m[2][3]); - } -} - -void -VRDisplayGVR::UpdateViewport() -{ - gvr_context* context = (mPresentingContext ? mPresentingContext : GetNonPresentingContext()); - - if (!context) { - return; - } - - GVR_CHECK(gvr_get_recommended_buffer_viewports(context, mViewportList)); - GVR_CHECK(gvr_buffer_viewport_list_get_item(mViewportList, 0, mLeftViewport)); - GVR_CHECK(gvr_buffer_viewport_list_get_item(mViewportList, 1, mRightViewport)); - - gvr_rectf fov = GVR_CHECK(gvr_buffer_viewport_get_source_fov(mLeftViewport)); - mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Left] = VRFieldOfView(fov.top, fov.right, fov.bottom, fov.left); - GVR_LOG("FOV:L top:%f right:%f bottom:%f left:%f",(float)fov.top, (float)fov.left, (float)fov.bottom, (float)fov.right); - - fov = GVR_CHECK(gvr_buffer_viewport_get_source_fov(mRightViewport)); - mDisplayInfo.mEyeFOV[VRDisplayInfo::Eye_Right] = VRFieldOfView(fov.top, fov.right, fov.bottom, fov.left); - GVR_LOG("FOV:R top:%f right:%f bottom:%f left:%f",(float)fov.top, (float)fov.left, (float)fov.bottom, (float)fov.right); - - gvr_sizei size = GVR_CHECK(gvr_get_maximum_effective_render_target_size(context)); - mDisplayInfo.mEyeResolution = IntSize(size.width / 2, size.height); - GVR_LOG("Eye Resolution: %dx%d",mDisplayInfo.mEyeResolution.width,mDisplayInfo.mEyeResolution.height); - - UpdateHeadToEye(context); -} - -void -VRDisplayGVR::RecreateSwapChain() -{ - MOZ_ASSERT(sGLContextEGL); - sGLContextEGL->MakeCurrent(); - if (mSwapChain) { - // gvr_swap_chain_destroy will set the pointer to null - GVR_CHECK(gvr_swap_chain_destroy(&mSwapChain)); - MOZ_ASSERT(!mSwapChain); - } - gvr_buffer_spec* spec = GVR_CHECK(gvr_buffer_spec_create(mPresentingContext)); - mFrameBufferSize = GVR_CHECK(gvr_get_maximum_effective_render_target_size(mPresentingContext)); - GVR_CHECK(gvr_buffer_spec_set_size(spec, mFrameBufferSize)); - GVR_CHECK(gvr_buffer_spec_set_samples(spec, 0)); - GVR_CHECK(gvr_buffer_spec_set_color_format(spec, GVR_COLOR_FORMAT_RGBA_8888)); - GVR_CHECK(gvr_buffer_spec_set_depth_stencil_format(spec, GVR_DEPTH_STENCIL_FORMAT_NONE)); - mSwapChain = GVR_CHECK(gvr_swap_chain_create(mPresentingContext, (const gvr_buffer_spec**)&spec, 1)); - GVR_CHECK(gvr_buffer_spec_destroy(&spec)); -} - -void -VRDisplayGVR::EnableControllers(const bool aEnable, VRSystemManager* aManager) -{ - if (aEnable && !mControllerAdded) { - // Sometimes the gamepad doesn't get removed cleanly so just try to remove it before adding it. - aManager->RemoveGamepad(mController->GetControllerInfo().mControllerID); - aManager->AddGamepad(mController->GetControllerInfo()); - mControllerAdded = true; - } else if (!aEnable && mControllerAdded) { - mControllerAdded = false; - aManager->RemoveGamepad(mController->GetControllerInfo().mControllerID); - } - - gvr_context* context = mPresentingContext; - - if (!context) { - if (mControllerContext) { - GVR_CHECK(gvr_controller_destroy(&mControllerContext)); - } - return; - } - - if ((aEnable && mControllerContext) || (!aEnable && !mControllerContext)) { - return; - } - - if (aEnable) { - if (!mControllerContext) { - int32_t options = GVR_CHECK(gvr_controller_get_default_options()); - options |= GVR_CONTROLLER_ENABLE_GYRO | GVR_CONTROLLER_ENABLE_ACCEL | GVR_CONTROLLER_ENABLE_ARM_MODEL; - mControllerContext = GVR_CHECK(gvr_controller_create_and_init(options, context)); - GVR_CHECK(gvr_controller_resume(mControllerContext)); - } - if (!mControllerState) { - mControllerState = GVR_CHECK(gvr_controller_state_create()); - } - } else { - GVR_CHECK(gvr_controller_pause(mControllerContext)); - GVR_CHECK(gvr_controller_destroy(&mControllerContext)); - } -} - -void -VRDisplayGVR::UpdateControllers(VRSystemManager* aManager) -{ - if (!mControllerContext) { - return; - } - - GVR_CHECK(gvr_controller_apply_arm_model(mControllerContext, 0, mController->GetHand() == dom::GamepadHand::Right ? GVR_CONTROLLER_RIGHT_HANDED : GVR_CONTROLLER_LEFT_HANDED, GVR_ARM_MODEL_FOLLOW_GAZE, mHeadMatrix)); - GVR_CHECK(gvr_controller_state_update(mControllerContext, 0, mControllerState)); - mController->Update(mControllerState, aManager); -} - - -void -VRDisplayGVR::GetControllers(nsTArray<RefPtr<VRControllerHost> >& aControllerResult) -{ - aControllerResult.AppendElement(mController.get()); -} - -VRControllerGVR::VRControllerGVR(dom::GamepadHand aHand, uint32_t aDisplayID) - : VRControllerHost(VRDeviceType::GVR, aHand, aDisplayID) -{ - MOZ_COUNT_CTOR_INHERITED(VRControllerGVR, VRControllerHost); - - VRControlerState& state = mControllerInfo.mControllerState; - strncpy(state.mControllerName, "Daydream Controller", kVRControllerNameMaxLen); - - // The gvr_controller_button enum starts with GVR_CONTROLLER_BUTTON_NONE at index zero - // so the GVR controller has one less button than GVR_CONTROLLER_BUTTON_COUNT specifies. - state.mNumButtons = GVR_CONTROLLER_BUTTON_COUNT - 1; // Skip dummy none button - state.mNumAxes = 2; - state.mNumHaptics = 0; -} - -VRControllerGVR::~VRControllerGVR() -{ - MOZ_COUNT_DTOR_INHERITED(VRControllerGVR, VRControllerHost); -} - -void -VRControllerGVR::Update(gvr_controller_state* aState, VRSystemManager* aManager) -{ - mPose.Clear(); - - if (gvr_controller_state_get_connection_state(aState) != GVR_CONTROLLER_CONNECTED) { - return; - } - const uint64_t previousPressMask = GetButtonPressed(); - const uint64_t previousTouchMask = GetButtonTouched(); - uint64_t currentPressMask = 0; - uint64_t currentTouchMask = 0; - // Index 0 is the dummy button so skip it. - for (int ix = 1; ix < GVR_CONTROLLER_BUTTON_COUNT; ix++) { - const uint64_t buttonMask = 0x01 << (ix - 1); - bool pressed = gvr_controller_state_get_button_state(aState, ix); - bool touched = pressed; - if (ix == GVR_CONTROLLER_BUTTON_CLICK) { - touched = gvr_controller_state_is_touching(aState); - double xAxis = 0.0; - double yAxis = 0.0; - if (touched) { - gvr_vec2f axes = gvr_controller_state_get_touch_pos(aState); - xAxis = (axes.x * 2.0) - 1.0; - yAxis = (axes.y * 2.0) - 1.0; - } - aManager->NewAxisMove(0, 0, xAxis); - aManager->NewAxisMove(0, 1, yAxis); - } - if (pressed) { - currentPressMask |= buttonMask; - } - if (touched) { - currentTouchMask |= buttonMask; - } - if (((currentPressMask & buttonMask) ^ (previousPressMask & buttonMask)) || - ((currentTouchMask & buttonMask) ^ (previousTouchMask & buttonMask))) { - aManager->NewButtonEvent(0, ix - 1, pressed, touched, pressed ? 1.0 : 0.0); - } - } - SetButtonPressed(currentPressMask); - SetButtonTouched(currentTouchMask); - - mPose.flags = dom::GamepadCapabilityFlags::Cap_Orientation | dom::GamepadCapabilityFlags::Cap_Position | dom::GamepadCapabilityFlags::Cap_LinearAcceleration; - - gvr_quatf ori = gvr_controller_state_get_orientation(aState); - mPose.orientation[0] = ori.qx; - mPose.orientation[1] = ori.qy; - mPose.orientation[2] = ori.qz; - mPose.orientation[3] = ori.qw; - mPose.isOrientationValid = true; - - gvr_vec3f acc = gvr_controller_state_get_accel(aState); - mPose.linearAcceleration[0] = acc.x; - mPose.linearAcceleration[1] = acc.y; - mPose.linearAcceleration[2] = acc.z; - - gvr_vec3f vel = gvr_controller_state_get_gyro(aState); - mPose.angularVelocity[0] = vel.x; - mPose.angularVelocity[1] = vel.y; - mPose.angularVelocity[2] = vel.z; - - gvr_vec3f pos = gvr_controller_state_get_position(aState); - mPose.position[0] = pos.x; - mPose.position[1] = pos.y; - mPose.position[2] = pos.z; - - aManager->NewPoseState(0, mPose); -} - -/*static*/ already_AddRefed<VRSystemManagerGVR> -VRSystemManagerGVR::Create() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!gfxPrefs::VREnabled()) { - return nullptr; - } - - RefPtr<VRSystemManagerGVR> manager = new VRSystemManagerGVR(); - return manager.forget(); -} - -void -VRSystemManagerGVR::Destroy() -{ - -} - -void -VRSystemManagerGVR::Shutdown() -{ - -} - -void -VRSystemManagerGVR::Enumerate() -{ - if (!GeckoVRManager::IsGVRPresent()) { - return; - } - - if (!mGVRHMD) { - mGVRHMD = new VRDisplayGVR(); - } -} - -bool -VRSystemManagerGVR::ShouldInhibitEnumeration() -{ - if (VRSystemManager::ShouldInhibitEnumeration()) { - return true; - } - if (mGVRHMD) { - // When we find an a VR device, don't - // allow any further enumeration as it - // may get picked up redundantly by other - // API's. - return true; - } - return false; -} - -void -VRSystemManagerGVR::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) -{ - if (mGVRHMD) { - aHMDResult.AppendElement(mGVRHMD); - } -} - -bool -VRSystemManagerGVR::GetIsPresenting() -{ - if (!mGVRHMD) { - return false; - } - - VRDisplayInfo displayInfo(mGVRHMD->GetDisplayInfo()); - return displayInfo.GetPresentingGroups() != kVRGroupNone; -} - -void -VRSystemManagerGVR::HandleInput() -{ - if (mGVRHMD) { - mGVRHMD->UpdateControllers(this); - } -} - -void -VRSystemManagerGVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) -{ - if (mGVRHMD) { - mGVRHMD->GetControllers(aControllerResult); - } -} - -void -VRSystemManagerGVR::ScanForControllers() -{ - if (mGVRHMD) { - mGVRHMD->EnableControllers(true, this); - } -} - -void -VRSystemManagerGVR::RemoveControllers() -{ - if (mGVRHMD) { - mGVRHMD->EnableControllers(false, this); - } -} - -void -VRSystemManagerGVR::VibrateHaptic(uint32_t aControllerIdx, - uint32_t aHapticIndex, - double aIntensity, - double aDuration, - const VRManagerPromise& aPromise) -{ - -} - -void -VRSystemManagerGVR::StopVibrateHaptic(uint32_t aControllerIdx) -{ - -} - -VRSystemManagerGVR::VRSystemManagerGVR() - : mGVRHMD(nullptr) -{ - -} - -VRSystemManagerGVR::~VRSystemManagerGVR() -{ - -} -
deleted file mode 100644 --- a/gfx/vr/gfxVRGVR.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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_GVR_H -#define GFX_VR_GVR_H - -#include "gfxVR.h" - -#include <memory> - -#include "mozilla/EnumeratedArray.h" -#include "mozilla/gfx/2D.h" -#include "mozilla/gfx/Matrix.h" -#include "mozilla/RefPtr.h" -#include "mozilla/UniquePtr.h" - -#include "nsTArray.h" -#include "nsIRunnable.h" -#include "nsIScreen.h" -#include "nsCOMPtr.h" - -#include "VRDisplayHost.h" - -#pragma GCC system_header -#pragma GCC visibility push(default) -#include "vr/gvr/capi/include/gvr.h" -#include "vr/gvr/capi/include/gvr_controller.h" -#pragma GCC visibility pop - - -namespace mozilla { -namespace gl { -class GLContextEGL; -} // namespace gl -namespace layers { -class EGLImageDescriptor; -} // namespace layers -namespace gfx { -namespace impl { - -class VRControllerGVR : public VRControllerHost -{ -public: - explicit VRControllerGVR(dom::GamepadHand aHand, uint32_t aDisplayID); - virtual ~VRControllerGVR(); - void Update(gvr_controller_state* aState, VRSystemManager* aManager); -}; - -class VRDisplayGVR : public VRDisplayHost -{ -public: - VRDisplayGVR(); - - // BEGIN VRDisplayHost interface - void ZeroSensor() override; - void StartPresentation() override; - void StopPresentation() override; - bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) override; -protected: - virtual VRHMDSensorState GetSensorState() override; - // END VRDisplayHost interface - -public: - void SetPaused(const bool aPaused); - void SetPresentingContext(void* aGVRPresentingContext); - void EnableControllers(const bool aEnable, VRSystemManager* aManager); - void UpdateControllers(VRSystemManager* aManager); - void GetControllers(nsTArray<RefPtr<VRControllerHost> >& aControllerResult); - -protected: - virtual ~VRDisplayGVR(); - void UpdateHeadToEye(gvr_context* aContext); - void UpdateViewport(); - void RecreateSwapChain(); - - bool mIsPresenting; - bool mControllerAdded; - - gfx::Matrix4x4 mHeadToEyes[2]; - gvr_context* mPresentingContext; - gvr_controller_context* mControllerContext; - gvr_controller_state* mControllerState; - gvr_buffer_viewport_list* mViewportList; - gvr_buffer_viewport* mLeftViewport; - gvr_buffer_viewport* mRightViewport; - gvr_mat4f mHeadMatrix; - gvr_swap_chain* mSwapChain; - gvr_sizei mFrameBufferSize; - - RefPtr<VRControllerGVR> mController; -}; - - -} // namespace impl - -class VRSystemManagerGVR : public VRSystemManager -{ -public: - static already_AddRefed<VRSystemManagerGVR> Create(); - - void Destroy() override; - void Shutdown() override; - void Enumerate() override; - bool ShouldInhibitEnumeration() override; - void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) override; - bool GetIsPresenting() override; - void HandleInput() override; - void GetControllers(nsTArray<RefPtr<VRControllerHost>>& - aControllerResult) override; - void ScanForControllers() override; - void RemoveControllers() override; - void VibrateHaptic(uint32_t aControllerIdx, - uint32_t aHapticIndex, - double aIntensity, - double aDuration, - const VRManagerPromise& aPromise) override; - void StopVibrateHaptic(uint32_t aControllerIdx) override; - -protected: - VRSystemManagerGVR(); - virtual ~VRSystemManagerGVR(); - -private: - RefPtr<impl::VRDisplayGVR> mGVRHMD; -}; - -} // namespace gfx -} // namespace mozilla - - -#endif /* GFX_VR_GVR_H */
deleted file mode 100644 --- a/gfx/vr/gfxVRGVRAPI.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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_GVR_API_H -#define GFX_VR_GVR_API_H -namespace mozilla { -namespace gfx { - -void SetGVRPresentingContext(void* aGVRPresentingContext); -void CleanupGVRNonPresentingContext(); -void SetGVRPaused(const bool aPaused); - -} // namespace gfx -} // namespace mozilla -#endif // GFX_VR_GVR_API_H
--- a/gfx/vr/gfxVROSVR.cpp +++ b/gfx/vr/gfxVROSVR.cpp @@ -360,28 +360,16 @@ VRDisplayOSVR::SubmitFrame(MacIOSurface* const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) { // XXX Add code to submit frame MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread()); return false; } -#elif defined(MOZ_ANDROID_GOOGLE_VR) - -bool -VRDisplayOSVR::SubmitFrame(const mozilla::layers::EGLImageDescriptor*, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) -{ - // XXX Add code to submit frame - MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread()); - return false; -} - #endif void VRDisplayOSVR::StartPresentation() { // XXX Add code to start VR Presentation }
--- a/gfx/vr/gfxVROSVR.h +++ b/gfx/vr/gfxVROSVR.h @@ -41,20 +41,16 @@ protected: const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; #elif defined(XP_MACOSX) virtual bool SubmitFrame(MacIOSurface* aMacIOSurface, const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; -#elif defined(MOZ_ANDROID_GOOGLE_VR) - virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor*, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) override; #endif public: explicit VRDisplayOSVR(OSVR_ClientContext* context, OSVR_ClientInterface* iface, OSVR_DisplayConfig* display); protected:
--- a/gfx/vr/gfxVRPuppet.cpp +++ b/gfx/vr/gfxVRPuppet.cpp @@ -553,22 +553,22 @@ VRDisplayPuppet::SubmitFrame(MacIOSurfac MOZ_ASSERT(false, "No support for showing VR frames on MacOSX yet."); break; } } return false; } -#elif defined(MOZ_ANDROID_GOOGLE_VR) +#elif defined(MOZ_WIDGET_ANDROID) bool -VRDisplayPuppet::SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor, - const gfx::Rect& aLeftEyeRect, - const gfx::Rect& aRightEyeRect) +VRDisplayPuppet::SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aDescriptor, + const gfx::Rect& aLeftEyeRect, + const gfx::Rect& aRightEyeRect) { MOZ_ASSERT(mSubmitThread->GetThread() == NS_GetCurrentThread()); return false; } #endif void
--- a/gfx/vr/gfxVRPuppet.h +++ b/gfx/vr/gfxVRPuppet.h @@ -37,18 +37,18 @@ protected: const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; #elif defined(XP_MACOSX) virtual bool SubmitFrame(MacIOSurface* aMacIOSurface, const IntSize& aSize, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; -#elif defined(MOZ_ANDROID_GOOGLE_VR) - virtual bool SubmitFrame(const mozilla::layers::EGLImageDescriptor* aDescriptor, +#elif defined(MOZ_WIDGET_ANDROID) + virtual bool SubmitFrame(const mozilla::layers::SurfaceTextureDescriptor& aDescriptor, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; #endif public: explicit VRDisplayPuppet(); void Refresh();
--- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -15,16 +15,18 @@ #include "mozilla/dom/VREventObserver.h" #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback #include "mozilla/dom/ContentChild.h" #include "nsContentUtils.h" #include "mozilla/dom/GamepadManager.h" #include "mozilla/dom/VRServiceTest.h" #include "mozilla/layers/SyncObject.h" +using namespace mozilla::dom; + namespace { const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex = nsTArray<RefPtr<dom::VREventObserver> >::NoIndex; } // namespace namespace mozilla { namespace gfx {
--- a/gfx/vr/ipc/VRMessageUtils.h +++ b/gfx/vr/ipc/VRMessageUtils.h @@ -42,16 +42,17 @@ struct ParamTraits<mozilla::gfx::VRDispl WriteParam(aMsg, displayName); WriteParam(aMsg, aParam.mCapabilityFlags); WriteParam(aMsg, aParam.mEyeResolution.width); WriteParam(aMsg, aParam.mEyeResolution.height); WriteParam(aMsg, aParam.mIsConnected); WriteParam(aMsg, aParam.mIsMounted); WriteParam(aMsg, aParam.mStageSize.width); WriteParam(aMsg, aParam.mStageSize.height); + WriteParam(aMsg, aParam.mPresentingGeneration); for (int i = 0; i < 16; i++) { // TODO - Should probably memcpy the whole array or // convert Maxtrix4x4 to a POD type and use it // instead WriteParam(aMsg, aParam.mSittingToStandingTransform[i]); } for (int i = 0; i < mozilla::gfx::VRDisplayState::NumEyes; i++) { WriteParam(aMsg, aParam.mEyeFOV[i]); @@ -66,17 +67,18 @@ struct ParamTraits<mozilla::gfx::VRDispl nsCString displayName; if (!ReadParam(aMsg, aIter, &(displayName)) || !ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) || !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.width)) || !ReadParam(aMsg, aIter, &(aResult->mEyeResolution.height)) || !ReadParam(aMsg, aIter, &(aResult->mIsConnected)) || !ReadParam(aMsg, aIter, &(aResult->mIsMounted)) || !ReadParam(aMsg, aIter, &(aResult->mStageSize.width)) || - !ReadParam(aMsg, aIter, &(aResult->mStageSize.height))) { + !ReadParam(aMsg, aIter, &(aResult->mStageSize.height)) || + !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration))) { return false; } for (int i = 0; i < 16; i++) { if (!ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform[i]))) { return false; } } strncpy(aResult->mDisplayName, displayName.BeginReading(), mozilla::gfx::kVRDisplayNameMaxLen); @@ -99,31 +101,29 @@ struct ParamTraits<mozilla::gfx::VRDispl static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, aParam.mType); WriteParam(aMsg, aParam.mDisplayID); WriteParam(aMsg, aParam.mPresentingGroups); WriteParam(aMsg, aParam.mGroupMask); WriteParam(aMsg, aParam.mFrameId); - WriteParam(aMsg, aParam.mPresentingGeneration); WriteParam(aMsg, aParam.mDisplayState); for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) { WriteParam(aMsg, aParam.mLastSensorState[i]); } } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { if (!ReadParam(aMsg, aIter, &(aResult->mType)) || !ReadParam(aMsg, aIter, &(aResult->mDisplayID)) || !ReadParam(aMsg, aIter, &(aResult->mPresentingGroups)) || !ReadParam(aMsg, aIter, &(aResult->mGroupMask)) || !ReadParam(aMsg, aIter, &(aResult->mFrameId)) || - !ReadParam(aMsg, aIter, &(aResult->mPresentingGeneration)) || !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) { return false; } for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) { if (!ReadParam(aMsg, aIter, &(aResult->mLastSensorState[i]))) { return false; } }
deleted file mode 100644 --- a/gfx/vr/jni/gfxGVRJNI.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- 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 <jni.h> - -extern "C" __attribute__((visibility("default"))) jlong -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate( - JNIEnv* env, - jobject jcaller, - jclass classLoader, - jobject appContext); - -// Step 2: method stubs. -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer); - -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer, - jlong expectedInterval, - jlong vsyncOffset); - -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer, - jlong syncTime, - jint currentRotation); - -namespace { - -bool -check(JNIEnv* env) { - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - env->ExceptionClear(); - return false; - } - return true; -} - -const char kDisplaySynchronizerClassPath[] = "com/google/vr/cardboard/DisplaySynchronizer"; - -static const JNINativeMethod kMethodsDisplaySynchronizer[] = { - {"nativeCreate", - "(" - "Ljava/lang/ClassLoader;" - "Landroid/content/Context;" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate)}, - {"nativeDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy)}, - {"nativeReset", - "(" - "J" - "J" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset)}, - {"nativeUpdate", - "(" - "J" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate)}, -}; -} - -bool -SetupGVRJNI(JNIEnv* env) -{ - jclass displaySynchronizerClazz = env->FindClass(kDisplaySynchronizerClassPath); - if (!check(env)) { return false; } - if (displaySynchronizerClazz == nullptr) { - return false; - } - env->RegisterNatives(displaySynchronizerClazz, kMethodsDisplaySynchronizer, sizeof(kMethodsDisplaySynchronizer) / sizeof(kMethodsDisplaySynchronizer[0])); - if (!check(env)) { return false; } - env->DeleteLocalRef(displaySynchronizerClazz); - if (!check(env)) { return false; } - - return true; -} -
--- a/gfx/vr/moz.build +++ b/gfx/vr/moz.build @@ -20,27 +20,31 @@ EXPORTS += [ LOCAL_INCLUDES += [ '/dom/base', '/gfx/layers/d3d11', '/gfx/thebes', ] UNIFIED_SOURCES += [ 'gfxVR.cpp', - 'gfxVROSVR.cpp', 'ipc/VRLayerChild.cpp', 'ipc/VRLayerParent.cpp', 'ipc/VRManagerChild.cpp', 'ipc/VRManagerParent.cpp', 'VRDisplayClient.cpp', 'VRDisplayPresentation.cpp', 'VRManager.cpp', 'VRThread.cpp', ] +if CONFIG['OS_TARGET'] != 'Android': + UNIFIED_SOURCES += [ + 'gfxVROSVR.cpp', + ] + # VRDisplayHost includes MacIOSurface.h which includes Mac headers # which define Size and Points types in the root namespace that # often conflict with our own types. SOURCES += [ 'gfxVRExternal.cpp', 'gfxVRPuppet.cpp', 'VRDisplayHost.cpp', ] @@ -54,22 +58,17 @@ if CONFIG['OS_TARGET'] in ('WINNT', 'Lin 'gfxVROpenVR.cpp', ] if CONFIG['OS_TARGET'] == 'WINNT': SOURCES += [ 'gfxVROculus.cpp', ] -if CONFIG['MOZ_ANDROID_GOOGLE_VR']: - SOURCES += [ - 'gfxVRGVR.cpp', - 'jni/gfxGVRJNI.cpp', - ] - CXXFLAGS += ['-I%s' % CONFIG['MOZ_ANDROID_GOOGLE_VR_INCLUDE']] +if CONFIG['OS_TARGET'] == 'Android': LOCAL_INCLUDES += ['/widget/android'] IPDL_SOURCES = [ 'ipc/PVRLayer.ipdl', 'ipc/PVRManager.ipdl', ] # For building with the real SDK instead of our local hack
--- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -99,18 +99,18 @@ DynamicImage::HasError() { return !mDrawable; } void DynamicImage::SetHasError() { } -ImageURL* -DynamicImage::GetURI() +nsIURI* +DynamicImage::GetURI() const { return nullptr; } // Methods inherited from XPCOM interfaces. NS_IMPL_ISUPPORTS(DynamicImage, imgIContainer)
--- a/image/DynamicImage.h +++ b/image/DynamicImage.h @@ -58,17 +58,17 @@ public: virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override; virtual void SetInnerWindowID(uint64_t aInnerWindowId) override; virtual uint64_t InnerWindowID() const override; virtual bool HasError() override; virtual void SetHasError() override; - virtual ImageURL* GetURI() override; + nsIURI* GetURI() const override; private: virtual ~DynamicImage() { } RefPtr<gfxDrawable> mDrawable; }; } // namespace image
--- a/image/Image.cpp +++ b/image/Image.cpp @@ -21,17 +21,17 @@ namespace image { ImageMemoryCounter::ImageMemoryCounter(Image* aImage, SizeOfState& aState, bool aIsUsed) : mIsUsed(aIsUsed) { MOZ_ASSERT(aImage); // Extract metadata about the image. - RefPtr<ImageURL> imageURL(aImage->GetURI()); + nsCOMPtr<nsIURI> imageURL(aImage->GetURI()); if (imageURL) { imageURL->GetSpec(mURI); } int32_t width = 0; int32_t height = 0; aImage->GetWidth(&width); aImage->GetHeight(&height); @@ -49,16 +49,30 @@ ImageMemoryCounter::ImageMemoryCounter(I } } /////////////////////////////////////////////////////////////////////////////// // Image Base Types /////////////////////////////////////////////////////////////////////////////// +bool +ImageResource::GetSpecTruncatedTo1k(nsCString& aSpec) const +{ + static const size_t sMaxTruncatedLength = 1024; + + mURI->GetSpec(aSpec); + if (sMaxTruncatedLength >= aSpec.Length()) { + return true; + } + + aSpec.Truncate(sMaxTruncatedLength); + return false; +} + void ImageResource::SetCurrentImage(ImageContainer* aContainer, SourceSurface* aSurface, bool aInTransaction) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aContainer); @@ -264,17 +278,17 @@ ImageResource::UpdateImageContainer() void ImageResource::ReleaseImageContainer() { MOZ_ASSERT(NS_IsMainThread()); mImageContainers.Clear(); } // Constructor -ImageResource::ImageResource(ImageURL* aURI) : +ImageResource::ImageResource(nsIURI* aURI) : mURI(aURI), mInnerWindowId(0), mAnimationConsumers(0), mAnimationMode(kNormalAnimMode), mInitialized(false), mAnimating(false), mError(false), mImageProducerID(ImageContainer::AllocateProducerID()), @@ -399,17 +413,17 @@ ImageResource::NotifyDrawingObservers() bool match = false; if ((NS_FAILED(mURI->SchemeIs("resource", &match)) || !match) && (NS_FAILED(mURI->SchemeIs("chrome", &match)) || !match)) { return; } // Record the image drawing for startup performance testing. - nsCOMPtr<nsIURI> uri = mURI->ToIURI(); + nsCOMPtr<nsIURI> uri = mURI; nsContentUtils::AddScriptRunner(NS_NewRunnableFunction( "image::ImageResource::NotifyDrawingObservers", [uri]() { nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); NS_WARNING_ASSERTION(obs, "Can't get an observer service handle"); if (obs) { nsAutoCString spec; uri->GetSpec(spec); obs->NotifyObservers(nullptr, "image-drawing", NS_ConvertUTF8toUTF16(spec).get());
--- a/image/Image.h +++ b/image/Image.h @@ -6,17 +6,16 @@ #ifndef mozilla_image_Image_h #define mozilla_image_Image_h #include "mozilla/MemoryReporting.h" #include "mozilla/Tuple.h" #include "mozilla/TimeStamp.h" #include "gfx2DGlue.h" #include "imgIContainer.h" -#include "ImageURL.h" #include "ImageContainer.h" #include "LookupResult.h" #include "nsStringFwd.h" #include "ProgressTracker.h" #include "SurfaceCache.h" class nsIRequest; class nsIInputStream; @@ -228,17 +227,17 @@ public: virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) = 0; virtual void SetInnerWindowID(uint64_t aInnerWindowId) = 0; virtual uint64_t InnerWindowID() const = 0; virtual bool HasError() = 0; virtual void SetHasError() = 0; - virtual ImageURL* GetURI() = 0; + virtual nsIURI* GetURI() const = 0; virtual void ReportUseCounters() { } }; class ImageResource : public Image { public: already_AddRefed<ProgressTracker> GetProgressTracker() override @@ -274,22 +273,24 @@ public: virtual bool HasError() override { return mError; } virtual void SetHasError() override { mError = true; } /* * Returns a non-AddRefed pointer to the URI associated with this image. * Illegal to use off-main-thread. */ - virtual ImageURL* GetURI() override { return mURI.get(); } + nsIURI* GetURI() const override { return mURI; } protected: - explicit ImageResource(ImageURL* aURI); + explicit ImageResource(nsIURI* aURI); ~ImageResource(); + bool GetSpecTruncatedTo1k(nsCString& aSpec) const; + // Shared functionality for implementors of imgIContainer. Every // implementation of attribute animationMode should forward here. nsresult GetAnimationModeInternal(uint16_t* aAnimationMode); nsresult SetAnimationModeInternal(uint16_t aAnimationMode); /** * Helper for RequestRefresh. * @@ -321,18 +322,18 @@ protected: void SendOnUnlockedDraw(uint32_t aFlags); #ifdef DEBUG // Records the image drawing for startup performance testing. void NotifyDrawingObservers(); #endif // Member data shared by all implementations of this abstract class - RefPtr<ProgressTracker> mProgressTracker; - RefPtr<ImageURL> mURI; + RefPtr<ProgressTracker> mProgressTracker; + nsCOMPtr<nsIURI> mURI; TimeStamp mLastRefreshTime; uint64_t mInnerWindowId; uint32_t mAnimationConsumers; uint16_t mAnimationMode; // Enum values in imgIContainer bool mInitialized:1; // Have we been initalized? bool mAnimating:1; // Are we currently animating? bool mError:1; // Error handling
--- a/image/ImageCacheKey.cpp +++ b/image/ImageCacheKey.cpp @@ -1,43 +1,33 @@ /* -*- Mode: C++; tab-width: 2; 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 "ImageCacheKey.h" +#include "mozilla/HashFunctions.h" #include "mozilla/Move.h" -#include "ImageURL.h" #include "nsLayoutUtils.h" #include "nsString.h" #include "mozilla/dom/BlobURLProtocolHandler.h" #include "mozilla/dom/File.h" #include "mozilla/dom/ServiceWorkerManager.h" #include "nsIDocument.h" #include "nsPrintfCString.h" namespace mozilla { using namespace dom; namespace image { -bool -URISchemeIs(ImageURL* aURI, const char* aScheme) -{ - bool schemeMatches = false; - if (NS_WARN_IF(NS_FAILED(aURI->SchemeIs(aScheme, &schemeMatches)))) { - return false; - } - return schemeMatches; -} - static Maybe<uint64_t> -BlobSerial(ImageURL* aURI) +BlobSerial(nsIURI* aURI) { nsAutoCString spec; aURI->GetSpec(spec); RefPtr<BlobImpl> blob; if (NS_SUCCEEDED(NS_GetBlobForBlobURISpec(spec, getter_AddRefs(blob))) && blob) { return Some(blob->GetSerialNumber()); @@ -45,61 +35,63 @@ BlobSerial(ImageURL* aURI) return Nothing(); } ImageCacheKey::ImageCacheKey(nsIURI* aURI, const OriginAttributes& aAttrs, nsIDocument* aDocument, nsresult& aRv) - : mURI(new ImageURL(aURI, aRv)) - , mOriginAttributes(aAttrs) - , mControlledDocument(GetControlledDocumentToken(aDocument)) - , mIsChrome(URISchemeIs(mURI, "chrome")) -{ - NS_ENSURE_SUCCESS_VOID(aRv); - - MOZ_ASSERT(NS_IsMainThread()); - - if (URISchemeIs(mURI, "blob")) { - mBlobSerial = BlobSerial(mURI); - } - - mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); -} - -ImageCacheKey::ImageCacheKey(ImageURL* aURI, - const OriginAttributes& aAttrs, - nsIDocument* aDocument) : mURI(aURI) , mOriginAttributes(aAttrs) , mControlledDocument(GetControlledDocumentToken(aDocument)) - , mIsChrome(URISchemeIs(mURI, "chrome")) + , mHash(0) + , mIsChrome(false) { - MOZ_ASSERT(aURI); - - if (URISchemeIs(mURI, "blob")) { + if (SchemeIs("blob")) { mBlobSerial = BlobSerial(mURI); + } else if (SchemeIs("chrome")) { + mIsChrome = true; } - mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); + // Since we frequently call Hash() several times in a row on the same + // ImageCacheKey, as an optimization we compute our hash once and store it. + + nsPrintfCString ptr("%p", mControlledDocument); + nsAutoCString suffix; + mOriginAttributes.CreateSuffix(suffix); + + if (mBlobSerial) { + aRv = mURI->GetRef(mBlobRef); + NS_ENSURE_SUCCESS_VOID(aRv); + mHash = HashGeneric(*mBlobSerial, HashString(mBlobRef)); + } else { + nsAutoCString spec; + aRv = mURI->GetSpec(spec); + NS_ENSURE_SUCCESS_VOID(aRv); + mHash = HashString(spec); + } + + mHash = AddToHash(mHash, HashString(suffix), HashString(ptr)); } ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) : mURI(aOther.mURI) , mBlobSerial(aOther.mBlobSerial) + , mBlobRef(aOther.mBlobRef) , mOriginAttributes(aOther.mOriginAttributes) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) { } ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) : mURI(std::move(aOther.mURI)) , mBlobSerial(std::move(aOther.mBlobSerial)) + , mBlobRef(std::move(aOther.mBlobRef)) , mOriginAttributes(aOther.mOriginAttributes) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) { } bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const @@ -111,44 +103,30 @@ ImageCacheKey::operator==(const ImageCac // The origin attributes always have to match. if (mOriginAttributes != aOther.mOriginAttributes) { return false; } if (mBlobSerial || aOther.mBlobSerial) { // If at least one of us has a blob serial, just compare the blob serial and // the ref portion of the URIs. return mBlobSerial == aOther.mBlobSerial && - mURI->HasSameRef(*aOther.mURI); + mBlobRef == aOther.mBlobRef; } // For non-blob URIs, compare the URIs. - return *mURI == *aOther.mURI; -} - -const char* -ImageCacheKey::Spec() const -{ - return mURI->Spec(); + bool equals = false; + nsresult rv = mURI->Equals(aOther.mURI, &equals); + return NS_SUCCEEDED(rv) && equals; } -/* static */ PLDHashNumber -ImageCacheKey::ComputeHash(ImageURL* aURI, - const Maybe<uint64_t>& aBlobSerial, - const OriginAttributes& aAttrs, - void* aControlledDocument) +bool +ImageCacheKey::SchemeIs(const char* aScheme) { - // Since we frequently call Hash() several times in a row on the same - // ImageCacheKey, as an optimization we compute our hash once and store it. - - nsPrintfCString ptr("%p", aControlledDocument); - nsAutoCString suffix; - aAttrs.CreateSuffix(suffix); - - return AddToHash(0, aURI->ComputeHash(aBlobSerial), - HashString(suffix), HashString(ptr)); + bool matches = false; + return NS_SUCCEEDED(mURI->SchemeIs(aScheme, &matches)) && matches; } /* static */ void* ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument) { // For non-controlled documents, we just return null. For controlled // documents, we cast the pointer into a void* to avoid dereferencing // it (since we only use it for comparisons), and return it.
--- a/image/ImageCacheKey.h +++ b/image/ImageCacheKey.h @@ -16,59 +16,53 @@ #include "PLDHashTable.h" class nsIDocument; class nsIURI; namespace mozilla { namespace image { -class ImageURL; - /** * An ImageLib cache entry key. * * We key the cache on the initial URI (before any redirects), with some * canonicalization applied. See ComputeHash() for the details. * Controlled documents do not share their cache entries with * non-controlled documents, or other controlled documents. */ class ImageCacheKey final { public: ImageCacheKey(nsIURI* aURI, const OriginAttributes& aAttrs, nsIDocument* aDocument, nsresult& aRv); - ImageCacheKey(ImageURL* aURI, const OriginAttributes& aAttrs, - nsIDocument* aDocument); ImageCacheKey(const ImageCacheKey& aOther); ImageCacheKey(ImageCacheKey&& aOther); bool operator==(const ImageCacheKey& aOther) const; PLDHashNumber Hash() const { return mHash; } - /// A weak pointer to the URI spec for this cache entry. For logging only. - const char* Spec() const; + /// A weak pointer to the URI. For logging only. + nsIURI* URI() const { return mURI; } /// Is this cache entry for a chrome image? bool IsChrome() const { return mIsChrome; } /// A token indicating which service worker controlled document this entry /// belongs to, if any. void* ControlledDocument() const { return mControlledDocument; } private: - static PLDHashNumber ComputeHash(ImageURL* aURI, - const Maybe<uint64_t>& aBlobSerial, - const OriginAttributes& aAttrs, - void* aControlledDocument); + bool SchemeIs(const char* aScheme); static void* GetControlledDocumentToken(nsIDocument* aDocument); - RefPtr<ImageURL> mURI; + nsCOMPtr<nsIURI> mURI; Maybe<uint64_t> mBlobSerial; + nsCString mBlobRef; OriginAttributes mOriginAttributes; void* mControlledDocument; PLDHashNumber mHash; bool mIsChrome; }; } // namespace image } // namespace mozilla
--- a/image/ImageFactory.cpp +++ b/image/ImageFactory.cpp @@ -29,17 +29,17 @@ namespace mozilla { namespace image { /*static*/ void ImageFactory::Initialize() { } static uint32_t -ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart) +ComputeImageFlags(nsIURI* uri, const nsCString& aMimeType, bool isMultiPart) { nsresult rv; // We default to the static globals. bool isDiscardable = gfxPrefs::ImageMemDiscardable(); bool doDecodeImmediately = gfxPrefs::ImageDecodeImmediatelyEnabled(); // We want UI to be as snappy as possible and not to flicker. Disable @@ -83,20 +83,20 @@ ComputeImageFlags(ImageURL* uri, const n imageFlags |= Image::INIT_FLAG_SYNC_LOAD; } return imageFlags; } #ifdef DEBUG static void -NotifyImageLoading(ImageURL* aURI) +NotifyImageLoading(nsIURI* aURI) { if (!NS_IsMainThread()) { - RefPtr<ImageURL> uri(aURI); + nsCOMPtr<nsIURI> uri(aURI); nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction("NotifyImageLoading", [uri] () -> void { NotifyImageLoading(uri); }); SystemGroup::Dispatch(TaskCategory::Other, ev.forget()); return; } @@ -109,17 +109,17 @@ NotifyImageLoading(ImageURL* aURI) } } #endif /* static */ already_AddRefed<Image> ImageFactory::CreateImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, bool aIsMultiPart, uint32_t aInnerWindowId) { MOZ_ASSERT(gfxPrefs::SingletonExists(), "Pref observers should have been initialized already"); // Compute the image's initialization flags. uint32_t imageFlags = ComputeImageFlags(aURI, aMimeType, aIsMultiPart); @@ -235,17 +235,17 @@ GetContentSize(nsIRequest* aRequest) // Fallback - neither http nor file. We'll use dynamic allocation. return 0; } /* static */ already_AddRefed<Image> ImageFactory::CreateRasterImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { MOZ_ASSERT(aProgressTracker); nsresult rv; RefPtr<RasterImage> newImage = new RasterImage(aURI); @@ -266,17 +266,17 @@ ImageFactory::CreateRasterImage(nsIReque return newImage.forget(); } /* static */ already_AddRefed<Image> ImageFactory::CreateVectorImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId) { MOZ_ASSERT(aProgressTracker); nsresult rv; RefPtr<VectorImage> newImage = new VectorImage(aURI);
--- a/image/ImageFactory.h +++ b/image/ImageFactory.h @@ -7,22 +7,22 @@ #ifndef mozilla_image_ImageFactory_h #define mozilla_image_ImageFactory_h #include "nsCOMPtr.h" #include "nsProxyRelease.h" #include "nsStringFwd.h" class nsIRequest; +class nsIURI; namespace mozilla { namespace image { class Image; -class ImageURL; class MultipartImage; class ProgressTracker; class ImageFactory { public: /** * Registers vars with Preferences. Should only be called on the main thread. @@ -38,17 +38,17 @@ public: * @param aMimeType The mimetype of the image. * @param aURI The URI of the image. * @param aIsMultiPart Whether the image is part of a multipart request. * @param aInnerWindowId The window this image belongs to. */ static already_AddRefed<Image> CreateImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, bool aIsMultiPart, uint32_t aInnerWindowId); /** * Creates a new image which isn't associated with a URI or loaded through * the usual image loading mechanism. * * @param aMimeType The mimetype of the image. * @param aSizeHint The length of the source data for the image. @@ -69,25 +69,25 @@ public: CreateMultipartImage(Image* aFirstPart, ProgressTracker* aProgressTracker); private: // Factory functions that create specific types of image containers. static already_AddRefed<Image> CreateRasterImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId); static already_AddRefed<Image> CreateVectorImage(nsIRequest* aRequest, ProgressTracker* aProgressTracker, const nsCString& aMimeType, - ImageURL* aURI, + nsIURI* aURI, uint32_t aImageFlags, uint32_t aInnerWindowId); // This is a static factory class, so disallow instantiation. virtual ~ImageFactory() = 0; }; } // namespace image
--- a/image/ImageLogging.h +++ b/image/ImageLogging.h @@ -3,16 +3,18 @@ * 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 mozilla_image_ImageLogging_h #define mozilla_image_ImageLogging_h #include "mozilla/Logging.h" +#include "Image.h" +#include "nsIURI.h" #include "prinrval.h" static mozilla::LazyLogModule gImgLog("imgRequest"); #define GIVE_ME_MS_NOW() PR_IntervalToMilliseconds(PR_IntervalNow()) using mozilla::LogLevel; @@ -71,16 +73,45 @@ public: , mFrom(from) , mFunc(fn) { MOZ_LOG(mLog, LogLevel::Debug, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n", GIVE_ME_MS_NOW(), mFrom, mFunc, paramName, paramValue)); } + /* nsIURI constructor */ + LogScope(mozilla::LogModule* aLog, void* from, const char* fn, + const char* paramName, nsIURI* aURI) + : mLog(aLog) + , mFrom(from) + , mFunc(fn) + { + if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { + static const size_t sMaxTruncatedLength = 1024; + nsAutoCString spec("<unknown>"); + if (aURI) { + aURI->GetSpec(spec); + if (spec.Length() >= sMaxTruncatedLength) { + spec.Truncate(sMaxTruncatedLength); + } + } + MOZ_LOG(aLog, LogLevel::Debug, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n", + GIVE_ME_MS_NOW(), from, fn, + paramName, spec.get())); + } + } + + /* Image constructor */ + LogScope(mozilla::LogModule* aLog, void* from, const char* fn, + const char* paramName, mozilla::image::Image* aImage) + : LogScope(aLog, from, fn, paramName, aImage ? aImage->GetURI() : nullptr) + { + } + ~LogScope() { MOZ_LOG(mLog, LogLevel::Debug, ("%d [this=%p] %s {EXIT}\n", GIVE_ME_MS_NOW(), mFrom, mFunc)); } private: mozilla::LogModule* mLog; @@ -116,16 +147,40 @@ public: LogFunc(mozilla::LogModule* aLog, void* from, const char* fn, const char* paramName, uint32_t paramValue) { MOZ_LOG(aLog, LogLevel::Debug, ("%d [this=%p] %s (%s=\"%d\")\n", GIVE_ME_MS_NOW(), from, fn, paramName, paramValue)); } + LogFunc(mozilla::LogModule* aLog, void* from, const char* fn, + const char* paramName, nsIURI* aURI) + { + if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { + static const size_t sMaxTruncatedLength = 1024; + nsAutoCString spec("<unknown>"); + if (aURI) { + aURI->GetSpec(spec); + if (spec.Length() >= sMaxTruncatedLength) { + spec.Truncate(sMaxTruncatedLength); + } + } + MOZ_LOG(aLog, LogLevel::Debug, ("%d [this=%p] %s (%s=\"%s\")\n", + GIVE_ME_MS_NOW(), from, fn, + paramName, spec.get())); + } + } + + LogFunc(mozilla::LogModule* aLog, void* from, const char* fn, + const char* paramName, mozilla::image::Image* aImage) + : LogFunc(aLog, from, fn, paramName, aImage ? aImage->GetURI() : nullptr) + { + } + }; class LogMessage { public: LogMessage(mozilla::LogModule* aLog, void* from, const char* fn, const char* msg) {
--- a/image/ImageOps.cpp +++ b/image/ImageOps.cpp @@ -11,16 +11,17 @@ #include "DecoderFactory.h" #include "DynamicImage.h" #include "FrozenImage.h" #include "IDecodingTask.h" #include "Image.h" #include "ImageMetadata.h" #include "imgIContainer.h" #include "mozilla/gfx/2D.h" +#include "nsNetUtil.h" // for NS_NewBufferedInputStream #include "nsStreamUtils.h" #include "OrientedImage.h" #include "SourceBuffer.h" using namespace mozilla::gfx; namespace mozilla { namespace image {
deleted file mode 100644 --- a/image/ImageURL.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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 mozilla_image_ImageURL_h -#define mozilla_image_ImageURL_h - -#include "nsIURI.h" -#include "MainThreadUtils.h" -#include "nsNetUtil.h" -#include "mozilla/HashFunctions.h" -#include "nsHashKeys.h" -#include "nsProxyRelease.h" - -namespace mozilla { -namespace image { - -class ImageCacheKey; - -/** ImageURL - * - * nsStandardURL is not threadsafe, so this class is created to hold only the - * necessary URL data required for image loading and decoding. - * - * Note: Although several APIs have the same or similar prototypes as those - * found in nsIURI/nsStandardURL, the class does not implement nsIURI. This is - * intentional; functionality is limited, and is only useful for imagelib code. - * By not implementing nsIURI, external code cannot unintentionally be given an - * nsIURI pointer with this limited class behind it; instead, conversion to a - * fully implemented nsIURI is required (e.g. through NS_NewURI). - */ -class ImageURL -{ -public: - explicit ImageURL(nsIURI* aURI, nsresult& aRv) - : mURI(new nsMainThreadPtrHolder<nsIURI>("ImageURL::mURI", aURI)) - { - MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!"); - - aRv = aURI->GetSpec(mSpec); - NS_ENSURE_SUCCESS_VOID(aRv); - - aRv = aURI->GetScheme(mScheme); - NS_ENSURE_SUCCESS_VOID(aRv); - - aRv = aURI->GetRef(mRef); - NS_ENSURE_SUCCESS_VOID(aRv); - } - - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageURL) - - nsresult GetSpec(nsACString& result) - { - result = mSpec; - return NS_OK; - } - - /// A weak pointer to the URI spec for this ImageURL. For logging only. - const char* Spec() const { return mSpec.get(); } - - enum TruncatedSpecStatus { - FitsInto1k, - TruncatedTo1k - }; - TruncatedSpecStatus GetSpecTruncatedTo1k(nsACString& result) - { - static const size_t sMaxTruncatedLength = 1024; - - if (sMaxTruncatedLength >= mSpec.Length()) { - result = mSpec; - return FitsInto1k; - } - - result = Substring(mSpec, 0, sMaxTruncatedLength); - return TruncatedTo1k; - } - - nsresult GetScheme(nsACString& result) - { - result = mScheme; - return NS_OK; - } - - nsresult SchemeIs(const char* scheme, bool* result) - { - MOZ_ASSERT(scheme, "scheme is null"); - MOZ_ASSERT(result, "result is null"); - - *result = mScheme.Equals(scheme); - return NS_OK; - } - - nsresult GetRef(nsACString& result) - { - result = mRef; - return NS_OK; - } - - already_AddRefed<nsIURI> ToIURI() - { - nsCOMPtr<nsIURI> newURI = mURI.get(); - return newURI.forget(); - } - - bool operator==(const ImageURL& aOther) const - { - // Note that we don't need to consider mScheme and mRef, because they're - // already represented in mSpec. - return mSpec == aOther.mSpec; - } - - bool HasSameRef(const ImageURL& aOther) const - { - return mRef == aOther.mRef; - } - -private: - friend class ImageCacheKey; - - PLDHashNumber ComputeHash(const Maybe<uint64_t>& aBlobSerial) const - { - if (aBlobSerial) { - // For blob URIs, we hash the serial number of the underlying blob, so that - // different blob URIs which point to the same blob share a cache entry. We - // also include the ref portion of the URI to support media fragments which - // requires us to create different Image objects even if the source data is - // the same. - return HashGeneric(*aBlobSerial, HashString(mRef)); - } - // For non-blob URIs, we hash the URI spec. - return HashString(mSpec); - } - - nsMainThreadPtrHandle<nsIURI> mURI; - - // Since this is a basic storage class, no duplication of spec parsing is - // included in the functionality. Instead, the class depends upon the - // parsing implementation in the nsIURI class used in object construction. - // This means each field is stored separately, but since only a few are - // required, this small memory tradeoff for threadsafe usage should be ok. - nsAutoCString mSpec; - nsAutoCString mScheme; - nsAutoCString mRef; - - ~ImageURL() { } -}; - -} // namespace image -} // namespace mozilla - -#endif // mozilla_image_ImageURL_h
--- a/image/ImageWrapper.cpp +++ b/image/ImageWrapper.cpp @@ -112,18 +112,18 @@ ImageWrapper::HasError() } void ImageWrapper::SetHasError() { mInnerImage->SetHasError(); } -ImageURL* -ImageWrapper::GetURI() +nsIURI* +ImageWrapper::GetURI() const { return mInnerImage->GetURI(); } // Methods inherited from XPCOM interfaces. NS_IMPL_ISUPPORTS(ImageWrapper, imgIContainer)
--- a/image/ImageWrapper.h +++ b/image/ImageWrapper.h @@ -50,17 +50,17 @@ public: virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override; virtual void SetInnerWindowID(uint64_t aInnerWindowId) override; virtual uint64_t InnerWindowID() const override; virtual bool HasError() override; virtual void SetHasError() override; - virtual ImageURL* GetURI() override; + nsIURI* GetURI() const override; protected: explicit ImageWrapper(Image* aInnerImage) : mInnerImage(aInnerImage) { MOZ_ASSERT(aInnerImage, "Need an image to wrap"); }
--- a/image/ProgressTracker.cpp +++ b/image/ProgressTracker.cpp @@ -173,26 +173,18 @@ ProgressTracker::Notify(IProgressObserve if (aObserver->NotificationsDeferred()) { // There is a pending notification, or the observer isn't ready yet. return; } if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { RefPtr<Image> image = GetImage(); - if (image && image->GetURI()) { - RefPtr<ImageURL> uri(image->GetURI()); - nsAutoCString spec; - uri->GetSpec(spec); - LOG_FUNC_WITH_PARAM(gImgLog, - "ProgressTracker::Notify async", "uri", spec.get()); - } else { - LOG_FUNC_WITH_PARAM(gImgLog, - "ProgressTracker::Notify async", "uri", "<unknown>"); - } + LOG_FUNC_WITH_PARAM(gImgLog, + "ProgressTracker::Notify async", "uri", image); } aObserver->MarkPendingNotify(); // If we have an existing runnable that we can use, we just append this // observer to its list of observers to be notified. This ensures we don't // unnecessarily delay onload. AsyncNotifyRunnable* runnable = @@ -248,22 +240,18 @@ ProgressTracker::NotifyCurrentState(IPro if (aObserver->NotificationsDeferred()) { // There is a pending notification, or the observer isn't ready yet. return; } if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { RefPtr<Image> image = GetImage(); - nsAutoCString spec; - if (image && image->GetURI()) { - image->GetURI()->GetSpec(spec); - } LOG_FUNC_WITH_PARAM(gImgLog, - "ProgressTracker::NotifyCurrentState", "uri", spec.get()); + "ProgressTracker::NotifyCurrentState", "uri", image); } aObserver->MarkPendingNotify(); nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this, aObserver); mEventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL); } @@ -396,23 +384,18 @@ ProgressTracker::SyncNotifyProgress(Prog } void ProgressTracker::SyncNotify(IProgressObserver* aObserver) { MOZ_ASSERT(NS_IsMainThread()); RefPtr<Image> image = GetImage(); - - nsAutoCString spec; - if (image && image->GetURI()) { - image->GetURI()->GetSpec(spec); - } LOG_SCOPE_WITH_PARAM(gImgLog, - "ProgressTracker::SyncNotify", "uri", spec.get()); + "ProgressTracker::SyncNotify", "uri", image); nsIntRect rect; if (image) { int32_t width, height; if (NS_FAILED(image->GetWidth(&width)) || NS_FAILED(image->GetHeight(&height))) { // Either the image has no intrinsic size, or it has an error. rect = GetMaxSizedIntRect(); @@ -591,21 +574,17 @@ ProgressTracker::FireFailureNotification { MOZ_ASSERT(NS_IsMainThread()); // Some kind of problem has happened with image decoding. // Report the URI to net:failed-to-process-uri-conent observers. RefPtr<Image> image = GetImage(); if (image) { // Should be on main thread, so ok to create a new nsIURI. - nsCOMPtr<nsIURI> uri; - { - RefPtr<ImageURL> threadsafeUriData = image->GetURI(); - uri = threadsafeUriData ? threadsafeUriData->ToIURI() : nullptr; - } + nsCOMPtr<nsIURI> uri = image->GetURI(); if (uri) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) { os->NotifyObservers(uri, "net:failed-to-process-uri-content", nullptr); } } } }
--- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -65,17 +65,17 @@ using std::min; #ifndef DEBUG NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, nsIProperties) #else NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, nsIProperties, imgIContainerDebug) #endif //****************************************************************************** -RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) : +RasterImage::RasterImage(nsIURI* aURI /* = nullptr */) : ImageResource(aURI), // invoke superclass's constructor mSize(0,0), mLockCount(0), mDecodeCount(0), #ifdef DEBUG mFramesNotified(0), #endif mSourceBuffer(MakeNotNull<SourceBuffer*>()), @@ -1812,18 +1812,18 @@ RasterImage::ReportDecoderError() do_GetService(NS_CONSOLESERVICE_CONTRACTID); nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); if (consoleService && errorObject) { nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated.")); nsAutoString src; if (GetURI()) { - nsCString uri; - if (GetURI()->GetSpecTruncatedTo1k(uri) == ImageURL::TruncatedTo1k) { + nsAutoCString uri; + if (!GetSpecTruncatedTo1k(uri)) { msg += NS_LITERAL_STRING(" URI in this note truncated due to length."); } src = NS_ConvertUTF8toUTF16(uri); } if (NS_SUCCEEDED(errorObject->InitWithWindowID( msg, src, EmptyString(), 0, 0, nsIScriptError::errorFlag,
--- a/image/RasterImage.h +++ b/image/RasterImage.h @@ -464,17 +464,17 @@ private: // data // Helpers bool CanDiscard(); bool IsOpaque(); DrawableSurface RequestDecodeForSizeInternal(const gfx::IntSize& aSize, uint32_t aFlags); protected: - explicit RasterImage(ImageURL* aURI = nullptr); + explicit RasterImage(nsIURI* aURI = nullptr); bool ShouldAnimate() override; friend class ImageFactory; }; inline NS_IMETHODIMP RasterImage::GetAnimationMode(uint16_t* aAnimationMode) {
--- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -366,17 +366,17 @@ private: NS_IMPL_ISUPPORTS(VectorImage, imgIContainer, nsIStreamListener, nsIRequestObserver) //------------------------------------------------------------------------------ // Constructor / Destructor -VectorImage::VectorImage(ImageURL* aURI /* = nullptr */) : +VectorImage::VectorImage(nsIURI* aURI /* = nullptr */) : ImageResource(aURI), // invoke superclass's constructor mLockCount(0), mIsInitialized(false), mIsFullyLoaded(false), mIsDrawing(false), mHaveAnimations(false), mHasPendingInvalidation(false) { } @@ -917,18 +917,17 @@ VectorImage::MaybeRestrictSVGContext(May const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags) { bool overridePAR = (aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext; bool haveContextPaint = aSVGContext && aSVGContext->GetContextPaint(); bool blockContextPaint = false; if (haveContextPaint) { - nsCOMPtr<nsIURI> imageURI = mURI->ToIURI(); - blockContextPaint = !SVGContextPaint::IsAllowedForImageFromURI(imageURI); + blockContextPaint = !SVGContextPaint::IsAllowedForImageFromURI(mURI); } if (overridePAR || blockContextPaint) { // The key that we create for the image surface cache must match the way // that the image will be painted, so we need to initialize a new matching // SVGImageContext here in order to generate the correct key. aNewSVGContext = aSVGContext; // copy
--- a/image/VectorImage.h +++ b/image/VectorImage.h @@ -68,17 +68,17 @@ public: // Callbacks for SVGLoadEventListener. void OnSVGDocumentLoaded(); void OnSVGDocumentError(); virtual void ReportUseCounters() override; protected: - explicit VectorImage(ImageURL* aURI = nullptr); + explicit VectorImage(nsIURI* aURI = nullptr); virtual ~VectorImage(); virtual nsresult StartAnimation() override; virtual nsresult StopAnimation() override; virtual bool ShouldAnimate() override; private: Tuple<ImgDrawResult, IntSize, RefPtr<SourceSurface>>
--- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -989,20 +989,20 @@ void imgCacheEntry::UpdateLoadTime() } void imgCacheEntry::SetHasNoProxies(bool hasNoProxies) { if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { if (hasNoProxies) { LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheEntry::SetHasNoProxies true", - "uri", mRequest->CacheKey().Spec()); + "uri", mRequest->CacheKey().URI()); } else { LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheEntry::SetHasNoProxies false", - "uri", mRequest->CacheKey().Spec()); + "uri", mRequest->CacheKey().URI()); } } mHasNoProxies = hasNoProxies; } imgCacheQueue::imgCacheQueue() : mDirty(false), @@ -1167,17 +1167,17 @@ imgLoader::CreateNewProxyForRequest(imgR RefPtr<imgRequestProxy> proxyRequest = new imgRequestProxy(); /* It is important to call |SetLoadFlags()| before calling |Init()| because |Init()| adds the request to the loadgroup. */ proxyRequest->SetLoadFlags(aLoadFlags); - RefPtr<ImageURL> uri; + nsCOMPtr<nsIURI> uri; aRequest->GetURI(getter_AddRefs(uri)); // init adds itself to imgRequest's list of observers nsresult rv = proxyRequest->Init(aRequest, aLoadGroup, aLoadingDocument, uri, aObserver); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -1210,17 +1210,17 @@ imgCacheExpirationTracker::NotifyExpired // mechanism doesn't. RefPtr<imgCacheEntry> kungFuDeathGrip(entry); if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { RefPtr<imgRequest> req = entry->GetRequest(); if (req) { LOG_FUNC_WITH_PARAM(gImgLog, "imgCacheExpirationTracker::NotifyExpired", - "entry", req->CacheKey().Spec()); + "entry", req->CacheKey().URI()); } } // We can be called multiple times on the same entry. Don't do work multiple // times. if (!entry->Evicted()) { entry->Loader()->RemoveFromCache(entry); } @@ -1575,17 +1575,17 @@ imgLoader::MinimizeCaches() } bool imgLoader::PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* entry) { imgCacheTable& cache = GetCache(aKey); LOG_STATIC_FUNC_WITH_PARAM(gImgLog, - "imgLoader::PutIntoCache", "uri", aKey.Spec()); + "imgLoader::PutIntoCache", "uri", aKey.URI()); // Check to see if this request already exists in the cache. If so, we'll // replace the old version. RefPtr<imgCacheEntry> tmpCacheEntry; if (cache.Get(aKey, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) { MOZ_LOG(gImgLog, LogLevel::Debug, ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache", nullptr)); @@ -1633,17 +1633,17 @@ imgLoader::PutIntoCache(const ImageCache return true; } bool imgLoader::SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry) { LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::SetHasNoProxies", "uri", - aRequest->CacheKey().Spec()); + aRequest->CacheKey().URI()); aEntry->SetHasNoProxies(true); if (aEntry->Evicted()) { return false; } imgCacheQueue& queue = GetCacheQueue(aRequest->IsChrome()); @@ -1668,17 +1668,17 @@ bool imgLoader::SetHasProxies(imgRequest* aRequest) { VerifyCacheSizes(); const ImageCacheKey& key = aRequest->CacheKey(); imgCacheTable& cache = GetCache(key); LOG_STATIC_FUNC_WITH_PARAM(gImgLog, - "imgLoader::SetHasProxies", "uri", key.Spec()); + "imgLoader::SetHasProxies", "uri", key.URI()); RefPtr<imgCacheEntry> entry; if (cache.Get(key, getter_AddRefs(entry)) && entry) { // Make sure the cache entry is for the right request RefPtr<imgRequest> entryRequest = entry->GetRequest(); if (entryRequest == aRequest && entry->HasNoProxies()) { imgCacheQueue& queue = GetCacheQueue(key); queue.Remove(entry); @@ -1724,17 +1724,17 @@ imgLoader::CheckCacheLimits(imgCacheTabl NS_ASSERTION(entry, "imgLoader::CheckCacheLimits -- NULL entry pointer"); if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { RefPtr<imgRequest> req = entry->GetRequest(); if (req) { LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::CheckCacheLimits", - "entry", req->CacheKey().Spec()); + "entry", req->CacheKey().URI()); } } if (entry) { // We just popped this entry from the queue, so pass AlreadyRemoved // to avoid searching the queue again in RemoveFromCache. RemoveFromCache(entry, QueueState::AlreadyRemoved); } @@ -1999,17 +1999,17 @@ imgLoader::ValidateEntry(imgCacheEntry* return !validateRequest; } bool imgLoader::RemoveFromCache(const ImageCacheKey& aKey) { LOG_STATIC_FUNC_WITH_PARAM(gImgLog, - "imgLoader::RemoveFromCache", "uri", aKey.Spec()); + "imgLoader::RemoveFromCache", "uri", aKey.URI()); imgCacheTable& cache = GetCache(aKey); imgCacheQueue& queue = GetCacheQueue(aKey); RefPtr<imgCacheEntry> entry; cache.Remove(aKey, getter_AddRefs(entry)); if (entry) { MOZ_ASSERT(!entry->Evicted(), "Evicting an already-evicted cache entry!"); @@ -2041,17 +2041,17 @@ imgLoader::RemoveFromCache(imgCacheEntry RefPtr<imgRequest> request = entry->GetRequest(); if (request) { const ImageCacheKey& key = request->CacheKey(); imgCacheTable& cache = GetCache(key); imgCacheQueue& queue = GetCacheQueue(key); LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "entry's uri", - key.Spec()); + key.URI()); cache.Remove(key); if (entry->HasNoProxies()) { LOG_STATIC_FUNC(gImgLog, "imgLoader::RemoveFromCache removing from tracker"); if (mCacheTracker) { mCacheTracker->RemoveObject(entry); @@ -2209,18 +2209,17 @@ imgLoader::LoadImage(nsIURI* aURI, VerifyCacheSizes(); NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer"); if (!aURI) { return NS_ERROR_NULL_POINTER; } - LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", - aURI->GetSpecOrDefault().get()); + LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", aURI); *_retval = nullptr; RefPtr<imgRequest> request; nsresult rv; nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL; @@ -2305,17 +2304,17 @@ imgLoader::LoadImage(nsIURI* aURI, aLoadingDocument, requestFlags, aContentPolicyType, true, _retval, aTriggeringPrincipal, corsmode)) { request = entry->GetRequest(); // If this entry has no proxies, its request has no reference to the // entry. if (entry->HasNoProxies()) { LOG_FUNC_WITH_PARAM(gImgLog, - "imgLoader::LoadImage() adding proxyless entry", "uri", key.Spec()); + "imgLoader::LoadImage() adding proxyless entry", "uri", key.URI()); MOZ_ASSERT(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!"); request->SetCacheEntry(entry); if (mCacheTracker && entry->GetExpirationState()->IsTracked()) { mCacheTracker->MarkUsed(entry); } } @@ -2593,17 +2592,17 @@ imgLoader::LoadImageWithChannel(nsIChann } if (request && entry) { // If this entry has no proxies, its request has no reference to // the entry. if (entry->HasNoProxies()) { LOG_FUNC_WITH_PARAM(gImgLog, "imgLoader::LoadImageWithChannel() adding proxyless entry", - "uri", key.Spec()); + "uri", key.URI()); MOZ_ASSERT(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!"); request->SetCacheEntry(entry); if (mCacheTracker && entry->GetExpirationState()->IsTracked()) { mCacheTracker->MarkUsed(entry); } } @@ -3062,27 +3061,21 @@ imgCacheValidator::OnStartRequest(nsIReq UpdateProxies(/* aCancelRequest */ false, /* aSyncNotify */ true); return NS_OK; } } // We can't load out of cache. We have to create a whole new request for the // data that's coming in off the channel. nsCOMPtr<nsIURI> uri; - { - RefPtr<ImageURL> imageURL; - mRequest->GetURI(getter_AddRefs(imageURL)); - uri = imageURL->ToIURI(); - } - - if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { - LOG_MSG_WITH_PARAM(gImgLog, - "imgCacheValidator::OnStartRequest creating new request", - "uri", uri->GetSpecOrDefault().get()); - } + mRequest->GetURI(getter_AddRefs(uri)); + + LOG_MSG_WITH_PARAM(gImgLog, + "imgCacheValidator::OnStartRequest creating new request", + "uri", uri); int32_t corsmode = mRequest->GetCORSMode(); ReferrerPolicy refpol = mRequest->GetReferrerPolicy(); nsCOMPtr<nsIPrincipal> triggeringPrincipal = mRequest->GetTriggeringPrincipal(); // Doom the old request's cache entry mRequest->RemoveFromCache();
--- a/image/imgLoader.h +++ b/image/imgLoader.h @@ -29,17 +29,16 @@ class imgLoader; class imgRequestProxy; class imgINotificationObserver; class nsILoadGroup; class imgCacheExpirationTracker; class imgMemoryReporter; namespace mozilla { namespace image { -class ImageURL; } // namespace image } // namespace mozilla class imgCacheEntry { public: static uint32_t SecondsFromPRTime(PRTime prTime); @@ -229,17 +228,16 @@ class imgLoader final : public imgILoade public imgICache, public nsSupportsWeakReference, public nsIObserver { virtual ~imgLoader(); public: typedef mozilla::image::ImageCacheKey ImageCacheKey; - typedef mozilla::image::ImageURL ImageURL; typedef nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>, imgCacheEntry> imgCacheTable; typedef nsTHashtable<nsPtrHashKey<imgRequest>> imgSet; typedef mozilla::net::ReferrerPolicy ReferrerPolicy; typedef mozilla::Mutex Mutex; NS_DECL_ISUPPORTS NS_DECL_IMGILOADER
--- a/image/imgRequest.cpp +++ b/image/imgRequest.cpp @@ -75,20 +75,18 @@ imgRequest::imgRequest(imgLoader* aLoade } imgRequest::~imgRequest() { if (mLoader) { mLoader->RemoveFromUncachedImages(this); } if (mURI) { - nsAutoCString spec; - mURI->GetSpec(spec); LOG_FUNC_WITH_PARAM(gImgLog, "imgRequest::~imgRequest()", - "keyuri", spec.get()); + "keyuri", mURI); } else LOG_FUNC(gImgLog, "imgRequest::~imgRequest()"); } nsresult imgRequest::Init(nsIURI *aURI, nsIURI *aFinalURI, bool aHadInsecureRedirect, @@ -106,27 +104,21 @@ imgRequest::Init(nsIURI *aURI, MOZ_ASSERT(!mImage, "Multiple calls to init"); MOZ_ASSERT(aURI, "No uri"); MOZ_ASSERT(aFinalURI, "No final uri"); MOZ_ASSERT(aRequest, "No request"); MOZ_ASSERT(aChannel, "No channel"); mProperties = do_CreateInstance("@mozilla.org/properties;1"); - - // Use ImageURL to ensure access to URI data off main thread. - nsresult rv; - mURI = new ImageURL(aURI, rv); - NS_ENSURE_SUCCESS(rv, rv); - + mURI = aURI; mFinalURI = aFinalURI; mRequest = aRequest; mChannel = aChannel; mTimedChannel = do_QueryInterface(mChannel); - mTriggeringPrincipal = aTriggeringPrincipal; mCORSMode = aCORSMode; mReferrerPolicy = aReferrerPolicy; // If the original URI and the final URI are different, check whether the // original URI is secure. We deliberately don't take the final URI into // account, as it needs to be handled using more complicated rules than // earlier elements of the redirect chain. @@ -260,22 +252,20 @@ imgRequest::RemoveProxy(imgRequestProxy* // been cancelled and thus removed from the cache, tell the image loader so // we can be evicted from the cache. if (mCacheEntry) { MOZ_ASSERT(mURI, "Removing last observer without key uri."); if (mLoader) { mLoader->SetHasNoProxies(this, mCacheEntry); } - } else if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { - nsAutoCString spec; - mURI->GetSpec(spec); + } else { LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy no cache entry", - "uri", spec.get()); + "uri", mURI); } /* If |aStatus| is a failure code, then cancel the load if it is still in progress. Otherwise, let the load continue, keeping 'this' in the cache with no observers. This way, if a proxy is destroyed without calling cancel on it, it won't leak and won't leave a bad pointer in the observer list. */ @@ -417,17 +407,17 @@ imgRequest::StartDecoding() bool imgRequest::IsDecodeRequested() const { MutexAutoLock lock(mMutex); return mDecodeRequested; } -nsresult imgRequest::GetURI(ImageURL** aURI) +nsresult imgRequest::GetURI(nsIURI** aURI) { MOZ_ASSERT(aURI); LOG_FUNC(gImgLog, "imgRequest::GetURI"); if (mURI) { *aURI = mURI; NS_ADDREF(*aURI); @@ -983,17 +973,17 @@ struct NewPartResult final RefPtr<image::Image> mImage; const bool mIsFirstPart; bool mSucceeded; bool mShouldResetCacheEntry; }; static NewPartResult PrepareForNewPart(nsIRequest* aRequest, nsIInputStream* aInStr, uint32_t aCount, - ImageURL* aURI, bool aIsMultipart, image::Image* aExistingImage, + nsIURI* aURI, bool aIsMultipart, image::Image* aExistingImage, ProgressTracker* aProgressTracker, uint32_t aInnerWindowId) { NewPartResult result(aExistingImage); if (aInStr) { mimetype_closure closure; closure.newType = &result.mContentType;
--- a/image/imgRequest.h +++ b/image/imgRequest.h @@ -30,32 +30,30 @@ class nsIApplicationCache; class nsIProperties; class nsIRequest; class nsITimedChannel; class nsIURI; namespace mozilla { namespace image { class Image; -class ImageURL; class ProgressTracker; } // namespace image } // namespace mozilla struct NewPartResult; class imgRequest final : public nsIStreamListener, public nsIThreadRetargetableStreamListener, public nsIChannelEventSink, public nsIInterfaceRequestor, public nsIAsyncVerifyRedirectCallback { typedef mozilla::image::Image Image; typedef mozilla::image::ImageCacheKey ImageCacheKey; - typedef mozilla::image::ImageURL ImageURL; typedef mozilla::image::ProgressTracker ProgressTracker; typedef mozilla::net::ReferrerPolicy ReferrerPolicy; public: imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey); NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSISTREAMLISTENER @@ -146,17 +144,17 @@ public: /// Get the ImageCacheKey associated with this request. const ImageCacheKey& CacheKey() const { return mCacheKey; } // Resize the cache entry to 0 if it exists void ResetCacheEntry(); // OK to use on any thread. - nsresult GetURI(ImageURL** aURI); + nsresult GetURI(nsIURI** aURI); nsresult GetFinalURI(nsIURI** aURI); bool IsScheme(const char* aScheme) const; bool IsChrome() const; bool IsData() const; nsresult GetImageErrorCode(void); /// Returns true if we've received any data. @@ -230,17 +228,17 @@ private: void AdjustPriorityInternal(int32_t aDelta); // Weak reference to parent loader; this request cannot outlive its owner. imgLoader* mLoader; nsCOMPtr<nsIRequest> mRequest; // The original URI we were loaded with. This is the same as the URI we are // keyed on in the cache. We store a string here to avoid off main thread // refcounting issues with nsStandardURL. - RefPtr<ImageURL> mURI; + nsCOMPtr<nsIURI> mURI; // The URI of the resource we ended up loading after all redirects, etc. nsCOMPtr<nsIURI> mFinalURI; // The principal which triggered the load of this image. Generally either // the principal of the document the image is being loaded into, or of the // stylesheet which specified the image to load. Used when validating for CORS. nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; // The principal of this image. nsCOMPtr<nsIPrincipal> mPrincipal;
--- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -175,17 +175,17 @@ imgRequestProxy::~imgRequestProxy() RemoveFromLoadGroup(); LOG_FUNC(gImgLog, "imgRequestProxy::~imgRequestProxy"); } nsresult imgRequestProxy::Init(imgRequest* aOwner, nsILoadGroup* aLoadGroup, nsIDocument* aLoadingDocument, - ImageURL* aURI, + nsIURI* aURI, imgINotificationObserver* aObserver) { MOZ_ASSERT(!GetOwner() && !mListener, "imgRequestProxy is already initialized"); LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", aOwner); @@ -767,43 +767,31 @@ imgRequestProxy::GetImageErrorCode(nsres return NS_OK; } NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI** aURI) { MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread to convert URI"); - nsCOMPtr<nsIURI> uri = mURI->ToIURI(); + nsCOMPtr<nsIURI> uri = mURI; uri.forget(aURI); return NS_OK; } nsresult imgRequestProxy::GetFinalURI(nsIURI** aURI) { if (!GetOwner()) { return NS_ERROR_FAILURE; } return GetOwner()->GetFinalURI(aURI); } -nsresult -imgRequestProxy::GetURI(ImageURL** aURI) -{ - if (!mURI) { - return NS_ERROR_FAILURE; - } - - NS_ADDREF(*aURI = mURI); - - return NS_OK; -} - NS_IMETHODIMP imgRequestProxy::GetNotificationObserver(imgINotificationObserver** aObserver) { *aObserver = mListener; NS_IF_ADDREF(*aObserver); return NS_OK; } @@ -1090,22 +1078,18 @@ imgRequestProxy::Notify(int32_t aType, c nsCOMPtr<imgINotificationObserver> listener(mListener); listener->Notify(this, aType, aRect); } void imgRequestProxy::OnLoadComplete(bool aLastPart) { - if (MOZ_LOG_TEST(gImgLog, LogLevel::Debug)) { - nsAutoCString name; - GetName(name); - LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnLoadComplete", - "name", name.get()); - } + LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnLoadComplete", + "uri", mURI); // There's all sorts of stuff here that could kill us (the OnStopRequest call // on the listener, the removal from the loadgroup, the release of the // listener, etc). Don't let them do it. RefPtr<imgRequestProxy> self(this); if (!IsOnEventTarget()) { DispatchWithTarget(NS_NewRunnableFunction("imgRequestProxy::OnLoadComplete",
--- a/image/imgRequestProxy.h +++ b/image/imgRequestProxy.h @@ -37,33 +37,31 @@ class ProxyBehaviour; namespace mozilla { namespace dom { class TabGroup; } namespace image { class Image; -class ImageURL; class ProgressTracker; } // namespace image } // namespace mozilla class imgRequestProxy : public imgIRequest, public mozilla::image::IProgressObserver, public nsISupportsPriority, public nsISecurityInfoProvider, public nsITimedChannel { protected: virtual ~imgRequestProxy(); public: typedef mozilla::image::Image Image; - typedef mozilla::image::ImageURL ImageURL; typedef mozilla::image::ProgressTracker ProgressTracker; MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy) NS_DECL_ISUPPORTS NS_DECL_IMGIREQUEST NS_DECL_NSIREQUEST NS_DECL_NSISUPPORTSPRIORITY NS_DECL_NSISECURITYINFOPROVIDER @@ -71,17 +69,17 @@ public: imgRequestProxy(); // Callers to Init or ChangeOwner are required to call NotifyListener after // (although not immediately after) doing so. nsresult Init(imgRequest* aOwner, nsILoadGroup* aLoadGroup, nsIDocument* aLoadingDocument, - ImageURL* aURI, + nsIURI* aURI, imgINotificationObserver* aObserver); nsresult ChangeOwner(imgRequest* aNewOwner); // this will change mOwner. // Do not call this if the // previous owner has already // sent notifications out! // Add the request to the load group, if any. This should only be called once @@ -145,18 +143,16 @@ public: nsIDocument* aLoadingDocument, imgRequestProxy** aClone); nsresult Clone(imgINotificationObserver* aObserver, nsIDocument* aLoadingDocument, imgRequestProxy** aClone); nsresult GetStaticRequest(nsIDocument* aLoadingDocument, imgRequestProxy** aReturn); - nsresult GetURI(ImageURL** aURI); - protected: friend class mozilla::image::ProgressTracker; friend class imgStatusNotifyRunnable; class imgCancelRunnable; friend class imgCancelRunnable; class imgCancelRunnable : public mozilla::Runnable @@ -225,17 +221,17 @@ private: void AddToOwner(nsIDocument* aLoadingDocument); void RemoveFromOwner(nsresult aStatus); nsresult DispatchWithTargetIfAvailable(already_AddRefed<nsIRunnable> aEvent); void DispatchWithTarget(already_AddRefed<nsIRunnable> aEvent); // The URI of our request. - RefPtr<ImageURL> mURI; + nsCOMPtr<nsIURI> mURI; // mListener is only promised to be a weak ref (see imgILoader.idl), // but we actually keep a strong ref to it until we've seen our // first OnStopRequest. imgINotificationObserver* MOZ_UNSAFE_REF("Observers must call Cancel() or " "CancelAndForgetObserver() before " "they are destroyed") mListener;
--- a/image/imgTools.cpp +++ b/image/imgTools.cpp @@ -13,16 +13,17 @@ #include "mozilla/RefPtr.h" #include "nsCOMPtr.h" #include "nsIDocument.h" #include "nsError.h" #include "imgLoader.h" #include "imgICache.h" #include "imgIContainer.h" #include "imgIEncoder.h" +#include "nsNetUtil.h" // for NS_NewBufferedInputStream #include "nsStreamUtils.h" #include "nsStringStream.h" #include "nsContentUtils.h" #include "nsProxyRelease.h" #include "ImageFactory.h" #include "Image.h" #include "ScriptedNotificationObserver.h" #include "imgIScriptedNotificationObserver.h"
--- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -622,32 +622,38 @@ AddAppDirToCommandLine(std::vector<std:: } bool GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts) { // We rely on the fact that InitializeChannel() has already been processed // on the IO thread before this point is reached. if (!GetChannel()) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(1 == 2); +#endif return false; } base::ProcessHandle process = 0; // send the child the PID so that it can open a ProcessHandle back to us. // probably don't want to do this in the long run char pidstring[32]; SprintfLiteral(pidstring, "%d", base::GetCurrentProcId()); const char* const childProcessType = XRE_ChildProcessTypeToString(mProcessType); PRFileDesc* crashAnnotationReadPipe; PRFileDesc* crashAnnotationWritePipe; if (PR_CreatePipe(&crashAnnotationReadPipe, &crashAnnotationWritePipe) != PR_SUCCESS) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(2 == 3); +#endif return false; } //-------------------------------------------------- #if defined(OS_POSIX) // For POSIX, we have to be extremely anal about *not* using // std::wstring in code compiled with Mozilla's -fshort-wchar // configuration, because chromium is compiled with -fno-short-wchar @@ -828,27 +834,36 @@ GeckoChildProcessHost::PerformAsyncLaunc const int kTimeoutMs = 10000; MachReceiveMessage child_message; ReceivePort parent_recv_port(mach_connection_name.c_str()); kern_return_t err = parent_recv_port.WaitForMessage(&child_message, kTimeoutMs); if (err != KERN_SUCCESS) { std::string errString = StringPrintf("0x%x %s", err, mach_error_string(err)); CHROMIUM_LOG(ERROR) << "parent WaitForMessage() failed: " << errString; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(3 == 4); +#endif return false; } task_t child_task = child_message.GetTranslatedPort(0); if (child_task == MACH_PORT_NULL) { CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(0) failed."; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(4 == 5); +#endif return false; } if (child_message.GetTranslatedPort(1) == MACH_PORT_NULL) { CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(1) failed."; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(5 == 6); +#endif return false; } MachPortSender parent_sender(child_message.GetTranslatedPort(1)); if (child_message.GetTranslatedPort(2) == MACH_PORT_NULL) { CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(2) failed."; } auto* parent_recv_port_memory_ack = new MachPortSender(child_message.GetTranslatedPort(2)); @@ -856,35 +871,47 @@ GeckoChildProcessHost::PerformAsyncLaunc if (child_message.GetTranslatedPort(3) == MACH_PORT_NULL) { CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(3) failed."; } auto* parent_send_port_memory = new MachPortSender(child_message.GetTranslatedPort(3)); MachSendMessage parent_message(/* id= */0); if (!parent_message.AddDescriptor(MachMsgPortDescriptor(bootstrap_port))) { CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << bootstrap_port << ") failed."; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(6 == 7); +#endif return false; } auto* parent_recv_port_memory = new ReceivePort(); if (!parent_message.AddDescriptor(MachMsgPortDescriptor(parent_recv_port_memory->GetPort()))) { CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << parent_recv_port_memory->GetPort() << ") failed."; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(7 == 8); +#endif return false; } auto* parent_send_port_memory_ack = new ReceivePort(); if (!parent_message.AddDescriptor(MachMsgPortDescriptor(parent_send_port_memory_ack->GetPort()))) { CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << parent_send_port_memory_ack->GetPort() << ") failed."; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(8 == 9); +#endif return false; } err = parent_sender.SendMessage(parent_message, kTimeoutMs); if (err != KERN_SUCCESS) { std::string errString = StringPrintf("0x%x %s", err, mach_error_string(err)); CHROMIUM_LOG(ERROR) << "parent SendMessage() failed: " << errString; +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(9 == 10); +#endif return false; } SharedMemoryBasic::SetupMachMemory(process, parent_recv_port_memory, parent_recv_port_memory_ack, parent_send_port_memory, parent_send_port_memory_ack, false); # endif // MOZ_WIDGET_COCOA @@ -943,26 +970,32 @@ GeckoChildProcessHost::PerformAsyncLaunc } # endif // defined(MOZ_CONTENT_SANDBOX) break; case GeckoProcessType_Plugin: if (mSandboxLevel > 0 && !PR_GetEnv("MOZ_DISABLE_NPAPI_SANDBOX")) { bool ok = mSandboxBroker.SetSecurityLevelForPluginProcess(mSandboxLevel); if (!ok) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(10 == 11); +#endif return false; } shouldSandboxCurrentProcess = true; } break; #ifdef MOZ_ENABLE_SKIA_PDF case GeckoProcessType_PDFium: if (!PR_GetEnv("MOZ_DISABLE_PDFIUM_SANDBOX")) { bool ok = mSandboxBroker.SetSecurityLevelForPDFiumProcess(); if (!ok) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(11 == 12); +#endif return false; } shouldSandboxCurrentProcess = true; } break; #endif case GeckoProcessType_IPDLUnitTest: // XXX: We don't sandbox this process type yet @@ -973,16 +1006,19 @@ GeckoChildProcessHost::PerformAsyncLaunc // not at USER_LOCKDOWN. So look in the command line arguments // to see if we're loading the path to the Widevine CDM, and if // so use sandbox level USER_RESTRICTED instead of USER_LOCKDOWN. bool isWidevine = std::any_of(aExtraOpts.begin(), aExtraOpts.end(), [](const std::string arg) { return arg.find("gmp-widevinecdm") != std::string::npos; }); auto level = isWidevine ? SandboxBroker::Restricted : SandboxBroker::LockDown; bool ok = mSandboxBroker.SetSecurityLevelForGMPlugin(level); if (!ok) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(12 == 13); +#endif return false; } shouldSandboxCurrentProcess = true; } break; case GeckoProcessType_GPU: if (mSandboxLevel > 0 && !PR_GetEnv("MOZ_DISABLE_GPU_SANDBOX")) { // For now we treat every failure as fatal in SetSecurityLevelForGPUProcess @@ -1082,16 +1118,19 @@ GeckoChildProcessHost::PerformAsyncLaunc # endif // MOZ_SANDBOX } #else // goes with defined(OS_POSIX) # error Sorry #endif // defined(OS_POSIX) if (!process) { +#ifdef ASYNC_CONTENTPROC_LAUNCH + MOZ_RELEASE_ASSERT(13 == 14); +#endif return false; } // NB: on OS X, we block much longer than we need to in order to // reach this call, waiting for the child process's task_t. The // best way to fix that is to refactor this file, hard. #if defined(MOZ_WIDGET_COCOA) mChildTask = child_task; #endif // defined(MOZ_WIDGET_COCOA)
--- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -1153,16 +1153,18 @@ function ArrayFlat(/* depth */) { // Step 6. FlattenIntoArray(A, O, sourceLen, 0, depthNum); // Step 7. return A; } +// https://tc39.github.io/proposal-flatMap/ +// May 23, 2018 function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunction, thisArg) { // Step 1. var targetIndex = start; // Steps 2-3. for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) { // Steps 3.a-c. if (sourceIndex in source) { @@ -1173,34 +1175,40 @@ function FlattenIntoArray(target, source // Step 3.c.ii.1. assert(arguments.length === 7, "thisArg is present"); // Step 3.c.ii.2. element = callContentFunction(mapperFunction, thisArg, element, sourceIndex, source); } // Step 3.c.iii. - var flattenable = IsArray(element); + var shouldFlatten = false; // Step 3.c.iv. - if (flattenable && depth > 0) { + if (depth > 0) { // Step 3.c.iv.1. + shouldFlatten = IsArray(element); + } + + // Step 3.c.v. + if (shouldFlatten) { + // Step 3.c.v.1. var elementLen = ToLength(element.length); - // Step 3.c.iv.2. + // Step 3.c.v.2. targetIndex = FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1); } else { - // Step 3.c.v.1. + // Step 3.c.vi.1. if (targetIndex >= MAX_NUMERIC_INDEX) ThrowTypeError(JSMSG_TOO_LONG_ARRAY); - // Step 3.c.v.2. + // Step 3.c.vi.2. _DefineDataProperty(target, targetIndex, element); - // Step 3.c.v.3. + // Step 3.c.vi.3. targetIndex++; } } } // Step 4. return targetIndex; }
--- a/layout/generic/nsFrameStateBits.h +++ b/layout/generic/nsFrameStateBits.h @@ -333,22 +333,34 @@ FRAME_STATE_GROUP(GridContainer, nsGridC FRAME_STATE_BIT(GridContainer, 20, NS_STATE_GRID_NORMAL_FLOW_CHILDREN_IN_CSS_ORDER) // True iff some first-in-flow in-flow children were pushed. // Note that those child frames may have been removed without this bit // being updated for performance reasons, so code shouldn't depend on // actually finding any pushed items when this bit is set. FRAME_STATE_BIT(GridContainer, 21, NS_STATE_GRID_DID_PUSH_ITEMS) -// True iff computed grid values should be generated on the next reflow +// True iff computed grid values should be generated on the next reflow. FRAME_STATE_BIT(GridContainer, 22, NS_STATE_GRID_GENERATE_COMPUTED_VALUES) -// True if the container has no grid items; may lie if there is a pending reflow +// True if the container has no grid items; may lie if there is a pending reflow. FRAME_STATE_BIT(GridContainer, 23, NS_STATE_GRID_SYNTHESIZE_BASELINE) +// True if the container is a subgrid in its inline axis. +FRAME_STATE_BIT(GridContainer, 24, NS_STATE_GRID_IS_COL_SUBGRID) + +// True if the container is a subgrid in its block axis. +FRAME_STATE_BIT(GridContainer, 25, NS_STATE_GRID_IS_ROW_SUBGRID) + +// The container contains one or more items subgridded in its inline axis. +FRAME_STATE_BIT(GridContainer, 26, NS_STATE_GRID_HAS_COL_SUBGRID_ITEM) + +// The container contains one or more items subgridded in its block axis. +FRAME_STATE_BIT(GridContainer, 27, NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM) + // == Frame state bits that apply to SVG frames =============================== FRAME_STATE_GROUP(SVG, nsSVGDisplayableFrame) FRAME_STATE_GROUP(SVG, nsSVGContainerFrame) FRAME_STATE_BIT(SVG, 20, NS_STATE_IS_OUTER_SVG) // If this bit is set, we are a <clipPath> element or descendant.
--- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -23,16 +23,17 @@ #include "mozilla/Poison.h" #include "nsAbsoluteContainingBlock.h" #include "nsAlgorithm.h" // for clamped() #include "nsCSSAnonBoxes.h" #include "nsCSSFrameConstructor.h" #include "nsDataHashtable.h" #include "nsDisplayList.h" #include "nsHashKeys.h" +#include "nsFieldSetFrame.h" #include "nsIFrameInlines.h" #include "nsPresContext.h" #include "nsReadableUtils.h" #include "nsTableWrapperFrame.h" using namespace mozilla; typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags; @@ -540,29 +541,54 @@ struct nsGridContainerFrame::GridItemInf // Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline. eContentBaseline = 0x10, eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline, // Should apply Automatic Minimum Size per: // https://drafts.csswg.org/css-grid/#min-size-auto eApplyAutoMinSize = 0x20, // Clamp per https://drafts.csswg.org/css-grid/#min-size-auto eClampMarginBoxMinSize = 0x40, + eIsSubgrid = 0x80, }; explicit GridItemInfo(nsIFrame* aFrame, const GridArea& aArea) : mFrame(aFrame) , mArea(aArea) { mState[eLogicalAxisBlock] = StateBits(0); mState[eLogicalAxisInline] = StateBits(0); + nsIFrame* innerFrame = InnerFrame(mFrame); + if (innerFrame->IsGridContainerFrame()) { + const auto* f = static_cast<nsGridContainerFrame*>(innerFrame); + auto parentWM = aFrame->GetParent()->GetWritingMode(); + bool isOrthogonal = parentWM.IsOrthogonalTo(f->GetWritingMode()); + if (f->IsColSubgrid()) { + mState[isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline] = + StateBits::eIsSubgrid; + } + if (f->IsRowSubgrid()) { + mState[isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock] = + StateBits::eIsSubgrid; + } + } mBaselineOffset[eLogicalAxisBlock] = nscoord(0); mBaselineOffset[eLogicalAxisInline] = nscoord(0); } + // Is this item a subgrid in the given container axis? + bool IsSubgrid(LogicalAxis aAxis) const { + return mState[aAxis] & StateBits::eIsSubgrid; + } + + // Is this item a subgrid in either axis? + bool IsSubgrid() const { + return IsSubgrid(eLogicalAxisInline) || IsSubgrid(eLogicalAxisBlock); + } + /** * If the item is [align|justify]-self:[last ]baseline aligned in the given * axis then set aBaselineOffset to the baseline offset and return aAlign. * Otherwise, return a fallback alignment. */ uint8_t GetSelfBaseline(uint8_t aAlign, LogicalAxis aAxis, nscoord* aBaselineOffset) const { @@ -606,16 +632,27 @@ struct nsGridContainerFrame::GridItemInf void Dump() const; #endif static bool IsStartRowLessThan(const GridItemInfo* a, const GridItemInfo* b) { return a->mArea.mRows.mStart < b->mArea.mRows.mStart; } + // Return the inner frame of aFrame that might be a grid container. + // This drills down through scroll frames and such. + static nsIFrame* InnerFrame(nsIFrame* aFrame) + { + nsIFrame* inner = aFrame; + if (MOZ_UNLIKELY(aFrame->IsFieldSetFrame())) { + inner = static_cast<nsFieldSetFrame*>(aFrame)->GetInner(); + } + return inner->GetContentInsertionFrame(); + } + nsIFrame* const mFrame; GridArea mArea; // Offset from the margin edge to the baseline (LogicalAxis index). It's from // the start edge when eFirstBaseline is set, end edge otherwise. It's mutable // since we update the value fairly late (just before reflowing the item). mutable nscoord mBaselineOffset[2]; mutable StateBits mState[2]; // state bits per axis (LogicalAxis index) static_assert(mozilla::eLogicalAxisBlock == 0, "unexpected index value"); @@ -631,16 +668,19 @@ void nsGridContainerFrame::GridItemInfo::Dump() const { auto Dump1 = [this] (const char* aMsg, LogicalAxis aAxis) { auto state = mState[aAxis]; if (!state) { return; } printf("%s", aMsg); + if (state & ItemState::eIsSubgrid) { + printf("subgrid "); + } if (state & ItemState::eIsFlexing) { printf("flexing "); } if (state & ItemState::eApplyAutoMinSize) { printf("auto-min-size "); } if (state & ItemState::eClampMarginBoxMinSize) { printf("clamp "); @@ -3126,16 +3166,20 @@ nsGridContainerFrame::Grid::PlaceGridIte const LogicalSize& aComputedMinSize, const LogicalSize& aComputedSize, const LogicalSize& aComputedMaxSize) { mAreas = aState.mFrame->GetImplicitNamedAreas(); const nsStylePosition* const gridStyle = aState.mGridStyle; MOZ_ASSERT(mCellMap.mCells.IsEmpty(), "unexpected entries in cell map"); + // SubgridPlaceGridItems will set these if we find any subgrid items. + aState.mFrame->RemoveStateBits(NS_STATE_GRID_HAS_COL_SUBGRID_ITEM | + NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM); + // http://dev.w3.org/csswg/css-grid/#grid-definition // Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End). // This is determined by the larger of the number of rows/columns defined // by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one. // Also initialize the Implicit Grid (mGridCol[Row]End) to the same values. // Note that this is for a grid with a 1,1 origin. We'll change that // to a 0,0 based grid after placing definite lines. auto areas = gridStyle->mGridTemplateAreas.get(); @@ -4116,17 +4160,17 @@ nsGridContainerFrame::Tracks::Initialize (ItemState::eSelfBaseline | ItemState::eContentBaseline)) != (ItemState::eSelfBaseline | ItemState::eContentBaseline), "*-self and *-content baseline bits are mutually exclusive"); MOZ_ASSERT(!(state & (ItemState::eFirstBaseline | ItemState::eLastBaseline)) == !(state & (ItemState::eSelfBaseline | ItemState::eContentBaseline)), "first/last bit requires self/content bit and vice versa"); - gridItem.mState[mAxis] = state; + gridItem.mState[mAxis] |= state; gridItem.mBaselineOffset[mAxis] = nscoord(0); } if (firstBaselineItems.IsEmpty() && lastBaselineItems.IsEmpty()) { return; } // TODO: CSS Align spec issue - how to align a baseline subtree in a track? @@ -6325,16 +6369,48 @@ nsGridContainerFrame::Reflow(nsPresConte DeleteProperty(SharedGridData::Prop()); } } FinishAndStoreOverflow(&aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } +void +nsGridContainerFrame::Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) +{ + nsContainerFrame::Init(aContent, aParent, aPrevInFlow); + + nsFrameState bits = nsFrameState(0); + if (MOZ_LIKELY(!aPrevInFlow)) { + // skip our scroll frame and such if we have it + auto* parent = aParent; + while (parent && parent->GetContent() == aContent) { + parent = parent->GetParent(); + } + if (parent && parent->IsGridContainerFrame()) { + const auto* pos = StylePosition(); + if (pos->GridTemplateColumns().mIsSubgrid) { + bits |= NS_STATE_GRID_IS_COL_SUBGRID; + } + if (pos->GridTemplateRows().mIsSubgrid) { + bits |= NS_STATE_GRID_IS_ROW_SUBGRID; + } + } + } else { + bits = aPrevInFlow->GetStateBits() & (NS_STATE_GRID_IS_COL_SUBGRID | + NS_STATE_GRID_IS_ROW_SUBGRID | + NS_STATE_GRID_HAS_COL_SUBGRID_ITEM | + NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM); + } + AddStateBits(bits); +} + nscoord nsGridContainerFrame::IntrinsicISize(gfxContext* aRenderingContext, IntrinsicISizeType aType) { RenumberList(); // Calculate the sum of column sizes under intrinsic sizing. // http://dev.w3.org/csswg/css-grid/#intrinsic-sizes
--- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -92,16 +92,18 @@ public: typedef mozilla::ComputedGridTrackInfo ComputedGridTrackInfo; typedef mozilla::ComputedGridLineInfo ComputedGridLineInfo; // nsIFrame overrides void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + void Init(nsIContent* aContent, nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; nscoord GetMinISize(gfxContext* aRenderingContext) override; nscoord GetPrefISize(gfxContext* aRenderingContext) override; void MarkIntrinsicISizesDirty() override; bool IsFrameOfType(uint32_t aFlags) const override { return nsContainerFrame::IsFrameOfType(aFlags & ~nsIFrame::eCanContainOverflowContainers); } @@ -212,16 +214,42 @@ public: typedef nsTArray<mozilla::css::GridNamedArea> ExplicitNamedAreas; NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty, ExplicitNamedAreas) ExplicitNamedAreas* GetExplicitNamedAreas() const { return GetProperty(ExplicitNamedAreasProperty()); } + /** Return true if this frame is subgridded in its aAxis. */ + bool IsSubgrid(mozilla::LogicalAxis aAxis) const { + return HasAnyStateBits( + aAxis == mozilla::eLogicalAxisBlock ? NS_STATE_GRID_IS_ROW_SUBGRID + : NS_STATE_GRID_IS_COL_SUBGRID); + } + bool IsColSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisInline); } + bool IsRowSubgrid() const { return IsSubgrid(mozilla::eLogicalAxisBlock); } + /** Return true if this frame is subgridded in any axis. */ + bool IsSubgrid() const { + return HasAnyStateBits(NS_STATE_GRID_IS_ROW_SUBGRID | + NS_STATE_GRID_IS_COL_SUBGRID); + } + + /** Return true if this frame has an item that is subgridded in our aAxis. */ + bool HasSubgridItems(mozilla::LogicalAxis aAxis) const { + return HasAnyStateBits( + aAxis == mozilla::eLogicalAxisBlock ? NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM + : NS_STATE_GRID_HAS_COL_SUBGRID_ITEM); + } + /** Return true if this frame has any subgrid items. */ + bool HasSubgridItems() const { + return HasAnyStateBits(NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM | + NS_STATE_GRID_HAS_COL_SUBGRID_ITEM); + } + /** * Return a containing grid frame, and ensure it has computed grid info * @return nullptr if aFrame has no grid container, or frame was destroyed * @note this might destroy layout/style data since it may flush layout */ static nsGridContainerFrame* GetGridFrameWithComputedInfo(nsIFrame* aFrame); struct TrackSize;
--- a/layout/style/test/test_font_loading_api.html +++ b/layout/style/test/test_font_loading_api.html @@ -223,18 +223,18 @@ function runTest() { is(Object.getPrototypeOf(FontFaceSetLoadEvent.prototype), Event.prototype, "FontFaceSetLoadEvent should inherit from Event (TEST 2)"); }).then(function() { // (TEST 3) Test that document.fonts.ready is resolved with the // document.fonts FontFaceSet. var p = Promise.resolve(); sourceDocuments.forEach(function({ doc, what }) { - p = p.then(doc.fonts.ready).then(function() { - return is_resolved_with(doc.fonts.ready, doc.fonts, "document.fonts.ready resolves with document.fonts", "(TEST 3) (" + what + ")"); + p = p.then(_ => { return doc.fonts.ready }).then(function() { + return is_resolved_with(doc.fonts.ready, doc.fonts, "document.fonts.ready resolves with document.fonts.", "(TEST 3) (" + what + ")"); }); }); return p; }).then(function() { // (TEST 4) Test that document.fonts in this test document starts out with no // FontFace objects in it.
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoVRManager.java @@ -5,121 +5,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; import org.mozilla.gecko.annotation.WrapForJNI; import org.mozilla.gecko.util.ThreadUtils; public class GeckoVRManager { - /** - * GeckoView applications implement this interface to provide GVR support for WebVR. - */ - public interface GVRDelegate { - /** - * Creates non-presenting context. Will be invoked in the compositor thread. - */ - long createNonPresentingContext(); - /** - * Destroys non-presenting context. Will be invoked in the compositor thread. - */ - void destroyNonPresentingContext(); - /** - * Called when WebVR needs a presenting context. Will be invoked in the UI thread. - */ - boolean enableVRMode(); - /** - * Called when WebVR has finished presenting. Will be invoked in the UI thread. - */ - void disableVRMode(); - } - - private static GVRDelegate mGVRDelegate; - - /** - * Set the GVR Delegate for GeckoView. - * @param delegate GVRDelegate instance or null to unset. - */ - public static void setGVRDelegate(GVRDelegate delegate) { - mGVRDelegate = delegate; - } - - /** - * Set the GVR paused state. - * @param aPaused True if the application is being paused, False if the - * application is resuming. - */ - @WrapForJNI(calledFrom = "ui") - public static native void setGVRPaused(final boolean aPaused); - - /** - * Set the GVR presenting context. - * @param aContext GVR context to use when WebVR starts to present. Pass in - * zero to stop presenting. - */ - @WrapForJNI(calledFrom = "ui") - public static native void setGVRPresentingContext(final long aContext); - - /** - * Inform WebVR that the non-presenting context needs to be destroyed. - */ - @WrapForJNI(calledFrom = "ui") - public static native void cleanupGVRNonPresentingContext(); + private static long mExternalContext; @WrapForJNI - /* package */ static boolean isGVRPresent() { - return mGVRDelegate != null; - } - - @WrapForJNI - /* package */ static long createGVRNonPresentingContext() { - if (mGVRDelegate == null) { - return 0; - } - return mGVRDelegate.createNonPresentingContext(); - } - - @WrapForJNI - /* package */ static void destroyGVRNonPresentingContext() { - if (mGVRDelegate == null) { - return; - } - mGVRDelegate.destroyNonPresentingContext(); + public static synchronized long getExternalContext() { + return mExternalContext; } - @WrapForJNI - /* package */ static void enableVRMode() { - if (!ThreadUtils.isOnUiThread()) { - ThreadUtils.postToUiThread(new Runnable() { - @Override - public void run() { - enableVRMode(); - } - }); - return; - } - - if (mGVRDelegate == null) { - return; - } - - mGVRDelegate.enableVRMode(); + public static synchronized void setExternalContext(final long externalContext) { + mExternalContext = externalContext; } - @WrapForJNI - /* package */ static void disableVRMode() { - if (!ThreadUtils.isOnUiThread()) { - ThreadUtils.postToUiThread(new Runnable() { - @Override - public void run() { - disableVRMode(); - } - }); - return; - } - - if (mGVRDelegate == null) { - return; - } - - mGVRDelegate.disableVRMode(); - } }
--- a/mobile/android/geckoview/src/thirdparty/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java +++ b/mobile/android/geckoview/src/thirdparty/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java @@ -26,23 +26,26 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.NoRouteToHostException; import java.net.ProtocolException; +import java.net.URISyntaxException; import java.net.URL; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.mozilla.gecko.util.ProxySelector; + /** * An {@link HttpDataSource} that uses Android's {@link HttpURLConnection}. * <p> * By default this implementation will not follow cross-protocol redirects (i.e. redirects from * HTTP to HTTPS or vice versa). Cross-protocol redirects can be enabled by using the * {@link #DefaultHttpDataSource(String, Predicate, TransferListener, int, int, boolean, * RequestProperties)} constructor and passing {@code true} as the second last argument. */ @@ -188,16 +191,18 @@ public class DefaultHttpDataSource imple this.dataSpec = dataSpec; this.bytesRead = 0; this.bytesSkipped = 0; try { connection = makeConnection(dataSpec); } catch (IOException e) { throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e, dataSpec, HttpDataSourceException.TYPE_OPEN); + } catch (URISyntaxException e) { + throw new HttpDataSourceException("URI invalid: " + dataSpec.uri.toString(), dataSpec, HttpDataSourceException.TYPE_OPEN); } int responseCode; try { responseCode = connection.getResponseCode(); } catch (IOException e) { closeConnectionQuietly(); throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e, @@ -332,17 +337,17 @@ public class DefaultHttpDataSource imple */ protected final long bytesRemaining() { return bytesToRead == C.LENGTH_UNSET ? bytesToRead : bytesToRead - bytesRead; } /** * Establishes a connection, following redirects to do so where permitted. */ - private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException { + private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException, URISyntaxException { URL url = new URL(dataSpec.uri.toString()); byte[] postBody = dataSpec.postBody; long position = dataSpec.position; long length = dataSpec.length; boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP); if (!allowCrossProtocolRedirects) { // HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection @@ -384,18 +389,24 @@ public class DefaultHttpDataSource imple * @param url The url to connect to. * @param postBody The body data for a POST request. * @param position The byte offset of the requested data. * @param length The length of the requested data, or {@link C#LENGTH_UNSET}. * @param allowGzip Whether to allow the use of gzip. * @param followRedirects Whether to follow redirects. */ private HttpURLConnection makeConnection(URL url, byte[] postBody, long position, - long length, boolean allowGzip, boolean followRedirects) throws IOException { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + long length, boolean allowGzip, boolean followRedirects) throws IOException, URISyntaxException { + /** + * Tor Project modified the way the connection object was created. For the sake of + * simplicity, instead of duplicating the whole file we changed the connection object + * to use the ProxySelector. + */ + HttpURLConnection connection = (HttpURLConnection) ProxySelector.openConnectionWithProxy(url.toURI()); + connection.setConnectTimeout(connectTimeoutMillis); connection.setReadTimeout(readTimeoutMillis); if (defaultRequestProperties != null) { for (Map.Entry<String, String> property : defaultRequestProperties.getSnapshot().entrySet()) { connection.setRequestProperty(property.getKey(), property.getValue()); } } for (Map.Entry<String, String> property : requestProperties.getSnapshot().entrySet()) {
--- a/modules/libpref/StaticPrefs.h +++ b/modules/libpref/StaticPrefs.h @@ -2,16 +2,21 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 mozilla_StaticPrefs_h #define mozilla_StaticPrefs_h +#include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" +#include "mozilla/TypeTraits.h" +#include "MainThreadUtils.h" + namespace mozilla { // These typedefs are for use within StaticPrefList.h. typedef const char* String; typedef Atomic<bool, Relaxed> RelaxedAtomicBool; typedef Atomic<bool, ReleaseAcquire> ReleaseAcquireAtomicBool; @@ -37,35 +42,46 @@ template<typename T, MemoryOrdering Orde struct StripAtomicImpl<Atomic<T, Order>> { typedef T Type; }; template<typename T> using StripAtomic = typename StripAtomicImpl<T>::Type; +template<typename T> +struct IsAtomic : FalseType {}; + +template<typename T, MemoryOrdering Order> +struct IsAtomic<Atomic<T, Order>> : TrueType {}; + class StaticPrefs { // For a VarCache pref like this: // // VARCACHE_PREF("my.varcache", my_varcache, int32_t, 99) // // we generate a static variable declaration and a getter definition: // // private: // static int32_t sVarCache_my_varcache; // public: // static int32_t my_varcache() { return sVarCache_my_varcache; } // -#define PREF(str, cpp_type, value) -#define VARCACHE_PREF(str, id, cpp_type, value) \ +#define PREF(str, cpp_type, default_value) +#define VARCACHE_PREF(str, id, cpp_type, default_value) \ private: \ static cpp_type sVarCache_##id; \ public: \ - static StripAtomic<cpp_type> id() { return sVarCache_##id; } + static StripAtomic<cpp_type> id() { \ + MOZ_ASSERT(IsAtomic<cpp_type>::value || NS_IsMainThread(), \ + "Non-atomic static pref '" str \ + "' being accessed on background thread"); \ + return sVarCache_##id; \ + } #include "mozilla/StaticPrefList.h" #undef PREF #undef VARCACHE_PREF public: static void InitAll(bool aIsStartup); };
--- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -79,17 +79,17 @@ //--------------------------------------------------------------------------- // Accessibility prefs //--------------------------------------------------------------------------- VARCACHE_PREF( "accessibility.monoaudio.enable", accessibility_monoaudio_enable, - bool, false + RelaxedAtomicBool, false ) //--------------------------------------------------------------------------- // DOM prefs //--------------------------------------------------------------------------- VARCACHE_PREF( "dom.webcomponents.shadowdom.report_usage", @@ -143,25 +143,25 @@ VARCACHE_PREF( ) // Time in milliseconds between the time a network buffer is seen and the timer // firing when the timer hasn't fired previously in this parse in the // off-the-main-thread HTML5 parser. VARCACHE_PREF( "html5.flushtimer.initialdelay", html5_flushtimer_initialdelay, - int32_t, 120 + RelaxedAtomicInt32, 120 ) // Time in milliseconds between the time a network buffer is seen and the timer // firing when the timer has already fired previously in this parse. VARCACHE_PREF( "html5.flushtimer.subsequentdelay", html5_flushtimer_subsequentdelay, - int32_t, 120 + RelaxedAtomicInt32, 120 ) //--------------------------------------------------------------------------- // Layout prefs //--------------------------------------------------------------------------- // Is parallel CSS parsing enabled? VARCACHE_PREF( @@ -354,17 +354,17 @@ VARCACHE_PREF( #ifdef ANDROID # define PREF_VALUE 32768 // Measured in KiB #else # define PREF_VALUE 512000 // Measured in KiB #endif VARCACHE_PREF( "media.cache_size", MediaCacheSize, - uint32_t, PREF_VALUE + RelaxedAtomicUint32, PREF_VALUE ) #undef PREF_VALUE // If a resource is known to be smaller than this size (in kilobytes), a // memory-backed MediaCache may be used; otherwise the (single shared global) // file-backed MediaCache is used. VARCACHE_PREF( "media.memory_cache_max_size", @@ -399,60 +399,60 @@ VARCACHE_PREF( #ifdef ANDROID # define PREF_VALUE 10 // Use a smaller limit to save battery. #else # define PREF_VALUE 30 #endif VARCACHE_PREF( "media.cache_resume_threshold", MediaCacheResumeThreshold, - int32_t, PREF_VALUE + RelaxedAtomicInt32, PREF_VALUE ) #undef PREF_VALUE // Stop reading ahead when our buffered data is this many seconds ahead of the // current playback position. This limit can stop us from using arbitrary // amounts of network bandwidth prefetching huge videos. #ifdef ANDROID # define PREF_VALUE 30 // Use a smaller limit to save battery. #else # define PREF_VALUE 60 #endif VARCACHE_PREF( "media.cache_readahead_limit", MediaCacheReadaheadLimit, - int32_t, PREF_VALUE + RelaxedAtomicInt32, PREF_VALUE ) #undef PREF_VALUE // AudioSink VARCACHE_PREF( "media.resampling.enabled", MediaResamplingEnabled, - bool, false + RelaxedAtomicBool, false ) #if defined(XP_WIN) || defined(XP_DARWIN) || defined(MOZ_PULSEAUDIO) // libcubeb backend implement .get_preferred_channel_layout # define PREF_VALUE false #else # define PREF_VALUE true #endif VARCACHE_PREF( "media.forcestereo.enabled", MediaForcestereoEnabled, - bool, PREF_VALUE + RelaxedAtomicBool, PREF_VALUE ) #undef PREF_VALUE // VideoSink VARCACHE_PREF( "media.ruin-av-sync.enabled", MediaRuinAvSyncEnabled, - bool, false + RelaxedAtomicBool, false ) // Encrypted Media Extensions #if defined(ANDROID) # if defined(NIGHTLY_BUILD) # define PREF_VALUE true # else # define PREF_VALUE false @@ -494,44 +494,44 @@ VARCACHE_PREF( #endif // Specifies whether the PDMFactory can create a test decoder that just outputs // blank frames/audio instead of actually decoding. The blank decoder works on // all platforms. VARCACHE_PREF( "media.use-blank-decoder", MediaUseBlankDecoder, - bool, false + RelaxedAtomicBool, false ) #if defined(XP_WIN) # define PREF_VALUE true #else # define PREF_VALUE false #endif VARCACHE_PREF( "media.gpu-process-decoder", MediaGpuProcessDecoder, - bool, PREF_VALUE + RelaxedAtomicBool, PREF_VALUE ) #undef PREF_VALUE #ifdef ANDROID // Enable the MediaCodec PlatformDecoderModule by default. VARCACHE_PREF( "media.android-media-codec.enabled", MediaAndroidMediaCodecEnabled, - bool, true + RelaxedAtomicBool, true ) VARCACHE_PREF( "media.android-media-codec.preferred", MediaAndroidMediaCodecPreferred, - bool, true + RelaxedAtomicBool, true ) #endif // ANDROID // WebRTC #ifdef MOZ_WEBRTC #ifdef ANDROID @@ -569,129 +569,129 @@ VARCACHE_PREF( # if defined(XP_MACOSX) # define PREF_VALUE false # else # define PREF_VALUE true # endif VARCACHE_PREF( "media.ffmpeg.enabled", MediaFfmpegEnabled, - bool, PREF_VALUE + RelaxedAtomicBool, PREF_VALUE ) #undef PREF_VALUE VARCACHE_PREF( "media.libavcodec.allow-obsolete", MediaLibavcodecAllowObsolete, bool, false ) #endif // MOZ_FFMPEG #ifdef MOZ_FFVPX VARCACHE_PREF( "media.ffvpx.enabled", MediaFfvpxEnabled, - bool, true + RelaxedAtomicBool, true ) #endif #if defined(MOZ_FFMPEG) || defined(MOZ_FFVPX) VARCACHE_PREF( "media.ffmpeg.low-latency.enabled", MediaFfmpegLowLatencyEnabled, bool, false ) #endif #ifdef MOZ_WMF VARCACHE_PREF( "media.wmf.enabled", MediaWmfEnabled, - bool, true + RelaxedAtomicBool, true ) // Whether DD should consider WMF-disabled a WMF failure, useful for testing. VARCACHE_PREF( "media.decoder-doctor.wmf-disabled-is-failure", MediaDecoderDoctorWmfDisabledIsFailure, bool, false ) VARCACHE_PREF( "media.wmf.vp9.enabled", MediaWmfVp9Enabled, - bool, true + RelaxedAtomicBool, true ) #endif // MOZ_WMF // Whether to check the decoder supports recycling. #ifdef ANDROID # define PREF_VALUE true #else # define PREF_VALUE false #endif VARCACHE_PREF( "media.decoder.recycle.enabled", MediaDecoderRecycleEnabled, - bool, PREF_VALUE + RelaxedAtomicBool, PREF_VALUE ) #undef PREF_VALUE // Should MFR try to skip to the next key frame? VARCACHE_PREF( "media.decoder.skip-to-next-key-frame.enabled", MediaDecoderSkipToNextKeyFrameEnabled, - bool, true + RelaxedAtomicBool, true ) VARCACHE_PREF( "media.gmp.decoder.enabled", MediaGmpDecoderEnabled, - bool, false + RelaxedAtomicBool, false ) VARCACHE_PREF( "media.eme.audio.blank", MediaEmeAudioBlank, - bool, false + RelaxedAtomicBool, false ) VARCACHE_PREF( "media.eme.video.blank", MediaEmeVideoBlank, - bool, false + RelaxedAtomicBool, false ) VARCACHE_PREF( "media.eme.chromium-api.video-shmems", MediaEmeChromiumApiVideoShmems, - uint32_t, 6 + RelaxedAtomicUint32, 6 ) // Whether to suspend decoding of videos in background tabs. VARCACHE_PREF( "media.suspend-bkgnd-video.enabled", MediaSuspendBkgndVideoEnabled, - bool, true + RelaxedAtomicBool, true ) // Delay, in ms, from time window goes to background to suspending // video decoders. Defaults to 10 seconds. VARCACHE_PREF( "media.suspend-bkgnd-video.delay-ms", MediaSuspendBkgndVideoDelayMs, RelaxedAtomicUint32, 10000 ) VARCACHE_PREF( "media.dormant-on-pause-timeout-ms", MediaDormantOnPauseTimeoutMs, - int32_t, 5000 + RelaxedAtomicInt32, 5000 ) VARCACHE_PREF( "media.webspeech.synth.force_global_queue", MediaWebspeechSynthForceGlobalQueue, bool, false ) @@ -752,32 +752,32 @@ VARCACHE_PREF( uint32_t, PREF_VALUE ) #undef PREF_VALUE // Ogg VARCACHE_PREF( "media.ogg.enabled", MediaOggEnabled, - bool, true + RelaxedAtomicBool, true ) // AV1 VARCACHE_PREF( "media.av1.enabled", MediaAv1Enabled, - bool, true + RelaxedAtomicBool, true ) // Flac // Use new MediaFormatReader architecture for plain ogg. VARCACHE_PREF( "media.ogg.flac.enabled", MediaOggFlacEnabled, - bool, true + RelaxedAtomicBool, true ) VARCACHE_PREF( "media.flac.enabled", MediaFlacEnabled, bool, true ) @@ -797,27 +797,27 @@ VARCACHE_PREF( #ifdef MOZ_FMP4 # define PREF_VALUE true #else # define PREF_VALUE false #endif VARCACHE_PREF( "media.mp4.enabled", mediaMp4Enabled, - bool, PREF_VALUE + RelaxedAtomicBool, PREF_VALUE ) #undef PREF_VALUE // Error/warning handling, Decoder Doctor. // // Set to true to force demux/decode warnings to be treated as errors. VARCACHE_PREF( "media.playback.warnings-as-errors", MediaPlaybackWarningsAsErrors, - bool, false + RelaxedAtomicBool, false ) // Resume video decoding when the cursor is hovering on a background tab to // reduce the resume latency and improve the user experience. VARCACHE_PREF( "media.resume-bkgnd-video-on-tabhover", MediaResumeBkgndVideoOnTabhover, bool, true @@ -834,17 +834,17 @@ VARCACHE_PREF( bool, PREF_VALUE ) #undef PREF_VALUE // Media Seamless Looping VARCACHE_PREF( "media.seamless-looping", MediaSeamlessLooping, - bool, true + RelaxedAtomicBool, true ) //--------------------------------------------------------------------------- // Network prefs //--------------------------------------------------------------------------- // Sub-resources HTTP-authentication: // 0 - don't allow sub-resources to open HTTP authentication credentials
--- a/widget/android/GeckoVRManager.h +++ b/widget/android/GeckoVRManager.h @@ -4,79 +4,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_GeckoVRManager_h_ #define mozilla_GeckoVRManager_h_ #include "GeneratedJNINatives.h" #include "mozilla/jni/Utils.h" -#if defined(MOZ_ANDROID_GOOGLE_VR) -#include "gfxVRGVRAPI.h" -extern bool SetupGVRJNI(JNIEnv* env); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) - namespace mozilla { class GeckoVRManager - : public mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager> { - typedef mozilla::java::GeckoVRManager::Natives<mozilla::GeckoVRManager> Super; public: - static void Init() - { - Super::Init(); -#if defined(MOZ_ANDROID_GOOGLE_VR) - SetupGVRJNI(jni::GetGeckoThreadEnv()); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) - } - - static void SetGVRPresentingContext(const int64_t aContext) - { -#if defined(MOZ_ANDROID_GOOGLE_VR) - mozilla::gfx::SetGVRPresentingContext((void*)aContext); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) - } - - static void CleanupGVRNonPresentingContext() - { -#if defined(MOZ_ANDROID_GOOGLE_VR) - mozilla::gfx::CleanupGVRNonPresentingContext(); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) + static void* GetExternalContext() { + return reinterpret_cast<void*>(mozilla::java::GeckoVRManager::GetExternalContext()); } - - static void SetGVRPaused(const bool aPaused) - { -#if defined(MOZ_ANDROID_GOOGLE_VR) - mozilla::gfx::SetGVRPaused(aPaused); -#endif // defined(MOZ_ANDROID_GOOGLE_VR) - } - - static void* CreateGVRNonPresentingContext() - { - return (void*)mozilla::java::GeckoVRManager::CreateGVRNonPresentingContext(); - } - - static void DestroyGVRNonPresentingContext() - { - mozilla::java::GeckoVRManager::DestroyGVRNonPresentingContext(); - } - - static void EnableVRMode() - { - mozilla::java::GeckoVRManager::EnableVRMode(); - } - - static void DisableVRMode() - { - mozilla::java::GeckoVRManager::DisableVRMode(); - } - - static bool IsGVRPresent() - { - return mozilla::java::GeckoVRManager::IsGVRPresent(); - } - }; } // namespace mozilla #endif // mozilla_GeckoVRManager_h_
--- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -420,17 +420,16 @@ nsAppShell::nsAppShell() AndroidBridge::ConstructBridge(); GeckoAppShellSupport::Init(); GeckoThreadSupport::Init(); mozilla::GeckoBatteryManager::Init(); mozilla::GeckoNetworkManager::Init(); mozilla::GeckoProcessManager::Init(); mozilla::GeckoScreenOrientation::Init(); mozilla::PrefsHelper::Init(); - mozilla::GeckoVRManager::Init(); nsWindow::InitNatives(); if (jni::IsFennec()) { BrowserLocaleManagerSupport::Init(); mozilla::ANRReporter::Init(); mozilla::MemoryMonitor::Init(); mozilla::widget::Telemetry::Init(); mozilla::ThumbnailHelper::Init();
--- a/xpcom/ds/nsGkAtomList.h +++ b/xpcom/ds/nsGkAtomList.h @@ -878,16 +878,17 @@ GK_ATOM(output, "output") GK_ATOM(overflow, "overflow") GK_ATOM(overlay, "overlay") GK_ATOM(p, "p") GK_ATOM(pack, "pack") GK_ATOM(page, "page") GK_ATOM(pageincrement, "pageincrement") GK_ATOM(paint_order, "paint-order") GK_ATOM(panel, "panel") +GK_ATOM(paragraph, "paragraph") GK_ATOM(param, "param") GK_ATOM(parameter, "parameter") GK_ATOM(parent, "parent") GK_ATOM(parentfocused, "parentfocused") GK_ATOM(password, "password") GK_ATOM(pattern, "pattern") GK_ATOM(patternSeparator, "pattern-separator") GK_ATOM(perMille, "per-mille")
--- a/xpcom/io/InputStreamLengthHelper.cpp +++ b/xpcom/io/InputStreamLengthHelper.cpp @@ -152,18 +152,20 @@ InputStreamLengthHelper::GetAsyncLength( // Let's be sure that we don't call ::Available() on main-thread. if (NS_IsMainThread()) { nsCOMPtr<nsIInputStreamLength> streamLength = do_QueryInterface(aStream); nsCOMPtr<nsIAsyncInputStreamLength> asyncStreamLength = do_QueryInterface(aStream); if (!streamLength && !asyncStreamLength) { // We cannot calculate the length of an async stream. We must fix the // caller if this happens. +#ifdef DEBUG nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream); MOZ_DIAGNOSTIC_ASSERT(!asyncStream); +#endif bool nonBlocking = false; if (NS_SUCCEEDED(aStream->IsNonBlocking(&nonBlocking)) && !nonBlocking) { nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); MOZ_ASSERT(target); RefPtr<AvailableEvent> event = new AvailableEvent(aStream, aCallback);