From 76fdf7909d6aa5fdd4c5ccc713d04bf0e87fc694 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Wed, 31 Jul 2024 11:36:16 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1222098 - Devicemotion event timestamp should return values from Android sensor API and not Gecko. r:smaug (0fb05341d5) - Bug 1266701 - some header missing in dom/events, r=jwatt (59a8a30af3) - namespace (c5796648b6) - Bug 1243555: Remove unnecessary nsDocShell static_cast in EventListenerManager::HandleEventInternal(). r=smaug (21c559122c) - Bug 1254629 - Let query events fail when content root is wrong; r=masayuki (64454249aa) - Bug 1224233 - fix crashy usage of IMENotificationSender::Run using on-screen keyboard on Windows, r=smaug (ddcdf13ad0) - Bug 1252058 IMEContentObserver::IMENotificationSender shouldn't post notifications when IMEContentObserver which is the owner of it stopped observing contents r=smaug (9f4a14f13a) - Bug 1259671 part.1 Rename InternalScrollPortEvent::orientType to InternalScrollPortEvent::OrientType r=smaug (eaefa4472f) - Bug 1259671 part.2 Rename InternalScrollPortEvent::vertical to InternalScrollPortEvent::eVertical r=smaug (91bcdcd1df) - Bug 1259671 part.3 Rename InternalScrollPortEvent::horizontal to InternalScrollPortEvent::eHorizontal r=smaug (f3c206dc4c) - Bug 1259671 part.4 Rename InternalScrollPortEvent::both to InternalScrollPortEvent::eBoth r=smaug (ac34dc95c1) - Bug 1259671 part.5 Rename InternalScrollPortEvent::orient to InternalScrollPortEvent::mOrient r=smaug (6736862c75) - Bug 1262324 (part 1) - Remove "locale.all" prefix from Unix charsets. r=emk. (b337137c3d) - Bug 1255655 - Const-ify dom encodings and similar arrays. r=baku. (93d79e84a7) - Bug 1262324 (part 2) - Introduce nsUConvProp. r=emk. (bad497dee6) - Bug 1257877 - Remove UTF-16 support from TextEncoder. r=hsivonen (ad647b12a3) - Bug 1120813 - Add support for the MS932 label of Shift_JIS. r=emk, r=Ms2ger (8a35fd93cf) - Bug 1250930 - Use correct global when creating a key in GenerateAsymmetricKeyTask r=bz (ba65e0ae34) - Bug 842818 - Allow calling WebCryptoTask::DispatchWithPromise() from workers r=keeler (e99301ba3e) - Bug 1251390. Make timer queries available at the appropriate time. r=jgilbert (f1a0dcf7d3) - Bug 1259696 - Check read buffer mode when doing CopyTexImage. r=jgilbert (fe51211b56) - Bug 1241042 - Get correct frag varying from angle validator. r=jmuizelaar (29a4298a7e) - Bug 1244611 - "Using named uniform buffer objects in the fragment shader fails". r=jgilbert (2e05e31d09) - Bug 1263018 - Only update active prog info if linking active prog. - r=jrmuizel (1603ebdd8c) - Bug 1257593 - Handle webgl FramebufferTexture2D() with an unbound texture. r=jgilbert (4d75981cb7) - Bug 1257593 followup, fix bustage from believing a reviewer and then sending a different patch to try (7766b0cdb4) - Bug 1258061 - Clarify FramebufferTexture2D handling for tex2D and cubeMap; r=jgilbert (0635d9412a) - Bug 1259449 - Require GLFeature::sync for WebGL's disjoint_timer_query. - r=jrmuizel (b6017134a3) - Bug 1247804 - Enable seamless cubemaps where available. - r=jrmuizel (e7fd3ec5ed) - Bug 1247977: More information when we hit the OpenGL error in FakeBlackTexture. r=jgilbert (f6f2c82e33) - Bug 1255655 - Const-ify sExtensionNames. r=mattwoodrow. (c0c60b34c7) - Bug 1262757 - Use StaticRefPtr for the global context in GLContextProviderWGL, r=jrmuizel (0cc29a3385) - Bug 1259811 - Require FBO support for GLContexts. - r=jrmuizel (ec3c1a6045) - Bug 1234441 - Allow malformed ESSL version string. - r=jrmuizel (8fda1569ab) - Bug 1199923 - Work around Intel Linux driver lying about max texture size - r=jgilbert (546b7dfe6a) - Bug 1262265 - Cleanup GLContext symbol init. - r=jrmuizel (8da8ce647a) - Bug 1232334 - [1.2] Only set context on successful attach. r=snorp (ca29c322bf) - Bug 1261320 - Check DataSurface is vaild before using, r=milan (be9aebba47) - Bug 1245868 - repalce pass by value with pass by pointer in IsHeadRequest. r=jst (f9d7f6185f) - fix tests (3ccf9d1715) - Bug 1232941 - Register Observer and listen to NS_XPCOM_SHUTDOWN_OBSERVER_ID for GATT, r=shuang (aa367807fa) - Bug 1239979: Init and uninit all Bluetooth profile managers, r=shuang (78c1ebbd13) - Bug 1239979: Uninitialized Bluetooth profile managers explictly to release refs, r=shuang (83b5389539) - Bug 1262630. Replace workers::GetGlobalObjectForGlobal with xpc::NativeGlobal. r=khuey (9f639580be) - Bug 1255817 part 6. Fix up some comments in CallbackObject that refer to things that no longer exist. r=bholley (575bf90c98) - Bug 1259545. Remove the JS_SaveFrameChain bits in CallbackObject error reporting, since they are no longer needed. r=bholley (16181ddb38) - Bug 1260511 part 2. Change XPConnect's handling of exceptions thrown from JS components so that if an nsresult integer is thrown we convert it into an actual exception object before handing it out to content instead of propagating out the numeric value. r=khuey (dc02854e3f) - Bug 1260511 part 3. In dom::Throw, ignore the pending xpconnect exception if we were given a non-default message string (because we don't want to lose that string). Also, make sure to always clear the pending xpconnect exception there. r=khuey (978a1e9132) - Bug 1250106 - Correctly set charging status and remaining time when battery level is rounded to 1.0 r=bz (662e18648c) - Bug 1253641 - DOMException's CC participant should traverse mData. r=khuey. (0a48e3f8e7) - Bug 1261115 - when Console is running in the main thread the existence of mWindow should always be ensured, r=smaug (caa1efd087) - Bug 1257208 - Use the nsTextNode concrete type in several places in DirectionalityUtils.cpp instead of nsINode and nsIContent; r=peterv (69529fd8d4) - Bug 1260982 - BlobFileImpl::GetType() should work also in workers, r=smaug (4b01d269bc) - Bug 1262104 - Remove a non-used CTOR for BlobImplFile, r=ehsan (37ee0ec6d4) - Bug 1259477 - Port test_document_register.html to mochitest-plain so that it can be turned on in e10s mode; r=mrbkap (411c220cda) - Bug 1222128 - Turn test_bug1011748.html into a browser mochitest to make it run properly in e10s mode r=bzbarsky (45403d3d15) - Bug 1259588 - new File("") throws TypeError exception, r=baku (05f6e7292d) - Bug 1264710 - Catch IDB exceptions in IndexedDBHelper. r=fabrice (0d3c860a89) - Bug 1263553 - Move MultipartBlobImpl into mozilla::dom namespace, r=smaug (e286c6cfe1) - Bug 1263551 - Remove unused method in MultipartBlobImpl, r=smaug (54c2da9a12) - Bug 1252687 - get rid of static nsStrings in PerformanceObserver.cpp r=bz (319f2697d4) - Bug 1148535 - Check if the density descriptor in srcset consists of a valid floating-point number. r=jdm (79ac8d8dea) - Bug 1257742 - Part 1: Follow the update-source-set rule to append default source into source set; r=jdm (853c69cc8c) - Bug 1257742 - Part 2: Allow both width and static density candidates showing in same selector; r=jdm (4f1e00225d) - Bug 1257742 - Part 3: Support using floating point in sizes descriptor; r=jdm (c1a7e36bb3) - Bug 1257742 - Part 4: Update web-platform test expectation; r=jdm (e41044b88e) - Bug 1262942 - Remove unnecessary warning message in ResponsiveImageSelector; r=jdm (ffb757204d) - Bug 1158412 - Remove assertion for document prescontex and add crash test; r=jdm (947ccdfbfc) - Bug 1237633 - Part 1: Percentages are not allowed in a . r=jdm (614b560097) - Bug 1237633 - Part 2: Avoid fatal assertion when a responsive image's size specifier is invalid. r=johns, r=jdm (4e90829d97) - Bug 495546 - Add crashtest. (c2765ecbf4) - fix some tests (d9b393b168) - Bug 1256419. Null-check our nsDOMWindowList before trying to get its length. r=smaug (6c14430e5d) - Bug 1162775: Make contentAreaDropListener use dataTransfer.files to get the files dropped. r=smaug (d2850f2008) - Bug 1220679 - replace AutoSafeJSContext with AutoJSAPI. r=bz. (64538bdd44) - reinstantiate assert, present in up to esr68 (221cec538a) - Bug 1209329 - Improve comments about about: URIs in nsContentUtils::InternalStorageAllowedForPrincipal, r=bholley (71152e5639) - Bug 1246250 - Deal with failure to create a blob actor. r=khuey (102686ac28) - Bug 1265902 - part 1 - be more efficient when using nsContentUtils::GetSurfaceData(); r=mccr8 (ba2a52abd3) - Bug 1258857 - Add empty items to an IPC transferable object for every flavor of the source object that did not have any data associated to it r=enndeakin (0a02b61566) - Bug 1265902 - part 2 - don't construct unnecessary string temporaries in TransferablesToIPCTransferables; r=mccr8 (aec10c8fc6) - remove unknown blob handling, not found in Tycho-dev repo, nor esr60 or TFF (eb6a24720a) - Bug 1155486 - Convert nsDOMAttributeMap::mLocalName to void* to ensure that we can never dereference it; r=baku (34e2864340) - Bug 1250926 - Remove unused SCRIPTABLE_FLAGS defines from nsDOMClassInfo; r=peterv (76917fb76b) - No bug. Helper tool to partially autogenerate portions of the release notes. (3818e5534b) - Bug 1203423 - Move call to AddClone outside nsMutationReceiver constructor; r=smaug (35c94ad785) - Bug 1254096 - Update CaretPositionFromPoint() for type=number, r=ehsan (df31edca8f) - Bug 1265771 P1 Only store active documents in the global observer list. r=bz (01502e91e5) - Bug 1265771 P2 Expand navigate-window.https.html wpt test to cover uncontrolled windows. r=bz (3333906720) - Bug 1265771 P3 Expand browser_force_refresh.js to verify Clients.matchAll() behavior on refresh. r=bz (01394ec8f1) - stop hiding things for _LIBCPP_VERSION (5de86e8bbf) --- dom/base/Console.cpp | 4 + dom/base/DOMException.cpp | 2 + dom/base/DirectionalityUtils.cpp | 51 +- dom/base/DirectionalityUtils.h | 4 +- dom/base/File.cpp | 75 +- dom/base/File.h | 17 +- dom/base/IndexedDBHelper.jsm | 33 +- dom/base/MultipartBlobImpl.h | 12 +- dom/base/PerformanceObserver.cpp | 19 +- dom/base/ResponsiveImageSelector.cpp | 151 +- dom/base/ResponsiveImageSelector.h | 12 +- dom/base/WindowNamedPropertiesHandler.cpp | 34 +- dom/base/contentAreaDropListener.js | 11 +- dom/base/crashtests/1158412.html | 22 + dom/base/crashtests/crashtests.list | 1 + dom/base/nsContentPermissionHelper.cpp | 10 +- dom/base/nsContentUtils.cpp | 97 +- dom/base/nsDOMAttributeMap.h | 6 +- dom/base/nsDOMClassInfo.cpp | 9 - dom/base/nsDOMMutationObserver.h | 3 +- dom/base/nsDocument.cpp | 50 +- dom/base/nsGenericDOMDataNode.cpp | 5 +- dom/base/nsINode.h | 7 +- dom/base/nsTextNode.h | 1 + dom/base/test/browser.ini | 3 + dom/base/test/browser_bug1011748.js | 31 + dom/base/test/chrome/chrome.ini | 1 - .../test/chrome/test_document_register.xul | 37 - dom/base/test/copypaste.js | 2 +- dom/base/test/mochitest.ini | 6 +- dom/base/test/test_bug1011748.html | 57 - dom/base/test/test_bug1259588.html | 13 + .../test/test_caretPositionFromPoint.html | 11 + dom/base/test/test_document_register.html | 27 + dom/battery/BatteryManager.cpp | 9 +- dom/bindings/CallbackObject.cpp | 40 +- dom/bindings/Exceptions.cpp | 30 +- .../bluedroid/BluetoothA2dpManager.cpp | 16 +- .../bluedroid/BluetoothA2dpManager.h | 1 + .../bluedroid/BluetoothAvrcpManager.cpp | 16 +- .../bluedroid/BluetoothAvrcpManager.h | 1 + .../bluedroid/BluetoothGattManager.cpp | 48 +- .../bluedroid/BluetoothGattManager.h | 2 + .../bluedroid/BluetoothMapSmsManager.cpp | 67 +- .../bluedroid/BluetoothMapSmsManager.h | 7 +- .../bluedroid/BluetoothOppManager.cpp | 78 +- dom/bluetooth/bluedroid/BluetoothOppManager.h | 7 +- .../bluedroid/BluetoothPbapManager.cpp | 67 +- .../bluedroid/BluetoothPbapManager.h | 7 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 10 +- .../hfp-fallback/BluetoothHfpManager.cpp | 2 + .../bluedroid/hfp/BluetoothHfpManager.cpp | 2 + dom/bluetooth/bluez/BluetoothHidManager.cpp | 24 + dom/bluetooth/bluez/BluetoothHidManager.h | 2 + dom/broadcastchannel/BroadcastChannelParent.h | 2 +- dom/broadcastchannel/moz.build | 2 +- dom/broadcastchannel/tests/browser.ini | 6 + .../tests/browser_private_browsing.js | 74 + dom/broadcastchannel/tests/chrome.ini | 6 - ...est_broadcastchannel_private_browsing.html | 118 - dom/cache/Manager.cpp | 4 +- dom/canvas/TexUnpackBlob.cpp | 8 +- dom/canvas/WebGL2ContextFramebuffers.cpp | 1 + dom/canvas/WebGLContext.cpp | 8 +- dom/canvas/WebGLContext.h | 3 +- dom/canvas/WebGLContextDraw.cpp | 27 +- dom/canvas/WebGLContextGL.cpp | 14 +- dom/canvas/WebGLContextValidate.cpp | 4 + .../WebGLExtensionDisjointTimerQuery.cpp | 13 +- dom/canvas/WebGLFramebuffer.cpp | 15 +- dom/canvas/WebGLFramebuffer.h | 7 +- dom/canvas/WebGLProgram.cpp | 43 +- dom/canvas/WebGLProgram.h | 18 +- dom/canvas/WebGLShader.cpp | 16 + dom/canvas/WebGLShader.h | 2 + dom/canvas/WebGLShaderValidator.cpp | 47 +- dom/canvas/WebGLShaderValidator.h | 3 + dom/canvas/WebGLTextureUpload.cpp | 26 +- dom/canvas/WebGLTimerQuery.cpp | 8 + dom/canvas/WebGLTimerQuery.h | 3 + dom/canvas/test/webgl-mochitest.ini | 2 +- dom/crypto/WebCryptoTask.cpp | 25 +- dom/crypto/WebCryptoTask.h | 2 +- dom/crypto/WebCryptoThreadPool.cpp | 2 + dom/encoding/EncodingUtils.cpp | 4 +- dom/encoding/FallbackEncoding.cpp | 6 +- dom/encoding/TextEncoder.cpp | 27 +- dom/encoding/TextEncoder.h | 20 +- dom/encoding/labelsencodings.properties | 1 + dom/encoding/test/test_TextDecoder.js | 2 +- dom/encoding/test/test_TextEncoder.js | 124 +- dom/encoding/test/unit/test_misc.js | 27 +- dom/encoding/test/unit/test_utf.js | 38 +- dom/events/DeviceMotionEvent.cpp | 21 +- dom/events/DeviceMotionEvent.h | 10 + dom/events/EventDispatcher.cpp | 10 + dom/events/EventListenerManager.cpp | 8 +- dom/events/EventListenerService.h | 2 +- dom/events/IMEContentObserver.cpp | 33 +- dom/events/UIEvent.cpp | 2 +- dom/html/crashtests/1237633.html | 1 + dom/html/crashtests/495546-1.html | 19 + dom/html/crashtests/crashtests.list | 5 +- dom/media/webrtc/RTCCertificate.cpp | 9 +- dom/system/nsDeviceSensors.cpp | 7 +- dom/system/nsDeviceSensors.h | 1 + dom/webidl/TextEncoder.webidl | 2 +- dom/workers/WorkerRunnable.cpp | 2 +- dom/workers/WorkerScope.cpp | 20 - dom/workers/Workers.h | 3 - .../browser_cached_force_refresh.html | 51 +- .../force_refresh_browser_worker.js | 12 + gfx/gl/AndroidSurfaceTexture.cpp | 26 +- gfx/gl/AndroidSurfaceTexture.h | 8 +- gfx/gl/GLContext.cpp | 2121 ++++++++--------- gfx/gl/GLContext.h | 35 +- gfx/gl/GLContextCGL.h | 2 +- gfx/gl/GLContextEAGL.h | 2 +- gfx/gl/GLContextFeatures.cpp | 9 + gfx/gl/GLContextProviderCGL.mm | 26 +- gfx/gl/GLContextProviderEAGL.mm | 20 +- gfx/gl/GLContextProviderEGL.cpp | 20 +- gfx/gl/GLContextProviderGLX.cpp | 16 +- gfx/gl/GLContextProviderWGL.cpp | 24 +- gfx/gl/GLLibraryEGL.h | 3 + gfx/gl/GLLibraryLoader.cpp | 6 +- gfx/gl/GLLibraryLoader.h | 4 +- gfx/gl/GLScreenBuffer.h | 4 + intl/locale/nsLanguageAtomService.cpp | 2 +- intl/locale/nsLanguageAtomService.h | 1 + intl/locale/nsUConvPropertySearch.cpp | 10 +- intl/locale/nsUConvPropertySearch.h | 9 +- intl/locale/props2arrays.py | 2 +- intl/locale/unix/nsUNIXCharset.cpp | 7 +- intl/locale/unix/unixcharset.properties | 778 +++--- intl/locale/windows/nsWinCharset.cpp | 2 +- js/src/devtools/release/release-notes | 195 ++ js/src/make-source-package.sh | 1 + layout/base/nsPresContext.h | 4 + layout/generic/nsGfxScrollFrame.cpp | 14 +- layout/xul/tree/nsTreeBodyFrame.cpp | 4 +- memory/mozalloc/throw_gcc.h | 17 +- .../sizes/parse-a-sizes-attribute.html.ini | 1020 ++++---- .../srcset/parse-a-srcset-attribute.html.ini | 20 - .../update-the-source-set.html.ini | 6 - .../the-navigator-object/content.html.ini | 21 - .../the-navigator-object/protocol.html.ini | 96 - .../Document-characterSet-normalization.html | 1 + .../tests/encoding/resources/encodings.js | 1 + .../service-worker/navigate-window.https.html | 64 +- .../test/unit/test_removeDataFromDomain.js | 70 +- widget/ContentEvents.h | 14 +- widget/PuppetWidget.cpp | 2 +- widget/tests/test_imestate.html | 6 +- 154 files changed, 3699 insertions(+), 3230 deletions(-) create mode 100644 dom/base/crashtests/1158412.html create mode 100644 dom/base/test/browser_bug1011748.js delete mode 100644 dom/base/test/chrome/test_document_register.xul delete mode 100644 dom/base/test/test_bug1011748.html create mode 100644 dom/base/test/test_bug1259588.html create mode 100644 dom/base/test/test_document_register.html create mode 100644 dom/broadcastchannel/tests/browser.ini create mode 100644 dom/broadcastchannel/tests/browser_private_browsing.js delete mode 100644 dom/broadcastchannel/tests/chrome.ini delete mode 100644 dom/broadcastchannel/tests/test_broadcastchannel_private_browsing.html create mode 100644 dom/html/crashtests/1237633.html create mode 100644 dom/html/crashtests/495546-1.html create mode 100644 js/src/devtools/release/release-notes delete mode 100644 testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp index ff255349bc..b4091f6535 100644 --- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -886,6 +886,8 @@ NS_INTERFACE_MAP_END /* static */ already_AddRefed Console::Create(nsPIDOMWindow* aWindow, ErrorResult& aRv) { + MOZ_ASSERT_IF(NS_IsMainThread(), aWindow); + RefPtr console = new Console(aWindow); console->Initialize(aRv); if (NS_WARN_IF(aRv.Failed())) { @@ -904,6 +906,8 @@ Console::Console(nsPIDOMWindow* aWindow) , mInnerID(0) , mStatus(eUnknown) { + MOZ_ASSERT_IF(NS_IsMainThread(), aWindow); + if (mWindow) { MOZ_ASSERT(mWindow->IsInnerWindow()); mInnerID = mWindow->WindowID(); diff --git a/dom/base/DOMException.cpp b/dom/base/DOMException.cpp index 99587382c6..bd58d1f271 100644 --- a/dom/base/DOMException.cpp +++ b/dom/base/DOMException.cpp @@ -177,6 +177,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Exception) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -187,6 +188,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mData) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER tmp->mThrownJSVal.setNull(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END diff --git a/dom/base/DirectionalityUtils.cpp b/dom/base/DirectionalityUtils.cpp index 156f1b5e2f..d5dc76206f 100644 --- a/dom/base/DirectionalityUtils.cpp +++ b/dom/base/DirectionalityUtils.cpp @@ -386,7 +386,7 @@ GetDirectionFromText(const nsTextFragment* aFrag, * know not to return it * @return the text node containing the character that determined the direction */ -static nsINode* +static nsTextNode* WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true, nsINode* aChangedNode = nullptr) { @@ -412,7 +412,7 @@ WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true, // We found a descendant text node with strong directional characters. // Set the directionality of aElement to the corresponding value. aElement->SetDirectionality(textNodeDir, aNotify); - return child; + return static_cast(child); } } child = child->GetNextNode(aElement); @@ -454,7 +454,7 @@ public: MOZ_COUNT_DTOR(nsTextNodeDirectionalityMap); } - void AddEntry(nsINode* aTextNode, Element* aElement) + void AddEntry(nsTextNode* aTextNode, Element* aElement) { if (!mElements.Contains(aElement)) { mElements.Put(aElement); @@ -463,7 +463,7 @@ public: } } - void RemoveEntry(nsINode* aTextNode, Element* aElement) + void RemoveEntry(nsTextNode* aTextNode, Element* aElement) { NS_ASSERTION(mElements.Contains(aElement), "element already removed from map"); @@ -505,7 +505,7 @@ private: // and remove the text node from the map nsINode* oldTextNode = static_cast(aData); Element* rootNode = aEntry->GetKey(); - nsINode* newTextNode = nullptr; + nsTextNode* newTextNode = nullptr; if (rootNode->GetParentNode() && rootNode->HasDirAuto()) { newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true, oldTextNode); @@ -551,14 +551,14 @@ public: MOZ_ASSERT(clearedEntries == 0, "Map should be empty already"); } - static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement) + static void RemoveElementFromMap(nsTextNode* aTextNode, Element* aElement) { if (aTextNode->HasTextNodeDirectionalityMap()) { GetDirectionalityMap(aTextNode)->RemoveEntry(aTextNode, aElement); } } - static void AddEntryToMap(nsINode* aTextNode, Element* aElement) + static void AddEntryToMap(nsTextNode* aTextNode, Element* aElement) { nsTextNodeDirectionalityMap* map = GetDirectionalityMap(aTextNode); if (!map) { @@ -576,8 +576,8 @@ public: return GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir); } - static void ResetTextNodeDirection(nsINode* aTextNode, - nsINode* aChangedTextNode) + static void ResetTextNodeDirection(nsTextNode* aTextNode, + nsTextNode* aChangedTextNode) { MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(), "Map missing in ResetTextNodeDirection"); @@ -651,7 +651,7 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir, void WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify) { - nsINode* setByNode; + nsTextNode* setByNode; Element* parent = aElement->GetParentElement(); while (parent && parent->NodeOrAncestorHasDirAuto()) { @@ -661,7 +661,7 @@ WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify) // Remove it from the map and reset its direction by the downward // propagation algorithm setByNode = - static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); + static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); if (setByNode) { nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, parent); } @@ -687,11 +687,10 @@ WalkDescendantsResetAutoDirection(Element* aElement) continue; } - if (child->HasTextNodeDirectionalityMap()) { - nsTextNodeDirectionalityMap::ResetTextNodeDirection(child, nullptr); - // Don't call nsTextNodeDirectionalityMap::EnsureMapIsClearFor(child) - // since ResetTextNodeDirection may have kept elements in child's - // DirectionalityMap. + if (child->NodeType() == nsIDOMNode::TEXT_NODE && + child->HasTextNodeDirectionalityMap()) { + nsTextNodeDirectionalityMap::ResetTextNodeDirection(static_cast(child), nullptr); + nsTextNodeDirectionalityMap::EnsureMapIsClearFor(child); } child = child->GetNextNode(aElement); } @@ -733,7 +732,7 @@ WalkDescendantsSetDirAuto(Element* aElement, bool aNotify) } } - nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify); + nsTextNode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify); if (textNode) { nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement); } @@ -754,7 +753,7 @@ WalkDescendantsClearAncestorDirAuto(Element* aElement) } } -void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir, +void SetAncestorDirectionIfAuto(nsTextNode* aTextNode, Directionality aDir, bool aNotify = true) { MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE, @@ -768,8 +767,8 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir, if (parent->HasDirAuto()) { bool resetDirection = false; - nsINode* directionWasSetByTextNode = - static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); + nsTextNode* directionWasSetByTextNode = + static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); if (!parent->HasDirAutoSet()) { // Fast path if parent's direction is not yet set by any descendant @@ -840,7 +839,7 @@ TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, } void -TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir, +TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir, bool aNotify) { Directionality newDir = GetDirectionFromText(aTextNode->GetText()); @@ -870,7 +869,7 @@ TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir, } void -SetDirectionFromNewTextNode(nsIContent* aTextNode) +SetDirectionFromNewTextNode(nsTextNode* aTextNode) { if (!NodeAffectsDirAutoAncestor(aTextNode)) { return; @@ -957,8 +956,8 @@ OnSetDirAttr(Element* aElement, const nsAttrValue* aNewValue, WalkDescendantsSetDirAuto(aElement, aNotify); } else { if (aElement->HasDirAutoSet()) { - nsINode* setByNode = - static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); + nsTextNode* setByNode = + static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement); } SetDirectionalityOnDescendants(aElement, @@ -1009,8 +1008,8 @@ SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent) void ResetDir(mozilla::dom::Element* aElement) { if (aElement->HasDirAutoSet()) { - nsINode* setByNode = - static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); + nsTextNode* setByNode = + static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement); } diff --git a/dom/base/DirectionalityUtils.h b/dom/base/DirectionalityUtils.h index 6d5927aa91..572182c908 100644 --- a/dom/base/DirectionalityUtils.h +++ b/dom/base/DirectionalityUtils.h @@ -89,14 +89,14 @@ bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, * After the contents of a text node have changed, change the directionality * of any elements whose directionality is determined by that node */ -void TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir, +void TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir, bool aNotify); /** * When a text node is appended to an element, find any ancestors with dir=auto * whose directionality will be determined by the text node */ -void SetDirectionFromNewTextNode(nsIContent* aTextNode); +void SetDirectionFromNewTextNode(nsTextNode* aTextNode); /** * When a text node is removed from a document, find any ancestors whose diff --git a/dom/base/File.cpp b/dom/base/File.cpp index 36d2abc988..b729381513 100644 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -39,11 +39,14 @@ #include "mozilla/dom/DOMError.h" #include "mozilla/dom/FileBinding.h" #include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/dom/WorkerRunnable.h" #include "nsThreadUtils.h" namespace mozilla { namespace dom { +using namespace workers; + // XXXkhuey the input stream that we pass out of a File // can outlive the actual File object. Thus, we must // ensure that the buffer underlying the stream we get @@ -619,7 +622,7 @@ File::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { if (!nsContentUtils::ThreadsafeIsCallerChrome()) { - aRv.Throw(NS_ERROR_FAILURE); + aRv.ThrowTypeError(NS_LITERAL_STRING("File")); return nullptr; } @@ -703,8 +706,7 @@ BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv) const return; } - workers::WorkerPrivate* workerPrivate = - workers::GetCurrentThreadWorkerPrivate(); + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); if (workerPrivate->UsesSystemPrincipal()) { @@ -862,17 +864,82 @@ BlobImplFile::GetSize(ErrorResult& aRv) return mLength; } +namespace { + +class GetTypeRunnable final : public nsRunnable +{ +public: + GetTypeRunnable(WorkerPrivate* aWorkerPrivate, + nsIEventTarget* aSyncLoopTarget, + BlobImpl* aBlobImpl) + : mWorkerPrivate(aWorkerPrivate) + , mSyncLoopTarget(aSyncLoopTarget) + , mBlobImpl(aBlobImpl) + { + MOZ_ASSERT(aWorkerPrivate); + MOZ_ASSERT(aSyncLoopTarget); + MOZ_ASSERT(aBlobImpl); + aWorkerPrivate->AssertIsOnWorkerThread(); + } + + NS_IMETHOD + Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + + nsAutoString type; + mBlobImpl->GetType(type); + + RefPtr runnable = + new MainThreadStopSyncLoopRunnable(mWorkerPrivate, + mSyncLoopTarget.forget(), true); + NS_WARN_IF(!runnable->Dispatch()); + return NS_OK; + } + +private: + ~GetTypeRunnable() + {} + + WorkerPrivate* mWorkerPrivate; + nsCOMPtr mSyncLoopTarget; + RefPtr mBlobImpl; +}; + +} // anonymous namespace + void BlobImplFile::GetType(nsAString& aType) { + aType.Truncate(); + if (mContentType.IsVoid()) { NS_ASSERTION(mWholeFile, "Should only use lazy ContentType when using the whole file"); + + if (!NS_IsMainThread()) { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + if (!workerPrivate) { + // I have no idea in which thread this method is called. We cannot + // return any valid value. + return; + } + + AutoSyncLoopHolder syncLoop(workerPrivate); + + RefPtr runnable = + new GetTypeRunnable(workerPrivate, syncLoop.EventTarget(), this); + nsresult rv = NS_DispatchToMainThread(runnable); + NS_WARN_IF(NS_FAILED(rv)); + + NS_WARN_IF(!syncLoop.Run()); + return; + } + nsresult rv; nsCOMPtr mimeService = do_GetService(NS_MIMESERVICE_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { - aType.Truncate(); return; } diff --git a/dom/base/File.h b/dom/base/File.h index 0c1825ab63..41dabdd14d 100644 --- a/dom/base/File.h +++ b/dom/base/File.h @@ -183,6 +183,12 @@ public: const nsAString& aName, const nsAString& aContentType, int64_t aLastModifiedDate); + // This method creates a BlobFileImpl for the new File object. This is + // thread-safe, cross-process, cross-thread as any other BlobImpl, but, when + // GetType() is called, it must dispatch a runnable to the main-thread in + // order to use nsIMIMEService. + // Would be nice if we try to avoid to use this method outside the + // main-thread to avoid extra runnables. static already_AddRefed CreateFromFile(nsISupports* aParent, nsIFile* aFile, bool aTemporary = false); @@ -689,17 +695,6 @@ public: } } - // Create as a file to be later initialized - BlobImplFile() - : BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX) - , mWholeFile(true) - , mIsTemporary(false) - { - // Lazily get the content type and size - mContentType.SetIsVoid(true); - mName.SetIsVoid(true); - } - // Overrides virtual uint64_t GetSize(ErrorResult& aRv) override; virtual void GetType(nsAString& aType) override; diff --git a/dom/base/IndexedDBHelper.jsm b/dom/base/IndexedDBHelper.jsm index 9cfc631d13..587fb901f9 100644 --- a/dom/base/IndexedDBHelper.jsm +++ b/dom/base/IndexedDBHelper.jsm @@ -24,6 +24,10 @@ Cu.importGlobalProperties(["indexedDB"]); XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm'); +function getErrorName(err) { + return err && err.name || "UnknownError"; +} + this.IndexedDBHelper = function IndexedDBHelper() { } @@ -62,7 +66,15 @@ IndexedDBHelper.prototype = { }; if (DEBUG) debug("Try to open database:" + self.dbName + " " + self.dbVersion); - let req = indexedDB.open(this.dbName, this.dbVersion); + let req; + try { + req = indexedDB.open(this.dbName, this.dbVersion); + } catch (e) { + if (DEBUG) debug("Error opening database: " + self.dbName); + Services.tm.currentThread.dispatch(() => invokeCallbacks(getErrorName(e)), + Ci.nsIThread.DISPATCH_NORMAL); + return; + } req.onsuccess = function (event) { if (DEBUG) debug("Opened database:" + self.dbName + " " + self.dbVersion); self._db = event.target.result; @@ -83,7 +95,7 @@ IndexedDBHelper.prototype = { }; req.onerror = function (aEvent) { if (DEBUG) debug("Failed to open database: " + self.dbName); - invokeCallbacks(aEvent.target.error.name); + invokeCallbacks(getErrorName(aEvent.target.error)); }; req.onblocked = function (aEvent) { if (DEBUG) debug("Opening database request is blocked."); @@ -135,8 +147,15 @@ IndexedDBHelper.prototype = { newTxn: function newTxn(txn_type, store_name, callback, successCb, failureCb) { this.ensureDB(function () { if (DEBUG) debug("Starting new transaction" + txn_type); - let txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type); - if (DEBUG) debug("Retrieving object store", this.dbName); + let txn; + try { + txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type); + } catch (e) { + if (DEBUG) debug("Error starting transaction: " + this.dbName); + failureCb(getErrorName(e)); + return; + } + if (DEBUG) debug("Retrieving object store: " + this.dbName); let stores; if (Array.isArray(store_name)) { stores = []; @@ -161,11 +180,7 @@ IndexedDBHelper.prototype = { * if txn was aborted by calling txn.abort() */ if (failureCb) { - if (event.target.error) { - failureCb(event.target.error.name); - } else { - failureCb("UnknownError"); - } + failureCb(getErrorName(event.target.error)); } }; callback(txn, stores); diff --git a/dom/base/MultipartBlobImpl.h b/dom/base/MultipartBlobImpl.h index 2239a4936e..680dfb6c66 100644 --- a/dom/base/MultipartBlobImpl.h +++ b/dom/base/MultipartBlobImpl.h @@ -16,8 +16,8 @@ #include #include "nsPIDOMWindow.h" -using namespace mozilla; -using namespace mozilla::dom; +namespace mozilla { +namespace dom { class MultipartBlobImpl final : public BlobImplBase { @@ -104,11 +104,6 @@ public: mName = aName; } - void SetFromNsIFile(bool aValue) - { - mIsFromNsIFile = aValue; - } - virtual bool MayBeClonedToOtherThreads() const override; protected: @@ -137,4 +132,7 @@ protected: bool mIsFromNsIFile; }; +} // dom namespace +} // mozilla namespace + #endif // mozilla_dom_MultipartBlobImpl_h diff --git a/dom/base/PerformanceObserver.cpp b/dom/base/PerformanceObserver.cpp index 1b8ab37a87..5665aa0d3b 100644 --- a/dom/base/PerformanceObserver.cpp +++ b/dom/base/PerformanceObserver.cpp @@ -135,14 +135,14 @@ PerformanceObserver::QueueEntry(PerformanceEntry* aEntry) mQueuedEntries.AppendElement(aEntry); } -static nsString sValidTypeNames[7] = { - NS_LITERAL_STRING("composite"), - NS_LITERAL_STRING("mark"), - NS_LITERAL_STRING("measure"), - NS_LITERAL_STRING("navigation"), - NS_LITERAL_STRING("render"), - NS_LITERAL_STRING("resource"), - NS_LITERAL_STRING("server") +static const char16_t* sValidTypeNames[7] = { + MOZ_UTF16("composite"), + MOZ_UTF16("mark"), + MOZ_UTF16("measure"), + MOZ_UTF16("navigation"), + MOZ_UTF16("render"), + MOZ_UTF16("resource"), + MOZ_UTF16("server") }; void @@ -156,7 +156,8 @@ PerformanceObserver::Observe(const PerformanceObserverInit& aOptions, nsTArray validEntryTypes; - for (const nsString& validTypeName : sValidTypeNames) { + for (const char16_t* name : sValidTypeNames) { + nsDependentString validTypeName(name); if (aOptions.mEntryTypes.Contains(validTypeName) && !validEntryTypes.Contains(validTypeName)) { validEntryTypes.AppendElement(validTypeName); diff --git a/dom/base/ResponsiveImageSelector.cpp b/dom/base/ResponsiveImageSelector.cpp index 75ff1a499c..4420667b02 100644 --- a/dom/base/ResponsiveImageSelector.cpp +++ b/dom/base/ResponsiveImageSelector.cpp @@ -43,6 +43,66 @@ ParseInteger(const nsAString& aString, int32_t& aInt) nsContentUtils::eParseHTMLInteger_NonStandard )); } +static bool +ParseFloat(const nsAString& aString, double& aDouble) +{ + // Check if it is a valid floating-point number first since the result of + // nsString.ToDouble() is more lenient than the spec, + // https://html.spec.whatwg.org/#valid-floating-point-number + nsAString::const_iterator iter, end; + aString.BeginReading(iter); + aString.EndReading(end); + + if (iter == end) { + return false; + } + + if (*iter == char16_t('-') && ++iter == end) { + return false; + } + + if (nsCRT::IsAsciiDigit(*iter)) { + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } else if (*iter == char16_t('.')) { + // Do nothing, jumps to fraction part + } else { + return false; + } + + // Fraction + if (*iter == char16_t('.')) { + ++iter; + if (iter == end || !nsCRT::IsAsciiDigit(*iter)) { + // U+002E FULL STOP character (.) must be followed by one or more ASCII digits + return false; + } + + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } + + if (iter != end && (*iter == char16_t('e') || *iter == char16_t('E'))) { + ++iter; + if (*iter == char16_t('-') || *iter == char16_t('+')) { + ++iter; + } + + if (iter == end || !nsCRT::IsAsciiDigit(*iter)) { + // Should have one or more ASCII digits + return false; + } + + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } + + if (iter != end) { + return false; + } + + nsresult rv; + aDouble = PromiseFlatString(aString).ToDouble(&rv); + return NS_SUCCEEDED(rv); +} + ResponsiveImageSelector::ResponsiveImageSelector(nsIContent *aContent) : mOwnerNode(aContent), mSelectedCandidateIndex(-1) @@ -72,14 +132,6 @@ ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet) return false; } - // Preserve the default source if we have one, it has a separate setter. - uint32_t prevNumCandidates = mCandidates.Length(); - nsString defaultURLString; - if (prevNumCandidates && (mCandidates[prevNumCandidates - 1].Type() == - ResponsiveImageCandidate::eCandidateType_Default)) { - defaultURLString = mCandidates[prevNumCandidates - 1].URLString(); - } - mCandidates.Clear(); nsAString::const_iterator iter, end; @@ -127,9 +179,7 @@ ResponsiveImageSelector::SetCandidatesFromSourceSet(const nsAString & aSrcSet) bool parsedCandidates = mCandidates.Length() > 0; // Re-add default to end of list - if (!defaultURLString.IsEmpty()) { - AppendDefaultCandidate(defaultURLString); - } + MaybeAppendDefaultCandidate(); return parsedCandidates; } @@ -173,10 +223,10 @@ ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString) mCandidates.RemoveElementAt(candidates - 1); } - // Add new default if set - if (!aURLString.IsEmpty()) { - AppendDefaultCandidate(aURLString); - } + mDefaultSourceURL = aURLString; + + // Add new default to end of list + MaybeAppendDefaultCandidate(); } void @@ -209,9 +259,8 @@ ResponsiveImageSelector::AppendCandidateIfUnique(const ResponsiveImageCandidate int numCandidates = mCandidates.Length(); // With the exception of Default, which should not be added until we are done - // building the list, the spec forbids mixing width and explicit density - // selectors in the same set. - if (numCandidates && mCandidates[0].Type() != aCandidate.Type()) { + // building the list. + if (aCandidate.Type() == ResponsiveImageCandidate::eCandidateType_Default) { return; } @@ -226,13 +275,31 @@ ResponsiveImageSelector::AppendCandidateIfUnique(const ResponsiveImageCandidate } void -ResponsiveImageSelector::AppendDefaultCandidate(const nsAString& aURLString) +ResponsiveImageSelector::MaybeAppendDefaultCandidate() { - NS_ENSURE_TRUE(!aURLString.IsEmpty(), /* void */); + if (mDefaultSourceURL.IsEmpty()) { + return; + } + + int numCandidates = mCandidates.Length(); + + // https://html.spec.whatwg.org/multipage/embedded-content.html#update-the-source-set + // step 4.1.3: + // If child has a src attribute whose value is not the empty string and source + // set does not contain an image source with a density descriptor value of 1, + // and no image source with a width descriptor, append child's src attribute + // value to source set. + for (int i = 0; i < numCandidates; i++) { + if (mCandidates[i].IsComputedFromWidth()) { + return; + } else if (mCandidates[i].Density(this) == 1.0) { + return; + } + } ResponsiveImageCandidate defaultCandidate; defaultCandidate.SetParameterDefault(); - defaultCandidate.SetURLSpec(aURLString); + defaultCandidate.SetURLSpec(mDefaultSourceURL); // We don't use MaybeAppend since we want to keep this even if it can never // match, as it may if the source set changes. mCandidates.AppendElement(defaultCandidate); @@ -303,22 +370,15 @@ ResponsiveImageSelector::SelectImage(bool aReselect) // the greatest density available // If the list contains computed width candidates, compute the current - // effective image width. Note that we currently disallow both computed and - // static density candidates in the same selector, so checking the first - // candidate is sufficient. - int32_t computedWidth = -1; - if (numCandidates && mCandidates[0].IsComputedFromWidth()) { - DebugOnly computeResult = \ - ComputeFinalWidthForCurrentViewport(&computedWidth); - MOZ_ASSERT(computeResult, - "Computed candidates not allowed without sizes data"); - - // If we have a default candidate in the list, don't consider it when using - // computed widths. (It has a static 1.0 density that is inapplicable to a - // sized-image) - if (numCandidates > 1 && mCandidates[numCandidates - 1].Type() == - ResponsiveImageCandidate::eCandidateType_Default) { - numCandidates--; + // effective image width. + double computedWidth = -1; + for (int i = 0; i < numCandidates; i++) { + if (mCandidates[i].IsComputedFromWidth()) { + DebugOnly computeResult = \ + ComputeFinalWidthForCurrentViewport(&computedWidth); + MOZ_ASSERT(computeResult, + "Computed candidates not allowed without sizes data"); + break; } } @@ -363,7 +423,7 @@ ResponsiveImageSelector::GetSelectedCandidateIndex() } bool -ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth) +ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth) { unsigned int numSizes = mSizeQueries.Length(); nsIDocument* doc = Document(); @@ -371,7 +431,6 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth) nsPresContext *pctx = presShell ? presShell->GetPresContext() : nullptr; if (!pctx) { - MOZ_ASSERT(false, "Unable to find presContext for this content"); return false; } @@ -396,8 +455,7 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(int32_t *aWidth) mSizeValues[i]); } - MOZ_ASSERT(effectiveWidth >= 0); - *aWidth = nsPresContext::AppUnitsToIntCSSPixels(std::max(effectiveWidth, 0)); + *aWidth = nsPresContext::AppUnitsToDoubleCSSPixels(std::max(effectiveWidth, 0)); return true; } @@ -533,9 +591,8 @@ ResponsiveImageDescriptors::AddDescriptor(const nsAString& aDescriptor) } else if (*descType == char16_t('x')) { // If the value is not a valid floating point number, it doesn't match this // descriptor, fall through. - nsresult rv; - double possibleDensity = PromiseFlatString(valueStr).ToDouble(&rv); - if (NS_SUCCEEDED(rv)) { + double possibleDensity = 0.0; + if (ParseFloat(valueStr, possibleDensity)) { if (possibleDensity >= 0.0 && mWidth.isNothing() && mDensity.isNothing() && @@ -674,7 +731,7 @@ double ResponsiveImageCandidate::Density(ResponsiveImageSelector *aSelector) const { if (mType == eCandidateType_ComputedFromWidth) { - int32_t width; + double width; if (!aSelector->ComputeFinalWidthForCurrentViewport(&width)) { return 1.0; } @@ -688,7 +745,7 @@ ResponsiveImageCandidate::Density(ResponsiveImageSelector *aSelector) const } double -ResponsiveImageCandidate::Density(int32_t aMatchingWidth) const +ResponsiveImageCandidate::Density(double aMatchingWidth) const { if (mType == eCandidateType_Invalid) { MOZ_ASSERT(false, "Getting density for uninitialized candidate"); @@ -706,7 +763,7 @@ ResponsiveImageCandidate::Density(int32_t aMatchingWidth) const MOZ_ASSERT(false, "Don't expect to have a negative matching width at this point"); return 1.0; } - double density = double(mValue.mWidth) / double(aMatchingWidth); + double density = double(mValue.mWidth) / aMatchingWidth; MOZ_ASSERT(density > 0.0); return density; } diff --git a/dom/base/ResponsiveImageSelector.h b/dom/base/ResponsiveImageSelector.h index a7f6ede569..6202608614 100644 --- a/dom/base/ResponsiveImageSelector.h +++ b/dom/base/ResponsiveImageSelector.h @@ -86,9 +86,9 @@ private: // candidate void AppendCandidateIfUnique(const ResponsiveImageCandidate &aCandidate); - // Append a default candidate with this URL. Does not check if the array - // already contains one, use SetDefaultSource instead. - void AppendDefaultCandidate(const nsAString& aURLString); + // Append a default candidate with this URL if necessary. Does not check if + // the array already contains one, use SetDefaultSource instead. + void MaybeAppendDefaultCandidate(); // Get index of selected candidate, triggering selection if necessary. int GetSelectedCandidateIndex(); @@ -102,9 +102,11 @@ private: // // aContext is the presContext to use for current viewport sizing, null will // use the associated content's context. - bool ComputeFinalWidthForCurrentViewport(int32_t *aWidth); + bool ComputeFinalWidthForCurrentViewport(double* aWidth); nsCOMPtr mOwnerNode; + // The cached URL for default candidate. + nsString mDefaultSourceURL; // If this array contains an eCandidateType_Default, it should be the last // element, such that the Setters can preserve/replace it respectively. nsTArray mCandidates; @@ -150,7 +152,7 @@ public: double Density(ResponsiveImageSelector *aSelector) const; // If the width is already known. Useful when iterating over candidates to // avoid having each call re-compute the width. - double Density(int32_t aMatchingWidth) const; + double Density(double aMatchingWidth) const; // If this selector is computed from the selector's matching width. bool IsComputedFromWidth() const; diff --git a/dom/base/WindowNamedPropertiesHandler.cpp b/dom/base/WindowNamedPropertiesHandler.cpp index deb17a54c5..b35f9534ae 100644 --- a/dom/base/WindowNamedPropertiesHandler.cpp +++ b/dom/base/WindowNamedPropertiesHandler.cpp @@ -186,22 +186,24 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx, nsGlobalWindow* outer = win->GetOuterWindowInternal(); if (outer) { nsDOMWindowList* childWindows = outer->GetWindowList(); - uint32_t length = childWindows->GetLength(); - for (uint32_t i = 0; i < length; ++i) { - nsCOMPtr item = - childWindows->GetDocShellTreeItemAt(i); - // This is a bit silly, since we could presumably just do - // item->GetWindow(). But it's not obvious whether this does the same - // thing as GetChildWindow() with the item's name (due to the complexity - // of FindChildWithName). Since GetChildWindow is what we use in - // getOwnPropDescriptor, let's try to be consistent. - nsString name; - item->GetName(name); - if (!names.Contains(name)) { - // Make sure we really would expose it from getOwnPropDescriptor. - nsCOMPtr childWin = win->GetChildWindow(name); - if (childWin && ShouldExposeChildWindow(name, childWin)) { - names.AppendElement(name); + if (childWindows) { + uint32_t length = childWindows->GetLength(); + for (uint32_t i = 0; i < length; ++i) { + nsCOMPtr item = + childWindows->GetDocShellTreeItemAt(i); + // This is a bit silly, since we could presumably just do + // item->GetWindow(). But it's not obvious whether this does the same + // thing as GetChildWindow() with the item's name (due to the complexity + // of FindChildWithName). Since GetChildWindow is what we use in + // getOwnPropDescriptor, let's try to be consistent. + nsString name; + item->GetName(name); + if (!names.Contains(name)) { + // Make sure we really would expose it from getOwnPropDescriptor. + nsCOMPtr childWin = win->GetChildWindow(name); + if (childWin && ShouldExposeChildWindow(name, childWin)) { + names.AppendElement(name); + } } } } diff --git a/dom/base/contentAreaDropListener.js b/dom/base/contentAreaDropListener.js index 44afa67157..8f54275195 100644 --- a/dom/base/contentAreaDropListener.js +++ b/dom/base/contentAreaDropListener.js @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/osfile.jsm"); const Cc = Components.classes; const Ci = Components.interfaces; @@ -42,13 +43,9 @@ ContentAreaDropListener.prototype = // For shortcuts, we want to check for the file type last, so that the // url pointed to in one of the url types is found first before the file // type, which points to the actual file. - let file = dt.mozGetDataAt("application/x-moz-file", 0); - if (file instanceof Ci.nsIFile) { - let ioService = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - let fileHandler = ioService.getProtocolHandler("file") - .QueryInterface(Ci.nsIFileProtocolHandler); - return [fileHandler.getURLSpecFromFile(file), file.leafName]; + let files = dt.files; + if (files && files.length) { + return [OS.Path.toFileURI(files[0].mozFullPath), files[0].name]; } return [ ]; diff --git a/dom/base/crashtests/1158412.html b/dom/base/crashtests/1158412.html new file mode 100644 index 0000000000..e62fce1ab9 --- /dev/null +++ b/dom/base/crashtests/1158412.html @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/dom/base/crashtests/crashtests.list b/dom/base/crashtests/crashtests.list index 6799f3f6c0..03b0aed11b 100644 --- a/dom/base/crashtests/crashtests.list +++ b/dom/base/crashtests/crashtests.list @@ -198,6 +198,7 @@ pref(dom.webcomponents.enabled,true) load 1027461-1.html pref(dom.webcomponents.enabled,true) load 1029710.html load 1154598.xhtml load 1157995.html +load 1158412.html load 1181619.html load structured_clone_container_throws.html HTTP(..) load xhr_abortinprogress.html diff --git a/dom/base/nsContentPermissionHelper.cpp b/dom/base/nsContentPermissionHelper.cpp index 1f4efe73b2..6bf700f0ee 100644 --- a/dom/base/nsContentPermissionHelper.cpp +++ b/dom/base/nsContentPermissionHelper.cpp @@ -32,6 +32,7 @@ #include "nsIDocument.h" #include "nsIDOMEvent.h" #include "nsWeakPtr.h" +#include "ScriptSettings.h" using mozilla::Unused; // using namespace mozilla::dom; @@ -708,7 +709,10 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices) for (uint32_t i = 0; i < mPermissionRequests.Length(); ++i) { nsCString type = mPermissionRequests[i].type(); - mozilla::AutoSafeJSContext cx; + AutoJSAPI jsapi; + jsapi.Init(); + + JSContext* cx = jsapi.cx(); JS::Rooted obj(cx, &aChoices.toObject()); JSAutoCompartment ac(cx, obj); @@ -716,10 +720,12 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices) if (!JS_GetProperty(cx, obj, type.BeginReading(), &val) || !val.isString()) { - // no setting for the permission type, skip it + // no setting for the permission type, clear exception and skip it + jsapi.ClearException(); } else { nsAutoJSString choice; if (!choice.init(cx, val)) { + jsapi.ClearException(); return NS_ERROR_FAILURE; } choices.AppendElement(PermissionChoice(type, choice)); diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 88061ffa3b..fe5f5cfa74 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -2721,7 +2721,7 @@ nsContentUtils::SubjectPrincipal() MOZ_ASSERT(NS_IsMainThread()); JSContext* cx = GetCurrentJSContext(); if (!cx) { - return GetSystemPrincipal(); + MOZ_CRASH("Accessing the Subject Principal without an AutoJSAPI on the stack is forbidden"); } JSCompartment *compartment = js::GetContextCompartment(cx); @@ -5797,26 +5797,6 @@ nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) NS_ENSURE_SUCCESS(rv, rv); if (uri && uri != aURI) { - return GetUTFOrigin(uri, aOrigin); - } - } else { - // We are probably dealing with an unknown blob URL. - bool isBlobURL = false; - nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL); - NS_ENSURE_SUCCESS(rv, rv); - - if (isBlobURL) { - nsAutoCString path; - rv = aURI->GetPath(path); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), path); - if (NS_FAILED(rv)) { - aOrigin.AssignLiteral("null"); - return NS_OK; - } - return GetUTFOrigin(uri, aOrigin); } } @@ -7386,14 +7366,14 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, nsAutoString dataAsString; text->GetData(dataAsString); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); - item->data() = nsString(dataAsString); + item->flavor() = flavorStr; + item->data() = dataAsString; } else if (ctext) { nsAutoCString dataAsString; ctext->GetData(dataAsString); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); - item->data() = nsCString(dataAsString); + item->flavor() = flavorStr; + item->data() = dataAsString; } else { nsCOMPtr sip = do_QueryInterface(data); @@ -7405,7 +7385,7 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, nsCOMPtr stream(do_QueryInterface(data)); if (stream) { IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); + item->flavor() = flavorStr; nsCString imageData; NS_ConsumeStream(stream, UINT32_MAX, imageData); @@ -7428,8 +7408,10 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, nsContentUtils::GetSurfaceData(dataSurface, &length, &stride); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); - item->data() = nsCString(surfaceData.get(), length); + item->flavor() = flavorStr; + // Turn item->data() into an nsCString prior to accessing it. + item->data() = EmptyCString(); + item->data().get_nsCString().Adopt(surfaceData.release(), length); IPCDataTransferImage& imageDetails = item->imageDetails(); mozilla::gfx::IntSize size = dataSurface->GetSize(); @@ -7478,17 +7460,32 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, blobImpl = do_QueryInterface(data); } if (blobImpl) { - IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); + IPCDataTransferData data; + + // If we failed to create the blob actor, then this blob probably + // can't get the file size for the underlying file, ignore it for + // now. TODO pass this through anyway. if (aChild) { - item->data() = - mozilla::dom::BlobChild::GetOrCreate(aChild, - static_cast(blobImpl.get())); + auto* child = mozilla::dom::BlobChild::GetOrCreate(aChild, + static_cast(blobImpl.get())); + if (!child) { + continue; + } + + data = child; } else if (aParent) { - item->data() = - mozilla::dom::BlobParent::GetOrCreate(aParent, - static_cast(blobImpl.get())); + auto* parent = mozilla::dom::BlobParent::GetOrCreate(aParent, + static_cast(blobImpl.get())); + if (!parent) { + continue; + } + + data = parent; } + + IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); + item->flavor() = flavorStr; + item->data() = data; } else { // This is a hack to support kFilePromiseMime. // On Windows there just needs to be an entry for it, @@ -7496,8 +7493,14 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, // nsContentAreaDragDropDataProvider as nsIFlavorDataProvider. if (flavorStr.EqualsLiteral(kFilePromiseMime)) { IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); + item->flavor() = flavorStr; item->data() = NS_ConvertUTF8toUTF16(flavorStr); + } else if (!data) { + // Empty element, transfer only the flavor + IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); + item->flavor() = flavorStr; + item->data() = EmptyCString(); + continue; } } } @@ -8147,6 +8150,26 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal, // About URIs are allowed to access storage, even if they don't have chrome // privileges. If this is not desired, than the consumer will have to // implement their own restriction functionality. + // + // This is due to backwards-compatibility and the state of storage access before + // the introducton of nsContentUtils::InternalStorageAllowedForPrincipal: + // + // BEFORE: + // localStorage, caches: allowed in 3rd-party iframes always + // IndexedDB: allowed in 3rd-party iframes only if 3rd party URI is an about: + // URI within a specific whitelist + // + // AFTER: + // localStorage, caches: allowed in 3rd-party iframes by default. Preference + // can be set to disable in 3rd-party, which will not disallow in about: URIs. + // IndexedDB: allowed in 3rd-party iframes by default. Preference can be set to + // disable in 3rd-party, which will disallow in about: URIs, unless they are + // within a specific whitelist. + // + // This means that behavior for storage with internal about: URIs should not be + // affected, which is desireable due to the lack of automated testing for about: + // URIs with these preferences set, and the importance of the correct functioning + // of these URIs even with custom preferences. nsCOMPtr uri; nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri)); if (NS_SUCCEEDED(rv) && uri) { diff --git a/dom/base/nsDOMAttributeMap.h b/dom/base/nsDOMAttributeMap.h index d403f209fe..07e4111d27 100644 --- a/dom/base/nsDOMAttributeMap.h +++ b/dom/base/nsDOMAttributeMap.h @@ -35,10 +35,10 @@ public: int32_t mNamespaceID; /** - * The atom for attribute, weak ref. is fine as we only use it for the - * hashcode, we never dereference it. + * The atom for attribute, stored as void*, to make sure that we only use it + * for the hashcode, and we can never dereference it. */ - nsIAtom* mLocalName; + void* mLocalName; nsAttrKey(int32_t aNs, nsIAtom* aName) : mNamespaceID(aNs), mLocalName(aName) {} diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index e1046aae4c..c220e423ab 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -121,15 +121,6 @@ using namespace mozilla::dom; // NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS // are defined in nsIDOMClassInfo.h. -#define ARRAY_SCRIPTABLE_FLAGS \ - (DOM_DEFAULT_SCRIPTABLE_FLAGS | \ - nsIXPCScriptable::WANT_GETPROPERTY | \ - nsIXPCScriptable::WANT_ENUMERATE) - -#define EVENTTARGET_SCRIPTABLE_FLAGS \ - (DOM_DEFAULT_SCRIPTABLE_FLAGS | \ - nsIXPCScriptable::WANT_ADDPROPERTY) - #define DOMCLASSINFO_STANDARD_FLAGS \ (nsIClassInfo::MAIN_THREAD_ONLY | \ nsIClassInfo::DOM_OBJECT | \ diff --git a/dom/base/nsDOMMutationObserver.h b/dom/base/nsDOMMutationObserver.h index 88edb452f2..13fd8c9059 100644 --- a/dom/base/nsDOMMutationObserver.h +++ b/dom/base/nsDOMMutationObserver.h @@ -335,6 +335,7 @@ public: nsMutationReceiverBase* aParent) { nsMutationReceiver* r = new nsMutationReceiver(aRegisterTarget, aParent); + aParent->AddClone(r); r->AddObserver(); return r; } @@ -397,7 +398,6 @@ protected: { NS_ASSERTION(!static_cast(aParent)->GetParent(), "Shouldn't create deep observer hierarchies!"); - aParent->AddClone(this); } virtual void AddMutationObserver() override @@ -421,6 +421,7 @@ public: nsMutationReceiverBase* aParent) { nsAnimationReceiver* r = new nsAnimationReceiver(aRegisterTarget, aParent); + aParent->AddClone(r); r->AddObserver(); return r; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 293420d807..b9280c095a 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -29,6 +29,7 @@ #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsILoadContext.h" +#include "nsITextControlFrame.h" #include "nsUnicharUtils.h" #include "nsContentList.h" #include "nsCSSPseudoElements.h" @@ -1676,11 +1677,6 @@ nsDocument::~nsDocument() mImageTracker.Clear(); mPlugins.Clear(); - - nsCOMPtr os = mozilla::services::GetObserverService(); - if (os) { - os->RemoveObserver(this, "service-worker-get-client"); - } } NS_INTERFACE_TABLE_HEAD(nsDocument) @@ -2082,11 +2078,6 @@ nsDocument::Init() mozilla::HoldJSObjects(this); - nsCOMPtr os = mozilla::services::GetObserverService(); - if (os) { - os->AddObserver(this, "service-worker-get-client", /* ownsWeak */ true); - } - return NS_OK; } @@ -4684,6 +4675,28 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) } swm->MaybeStopControlling(this); } + + // Remove ourself from the list of clients. We only register + // content principal documents in this list. + if (!nsContentUtils::IsSystemPrincipal(GetPrincipal()) && + !GetPrincipal()->GetIsNullPrincipal()) { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->RemoveObserver(this, "service-worker-get-client"); + } + } + + } else if (!mScriptGlobalObject && aScriptGlobalObject && + mDocumentContainer && GetChannel() && + !nsContentUtils::IsSystemPrincipal(GetPrincipal()) && + !GetPrincipal()->GetIsNullPrincipal()) { + // This document is being activated. Register it in the list of + // clients. We only do this for content principal documents + // since we can never observe system or null principals. + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->AddObserver(this, "service-worker-get-client", /* ownsWeak */ false); + } } // BlockOnload() might be called before mScriptGlobalObject is set. @@ -10810,10 +10823,8 @@ nsIDocument::CaretPositionFromPoint(float aX, float aY) nsIContent* nonanon = node->FindFirstNonChromeOnlyAccessContent(); nsCOMPtr input = do_QueryInterface(nonanon); nsCOMPtr textArea = do_QueryInterface(nonanon); - bool isText; - if (textArea || (input && - NS_SUCCEEDED(input->MozIsTextField(false, &isText)) && - isText)) { + nsITextControlFrame* textFrame = do_QueryFrame(nonanon->GetPrimaryFrame()); + if (!!textFrame) { // If the anonymous content node has a child, then we need to make sure // that we get the appropriate child, as otherwise the offset may not be // correct when we construct a range for it. @@ -12422,11 +12433,18 @@ nsDocument::Observe(nsISupports *aSubject, OnAppThemeChanged(); } } else if (strcmp("service-worker-get-client", aTopic) == 0) { - nsAutoString clientId; - GetOrCreateId(clientId); + // No need to generate the ID if it doesn't exist here. The ID being + // requested must already be generated in order to passed in as + // aSubject. + nsString clientId = GetId(); if (!clientId.IsEmpty() && clientId.Equals(aData)) { nsCOMPtr ifptr = do_QueryInterface(aSubject); if (ifptr) { +#ifdef DEBUG + nsCOMPtr value; + MOZ_ALWAYS_SUCCEEDS(ifptr->GetData(getter_AddRefs(value))); + MOZ_ASSERT(!value); +#endif ifptr->SetData(static_cast(this)); ifptr->SetDataIID(&NS_GET_IID(nsIDocument)); } diff --git a/dom/base/nsGenericDOMDataNode.cpp b/dom/base/nsGenericDOMDataNode.cpp index 505599dc03..494c66c06e 100644 --- a/dom/base/nsGenericDOMDataNode.cpp +++ b/dom/base/nsGenericDOMDataNode.cpp @@ -371,7 +371,10 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount, } if (dirAffectsAncestor) { - TextNodeChangedDirection(this, oldDir, aNotify); + // dirAffectsAncestor being true implies that we have a text node, see + // above. + MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE); + TextNodeChangedDirection(static_cast(this), oldDir, aNotify); } // Notify observers diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index bb8e0fcb9e..311610e05d 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -1598,8 +1598,11 @@ public: "ClearHasTextNodeDirectionalityMap on non-text node"); ClearBoolFlag(NodeHasTextNodeDirectionalityMap); } - bool HasTextNodeDirectionalityMap() const - { return GetBoolFlag(NodeHasTextNodeDirectionalityMap); } + bool HasTextNodeDirectionalityMap() const { + MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, + "HasTextNodeDirectionalityMap on non-text node"); + return GetBoolFlag(NodeHasTextNodeDirectionalityMap); + } void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); } void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); } diff --git a/dom/base/nsTextNode.h b/dom/base/nsTextNode.h index 24725ecb81..488540a826 100644 --- a/dom/base/nsTextNode.h +++ b/dom/base/nsTextNode.h @@ -49,6 +49,7 @@ public: // nsIDOMNode NS_FORWARD_NSIDOMNODE_TO_NSINODE + using mozilla::dom::Text::GetParentElement; // nsIDOMCharacterData NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::) diff --git a/dom/base/test/browser.ini b/dom/base/test/browser.ini index 64a31e34f6..1fc1c68546 100644 --- a/dom/base/test/browser.ini +++ b/dom/base/test/browser.ini @@ -1,5 +1,7 @@ [DEFAULT] support-files = + file_bug1011748_redirect.sjs + file_bug1011748_OK.sjs file_messagemanager_unload.html file_use_counter_outer.html file_use_counter_svg_getElementById.svg @@ -28,3 +30,4 @@ skip-if = e10s # We need bug 918634 to land before this can be tested with e10s. [browser_use_counters.js] [browser_bug1238440.js] skip-if = e10s +[browser_bug1011748.js] diff --git a/dom/base/test/browser_bug1011748.js b/dom/base/test/browser_bug1011748.js new file mode 100644 index 0000000000..a2158500df --- /dev/null +++ b/dom/base/test/browser_bug1011748.js @@ -0,0 +1,31 @@ +const gHttpTestRoot = "http://example.com/browser/dom/base/test/"; + +add_task(function* () { + var statusTexts = []; + var xhr = new XMLHttpRequest(); + var observer = { + observe: function (aSubject, aTopic, aData) { + try { + var channel = aSubject.QueryInterface(Ci.nsIHttpChannel); + channel.getResponseHeader("Location"); + } catch (e) { + return; + } + statusTexts.push(xhr.statusText); + } + }; + + Services.obs.addObserver(observer, "http-on-examine-response", false); + yield new Promise((resolve) => { + xhr.addEventListener("load", function() { + statusTexts.push(this.statusText); + is(statusTexts[0], "", "Empty statusText value for HTTP 302"); + is(statusTexts[1], "OK", "OK statusText value for the redirect."); + resolve(); + }); + xhr.open("GET", gHttpTestRoot+ "file_bug1011748_redirect.sjs", true); + xhr.send(); + }); + + Services.obs.removeObserver(observer, "http-on-examine-response"); +}); diff --git a/dom/base/test/chrome/chrome.ini b/dom/base/test/chrome/chrome.ini index f7d5b62f19..f608a22281 100644 --- a/dom/base/test/chrome/chrome.ini +++ b/dom/base/test/chrome/chrome.ini @@ -70,7 +70,6 @@ skip-if = buildapp == 'mulet' [test_bug1346936.html] [test_cpows.xul] skip-if = buildapp == 'mulet' -[test_document_register.xul] [test_mutationobserver_anonymous.html] [test_registerElement_content.xul] [test_registerElement_ep.xul] diff --git a/dom/base/test/chrome/test_document_register.xul b/dom/base/test/chrome/test_document_register.xul deleted file mode 100644 index 84333bb0e5..0000000000 --- a/dom/base/test/chrome/test_document_register.xul +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - Mozilla Bug 783129 - - - - - - diff --git a/dom/base/test/copypaste.js b/dom/base/test/copypaste.js index 27f9779109..6fa3cb909e 100644 --- a/dom/base/test/copypaste.js +++ b/dom/base/test/copypaste.js @@ -122,7 +122,7 @@ function testCopyPaste (isXHTML) { function testPasteHTML(id, expected) { var contentEditable = $(id); contentEditable.focus(); - synthesizeKey("v", {accelKey: 1}); + synthesizeKey("v", {accelKey: true}); is(contentEditable.innerHTML, expected, id+".innerHtml after the paste"); } function testSelectionToString(expected) { diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 5ef6e1216a..8fbaeedbaa 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -817,9 +817,6 @@ support-files = bug444546.sjs [test_bug503473.html] disabled = Disabled due to making the harness time out support-files = file_bug503473-frame.sjs -[test_bug1011748.html] -skip-if = buildapp == 'b2g' || e10s -support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs [test_bug1025933.html] [test_bug1037687.html] [test_element.matches.html] @@ -855,3 +852,6 @@ skip-if = buildapp == 'b2g' #no ssl support [test_bug1187157.html] [test_bug769117.html] [test_bug1250148.html] +[test_document_register.html] +[test_bug962251.html] +[test_bug1259588.html] diff --git a/dom/base/test/test_bug1011748.html b/dom/base/test/test_bug1011748.html deleted file mode 100644 index 3ab23cc972..0000000000 --- a/dom/base/test/test_bug1011748.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - Test for Bug 1011748 - - - - - -Mozilla Bug 1011748 -

- -
-
- - diff --git a/dom/base/test/test_bug1259588.html b/dom/base/test/test_bug1259588.html new file mode 100644 index 0000000000..40a272f905 --- /dev/null +++ b/dom/base/test/test_bug1259588.html @@ -0,0 +1,13 @@ + + +Test for Bug 1259588 + + +
+ diff --git a/dom/base/test/test_caretPositionFromPoint.html b/dom/base/test/test_caretPositionFromPoint.html index 05d31ab504..4a613935d9 100644 --- a/dom/base/test/test_caretPositionFromPoint.html +++ b/dom/base/test/test_caretPositionFromPoint.html @@ -91,6 +91,16 @@ todo(false, "test5Rect: (" + test5Rect.top + ", " + test5Rect.left + ", " + test5Rect.width + ", " + test5Rect.height + ")"); checkOffsetsFromPoint(test5x, test5y, 0, 'test5'); + // Check the first and last characters of the numeric input. + var test6Element = document.getElementById("test6"); + var test6Rect = test6Element.getBoundingClientRect(); + checkOffsetsFromPoint(Math.round(test6Rect.left + 5), + Math.round(test6Rect.top + (test6Rect.height / 2)), + 0, "test6"); + checkOffsetsFromPoint(Math.round(test6Rect.left + test6Rect.width - 30), + Math.round(test6Rect.top + (test6Rect.height / 2)), + 5, "test6"); + SimpleTest.finish(); } @@ -104,5 +114,6 @@ marquee +
diff --git a/dom/base/test/test_document_register.html b/dom/base/test/test_document_register.html new file mode 100644 index 0000000000..6cf15a52f2 --- /dev/null +++ b/dom/base/test/test_document_register.html @@ -0,0 +1,27 @@ + + + + + + + + Mozilla Bug 783129 + + + + diff --git a/dom/battery/BatteryManager.cpp b/dom/battery/BatteryManager.cpp index 86d1d5cbcd..9454d5aa04 100644 --- a/dom/battery/BatteryManager.cpp +++ b/dom/battery/BatteryManager.cpp @@ -140,15 +140,18 @@ BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInf doc->NodePrincipal()->GetAppStatus(&status); } + mCharging = aBatteryInfo.charging(); + mRemainingTime = aBatteryInfo.remainingTime(); + if (!nsContentUtils::IsChromeDoc(doc) && status != nsIPrincipal::APP_STATUS_CERTIFIED) { mLevel = lround(mLevel * 10.0) / 10.0; + if (mLevel == 1.0) { + mRemainingTime = mCharging ? kDefaultRemainingTime : kUnknownRemainingTime; + } } - mCharging = aBatteryInfo.charging(); - mRemainingTime = aBatteryInfo.remainingTime(); - // Add some guards to make sure the values are coherent. if (mLevel == 1.0 && mCharging == true && mRemainingTime != kDefaultRemainingTime) { diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index ce00d65cbd..26909d247f 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -101,7 +101,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, } } else { JSObject *global = js::GetGlobalForObjectCrossCompartment(realCallback); - globalObject = workers::GetGlobalObjectForGlobal(global); + globalObject = xpc::NativeGlobal(global); MOZ_ASSERT(globalObject); } @@ -245,41 +245,13 @@ CallbackObject::CallSetup::~CallSetup() if (needToDealWithException) { // Either we're supposed to report our exceptions, or we're supposed to // re-throw them but we failed to get the exception value. Either way, - // just report the pending exception, if any. - // - // We don't use nsJSUtils::ReportPendingException here because all it - // does at this point is JS_SaveFrameChain and enter a compartment around - // a JS_ReportPendingException call. But our mAutoEntryScript should - // already do a JS_SaveFrameChain and we are already in the compartment - // we want to be in, so all nsJSUtils::ReportPendingException would do is - // screw up our compartment, which is exactly what we do not want. - // - // XXXbz FIXME: bug 979525 means we don't always JS_SaveFrameChain here, - // so we need to go ahead and do that. This is also the reason we don't - // just rely on ~AutoJSAPI reporting the exception for us. I think if we - // didn't need to JS_SaveFrameChain here, we could just rely on that. - JS::Rooted oldGlobal(mCx, JS::CurrentGlobalOrNull(mCx)); - MOZ_ASSERT(oldGlobal, "How can we not have a global here??"); - bool saved = JS_SaveFrameChain(mCx); - // Make sure the JSAutoCompartment goes out of scope before the - // JS_RestoreFrameChain call! - { - JSAutoCompartment ac(mCx, oldGlobal); - MOZ_ASSERT(!JS::DescribeScriptedCaller(mCx), - "Our comment above about JS_SaveFrameChain having been " - "called is a lie?"); - // Note that we don't JS_ReportPendingException here because we want to - // go through our AutoEntryScript's reporting mechanism instead, since - // it currently owns error reporting. - mAutoEntryScript->ReportException(); - } - if (saved) { - JS_RestoreFrameChain(mCx); - } - + // we'll just report the pending exception, if any, once ~mAutoEntryScript + // runs. Note that we've already run ~mAc, effectively, so we don't have + // to worry about ordering here. if (mErrorResult.IsJSContextException()) { // XXXkhuey bug 1117269. - // This isn't true anymore ... so throw something else. + // This won't be true anymore because we will report the exception on + // the JSContext ... so throw something else. mErrorResult.Throw(NS_ERROR_UNEXPECTED); } } diff --git a/dom/bindings/Exceptions.cpp b/dom/bindings/Exceptions.cpp index 6757ec964e..6b71549702 100644 --- a/dom/bindings/Exceptions.cpp +++ b/dom/bindings/Exceptions.cpp @@ -66,6 +66,24 @@ ThrowExceptionObject(JSContext* aCx, Exception* aException) // thread. if (NS_IsMainThread() && !nsContentUtils::IsCallerChrome() && aException->StealJSVal(thrown.address())) { + // Now check for the case when thrown is a number which matches + // aException->GetResult(). This would indicate that what actually got + // thrown was an nsresult value. In that situation, we should go back + // through dom::Throw with that nsresult value, because it will make sure to + // create the right sort of Exception or DOMException, with the right + // global. + if (thrown.isNumber()) { + nsresult exceptionResult; + if (NS_SUCCEEDED(aException->GetResult(&exceptionResult)) && + double(exceptionResult) == thrown.toNumber()) { + // The return value semantics here are a bit weird. Throw() always + // returns false. But we want to return true if we managed to throw an + // exception (otherwise our caller will assume OOM)... which Throw() + // always will. So we just return true unconditionally. + Throw(aCx, exceptionResult); + return true; + } + } if (!JS_WrapValue(aCx, &thrown)) { return false; } @@ -103,15 +121,17 @@ Throw(JSContext* aCx, nsresult aRv, const nsACString& aMessage) CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get(); nsCOMPtr existingException = runtime->GetPendingException(); - if (existingException) { + // Make sure to clear the pending exception now. Either we're going to reuse + // it (and we already grabbed it), or we plan to throw something else and this + // pending exception is no longer relevant. + runtime->SetPendingException(nullptr); + + // Ignore the pending exception if we have a non-default message passed in. + if (aMessage.IsEmpty() && existingException) { nsresult nr; if (NS_SUCCEEDED(existingException->GetResult(&nr)) && aRv == nr) { // Reuse the existing exception. - - // Clear pending exception - runtime->SetPendingException(nullptr); - if (!ThrowExceptionObject(aCx, existingException)) { // If we weren't able to throw an exception we're // most likely out of memory diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp index ca7af7dcdf..48db47da3b 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp @@ -228,6 +228,10 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes) } BluetoothA2dpManager::~BluetoothA2dpManager() +{ } + +void +BluetoothA2dpManager::Uninit() { nsCOMPtr obs = services::GetObserverService(); NS_ENSURE_TRUE_VOID(obs); @@ -273,9 +277,9 @@ BluetoothA2dpManager::Get() // If we're in shutdown, don't create a new instance NS_ENSURE_FALSE(sInShutdown, nullptr); - // Create a new instance, register, and return - BluetoothA2dpManager* manager = new BluetoothA2dpManager(); - sBluetoothA2dpManager = manager; + // Create a new instance and return + sBluetoothA2dpManager = new BluetoothA2dpManager(); + return sBluetoothA2dpManager; } @@ -297,6 +301,9 @@ public: sBtA2dpInterface->SetNotificationHandler(nullptr); sBtA2dpInterface = nullptr; + sBluetoothA2dpManager->Uninit(); + sBluetoothA2dpManager = nullptr; + if (mRes) { mRes->OnError(NS_ERROR_FAILURE); } @@ -309,6 +316,9 @@ public: sBtA2dpInterface->SetNotificationHandler(nullptr); sBtA2dpInterface = nullptr; + sBluetoothA2dpManager->Uninit(); + sBluetoothA2dpManager = nullptr; + if (mRes) { mRes->Deinit(); } diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h index dda282654b..339e9bae6a 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h +++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h @@ -58,6 +58,7 @@ private: BluetoothA2dpManager(); + void Uninit(); void HandleShutdown(); void NotifyConnectionStatusChanged(); diff --git a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp index 9584e8f6e1..2c3e03bceb 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp @@ -268,6 +268,10 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes) } BluetoothAvrcpManager::~BluetoothAvrcpManager() +{ } + +void +BluetoothAvrcpManager::Uninit() { nsCOMPtr obs = services::GetObserverService(); NS_ENSURE_TRUE_VOID(obs); @@ -294,9 +298,9 @@ BluetoothAvrcpManager::Get() // If we're in shutdown, don't create a new instance NS_ENSURE_FALSE(sInShutdown, nullptr); - // Create a new instance, register, and return - BluetoothAvrcpManager* manager = new BluetoothAvrcpManager(); - sBluetoothAvrcpManager = manager; + // Create a new instance and return + sBluetoothAvrcpManager = new BluetoothAvrcpManager(); + return sBluetoothAvrcpManager; } @@ -318,6 +322,9 @@ public: sBtAvrcpInterface->SetNotificationHandler(nullptr); sBtAvrcpInterface = nullptr; + sBluetoothAvrcpManager->Uninit(); + sBluetoothAvrcpManager = nullptr; + if (mRes) { mRes->OnError(NS_ERROR_FAILURE); } @@ -330,6 +337,9 @@ public: sBtAvrcpInterface->SetNotificationHandler(nullptr); sBtAvrcpInterface = nullptr; + sBluetoothAvrcpManager->Uninit(); + sBluetoothAvrcpManager = nullptr; + if (mRes) { mRes->Deinit(); } diff --git a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h index 5714d656ea..22998ebd6b 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h +++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h @@ -71,6 +71,7 @@ private: BluetoothAvrcpManager(); + void Uninit(); void HandleShutdown(); void NotifyConnectionStatusChanged(); diff --git a/dom/bluetooth/bluedroid/BluetoothGattManager.cpp b/dom/bluetooth/bluedroid/BluetoothGattManager.cpp index a9c708e94c..5c8eb6b2a6 100644 --- a/dom/bluetooth/bluedroid/BluetoothGattManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothGattManager.cpp @@ -389,11 +389,41 @@ BluetoothGattManager::Get() NS_ENSURE_FALSE(mInShutdown, nullptr); // Create a new instance, register, and return - BluetoothGattManager* manager = new BluetoothGattManager(); + RefPtr manager = new BluetoothGattManager(); + NS_ENSURE_SUCCESS(manager->Init(), nullptr); + sBluetoothGattManager = manager; + return sBluetoothGattManager; } +nsresult +BluetoothGattManager::Init() +{ + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr obs = services::GetObserverService(); + NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE); + + auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + if (NS_FAILED(rv)) { + BT_WARNING("Failed to add observers!"); + return rv; + } + + return NS_OK; +} + +void +BluetoothGattManager::Uninit() +{ + nsCOMPtr obs = services::GetObserverService(); + NS_ENSURE_TRUE_VOID(obs); + if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { + BT_WARNING("Failed to remove shutdown observer!"); + } +} + class BluetoothGattManager::RegisterModuleResultHandler final : public BluetoothSetupResultHandler { @@ -552,6 +582,11 @@ public: sBluetoothGattInterface->SetNotificationHandler(nullptr); sBluetoothGattInterface = nullptr; + sClients = nullptr; + sServers = nullptr; + + sBluetoothGattManager->Uninit(); + sBluetoothGattManager = nullptr; if (mRes) { mRes->OnError(NS_ERROR_FAILURE); @@ -567,6 +602,9 @@ public: sClients = nullptr; sServers = nullptr; + sBluetoothGattManager->Uninit(); + sBluetoothGattManager = nullptr; + if (mRes) { mRes->Deinit(); } @@ -4073,13 +4111,7 @@ BluetoothGattManager::BluetoothGattManager() { } BluetoothGattManager::~BluetoothGattManager() -{ - nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE_VOID(obs); - if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { - BT_WARNING("Failed to remove shutdown observer!"); - } -} +{ } NS_IMETHODIMP BluetoothGattManager::Observe(nsISupports* aSubject, diff --git a/dom/bluetooth/bluedroid/BluetoothGattManager.h b/dom/bluetooth/bluedroid/BluetoothGattManager.h index adfe13ae74..47f2b75622 100644 --- a/dom/bluetooth/bluedroid/BluetoothGattManager.h +++ b/dom/bluetooth/bluedroid/BluetoothGattManager.h @@ -217,6 +217,8 @@ private: BluetoothGattManager(); + nsresult Init(); + void Uninit(); void HandleShutdown(); void RegisterClientNotification(BluetoothGattStatus aStatus, diff --git a/dom/bluetooth/bluedroid/BluetoothMapSmsManager.cpp b/dom/bluetooth/bluedroid/BluetoothMapSmsManager.cpp index a4573cd461..9755c8f550 100644 --- a/dom/bluetooth/bluedroid/BluetoothMapSmsManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothMapSmsManager.cpp @@ -83,6 +83,8 @@ BluetoothMapSmsManager::HandleShutdown() sInShutdown = true; Disconnect(nullptr); + Uninit(); + sMapSmsManager = nullptr; } @@ -97,27 +99,19 @@ BluetoothMapSmsManager::BluetoothMapSmsManager() } BluetoothMapSmsManager::~BluetoothMapSmsManager() -{ - nsCOMPtr obs = services::GetObserverService(); - if (NS_WARN_IF(!obs)) { - return; - } +{ } - NS_WARN_IF(NS_FAILED( - obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))); -} - -bool +nsresult BluetoothMapSmsManager::Init() { nsCOMPtr obs = services::GetObserverService(); if (NS_WARN_IF(!obs)) { - return false; + return NS_ERROR_NOT_AVAILABLE; } - if (NS_WARN_IF(NS_FAILED( - obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) { - return false; + auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } /** @@ -129,7 +123,46 @@ BluetoothMapSmsManager::Init() * absence of read events when device boots up. */ - return true; + return NS_OK; +} + +void +BluetoothMapSmsManager::Uninit() +{ + nsCOMPtr obs = services::GetObserverService(); + if (NS_WARN_IF(!obs)) { + return; + } + + NS_WARN_IF(NS_FAILED( + obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))); +} + +// static +void +BluetoothMapSmsManager::InitMapSmsInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (aRes) { + aRes->Init(); + } +} + +// static +void +BluetoothMapSmsManager::DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (sMapSmsManager) { + sMapSmsManager->Uninit(); + sMapSmsManager = nullptr; + } + + if (aRes) { + aRes->Deinit(); + } } //static @@ -149,8 +182,8 @@ BluetoothMapSmsManager::Get() } // Create a new instance, register, and return - BluetoothMapSmsManager *manager = new BluetoothMapSmsManager(); - if (NS_WARN_IF(!manager->Init())) { + RefPtr manager = new BluetoothMapSmsManager(); + if (NS_WARN_IF(NS_FAILED(manager->Init()))) { return nullptr; } diff --git a/dom/bluetooth/bluedroid/BluetoothMapSmsManager.h b/dom/bluetooth/bluedroid/BluetoothMapSmsManager.h index 843e0b6c80..2d9fe1fbb4 100644 --- a/dom/bluetooth/bluedroid/BluetoothMapSmsManager.h +++ b/dom/bluetooth/bluedroid/BluetoothMapSmsManager.h @@ -86,7 +86,10 @@ public: // By defualt SMS/MMS is default supported static const int SDP_SMS_MMS_INSTANCE_ID = 0; + static void InitMapSmsInterface(BluetoothProfileResultHandler* aRes); + static void DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes); static BluetoothMapSmsManager* Get(); + bool Listen(); /** @@ -194,7 +197,9 @@ protected: private: BluetoothMapSmsManager(); - bool Init(); + + nsresult Init(); + void Uninit(); void HandleShutdown(); void ReplyToConnect(); diff --git a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp index 63d974dd68..2ea8e2eb11 100644 --- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp @@ -213,31 +213,24 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false) { } BluetoothOppManager::~BluetoothOppManager() -{ - nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE_VOID(obs); - if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { - BT_WARNING("Failed to remove shutdown observer!"); - } +{ } - if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) { - BT_WARNING("Failed to remove volume observer!"); - } -} - -bool +nsresult BluetoothOppManager::Init() { nsCOMPtr obs = services::GetObserverService(); - NS_ENSURE_TRUE(obs, false); - if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) { + NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE); + + auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + if (NS_FAILED(rv)) { BT_WARNING("Failed to add shutdown observer!"); - return false; + return rv; } - if (NS_FAILED(obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false))) { + rv = obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false); + if (NS_FAILED(rv)) { BT_WARNING("Failed to add ns volume observer!"); - return false; + return rv; } /** @@ -249,7 +242,49 @@ BluetoothOppManager::Init() * absence of read events when device boots up. */ - return true; + return NS_OK; +} + +void +BluetoothOppManager::Uninit() +{ + nsCOMPtr obs = services::GetObserverService(); + NS_ENSURE_TRUE_VOID(obs); + + if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { + BT_WARNING("Failed to remove shutdown observer!"); + } + + if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) { + BT_WARNING("Failed to remove volume observer!"); + } +} + +// static +void +BluetoothOppManager::InitOppInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (aRes) { + aRes->Init(); + } +} + +// static +void +BluetoothOppManager::DeinitOppInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (sBluetoothOppManager) { + sBluetoothOppManager->Uninit(); + sBluetoothOppManager = nullptr; + } + + if (aRes) { + aRes->Deinit(); + } } //static @@ -267,10 +302,11 @@ BluetoothOppManager::Get() NS_ENSURE_FALSE(sInShutdown, nullptr); // Create a new instance, register, and return - BluetoothOppManager *manager = new BluetoothOppManager(); - NS_ENSURE_TRUE(manager->Init(), nullptr); + RefPtr manager = new BluetoothOppManager(); + NS_ENSURE_SUCCESS(manager->Init(), nullptr); sBluetoothOppManager = manager; + return sBluetoothOppManager; } @@ -309,6 +345,8 @@ BluetoothOppManager::HandleShutdown() MOZ_ASSERT(NS_IsMainThread()); sInShutdown = true; Disconnect(nullptr); + Uninit(); + sBluetoothOppManager = nullptr; } diff --git a/dom/bluetooth/bluedroid/BluetoothOppManager.h b/dom/bluetooth/bluedroid/BluetoothOppManager.h index b7aa7f4c2a..34fece7a2b 100644 --- a/dom/bluetooth/bluedroid/BluetoothOppManager.h +++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h @@ -40,6 +40,7 @@ class BluetoothOppManager : public BluetoothSocketObserver class SendSocketDataTask; public: + BT_DECL_PROFILE_MGR_BASE BT_DECL_SOCKET_OBSERVER virtual void GetName(nsACString& aName) @@ -49,7 +50,10 @@ public: static const int MAX_PACKET_LENGTH = 0xFFFE; + static void InitOppInterface(BluetoothProfileResultHandler* aRes); + static void DeinitOppInterface(BluetoothProfileResultHandler* aRes); static BluetoothOppManager* Get(); + void ClientDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage); void ServerDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage); @@ -75,7 +79,8 @@ protected: private: BluetoothOppManager(); - bool Init(); + nsresult Init(); + void Uninit(); void HandleShutdown(); void HandleVolumeStateChanged(nsISupports* aSubject); diff --git a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp index ee47b602d9..0e06ead7bd 100644 --- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp @@ -93,6 +93,8 @@ BluetoothPbapManager::HandleShutdown() sInShutdown = true; Disconnect(nullptr); + Uninit(); + sPbapManager = nullptr; } @@ -104,27 +106,19 @@ BluetoothPbapManager::BluetoothPbapManager() : mPhonebookSizeRequired(false) } BluetoothPbapManager::~BluetoothPbapManager() -{ - nsCOMPtr obs = services::GetObserverService(); - if (NS_WARN_IF(!obs)) { - return; - } +{ } - NS_WARN_IF(NS_FAILED( - obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))); -} - -bool +nsresult BluetoothPbapManager::Init() { nsCOMPtr obs = services::GetObserverService(); if (NS_WARN_IF(!obs)) { - return false; + return NS_ERROR_NOT_AVAILABLE; } - if (NS_WARN_IF(NS_FAILED( - obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) { - return false; + auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } /** @@ -136,7 +130,46 @@ BluetoothPbapManager::Init() * absence of read events when device boots up. */ - return true; + return NS_OK; +} + +void +BluetoothPbapManager::Uninit() +{ + nsCOMPtr obs = services::GetObserverService(); + if (NS_WARN_IF(!obs)) { + return; + } + + NS_WARN_IF(NS_FAILED( + obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))); +} + +// static +void +BluetoothPbapManager::InitPbapInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (aRes) { + aRes->Init(); + } +} + +// static +void +BluetoothPbapManager::DeinitPbapInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (sPbapManager) { + sPbapManager->Uninit(); + sPbapManager = nullptr; + } + + if (aRes) { + aRes->Deinit(); + } } //static @@ -156,8 +189,8 @@ BluetoothPbapManager::Get() } // Create a new instance, register, and return - BluetoothPbapManager *manager = new BluetoothPbapManager(); - if (NS_WARN_IF(!manager->Init())) { + RefPtr manager = new BluetoothPbapManager(); + if (NS_WARN_IF(NS_FAILED(manager->Init()))) { return nullptr; } diff --git a/dom/bluetooth/bluedroid/BluetoothPbapManager.h b/dom/bluetooth/bluedroid/BluetoothPbapManager.h index 556efe5db0..47833b360c 100644 --- a/dom/bluetooth/bluedroid/BluetoothPbapManager.h +++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.h @@ -67,7 +67,10 @@ public: static const int MAX_PACKET_LENGTH = 0xFFFE; static const int DIGEST_LENGTH = 16; + static void InitPbapInterface(BluetoothProfileResultHandler* aRes); + static void DeinitPbapInterface(BluetoothProfileResultHandler* aRes); static BluetoothPbapManager* Get(); + bool Listen(); /** @@ -146,7 +149,9 @@ protected: private: BluetoothPbapManager(); - bool Init(); + + nsresult Init(); + void Uninit(); void HandleShutdown(); void ReplyToConnect(const nsAString& aPassword = EmptyString()); diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 0ca3bb125a..fc87912547 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -138,6 +138,10 @@ public: void Init() override { static void (* const sInitManager[])(BluetoothProfileResultHandler*) = { + BluetoothMapSmsManager::InitMapSmsInterface, + BluetoothOppManager::InitOppInterface, + BluetoothPbapManager::InitPbapInterface, + BluetoothHidManager::InitHidInterface, BluetoothHfpManager::InitHfpInterface, BluetoothA2dpManager::InitA2dpInterface, BluetoothAvrcpManager::InitAvrcpInterface, @@ -2037,7 +2041,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState) BluetoothGattManager::DeinitGattInterface, BluetoothAvrcpManager::DeinitAvrcpInterface, BluetoothA2dpManager::DeinitA2dpInterface, - BluetoothHfpManager::DeinitHfpInterface + BluetoothHfpManager::DeinitHfpInterface, + BluetoothHidManager::DeinitHidInterface, + BluetoothPbapManager::DeinitPbapInterface, + BluetoothOppManager::DeinitOppInterface, + BluetoothMapSmsManager::DeinitMapSmsInterface }; // Return error if BluetoothService is unavailable diff --git a/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp b/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp index f8555430f4..16d010723b 100644 --- a/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp +++ b/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp @@ -176,6 +176,8 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); + sBluetoothHfpManager = nullptr; + /** * TODO: * Implement DeinitHfpInterface() for applications that want to create SCO diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp index 7a6592e30c..427a5e7724 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ -446,6 +446,7 @@ public: sBluetoothHfpInterface->SetNotificationHandler(nullptr); sBluetoothHfpInterface = nullptr; + sBluetoothHfpManager = nullptr; if (mRes) { mRes->OnError(NS_ERROR_FAILURE); @@ -458,6 +459,7 @@ public: sBluetoothHfpInterface->SetNotificationHandler(nullptr); sBluetoothHfpInterface = nullptr; + sBluetoothHfpManager = nullptr; if (mRes) { mRes->Deinit(); diff --git a/dom/bluetooth/bluez/BluetoothHidManager.cpp b/dom/bluetooth/bluez/BluetoothHidManager.cpp index 5dc2056ccb..316d301ec8 100644 --- a/dom/bluetooth/bluez/BluetoothHidManager.cpp +++ b/dom/bluetooth/bluez/BluetoothHidManager.cpp @@ -78,6 +78,30 @@ BluetoothHidManager::~BluetoothHidManager() } } +// static +void +BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (aRes) { + aRes->Init(); + } +} + +// static +void +BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + sBluetoothHidManager = nullptr; + + if (aRes) { + aRes->Deinit(); + } +} + //static BluetoothHidManager* BluetoothHidManager::Get() diff --git a/dom/bluetooth/bluez/BluetoothHidManager.h b/dom/bluetooth/bluez/BluetoothHidManager.h index 7684974e84..fc0f7a258b 100644 --- a/dom/bluetooth/bluez/BluetoothHidManager.h +++ b/dom/bluetooth/bluez/BluetoothHidManager.h @@ -22,6 +22,8 @@ public: aName.AssignLiteral("HID"); } + static void InitHidInterface(BluetoothProfileResultHandler* aRes); + static void DeinitHidInterface(BluetoothProfileResultHandler* aRes); static BluetoothHidManager* Get(); // HID-specific functions diff --git a/dom/broadcastchannel/BroadcastChannelParent.h b/dom/broadcastchannel/BroadcastChannelParent.h index f9019aa9e4..3311db4298 100644 --- a/dom/broadcastchannel/BroadcastChannelParent.h +++ b/dom/broadcastchannel/BroadcastChannelParent.h @@ -14,7 +14,7 @@ namespace mozilla { namespace ipc { class BackgroundParentImpl; class PrincipalInfo; -} +} // namespace ipc namespace dom { diff --git a/dom/broadcastchannel/moz.build b/dom/broadcastchannel/moz.build index 7175711a80..871bcb6326 100644 --- a/dom/broadcastchannel/moz.build +++ b/dom/broadcastchannel/moz.build @@ -24,7 +24,7 @@ LOCAL_INCLUDES += [ ] MOCHITEST_MANIFESTS += ['tests/mochitest.ini'] -MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini'] +BROWSER_CHROME_MANIFESTS += ['tests/browser.ini'] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/dom/broadcastchannel/tests/browser.ini b/dom/broadcastchannel/tests/browser.ini new file mode 100644 index 0000000000..83c4fd27cf --- /dev/null +++ b/dom/broadcastchannel/tests/browser.ini @@ -0,0 +1,6 @@ +[DEFAULT] +skip-if = buildapp == 'b2g' || os == 'android' +support-files = + blank.html + +[browser_private_browsing.js] diff --git a/dom/broadcastchannel/tests/browser_private_browsing.js b/dom/broadcastchannel/tests/browser_private_browsing.js new file mode 100644 index 0000000000..5724225fc3 --- /dev/null +++ b/dom/broadcastchannel/tests/browser_private_browsing.js @@ -0,0 +1,74 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const URL = "http://mochi.test:8888/browser/dom/broadcastchannel/tests/blank.html"; + +add_task(function*() { + var win1 = OpenBrowserWindow({private: true}); + var win1Promise = new win1.Promise(resolve => { + win1.addEventListener("load", function onLoad() { + win1.removeEventListener("load", onLoad, false); + resolve(); + }); + }); + yield win1Promise; + + var win2 = OpenBrowserWindow({private: false}); + var win2Promise = new win2.Promise(resolve => { + win2.addEventListener("load", function onLoad() { + win2.removeEventListener("load", onLoad, false); + resolve(); + }); + }); + yield win2Promise; + + var tab1 = win1.gBrowser.addTab(URL); + yield BrowserTestUtils.browserLoaded(win1.gBrowser.getBrowserForTab(tab1)); + var browser1 = gBrowser.getBrowserForTab(tab1); + + var tab2 = win2.gBrowser.addTab(URL); + yield BrowserTestUtils.browserLoaded(win2.gBrowser.getBrowserForTab(tab2)); + var browser2 = gBrowser.getBrowserForTab(tab2); + + var p1 = ContentTask.spawn(browser1, null, function(opts) { + return new content.window.Promise(resolve => { + content.window.bc = new content.window.BroadcastChannel('foobar'); + content.window.bc.onmessage = function(e) { resolve(e.data); } + }); + }); + + var p2 = ContentTask.spawn(browser2, null, function(opts) { + return new content.window.Promise(resolve => { + content.window.bc = new content.window.BroadcastChannel('foobar'); + content.window.bc.onmessage = function(e) { resolve(e.data); } + }); + }); + + yield ContentTask.spawn(browser1, null, function(opts) { + return new content.window.Promise(resolve => { + var bc = new content.window.BroadcastChannel('foobar'); + bc.postMessage('hello world from private browsing'); + resolve(); + }); + }); + + yield ContentTask.spawn(browser2, null, function(opts) { + return new content.window.Promise(resolve => { + var bc = new content.window.BroadcastChannel('foobar'); + bc.postMessage('hello world from non private browsing'); + resolve(); + }); + }); + + var what1 = yield p1; + ok(what1, 'hello world from private browsing', 'No messages received from the other window.'); + + var what2 = yield p2; + ok(what1, 'hello world from non private browsing', 'No messages received from the other window.'); + + yield BrowserTestUtils.removeTab(tab1); + yield BrowserTestUtils.closeWindow(win1); + + yield BrowserTestUtils.removeTab(tab2); + yield BrowserTestUtils.closeWindow(win2); +}); diff --git a/dom/broadcastchannel/tests/chrome.ini b/dom/broadcastchannel/tests/chrome.ini deleted file mode 100644 index a61b9b5f52..0000000000 --- a/dom/broadcastchannel/tests/chrome.ini +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -skip-if = e10s || buildapp == 'b2g' -support-files = - blank.html - -[test_broadcastchannel_private_browsing.html] diff --git a/dom/broadcastchannel/tests/test_broadcastchannel_private_browsing.html b/dom/broadcastchannel/tests/test_broadcastchannel_private_browsing.html deleted file mode 100644 index eb4d2e3709..0000000000 --- a/dom/broadcastchannel/tests/test_broadcastchannel_private_browsing.html +++ /dev/null @@ -1,118 +0,0 @@ - - - Test for BroadcastChannel - Private Browsing - - - - - - - - - - diff --git a/dom/cache/Manager.cpp b/dom/cache/Manager.cpp index 5cf3badd49..19c95e3210 100644 --- a/dom/cache/Manager.cpp +++ b/dom/cache/Manager.cpp @@ -147,12 +147,12 @@ private: nsTArray mDeletedBodyIdList; }; -bool IsHeadRequest(CacheRequest aRequest, CacheQueryParams aParams) +bool IsHeadRequest(const CacheRequest& aRequest, const CacheQueryParams& aParams) { return !aParams.ignoreMethod() && aRequest.method().LowerCaseEqualsLiteral("head"); } -bool IsHeadRequest(CacheRequestOrVoid aRequest, CacheQueryParams aParams) +bool IsHeadRequest(const CacheRequestOrVoid& aRequest, const CacheQueryParams& aParams) { if (aRequest.type() == CacheRequestOrVoid::TCacheRequest) { return !aParams.ignoreMethod() && diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp index 994496c16b..05aa605a44 100644 --- a/dom/canvas/TexUnpackBlob.cpp +++ b/dom/canvas/TexUnpackBlob.cpp @@ -756,7 +756,13 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f // call into GL, instead of trying to keep MakeCurrent-ed. RefPtr dataSurf = mSurf->GetDataSurface(); - MOZ_ASSERT(dataSurf); + + if (!dataSurf) { + // Since GetDataSurface didn't return error code, assume system + // is out of memory + *out_glError = LOCAL_GL_OUT_OF_MEMORY; + return; + } GLenum error; if (UploadDataSurface(isSubImage, webgl, target, level, dui, xOffset, yOffset, diff --git a/dom/canvas/WebGL2ContextFramebuffers.cpp b/dom/canvas/WebGL2ContextFramebuffers.cpp index 4c836d4869..3e415e4daa 100644 --- a/dom/canvas/WebGL2ContextFramebuffers.cpp +++ b/dom/canvas/WebGL2ContextFramebuffers.cpp @@ -556,6 +556,7 @@ WebGL2Context::ReadBuffer(GLenum mode) } MakeContextCurrent(); + mBoundReadFramebuffer->SetReadBufferMode(mode); gl->fReadBuffer(mode); return; } diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 85a0075209..768000f11f 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -1472,7 +1472,7 @@ CheckContextLost(GLContext* gl, bool* const out_isGuilty) bool isEGL = gl->GetContextType() == gl::GLContextType::EGL; GLenum resetStatus = LOCAL_GL_NO_ERROR; - if (gl->HasRobustness()) { + if (gl->IsSupported(GLFeature::robustness)) { gl->MakeCurrent(); resetStatus = gl->fGetGraphicsResetStatus(); } else if (isEGL) { @@ -1800,7 +1800,8 @@ WebGLContext::DidRefresh() bool WebGLContext::ValidateCurFBForRead(const char* funcName, const webgl::FormatUsageInfo** const out_format, - uint32_t* const out_width, uint32_t* const out_height) + uint32_t* const out_width, uint32_t* const out_height, + GLenum* const out_mode) { if (!mBoundReadFramebuffer) { ClearBackbufferIfNeeded(); @@ -1816,11 +1817,12 @@ WebGLContext::ValidateCurFBForRead(const char* funcName, *out_width = mWidth; *out_height = mHeight; + *out_mode = gl->Screen()->GetReadBufferMode(); return true; } return mBoundReadFramebuffer->ValidateForRead(funcName, out_format, out_width, - out_height); + out_height, out_mode); } //////////////////////////////////////////////////////////////////////////////// diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 759c0efb82..17f1be6252 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1277,7 +1277,8 @@ protected: bool ValidateCurFBForRead(const char* funcName, const webgl::FormatUsageInfo** const out_format, - uint32_t* const out_width, uint32_t* const out_height); + uint32_t* const out_width, uint32_t* const out_height, + GLenum* const out_mode); void Invalidate(); void DestroyResourcesAndContext(); diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp index f407b41ce7..545af135bd 100644 --- a/dom/canvas/WebGLContextDraw.cpp +++ b/dom/canvas/WebGLContextDraw.cpp @@ -360,8 +360,10 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, return false; } - // Any checks below this depend on a program being available. - if (!mCurrentProgram) { + // Any checks below this depend on mActiveProgramLinkInfo being available. + if (!mActiveProgramLinkInfo) { + // Technically, this will only be null iff CURRENT_PROGRAM is null. + // But it's better to branch on what we actually care about. ErrorInvalidOperation("%s: null CURRENT_PROGRAM", info); return false; } @@ -841,19 +843,34 @@ WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget ta const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE}; UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation. + MOZ_ASSERT(gl->IsCurrent()); if (target == LOCAL_GL_TEXTURE_CUBE_MAP) { for (int i = 0; i < 6; ++i) { const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1, zeros.get()); - if (error) - MOZ_CRASH("Unexpected error during FakeBlack creation."); + if (error) { + const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, " + "for `curTarget`: 0x%04x, " + "`dui`: {0x%04x, 0x%04x, 0x%04x}.", + error, curTarget.get(), dui.internalFormat, + dui.unpackFormat, dui.unpackType); + gfxCriticalError() << text.BeginReading(); + MOZ_CRASH("Unexpected error during cube map FakeBlack creation."); + } } } else { const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1, zeros.get()); - if (error) + if (error) { + const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, " + "for `target`: 0x%04x, " + "`dui`: {0x%04x, 0x%04x, 0x%04x}.", + error, target.get(), dui.internalFormat, + dui.unpackFormat, dui.unpackType); + gfxCriticalError() << text.BeginReading(); MOZ_CRASH("Unexpected error during FakeBlack creation."); + } } } diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index 4954291361..516f071878 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -1088,14 +1088,19 @@ WebGLContext::LinkProgram(WebGLProgram* prog) prog->LinkProgram(); - if (prog->IsLinked()) { + if (!prog->IsLinked()) { + // If we failed to link, but `prog == mCurrentProgram`, we are *not* supposed to + // null out mActiveProgramLinkInfo. + return; + } + + if (prog == mCurrentProgram) { mActiveProgramLinkInfo = prog->LinkInfo(); if (gl->WorkAroundDriverBugs() && gl->Vendor() == gl::GLVendor::NVIDIA) { - if (mCurrentProgram == prog) - gl->fUseProgram(prog->mGLName); + gl->fUseProgram(prog->mGLName); } } } @@ -1571,7 +1576,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum const webgl::FormatUsageInfo* srcFormat; uint32_t srcWidth; uint32_t srcHeight; - if (!ValidateCurFBForRead("readPixels", &srcFormat, &srcWidth, &srcHeight)) + GLenum srcMode; + if (!ValidateCurFBForRead("readPixels", &srcFormat, &srcWidth, &srcHeight, &srcMode)) return; // Check the format and type params to assure they are an acceptable pair (as per spec) diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index 6c3b4ec41f..6b7c4986f0 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -911,6 +911,10 @@ WebGLContext::InitAndValidateGL() } #endif + if (gl->IsSupported(gl::GLFeature::seamless_cube_map_opt_in)) { + gl->fEnable(LOCAL_GL_TEXTURE_CUBE_MAP_SEAMLESS); + } + // Check the shader validator pref mBypassShaderValidation = gfxPrefs::WebGLBypassShaderValidator(); diff --git a/dom/canvas/WebGLExtensionDisjointTimerQuery.cpp b/dom/canvas/WebGLExtensionDisjointTimerQuery.cpp index fd3112c254..81cc050c03 100644 --- a/dom/canvas/WebGLExtensionDisjointTimerQuery.cpp +++ b/dom/canvas/WebGLExtensionDisjointTimerQuery.cpp @@ -12,6 +12,7 @@ #include "GLContext.h" #include "WebGLContext.h" #include "WebGLTimerQuery.h" +#include "gfxPrefs.h" namespace mozilla { @@ -117,6 +118,7 @@ WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) mContext->MakeContextCurrent(); mContext->GL()->fEndQuery(target); + mActiveQuery->QueueAvailablity(); mActiveQuery = nullptr; } @@ -139,6 +141,7 @@ WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query, mContext->MakeContextCurrent(); mContext->GL()->fQueryCounter(query->mGLName, target); query->mTarget = LOCAL_GL_TIMESTAMP_EXT; + query->QueueAvailablity(); } void @@ -221,7 +224,8 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx, mContext->GL()->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT, &avail); - retval.set(JS::BooleanValue(bool(avail))); + bool canBeAvailable = query->CanBeAvailable() || gfxPrefs::WebGLImmediateQueries(); + retval.set(JS::BooleanValue(bool(avail) && canBeAvailable)); break; } default: @@ -238,10 +242,13 @@ WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl) gl::GLContext* gl = webgl->GL(); return gl->IsSupported(gl::GLFeature::query_objects) && gl->IsSupported(gl::GLFeature::get_query_object_i64v) && - gl->IsSupported(gl::GLFeature::query_counter); // provides GL_TIMESTAMP + gl->IsSupported(gl::GLFeature::query_counter) && // provides GL_TIMESTAMP + gl->IsSupported(gl::GLFeature::sync); // provides glGetInteger64v + // 'sync' provides glGetInteger64v either by supporting ARB_sync, GL3+, or GLES3+. + // Since there are no differences between support for glGetInteger64v and support for + // 'sync', we just piggy-back off of 'sync'. } - IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery, EXT_disjoint_timer_query) } // namespace mozilla diff --git a/dom/canvas/WebGLFramebuffer.cpp b/dom/canvas/WebGLFramebuffer.cpp index 333ed95090..a2b5b3b70a 100644 --- a/dom/canvas/WebGLFramebuffer.cpp +++ b/dom/canvas/WebGLFramebuffer.cpp @@ -624,9 +624,14 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum attachment, TexImageTarget texImag return; if (tex) { - bool isTexture2D = tex->Target() == LOCAL_GL_TEXTURE_2D; - bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D; - if (isTexture2D != isTexTarget2D) { + if (!tex->HasEverBeenBound()) { + mContext->ErrorInvalidOperation("framebufferTexture2D: the texture" + " is not the name of a texture."); + return; + } + + const TexTarget destTexTarget = TexImageTargetToTexTarget(texImageTarget); + if (tex->Target() != destTexTarget) { mContext->ErrorInvalidOperation("framebufferTexture2D: Mismatched" " texture and texture target."); return; @@ -1140,7 +1145,8 @@ WebGLFramebuffer::FinalizeAttachments() const bool WebGLFramebuffer::ValidateForRead(const char* funcName, const webgl::FormatUsageInfo** const out_format, - uint32_t* const out_width, uint32_t* const out_height) + uint32_t* const out_width, uint32_t* const out_height, + GLenum* const out_mode) { if (!ValidateAndInitAttachments(funcName)) return false; @@ -1158,6 +1164,7 @@ WebGLFramebuffer::ValidateForRead(const char* funcName, return false; } + *out_mode = mReadBufferMode; *out_format = attachPoint->Format(); attachPoint->Size(out_width, out_height); return true; diff --git a/dom/canvas/WebGLFramebuffer.h b/dom/canvas/WebGLFramebuffer.h index 53c440dd87..ceb44a9f96 100644 --- a/dom/canvas/WebGLFramebuffer.h +++ b/dom/canvas/WebGLFramebuffer.h @@ -253,6 +253,10 @@ public: return mDepthStencilAttachment; } + void SetReadBufferMode(GLenum readBufferMode) { + mReadBufferMode = readBufferMode; + } + protected: WebGLFBAttachPoint* GetAttachPoint(GLenum attachment); // Fallible @@ -280,7 +284,8 @@ public: bool ValidateForRead(const char* info, const webgl::FormatUsageInfo** const out_format, - uint32_t* const out_width, uint32_t* const out_height); + uint32_t* const out_width, uint32_t* const out_height, + GLenum* const out_mode); JS::Value GetAttachmentParameter(const char* funcName, JSContext* cx, GLenum target, GLenum attachment, GLenum pname, diff --git a/dom/canvas/WebGLProgram.cpp b/dom/canvas/WebGLProgram.cpp index 3f256bcf3f..be2377ee7c 100644 --- a/dom/canvas/WebGLProgram.cpp +++ b/dom/canvas/WebGLProgram.cpp @@ -342,7 +342,6 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl) webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* prog) : prog(prog) - , fragDataMap(nullptr) { } //////////////////////////////////////////////////////////////////////////////// @@ -569,8 +568,9 @@ WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const const NS_LossyConvertUTF16toASCII userName(userName_wide); nsCString mappedName; - if (!LinkInfo()->FindFragData(userName, &mappedName)) - return -1; + if (!FindActiveOutputMappedNameByUserName(userName, &mappedName)) { + mappedName = userName; + } gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); @@ -885,7 +885,7 @@ WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockB gl->fUniformBlockBinding(mGLName, uniformBlockIndex, uniformBlockBinding); } -bool +void WebGLProgram::LinkProgram() { mContext->InvalidateBufferFetching(); // we do it early in this function @@ -897,18 +897,18 @@ WebGLProgram::LinkProgram() if (!mVertShader || !mVertShader->IsCompiled()) { mLinkLog.AssignLiteral("Must have a compiled vertex shader attached."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + return; } if (!mFragShader || !mFragShader->IsCompiled()) { mLinkLog.AssignLiteral("Must have an compiled fragment shader attached."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + return; } if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) { mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + return; } gl::GLContext* gl = mContext->gl; @@ -925,14 +925,14 @@ WebGLProgram::LinkProgram() mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on" " Mesa drivers to avoid crashing."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + return; } // Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count. if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) { mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + return; } } @@ -954,8 +954,9 @@ WebGLProgram::LinkProgram() &mTempMappedVaryings); } - if (LinkAndUpdate()) - return true; + LinkAndUpdate(); + if (IsLinked()) + return; // Failed link. if (mContext->ShouldGenerateWarnings()) { @@ -970,8 +971,6 @@ WebGLProgram::LinkProgram() mLinkLog.BeginReading()); } } - - return false; } bool @@ -1013,7 +1012,7 @@ WebGLProgram::ValidateProgram() const //////////////////////////////////////////////////////////////////////////////// -bool +void WebGLProgram::LinkAndUpdate() { mMostRecentLinkInfo = nullptr; @@ -1039,15 +1038,21 @@ WebGLProgram::LinkAndUpdate() GLint ok = 0; gl->fGetProgramiv(mGLName, LOCAL_GL_LINK_STATUS, &ok); if (!ok) - return false; + return; mMostRecentLinkInfo = QueryProgramInfo(this, gl); + MOZ_RELEASE_ASSERT(mMostRecentLinkInfo); +} - MOZ_ASSERT(mMostRecentLinkInfo); - if (!mMostRecentLinkInfo) - mLinkLog.AssignLiteral("Failed to gather program info."); +bool +WebGLProgram::FindActiveOutputMappedNameByUserName(const nsACString& userName, + nsCString* const out_mappedName) const +{ + if (mFragShader->FindActiveOutputMappedNameByUserName(userName, out_mappedName)) { + return true; + } - return mMostRecentLinkInfo; + return false; } bool diff --git a/dom/canvas/WebGLProgram.h b/dom/canvas/WebGLProgram.h index b0b611c74a..161f42004f 100644 --- a/dom/canvas/WebGLProgram.h +++ b/dom/canvas/WebGLProgram.h @@ -67,7 +67,6 @@ struct LinkedProgramInfo final std::map attribMap; std::map uniformMap; std::map transformFeedbackVaryingsMap; - std::map* fragDataMap; std::vector> uniformBlocks; @@ -112,17 +111,6 @@ struct LinkedProgramInfo final return false; } - bool FindFragData(const nsCString& baseUserName, - nsCString* const out_baseMappedName) const - { - if (!fragDataMap) { - *out_baseMappedName = baseUserName; - return true; - } - - MOZ_CRASH("Not implemented."); - } - bool HasActiveAttrib(GLuint loc) const { auto itr = activeAttribLocs.find(loc); return itr != activeAttribLocs.end(); @@ -168,12 +156,14 @@ public: dom::Nullable< nsTArray >& retval) const; void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const; - bool LinkProgram(); + void LinkProgram(); bool UseProgram() const; void ValidateProgram() const; //////////////// + bool FindActiveOutputMappedNameByUserName(const nsACString& userName, + nsCString* const out_mappedName) const; bool FindAttribUserNameByMappedName(const nsACString& mappedName, nsDependentCString* const out_userName) const; bool FindVaryingByMappedName(const nsACString& mappedName, @@ -205,7 +195,7 @@ public: private: ~WebGLProgram(); - bool LinkAndUpdate(); + void LinkAndUpdate(); public: const GLuint mGLName; diff --git a/dom/canvas/WebGLShader.cpp b/dom/canvas/WebGLShader.cpp index 02652e4dc6..6c540a0468 100644 --- a/dom/canvas/WebGLShader.cpp +++ b/dom/canvas/WebGLShader.cpp @@ -329,6 +329,22 @@ WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName, mContext->gl->fBindAttribLocation(prog, index, mappedNameStr->c_str()); } +bool +WebGLShader::FindActiveOutputMappedNameByUserName(const nsACString& userName, + nsCString* const out_mappedName) const +{ + if (!mValidator) + return false; + + const std::string userNameStr(userName.BeginReading()); + const std::string* mappedNameStr; + if (!mValidator->FindActiveOutputMappedNameByUserName(userNameStr, &mappedNameStr)) + return false; + + *out_mappedName = mappedNameStr->c_str(); + return true; +} + bool WebGLShader::FindAttribUserNameByMappedName(const nsACString& mappedName, nsDependentCString* const out_userName) const diff --git a/dom/canvas/WebGLShader.h b/dom/canvas/WebGLShader.h index 46f8d745e0..79b332e0d2 100644 --- a/dom/canvas/WebGLShader.h +++ b/dom/canvas/WebGLShader.h @@ -52,6 +52,8 @@ public: size_t CalcNumSamplerUniforms() const; size_t NumAttributes() const; void BindAttribLocation(GLuint prog, const nsCString& userName, GLuint index) const; + bool FindActiveOutputMappedNameByUserName(const nsACString& userName, + nsCString* const out_mappedName) const; bool FindAttribUserNameByMappedName(const nsACString& mappedName, nsDependentCString* const out_userName) const; bool FindVaryingByMappedName(const nsACString& mappedName, diff --git a/dom/canvas/WebGLShaderValidator.cpp b/dom/canvas/WebGLShaderValidator.cpp index 1bfe5161f2..f5368c406c 100644 --- a/dom/canvas/WebGLShaderValidator.cpp +++ b/dom/canvas/WebGLShaderValidator.cpp @@ -401,6 +401,21 @@ ShaderValidator::FindAttribUserNameByMappedName(const std::string& mappedName, return false; } +bool +ShaderValidator::FindActiveOutputMappedNameByUserName(const std::string& userName, + const std::string** const out_mappedName) const +{ + const std::vector& varibles = *ShGetOutputVariables(mHandle); + for (auto itr = varibles.begin(); itr != varibles.end(); ++itr) { + if (itr->name == userName) { + *out_mappedName = &(itr->mappedName); + return true; + } + } + + return false; +} + bool ShaderValidator::FindAttribMappedNameByUserName(const std::string& userName, const std::string** const out_mappedName) const @@ -464,14 +479,44 @@ ShaderValidator::FindUniformByMappedName(const std::string& mappedName, return true; } + const size_t dotPos = mappedName.find("."); + const std::vector& interfaces = *ShGetInterfaceBlocks(mHandle); for (const auto& interface : interfaces) { + + std::string mappedFieldName; + const bool hasInstanceName = !interface.instanceName.empty(); + + // If the InterfaceBlock has an instanceName, all variables defined + // within the block are qualified with the block name, as opposed + // to being placed in the global scope. + if (hasInstanceName) { + + // If mappedName has no block name prefix, skip + if (std::string::npos == dotPos) + continue; + + // If mappedName has a block name prefix that doesn't match, skip + const std::string mappedInterfaceBlockName = mappedName.substr(0, dotPos); + if (interface.mappedName != mappedInterfaceBlockName) + continue; + + mappedFieldName = mappedName.substr(dotPos + 1); + } else { + mappedFieldName = mappedName; + } + for (const auto& field : interface.fields) { const sh::ShaderVariable* found; - if (!field.findInfoByMappedName(mappedName, &found, out_userName)) + if (!field.findInfoByMappedName(mappedFieldName, &found, out_userName)) continue; + if (hasInstanceName) { + // Prepend the user name of the interface that matched + *out_userName = interface.name + "." + *out_userName; + } + *out_isArray = found->isArray(); return true; } diff --git a/dom/canvas/WebGLShaderValidator.h b/dom/canvas/WebGLShaderValidator.h index 5d4efe1c8f..ceccadca83 100644 --- a/dom/canvas/WebGLShaderValidator.h +++ b/dom/canvas/WebGLShaderValidator.h @@ -48,6 +48,9 @@ public: bool FindAttribUserNameByMappedName(const std::string& mappedName, const std::string** const out_userName) const; + bool FindActiveOutputMappedNameByUserName(const std::string& userName, + const std::string** const out_mappedName) const; + bool FindAttribMappedNameByUserName(const std::string& userName, const std::string** const out_mappedName) const; diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp index 8fc8e4380c..844e388c73 100644 --- a/dom/canvas/WebGLTextureUpload.cpp +++ b/dom/canvas/WebGLTextureUpload.cpp @@ -1719,10 +1719,21 @@ WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level, GLenum internal const webgl::FormatUsageInfo* srcUsage; uint32_t srcWidth; uint32_t srcHeight; - if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight)) + GLenum srcMode; + if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight, + &srcMode)) return; auto srcFormat = srcUsage->format; + // GLES 3.0.4 p145: + // "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an + // INVALID_OPERATION error if any of the following conditions is true: READ_BUFFER + // is NONE" + if (srcMode == LOCAL_GL_NONE) { + mContext->ErrorInvalidOperation("%s: READ_BUFFER is NONE. ", funcName); + return; + } + //////////////////////////////////// // Check that source and dest info are compatible @@ -1869,10 +1880,21 @@ WebGLTexture::CopyTexSubImage(const char* funcName, TexImageTarget target, GLint const webgl::FormatUsageInfo* srcUsage; uint32_t srcWidth; uint32_t srcHeight; - if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight)) + GLenum srcMode; + if (!mContext->ValidateCurFBForRead(funcName, &srcUsage, &srcWidth, &srcHeight, + &srcMode)) return; auto srcFormat = srcUsage->format; + // GLES 3.0.4 p145: + // "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an + // INVALID_OPERATION error if any of the following conditions is true: READ_BUFFER + // is NONE" + if (srcMode == LOCAL_GL_NONE) { + mContext->ErrorInvalidOperation("%s: READ_BUFFER is NONE. ", funcName); + return; + } + //////////////////////////////////// // Check that source and dest info are compatible diff --git a/dom/canvas/WebGLTimerQuery.cpp b/dom/canvas/WebGLTimerQuery.cpp index 5bdc1648d3..77c5c71638 100644 --- a/dom/canvas/WebGLTimerQuery.cpp +++ b/dom/canvas/WebGLTimerQuery.cpp @@ -10,6 +10,7 @@ #include "mozilla/dom/WebGLRenderingContextBinding.h" #include "nsContentUtils.h" #include "WebGLContext.h" +#include "nsThreadUtils.h" namespace mozilla { @@ -23,6 +24,7 @@ WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint name) : WebGLContextBoundObject(webgl) , mGLName(name) , mTarget(LOCAL_GL_NONE) + , mCanBeAvailable(false) { } @@ -53,6 +55,12 @@ WebGLTimerQuery::GetParentObject() const return mContext; } +void +WebGLTimerQuery::QueueAvailablity() +{ + RefPtr self = this; + NS_DispatchToCurrentThread(NS_NewRunnableFunction([self] { self->mCanBeAvailable = true; })); +} NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery) diff --git a/dom/canvas/WebGLTimerQuery.h b/dom/canvas/WebGLTimerQuery.h index 681adc3379..2f05bda36e 100644 --- a/dom/canvas/WebGLTimerQuery.h +++ b/dom/canvas/WebGLTimerQuery.h @@ -24,6 +24,8 @@ public: void Delete(); bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; } + bool CanBeAvailable() const { return mCanBeAvailable; } + void QueueAvailablity(); GLenum Target() const { return mTarget; } WebGLContext* GetParentObject() const; @@ -41,6 +43,7 @@ private: ~WebGLTimerQuery(); GLenum mTarget; + bool mCanBeAvailable; friend class WebGLExtensionDisjointTimerQuery; }; diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index 3778f28ac1..02f222778b 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -15,7 +15,7 @@ fail-if = (os == 'android') [webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html] fail-if = (os == 'android') [webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html] -fail-if = (os == 'android') || (os == 'mac') || (os == 'win' && (os_version == '5.1' || os_version == '6.1')) +fail-if = (os == 'android') || (os == 'mac') || (os == 'win') [webgl-mochitest/ensure-exts/test_EXT_frag_depth.html] fail-if = (os == 'android') [webgl-mochitest/ensure-exts/test_EXT_sRGB.html] diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp index 5c33065c1e..db2c8af607 100644 --- a/dom/crypto/WebCryptoTask.cpp +++ b/dom/crypto/WebCryptoTask.cpp @@ -340,7 +340,6 @@ CloneData(JSContext* aCx, CryptoBuffer& aDst, JS::Handle aSrc) void WebCryptoTask::DispatchWithPromise(Promise* aResultPromise) { - MOZ_ASSERT(NS_IsMainThread()); mResultPromise = aResultPromise; // Fail if an error was set during the constructor @@ -357,13 +356,6 @@ WebCryptoTask::DispatchWithPromise(Promise* aResultPromise) return; } - // Ensure that NSS is initialized, since presumably CalculateResult - // will use NSS functions - if (!EnsureNSSInitializedChromeOrContent()) { - mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR; - MAYBE_EARLY_FAIL(mEarlyRv) - } - // Store calling thread and dispatch to thread pool. mOriginalThread = NS_GetCurrentThread(); mEarlyRv = WebCryptoThreadPool::Dispatch(this); @@ -2316,16 +2308,10 @@ private: }; GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask( - JSContext* aCx, const ObjectOrString& aAlgorithm, bool aExtractable, - const Sequence& aKeyUsages) + nsIGlobalObject* aGlobal, JSContext* aCx, const ObjectOrString& aAlgorithm, + bool aExtractable, const Sequence& aKeyUsages) : mKeyPair(new CryptoKeyPair()) { - nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)); - if (!global) { - mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR; - return; - } - mArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!mArena) { mEarlyRv = NS_ERROR_DOM_UNKNOWN_ERR; @@ -2333,8 +2319,8 @@ GenerateAsymmetricKeyTask::GenerateAsymmetricKeyTask( } // Create an empty key pair and set easy attributes - mKeyPair->mPrivateKey = new CryptoKey(global); - mKeyPair->mPublicKey = new CryptoKey(global); + mKeyPair->mPrivateKey = new CryptoKey(aGlobal); + mKeyPair->mPublicKey = new CryptoKey(aGlobal); // Extract algorithm name mEarlyRv = GetAlgorithmName(aCx, aAlgorithm, mAlgName); @@ -3420,7 +3406,8 @@ WebCryptoTask::CreateGenerateKeyTask(nsIGlobalObject* aGlobal, algName.EqualsASCII(WEBCRYPTO_ALG_ECDH) || algName.EqualsASCII(WEBCRYPTO_ALG_ECDSA) || algName.EqualsASCII(WEBCRYPTO_ALG_DH)) { - return new GenerateAsymmetricKeyTask(aCx, aAlgorithm, aExtractable, aKeyUsages); + return new GenerateAsymmetricKeyTask(aGlobal, aCx, aAlgorithm, aExtractable, + aKeyUsages); } else { return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR); } diff --git a/dom/crypto/WebCryptoTask.h b/dom/crypto/WebCryptoTask.h index 33cb6273ff..0c99eacf49 100644 --- a/dom/crypto/WebCryptoTask.h +++ b/dom/crypto/WebCryptoTask.h @@ -232,7 +232,7 @@ private: class GenerateAsymmetricKeyTask : public WebCryptoTask { public: - GenerateAsymmetricKeyTask(JSContext* aCx, + GenerateAsymmetricKeyTask(nsIGlobalObject* aGlobal, JSContext* aCx, const ObjectOrString& aAlgorithm, bool aExtractable, const Sequence& aKeyUsages); protected: diff --git a/dom/crypto/WebCryptoThreadPool.cpp b/dom/crypto/WebCryptoThreadPool.cpp index 3abe347dde..b0dff16acd 100644 --- a/dom/crypto/WebCryptoThreadPool.cpp +++ b/dom/crypto/WebCryptoThreadPool.cpp @@ -65,6 +65,8 @@ WebCryptoThreadPool::DispatchInternal(nsIRunnable* aRunnable) MutexAutoLock lock(mMutex); if (!mPool) { + NS_ENSURE_TRUE(EnsureNSSInitializedChromeOrContent(), NS_ERROR_FAILURE); + nsCOMPtr pool(do_CreateInstance(NS_THREADPOOL_CONTRACTID)); NS_ENSURE_TRUE(pool, NS_ERROR_FAILURE); diff --git a/dom/encoding/EncodingUtils.cpp b/dom/encoding/EncodingUtils.cpp index 00f8372906..c9675bfcc7 100644 --- a/dom/encoding/EncodingUtils.cpp +++ b/dom/encoding/EncodingUtils.cpp @@ -15,11 +15,11 @@ namespace mozilla { namespace dom { -static const char* labelsEncodings[][3] = { +static const nsUConvProp labelsEncodings[] = { #include "labelsencodings.properties.h" }; -static const char* encodingsGroups[][3] = { +static const nsUConvProp encodingsGroups[] = { #include "encodingsgroups.properties.h" }; diff --git a/dom/encoding/FallbackEncoding.cpp b/dom/encoding/FallbackEncoding.cpp index f77e17ac6e..533a619c7d 100644 --- a/dom/encoding/FallbackEncoding.cpp +++ b/dom/encoding/FallbackEncoding.cpp @@ -15,15 +15,15 @@ namespace mozilla { namespace dom { -static const char* localesFallbacks[][3] = { +static const nsUConvProp localesFallbacks[] = { #include "localesfallbacks.properties.h" }; -static const char* domainsFallbacks[][3] = { +static const nsUConvProp domainsFallbacks[] = { #include "domainsfallbacks.properties.h" }; -static const char* nonParticipatingDomains[][3] = { +static const nsUConvProp nonParticipatingDomains[] = { #include "nonparticipatingdomains.properties.h" }; diff --git a/dom/encoding/TextEncoder.cpp b/dom/encoding/TextEncoder.cpp index 85bc0ff3cb..b1cd222331 100644 --- a/dom/encoding/TextEncoder.cpp +++ b/dom/encoding/TextEncoder.cpp @@ -13,28 +13,10 @@ namespace mozilla { namespace dom { void -TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv) +TextEncoder::Init() { - nsAutoString label(aEncoding); - EncodingUtils::TrimSpaceCharacters(label); - - // Let encoding be the result of getting an encoding from label. - // If encoding is failure, or is none of utf-8, utf-16, and utf-16be, - // throw a RangeError (https://encoding.spec.whatwg.org/#dom-textencoder). - if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) { - aRv.ThrowRangeError(label); - return; - } - - if (!mEncoding.EqualsLiteral("UTF-8") && - !mEncoding.EqualsLiteral("UTF-16LE") && - !mEncoding.EqualsLiteral("UTF-16BE")) { - aRv.ThrowRangeError(); - return; - } - - // Create an encoder object for mEncoding. - mEncoder = EncodingUtils::EncoderForEncoding(mEncoding); + // Create an encoder object for utf-8. + mEncoder = EncodingUtils::EncoderForEncoding(NS_LITERAL_CSTRING("UTF-8")); } void @@ -92,8 +74,7 @@ TextEncoder::Encode(JSContext* aCx, void TextEncoder::GetEncoding(nsAString& aEncoding) { - CopyASCIItoUTF16(mEncoding, aEncoding); - nsContentUtils::ASCIIToLower(aEncoding); + aEncoding.AssignLiteral("utf-8"); } } // namespace dom diff --git a/dom/encoding/TextEncoder.h b/dom/encoding/TextEncoder.h index 52273907e0..ed08e40234 100644 --- a/dom/encoding/TextEncoder.h +++ b/dom/encoding/TextEncoder.h @@ -24,14 +24,10 @@ public: static TextEncoder* Constructor(const GlobalObject& aGlobal, - const nsAString& aEncoding, ErrorResult& aRv) { nsAutoPtr txtEncoder(new TextEncoder()); - txtEncoder->Init(aEncoding, aRv); - if (aRv.Failed()) { - return nullptr; - } + txtEncoder->Init(); return txtEncoder.forget(); } @@ -50,16 +46,7 @@ public: protected: - /** - * Validates provided encoding and throws an exception if invalid encoding. - * If no encoding is provided then mEncoding is default initialised to "utf-8". - * - * @param aEncoding Optional encoding (case insensitive) provided. - * (valid values are "utf-8", "utf-16", "utf-16be") - * Default value is "utf-8" if no encoding is provided. - * @return aRv EncodingError exception else null. - */ - void Init(const nsAString& aEncoding, ErrorResult& aRv); + void Init(); public: /** @@ -70,7 +57,7 @@ public: void GetEncoding(nsAString& aEncoding); /** - * Encodes incoming utf-16 code units/ DOM string to the requested encoding. + * Encodes incoming utf-16 code units/ DOM string to utf-8. * * @param aCx Javascript context. * @param aObj the wrapper of the TextEncoder @@ -84,7 +71,6 @@ public: JS::MutableHandle aRetval, ErrorResult& aRv); private: - nsCString mEncoding; nsCOMPtr mEncoder; }; diff --git a/dom/encoding/labelsencodings.properties b/dom/encoding/labelsencodings.properties index 42816c26d2..9bdee501ae 100644 --- a/dom/encoding/labelsencodings.properties +++ b/dom/encoding/labelsencodings.properties @@ -199,6 +199,7 @@ x-euc-jp=EUC-JP csiso2022jp=ISO-2022-JP iso-2022-jp=ISO-2022-JP csshiftjis=Shift_JIS +ms932=Shift_JIS ms_kanji=Shift_JIS shift-jis=Shift_JIS shift_jis=Shift_JIS diff --git a/dom/encoding/test/test_TextDecoder.js b/dom/encoding/test/test_TextDecoder.js index f6f726f18b..018add0eac 100644 --- a/dom/encoding/test/test_TextDecoder.js +++ b/dom/encoding/test/test_TextDecoder.js @@ -359,7 +359,7 @@ function testDecoderGetEncoding() {encoding: "big5", labels: ["big5", "cn-big5", "csbig5", "x-x-big5", "big5-hkscs"]}, {encoding: "euc-jp", labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"]}, {encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"]}, - {encoding: "shift_jis", labels: ["csshiftjis", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]}, + {encoding: "shift_jis", labels: ["csshiftjis", "ms932", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]}, {encoding: "euc-kr", labels: ["cseuckr", "csksc56011987", "euc-kr", "iso-ir-149", "korean", "ks_c_5601-1987", "ks_c_5601-1989", "ksc5601", "ksc_5601", "windows-949"]}, {encoding: "utf-16le", labels: ["utf-16", "utf-16le"]}, {encoding: "utf-16be", labels: ["utf-16be"]}, diff --git a/dom/encoding/test/test_TextEncoder.js b/dom/encoding/test/test_TextEncoder.js index 6ecba52ef3..7aa521398d 100644 --- a/dom/encoding/test/test_TextEncoder.js +++ b/dom/encoding/test/test_TextEncoder.js @@ -4,6 +4,15 @@ */ function runTextEncoderTests() +{ + test(testEncoderEncode, "testEncoderEncode"); + test(testEncoderGetEncoding, "testEncoderGetEncoding"); + test(testInvalidSequence, "testInvalidSequence"); + test(testInputString, "testInputString"); + test(testStreamingOptions, "testStreamingOptions"); +} + +function testEncoderEncode() { var data = "\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09" + "\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14" @@ -46,19 +55,9 @@ function runTextEncoderTests() 0xB9, 0x98, 0xE0, 0xB9, 0x99, 0xE0, 0xB9, 0x9A, 0xE0, 0xB9, 0x9B]; - test(testEncoderGetEncoding, "testEncoderGetEncoding"); - test(testInvalidSequence, "testInvalidSequence"); - test(testEncodeUTF16ToUTF16, "testEncodeUTF16ToUTF16"); - test(function() { - testConstructorEncodingOption(data, expectedString) - }, "testConstructorEncodingOption"); - test(function() { - testEncodingValues(data, expectedString) - }, "testEncodingValues"); - test(function() { - testInputString(data, expectedString) - }, "testInputString"); - test(testStreamingOptions, "testStreamingOptions"); + // valid encoding passed + testSingleString({input: data, expected: expectedString, + msg: "testing encoding with valid utf-8 encoding."}); } function testInvalidSequence() @@ -68,77 +67,18 @@ function testInvalidSequence() 0xE0, 0xB9, 0x85]; //Test null input string - testSingleString({encoding: "utf-8", input: data, expected: expectedString, + testSingleString({input: data, expected: expectedString, msg: "encoder with replacement character test."}); } -function testEncodeUTF16ToUTF16() -{ - var data = "\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c" - + "\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56" - + "\u0e57\u0e58\u0e59\u0e5a\u0e5b"; - - var expected = [0x43, 0x0E, 0x44, 0x0E, 0x45, 0x0E, 0x46, 0x0E, 0x47, 0x0E, - 0x48, 0x0E, 0x49, 0x0E, 0x4A, 0x0E, 0x4B, 0x0E, 0x4C, 0x0E, - 0x4D, 0x0E, 0x4E, 0x0E, 0x4F, 0x0E, 0x50, 0x0E, 0x51, 0x0E, - 0x52, 0x0E, 0x53, 0x0E, 0x54, 0x0E, 0x55, 0x0E, 0x56, 0x0E, - 0x57, 0x0E, 0x58, 0x0E, 0x59, 0x0E, 0x5A, 0x0E, 0x5B, 0x0E]; - - testSingleString({encoding: "Utf-16", input: data, expected: expected, - msg: "testing encoding from utf-16 to utf-16 zero."}); -} - -function testConstructorEncodingOption(aData, aExpectedString) -{ - function errorMessage(encoding) { - return `The given encoding '${String(encoding).trim()}' is not supported.`; - } - - // valid encoding passed - var encoding = "UTF-8"; - testSingleString({encoding: encoding, input: aData, expected: aExpectedString, - msg: "testing encoding with valid utf-8 encoding."}); - - // passing spaces for encoding - encoding = " "; - testSingleString({encoding: encoding, input: aData, error: "RangeError", - errorMessage: errorMessage(encoding), - msg: "constructor encoding, spaces encoding test."}); - - // invalid encoding passed - encoding = "asdfasdf"; - testSingleString({encoding: encoding, input: aData, error: "RangeError", - errorMessage: errorMessage(encoding), - msg: "constructor encoding, invalid encoding test."}); - - // null encoding passed - encoding = null; - testSingleString({encoding: encoding, input: aData, error: "RangeError", - errorMessage: errorMessage(encoding), - msg: "constructor encoding, \"null\" encoding test."}); - - // empty encoding passed - encoding = ""; - testSingleString({encoding: encoding, input: aData, error: "RangeError", - errorMessage: errorMessage(encoding), - msg: "constructor encoding, empty encoding test."}); -} - -function testEncodingValues(aData, aExpectedString) -{ - var encoding = "ISO-8859-11"; - testSingleString({encoding: aData, input: encoding, error: "RangeError", - msg: "encoder encoding values test."}); -} - -function testInputString(aData, aExpectedString) +function testInputString() { //Test null input string - testSingleString({encoding: "utf-8", input: "", expected: [], + testSingleString({input: "", expected: [], msg: "encoder null input string test."}); //Test spaces as input string - testSingleString({encoding: "utf-8", input: " ", expected: [32, 32], + testSingleString({input: " ", expected: [32, 32], msg: "spaces as input string."}); } @@ -147,7 +87,7 @@ function testSingleString(test) var outText; try { var stream = test.stream ? {stream: true} : null; - outText = (new TextEncoder(test.encoding)).encode(test.input, stream); + outText = (new TextEncoder()).encode(test.input, stream); } catch (e) { assert_equals(e.name, test.error, test.msg + " error thrown from the constructor."); if (test.errorMessage) { @@ -223,13 +163,9 @@ function testStreamingOptions() 0xE0, 0xB9, 0x98, 0xE0, 0xB9, 0x99, 0xE0, 0xB9, 0x9A, 0xE0, 0xB9, 0x9B]]; - var expectedUTF16 = data.map(function(d) { - return new Uint8Array(new Uint16Array(arrayFromString(d)).buffer); - }); - // STREAMING TEST ONE: test streaming three valid strings with stream option // set to true for all three. - testArrayOfStrings({encoding: "utf-8", array: [ + testArrayOfStrings({array: [ {input: data[0], stream: true, expected: expected[0]}, {input: data[1], stream: true, expected: expected[1]}, {input: data[2], stream: true, expected: expected[2]}, @@ -238,10 +174,10 @@ function testStreamingOptions() // STREAMING TEST TWO: test streaming valid strings with stream option // streaming option: false from constructor, string 1 stream: true, // string 2 stream: false, string 3 stream: false - testArrayOfStrings({encoding: "utf-16", array: [ - {input: data[0], stream: true, expected: expectedUTF16[0]}, - {input: data[1], expected: expectedUTF16[1]}, - {input: data[2], expected: expectedUTF16[2]}, + testArrayOfStrings({array: [ + {input: data[0], stream: true, expected: expected[0]}, + {input: data[1], expected: expected[1]}, + {input: data[2], expected: expected[2]}, ], msg: "streaming test two."}); } @@ -253,7 +189,7 @@ function testArrayOfStrings(test) { var encoder; try { - encoder = new TextEncoder(test.encoding); + encoder = new TextEncoder(); } catch (e) { assert_equals(e.name, test.error, test.msg); return; @@ -278,16 +214,6 @@ function testArrayOfStrings(test) function testEncoderGetEncoding() { - var labelEncodings = [ - {encoding: "utf-8", labels: ["unicode-1-1-utf-8", "utf-8", "utf8"]}, - {encoding: "utf-16le", labels: ["utf-16", "utf-16"]}, - {encoding: "utf-16be", labels: ["utf-16be"]}, - ]; - - for (var le of labelEncodings) { - for (var label of le.labels) { - var encoder = new TextEncoder(label); - assert_equals(encoder.encoding, le.encoding, label + " label encoding test."); - } - } + var encoder = new TextEncoder(); + assert_equals(encoder.encoding, "utf-8", "TextEncoder encoding test."); } diff --git a/dom/encoding/test/unit/test_misc.js b/dom/encoding/test/unit/test_misc.js index bb79c34c72..18ea53f72b 100644 --- a/dom/encoding/test/unit/test_misc.js +++ b/dom/encoding/test/unit/test_misc.js @@ -133,7 +133,17 @@ test( function () { ["utf-8", "utf-16le", "utf-16be"].forEach(function (encoding) { var string = "\x00123ABCabc\x80\xFF\u0100\u1000\uFFFD\uD800\uDC00\uDBFF\uDFFF"; - var encoded = new TextEncoder(encoding).encode(string); + var octets = { + "utf-16le": [0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,0x00, + 0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,0x00, + 0x00,0x01,0x00,0x10,0xFD,0xFF,0x00,0xD8,0x00,0xDC,0xFF,0xDB, + 0xFF,0xDF], + "utf-16be": [0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42, + 0x00,0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF, + 0x01,0x00,0x10,0x00,0xFF,0xFD,0xD8,0x00,0xDC,0x00,0xDB,0xFF, + 0xDF,0xFF] + }; + var encoded = octets[encoding] || new TextEncoder(encoding).encode(string); for (var len = 1; len <= 5; ++len) { var out = "", decoder = new TextDecoder(encoding); @@ -204,19 +214,12 @@ test( test( function () { - var utf_encodings = ["utf-8", "utf-16le", "utf-16be"]; + var encodings = ["utf-8", "ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined", "utf-16le", "utf-16be"]; - var legacy_encodings = ["ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-8-i", "iso-8859-10", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u", "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "x-mac-cyrillic", "gbk", "gb18030", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr", "x-user-defined"]; - - utf_encodings.forEach(function(encoding) { + encodings.forEach(function(encoding) { assert_equals(new TextDecoder(encoding).encoding, encoding); - assert_equals(new TextEncoder(encoding).encoding, encoding); - }); - - legacy_encodings.forEach(function(encoding) { - assert_equals(new TextDecoder(encoding).encoding, encoding); - assert_throws({name: 'RangeError'}, function() { new TextEncoder(encoding); }); + assert_equals(new TextEncoder(encoding).encoding, "utf-8"); }); }, - "Non-UTF encodings supported only for decode, not encode" + "Non-UTF-8 encodings supported only for decode, not encode" ); diff --git a/dom/encoding/test/unit/test_utf.js b/dom/encoding/test/unit/test_utf.js index 72d16eb732..d72ffe4100 100644 --- a/dom/encoding/test/unit/test_utf.js +++ b/dom/encoding/test/unit/test_utf.js @@ -42,6 +42,28 @@ function encode_utf8(string) { return octets; } +function encode_utf16le(string) { + var octets = new Uint8Array(string.length * 2); + var di = 0; + for (var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + octets[di++] = code & 0xFF; + octets[di++] = code >> 8; + } + return octets; +} + +function encode_utf16be(string) { + var octets = new Uint8Array(string.length * 2); + var di = 0; + for (var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + octets[di++] = code >> 8; + octets[di++] = code & 0xFF; + } + return octets; +} + function decode_utf8(octets) { var utf8 = String.fromCharCode.apply(null, octets); return decodeURIComponent(escape(utf8)); @@ -94,13 +116,11 @@ function test_utf_roundtrip () { var block, block_tag, i, j, encoded, decoded, exp_encoded, exp_decoded; - var TE_U16LE = new TextEncoder("UTF-16LE"); var TD_U16LE = new TextDecoder("UTF-16LE"); - var TE_U16BE = new TextEncoder("UTF-16BE"); var TD_U16BE = new TextDecoder("UTF-16BE"); - var TE_U8 = new TextEncoder("UTF-8"); + var TE_U8 = new TextEncoder(); var TD_U8 = new TextDecoder("UTF-8"); for (i = MIN_CODEPOINT; i < MAX_CODEPOINT; i += BLOCK_SIZE) { @@ -108,11 +128,11 @@ function test_utf_roundtrip () { block = genblock(i, BLOCK_SIZE); // test UTF-16LE, UTF-16BE, and UTF-8 encodings against themselves - encoded = TE_U16LE.encode(block); + encoded = encode_utf16le(block); decoded = TD_U16LE.decode(encoded); assert_string_equals(block, decoded, "UTF-16LE round trip " + block_tag); - encoded = TE_U16BE.encode(block); + encoded = encode_utf16be(block); decoded = TD_U16BE.decode(encoded); assert_string_equals(block, decoded, "UTF-16BE round trip " + block_tag); @@ -145,12 +165,12 @@ function test_utf_samples () { expected: [0x00, 0x7A, 0x00, 0xA2, 0x6C, 0x34, 0xD8, 0x34, 0xDD, 0x1E, 0xDB, 0xFF, 0xDF, 0xFD] } ]; + var encoded = new TextEncoder().encode(sample); + assert_array_equals(encoded, cases[0].expected, + "expected equal encodings"); + cases.forEach( function(t) { - var encoded = new TextEncoder(t.encoding).encode(sample); - assert_array_equals(encoded, t.expected, - "expected equal encodings - " + t.encoding); - var decoded = new TextDecoder(t.encoding) .decode(new Uint8Array(t.expected)); assert_equals(decoded, sample, diff --git a/dom/events/DeviceMotionEvent.cpp b/dom/events/DeviceMotionEvent.cpp index b78241ef09..7e6b882395 100644 --- a/dom/events/DeviceMotionEvent.cpp +++ b/dom/events/DeviceMotionEvent.cpp @@ -34,6 +34,22 @@ DeviceMotionEvent::InitDeviceMotionEvent( const DeviceAccelerationInit& aAccelIncludingGravity, const DeviceRotationRateInit& aRotationRate, Nullable aInterval) +{ + InitDeviceMotionEvent(aType, aCanBubble, aCancelable, aAcceleration, + aAccelIncludingGravity, aRotationRate, aInterval, + Nullable()); +} + +void +DeviceMotionEvent::InitDeviceMotionEvent( + const nsAString& aType, + bool aCanBubble, + bool aCancelable, + const DeviceAccelerationInit& aAcceleration, + const DeviceAccelerationInit& aAccelIncludingGravity, + const DeviceRotationRateInit& aRotationRate, + Nullable aInterval, + Nullable aTimeStamp) { Event::InitEvent(aType, aCanBubble, aCancelable); @@ -50,6 +66,9 @@ DeviceMotionEvent::InitDeviceMotionEvent( aRotationRate.mBeta, aRotationRate.mGamma); mInterval = aInterval; + if (!aTimeStamp.IsNull()) { + mEvent->mTime = aTimeStamp.Value(); + } } already_AddRefed @@ -141,7 +160,7 @@ using namespace mozilla::dom; already_AddRefed NS_NewDOMDeviceMotionEvent(EventTarget* aOwner, nsPresContext* aPresContext, - WidgetEvent* aEvent) + WidgetEvent* aEvent) { RefPtr it = new DeviceMotionEvent(aOwner, aPresContext, aEvent); diff --git a/dom/events/DeviceMotionEvent.h b/dom/events/DeviceMotionEvent.h index ca631787d8..6e6f3d9e5f 100644 --- a/dom/events/DeviceMotionEvent.h +++ b/dom/events/DeviceMotionEvent.h @@ -130,6 +130,16 @@ public: const DeviceRotationRateInit& aRotationRate, Nullable aInterval); + void InitDeviceMotionEvent( + const nsAString& aType, + bool aCanBubble, + bool aCancelable, + const DeviceAccelerationInit& aAcceleration, + const DeviceAccelerationInit& aAccelerationIncludingGravity, + const DeviceRotationRateInit& aRotationRate, + Nullable aInterval, + Nullable aTimeStamp); + static already_AddRefed Constructor(const GlobalObject& aGlobal, const nsAString& aType, diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index 15dc8ebf13..4ef54cebcc 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -12,7 +12,17 @@ #include "nsIDocument.h" #include "nsINode.h" #include "nsPIDOMWindow.h" +#include "AnimationEvent.h" +#include "BeforeAfterKeyboardEvent.h" +#include "BeforeUnloadEvent.h" +#include "ClipboardEvent.h" +#include "CommandEvent.h" +#include "CompositionEvent.h" +#include "DataContainerEvent.h" +#include "DeviceMotionEvent.h" +#include "DragEvent.h" #include "GeckoProfiler.h" +#include "KeyboardEvent.h" #include "mozilla/ContentEvents.h" #include "mozilla/dom/CloseEvent.h" #include "mozilla/dom/CustomEvent.h" diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index b43b9605ec..a0f3cbbaab 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -30,7 +30,6 @@ #include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsContentUtils.h" -#include "nsDocShell.h" #include "nsDOMCID.h" #include "nsError.h" #include "nsGkAtoms.h" @@ -1197,15 +1196,14 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext, // Maybe add a marker to the docshell's timeline, but only // bother with all the logic if some docshell is recording. - nsDocShell* docShell; + nsCOMPtr docShell; RefPtr timelines = TimelineConsumers::Get(); bool needsEndEventMarker = false; if (mIsMainThreadELM && listener->mListenerType != Listener::eNativeListener) { - nsCOMPtr docShellComPtr = GetDocShellForTarget(); - if (docShellComPtr) { - docShell = static_cast(docShellComPtr.get()); + docShell = GetDocShellForTarget(); + if (docShell) { if (timelines && timelines->HasConsumer(docShell)) { needsEndEventMarker = true; nsAutoString typeStr; diff --git a/dom/events/EventListenerService.h b/dom/events/EventListenerService.h index 8c0db5710f..7c478fd019 100644 --- a/dom/events/EventListenerService.h +++ b/dom/events/EventListenerService.h @@ -23,7 +23,7 @@ class nsIMutableArray; namespace mozilla { namespace dom { class EventTarget; -}; +} // namespace dom template class Maybe; diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index fa50fac528..04d2c738b8 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -740,10 +740,11 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent) mIsHandlingQueryContentEvent = true; ContentEventHandler handler(GetPresContext()); nsresult rv = handler.HandleQueryContentEvent(aEvent); - if (aEvent->mSucceeded) { - // We need to guarantee that mRootContent should be always same value for - // the observing editor. - aEvent->mReply.mContentsRoot = mRootContent; + + if (!IsInitializedWithPlugin() && + NS_WARN_IF(aEvent->mReply.mContentsRoot != mRootContent)) { + // Focus has changed unexpectedly, so make the query fail. + aEvent->mSucceeded = false; } return rv; } @@ -1263,7 +1264,8 @@ IMEContentObserver::UpdateSelectionCache() WidgetQueryContentEvent selection(true, eQuerySelectedText, mWidget); ContentEventHandler handler(GetPresContext()); handler.OnQuerySelectedText(&selection); - if (NS_WARN_IF(!selection.mSucceeded)) { + if (NS_WARN_IF(!selection.mSucceeded) || + NS_WARN_IF(selection.mReply.mContentsRoot != mRootContent)) { return false; } @@ -1404,7 +1406,8 @@ IMEContentObserver::TryToFlushPendingNotifications() MOZ_LOG(sIMECOLog, LogLevel::Debug, ("IMECO: 0x%p IMEContentObserver::TryToFlushPendingNotifications(), " "performing queued IMENotificationSender forcibly", this)); - mQueuedSender->Run(); + RefPtr queuedSender = mQueuedSender; + queuedSender->Run(); } /****************************************************************************** @@ -1549,12 +1552,18 @@ IMEContentObserver::IMENotificationSender::Run() // If notifications caused some new change, we should notify them now. if (mIMEContentObserver->NeedsToNotifyIMEOfSomething()) { - MOZ_LOG(sIMECOLog, LogLevel::Debug, - ("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), " - "posting IMENotificationSender to current thread", this)); - mIMEContentObserver->mQueuedSender = - new IMENotificationSender(mIMEContentObserver); - NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender); + if (mIMEContentObserver->GetState() == eState_StoppedObserving) { + MOZ_LOG(sIMECOLog, LogLevel::Debug, + ("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), " + "waiting IMENotificationSender to be reinitialized", this)); + } else { + MOZ_LOG(sIMECOLog, LogLevel::Debug, + ("IMECO: 0x%p IMEContentObserver::IMENotificationSender::Run(), " + "posting IMENotificationSender to current thread", this)); + mIMEContentObserver->mQueuedSender = + new IMENotificationSender(mIMEContentObserver); + NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender); + } } return NS_OK; } diff --git a/dom/events/UIEvent.cpp b/dom/events/UIEvent.cpp index 5aeb23917b..77a0700629 100644 --- a/dom/events/UIEvent.cpp +++ b/dom/events/UIEvent.cpp @@ -57,7 +57,7 @@ UIEvent::UIEvent(EventTarget* aOwner, case eScrollPortEventClass: { InternalScrollPortEvent* scrollEvent = mEvent->AsScrollPortEvent(); - mDetail = (int32_t)scrollEvent->orient; + mDetail = static_cast(scrollEvent->mOrient); break; } diff --git a/dom/html/crashtests/1237633.html b/dom/html/crashtests/1237633.html new file mode 100644 index 0000000000..c235f03158 --- /dev/null +++ b/dom/html/crashtests/1237633.html @@ -0,0 +1 @@ + diff --git a/dom/html/crashtests/495546-1.html b/dom/html/crashtests/495546-1.html new file mode 100644 index 0000000000..0547b98674 --- /dev/null +++ b/dom/html/crashtests/495546-1.html @@ -0,0 +1,19 @@ + + + + + + + diff --git a/dom/html/crashtests/crashtests.list b/dom/html/crashtests/crashtests.list index 60f6ab396f..ba5aef050c 100644 --- a/dom/html/crashtests/crashtests.list +++ b/dom/html/crashtests/crashtests.list @@ -24,6 +24,7 @@ load 468562-1.html load 468562-2.html load 494225.html load 495543.svg +load 495546-1.html load 504183-1.html load 515829-1.html load 515829-2.html @@ -73,5 +74,7 @@ load 916322-1.html load 916322-2.html load 1032654.html pref(dom.image.srcset.enabled,true) load 1141260.html -asserts(0-3) load 1350972.html +load 1228876.html load 1230110.html +load 1237633.html +asserts(0-3) load 1350972.html diff --git a/dom/media/webrtc/RTCCertificate.cpp b/dom/media/webrtc/RTCCertificate.cpp index 0fc7581d6d..814a5f9a29 100644 --- a/dom/media/webrtc/RTCCertificate.cpp +++ b/dom/media/webrtc/RTCCertificate.cpp @@ -44,9 +44,10 @@ const size_t RTCCertificateMinRsaSize = 1024; class GenerateRTCCertificateTask : public GenerateAsymmetricKeyTask { public: - GenerateRTCCertificateTask(JSContext* aCx, const ObjectOrString& aAlgorithm, - const Sequence& aKeyUsages) - : GenerateAsymmetricKeyTask(aCx, aAlgorithm, true, aKeyUsages), + GenerateRTCCertificateTask(nsIGlobalObject* aGlobal, JSContext* aCx, + const ObjectOrString& aAlgorithm, + const Sequence& aKeyUsages) + : GenerateAsymmetricKeyTask(aGlobal, aCx, aAlgorithm, true, aKeyUsages), mExpires(0), mAuthType(ssl_kea_null), mCertificate(nullptr), @@ -263,7 +264,7 @@ RTCCertificate::GenerateCertificate( return nullptr; } RefPtr task = - new GenerateRTCCertificateTask(aGlobal.Context(), + new GenerateRTCCertificateTask(global, aGlobal.Context(), aKeygenAlgorithm, usages); task->DispatchWithPromise(p); return p.forget(); diff --git a/dom/system/nsDeviceSensors.cpp b/dom/system/nsDeviceSensors.cpp index cfb89f0db0..3b0a324a97 100644 --- a/dom/system/nsDeviceSensors.cpp +++ b/dom/system/nsDeviceSensors.cpp @@ -332,6 +332,7 @@ nsDeviceSensors::Notify(const mozilla::hal::SensorData& aSensorData) double y = len > 1 ? values[1] : 0.0; double z = len > 2 ? values[2] : 0.0; double w = len > 3 ? values[3] : 0.0; + PRTime timestamp = aSensorData.timestamp(); nsCOMArray windowListeners; for (uint32_t i = 0; i < mWindowListeners[type]->Length(); i++) { @@ -354,7 +355,7 @@ nsDeviceSensors::Notify(const mozilla::hal::SensorData& aSensorData) if (type == nsIDeviceSensorData::TYPE_ACCELERATION || type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION || type == nsIDeviceSensorData::TYPE_GYROSCOPE) { - FireDOMMotionEvent(domdoc, target, type, x, y, z); + FireDOMMotionEvent(domdoc, target, type, timestamp, x, y, z); } else if (type == nsIDeviceSensorData::TYPE_ORIENTATION) { FireDOMOrientationEvent(target, x, y, z, Orientation::kAbsolute); } else if (type == nsIDeviceSensorData::TYPE_ROTATION_VECTOR) { @@ -491,6 +492,7 @@ void nsDeviceSensors::FireDOMMotionEvent(nsIDOMDocument *domdoc, EventTarget* target, uint32_t type, + PRTime timestamp, double x, double y, double z) @@ -556,7 +558,8 @@ nsDeviceSensors::FireDOMMotionEvent(nsIDOMDocument *domdoc, *mLastAcceleration, *mLastAccelerationIncludingGravity, *mLastRotationRate, - Nullable(DEFAULT_SENSOR_POLL)); + Nullable(DEFAULT_SENSOR_POLL), + Nullable(timestamp)); event->SetTrusted(true); diff --git a/dom/system/nsDeviceSensors.h b/dom/system/nsDeviceSensors.h index 6f7df48d9a..bed6cd69d9 100644 --- a/dom/system/nsDeviceSensors.h +++ b/dom/system/nsDeviceSensors.h @@ -63,6 +63,7 @@ private: void FireDOMMotionEvent(class nsIDOMDocument *domDoc, mozilla::dom::EventTarget* target, uint32_t type, + PRTime timestamp, double x, double y, double z); diff --git a/dom/webidl/TextEncoder.webidl b/dom/webidl/TextEncoder.webidl index a031e6d262..9269b572d4 100644 --- a/dom/webidl/TextEncoder.webidl +++ b/dom/webidl/TextEncoder.webidl @@ -10,7 +10,7 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -[Constructor(optional DOMString utfLabel = "utf-8"), +[Constructor, Exposed=(Window,Worker,System)] interface TextEncoder { [Constant] diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index df951f4629..7f6b5386b5 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -288,7 +288,7 @@ WorkerRunnable::Run() JSObject* global = JS::CurrentGlobalOrNull(cx); if (global) { - globalObject = GetGlobalObjectForGlobal(global); + globalObject = xpc::NativeGlobal(global); } else { globalObject = DefaultGlobalObject(); } diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index f97efc9b82..2430d04b0b 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -879,26 +879,6 @@ WorkerDebuggerGlobalScope::Dump(JSContext* aCx, } } -nsIGlobalObject* -GetGlobalObjectForGlobal(JSObject* global) -{ - nsIGlobalObject* globalObject = nullptr; - UNWRAP_WORKER_OBJECT(WorkerGlobalScope, global, globalObject); - - if (!globalObject) { - UNWRAP_OBJECT(WorkerDebuggerGlobalScope, global, globalObject); - - if (!globalObject) { - MOZ_ASSERT(IsDebuggerSandbox(global)); - globalObject = static_cast(JS_GetPrivate(global)); - - MOZ_ASSERT(globalObject); - } - } - - return globalObject; -} - bool IsWorkerGlobal(JSObject* object) { diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 6c8db6dd03..5b4f06ca5e 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -361,9 +361,6 @@ ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult); } // namespace exceptions -nsIGlobalObject* -GetGlobalObjectForGlobal(JSObject* global); - bool IsWorkerGlobal(JSObject* global); diff --git a/dom/workers/test/serviceworkers/browser_cached_force_refresh.html b/dom/workers/test/serviceworkers/browser_cached_force_refresh.html index 4b550a3d23..33bd8cdaa6 100644 --- a/dom/workers/test/serviceworkers/browser_cached_force_refresh.html +++ b/dom/workers/test/serviceworkers/browser_cached_force_refresh.html @@ -8,9 +8,56 @@ diff --git a/dom/workers/test/serviceworkers/force_refresh_browser_worker.js b/dom/workers/test/serviceworkers/force_refresh_browser_worker.js index 0fe91ed95a..96d9d0f176 100644 --- a/dom/workers/test/serviceworkers/force_refresh_browser_worker.js +++ b/dom/workers/test/serviceworkers/force_refresh_browser_worker.js @@ -20,3 +20,15 @@ self.addEventListener('fetch', function (event) { }) ); }); + +self.addEventListener('message', function (event) { + if (event.data.type === 'GET_UNCONTROLLED_CLIENTS') { + event.waitUntil(clients.matchAll({ includeUncontrolled: true }) + .then(function(clientList) { + var resultList = clientList.map(function(c) { + return { url: c.url, frameType: c.frameType }; + }); + event.source.postMessage({ type: 'CLIENTS', detail: resultList }); + })); + } +}); diff --git a/gfx/gl/AndroidSurfaceTexture.cpp b/gfx/gl/AndroidSurfaceTexture.cpp index 0e7611c9e9..08d880c7ca 100644 --- a/gfx/gl/AndroidSurfaceTexture.cpp +++ b/gfx/gl/AndroidSurfaceTexture.cpp @@ -129,13 +129,15 @@ AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout) MOZ_ASSERT(aContext->IsOwningThreadCurrent(), "Trying to attach GLContext from different thread"); - mAttachedContext = aContext; - mAttachedContext->MakeCurrent(); aContext->fGenTextures(1, &mTexture); - UpdateCanDetach(); + if (NS_FAILED(mSurfaceTexture->AttachToGLContext(mTexture))) { + return NS_ERROR_NOT_AVAILABLE; + } + mAttachedContext = aContext; + mAttachedContext->MakeCurrent(); - return mSurfaceTexture->AttachToGLContext(mTexture); + return NS_OK; } nsresult @@ -160,24 +162,21 @@ AndroidSurfaceTexture::Detach() return NS_OK; } -void -AndroidSurfaceTexture::UpdateCanDetach() +bool +AndroidSurfaceTexture::CanDetach() const { // The API for attach/detach only exists on 16+, and PowerVR has some sort of - // fencing issue. Additionally, attach/detach seems to be busted on at least some - // Mali adapters (400MP2 for sure, bug 1131793) - bool canDetach = gfxPrefs::SurfaceTextureDetachEnabled(); - - mCanDetach = AndroidBridge::Bridge()->GetAPIVersion() >= 16 && + // fencing issue. Additionally, attach/detach seems to be busted on at least + // some Mali adapters (400MP2 for sure, bug 1131793) + return AndroidBridge::Bridge()->GetAPIVersion() >= 16 && (!mAttachedContext || mAttachedContext->Vendor() != GLVendor::Imagination) && (!mAttachedContext || mAttachedContext->Vendor() != GLVendor::ARM /* Mali */) && - canDetach; + gfxPrefs::SurfaceTextureDetachEnabled(); } bool AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture) { - UpdateCanDetach(); if (!aTexture && !CanDetach()) { // We have no texture and cannot initialize detached, bail out @@ -214,7 +213,6 @@ AndroidSurfaceTexture::AndroidSurfaceTexture() , mSurfaceTexture() , mSurface() , mAttachedContext(nullptr) - , mCanDetach(false) , mMonitor("AndroidSurfaceTexture::mContextMonitor") { } diff --git a/gfx/gl/AndroidSurfaceTexture.h b/gfx/gl/AndroidSurfaceTexture.h index fcff8f2934..19f161e63b 100644 --- a/gfx/gl/AndroidSurfaceTexture.h +++ b/gfx/gl/AndroidSurfaceTexture.h @@ -56,9 +56,9 @@ public: nsresult Detach(); - // Ability to detach is based on API version (16+), and we also block PowerVR since it has some type - // of fencing problem. Bug 1100126. - bool CanDetach() const { return mCanDetach; } + // Ability to detach is based on API version (16+), and we also block PowerVR + // since it has some type of fencing problem. Bug 1100126. + bool CanDetach() const; GLContext* AttachedContext() const { return mAttachedContext; } @@ -90,14 +90,12 @@ private: ~AndroidSurfaceTexture(); bool Init(GLContext* aContext, GLuint aTexture); - void UpdateCanDetach(); GLuint mTexture; widget::sdk::SurfaceTexture::GlobalRef mSurfaceTexture; widget::sdk::Surface::GlobalRef mSurface; GLContext* mAttachedContext; - bool mCanDetach; RefPtr mNativeWindow; int mID; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index a839e7b074..839f8129fa 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -64,7 +64,7 @@ uint32_t GLContext::sDebugMode = 0; #define END_SYMBOLS { nullptr, { nullptr } } // should match the order of GLExtensions, and be null-terminated. -static const char *sExtensionNames[] = { +static const char* const sExtensionNames[] = { "NO_EXTENSION", "GL_AMD_compressed_ATC_texture", "GL_ANGLE_depth_texture", @@ -98,6 +98,7 @@ static const char *sExtensionNames[] = { "GL_ARB_pixel_buffer_object", "GL_ARB_robustness", "GL_ARB_sampler_objects", + "GL_ARB_seamless_cube_map", "GL_ARB_sync", "GL_ARB_texture_compression", "GL_ARB_texture_float", @@ -227,9 +228,20 @@ ParseGLSLVersion(GLContext* gl, uint32_t* out_version) return true; } + const auto fnSkipPrefix = [&versionString](const char* prefix) { + const auto len = strlen(prefix); + if (strncmp(versionString, prefix, len) == 0) + versionString += len; + }; + const char kGLESVersionPrefix[] = "OpenGL ES GLSL ES"; - if (strncmp(versionString, kGLESVersionPrefix, strlen(kGLESVersionPrefix)) == 0) - versionString += strlen(kGLESVersionPrefix); + fnSkipPrefix(kGLESVersionPrefix); + + if (gl->WorkAroundDriverBugs()) { + // Nexus 7 2013 (bug 1234441) + const char kBadGLESVersionPrefix[] = "OpenGL ES GLSL"; + fnSkipPrefix(kBadGLESVersionPrefix); + } const char* itr = versionString; char* end = nullptr; @@ -386,17 +398,15 @@ ParseGLVersion(GLContext* gl, uint32_t* out_version) } GLContext::GLContext(const SurfaceCaps& caps, - GLContext* sharedContext, - bool isOffscreen) - : mInitialized(false), - mIsOffscreen(isOffscreen), + GLContext* sharedContext, + bool isOffscreen) + : mIsOffscreen(isOffscreen), mContextLost(false), mVersion(0), mProfile(ContextProfile::Unknown), mShadingLanguageVersion(0), mVendor(GLVendor::Other), mRenderer(GLRenderer::Other), - mHasRobustness(false), mTopError(LOCAL_GL_NO_ERROR), mSharedContext(sharedContext), mCaps(caps), @@ -446,7 +456,7 @@ GLContext::StaticDebugCallback(GLenum source, } static void -ClearSymbols(GLLibraryLoader::SymLoadStruct *symbols) +ClearSymbols(const GLLibraryLoader::SymLoadStruct* symbols) { while (symbols->symPointer) { *symbols->symPointer = nullptr; @@ -455,15 +465,81 @@ ClearSymbols(GLLibraryLoader::SymLoadStruct *symbols) } bool -GLContext::InitWithPrefix(const char *prefix, bool trygl) +GLContext::InitWithPrefix(const char* prefix, bool trygl) { - if (mInitialized) { - return true; + MOZ_RELEASE_ASSERT(!mSymbols.fBindFramebuffer, + "InitWithPrefix should only be called once."); + + if (!InitWithPrefixImpl(prefix, trygl)) { + // If initialization fails, zero the symbols to avoid hard-to-understand bugs. + mSymbols.Zero(); + NS_WARNING("GLContext::InitWithPrefix failed!"); + return false; } + return true; +} + +static bool +LoadGLSymbols(GLContext* gl, const char* prefix, bool trygl, + const GLLibraryLoader::SymLoadStruct* list, const char* desc) +{ + if (gl->LoadSymbols(list, trygl, prefix)) + return true; + + ClearSymbols(list); + + if (desc) { + const nsPrintfCString err("Failed to load symbols for %s.", desc); + NS_ERROR(err.BeginReading()); + } + return false; +} + +bool +GLContext::LoadExtSymbols(const char* prefix, bool trygl, const SymLoadStruct* list, + GLExtensions ext) +{ + const char* extName = sExtensionNames[size_t(ext)]; + if (!LoadGLSymbols(this, prefix, trygl, list, extName)) { + MarkExtensionUnsupported(ext); + return false; + } + return true; +}; + +bool +GLContext::LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruct* list, + GLFeature feature) +{ + const char* featureName = GetFeatureName(feature); + if (!LoadGLSymbols(this, prefix, trygl, list, featureName)) { + MarkUnsupported(feature); + return false; + } + return true; +}; + +bool +GLContext::InitWithPrefixImpl(const char* prefix, bool trygl) +{ mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs(); - SymLoadStruct symbols[] = { +#ifdef MOZ_GL_DEBUG + if (gfxEnv::GlDebug()) + sDebugMode |= DebugEnabled; + + // enables extra verbose output, informing of the start and finish of every GL call. + // useful e.g. to record information to investigate graphics system crashes/lockups + if (gfxEnv::GlDebugVerbose()) + sDebugMode |= DebugTrace; + + // aborts on GL error. Can be useful to debug quicker code that is known not to generate any GL error in principle. + if (gfxEnv::GlDebugAbortOnError()) + sDebugMode |= DebugAbortOnError; +#endif + + const SymLoadStruct coreSymbols[] = { { (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", nullptr } }, { (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", nullptr } }, { (PRFuncPtr*) &mSymbols.fBindAttribLocation, { "BindAttribLocation", "BindAttribLocationARB", nullptr } }, @@ -590,1171 +666,922 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) { (PRFuncPtr*) &mSymbols.fDeleteShader, { "DeleteShader", "DeleteShaderARB", nullptr } }, END_SYMBOLS - }; - mInitialized = LoadSymbols(&symbols[0], trygl, prefix); + if (!LoadGLSymbols(this, prefix, trygl, coreSymbols, "GL")) + return false; + + //////////////// + MakeCurrent(); - if (mInitialized) { - MOZ_ASSERT(mProfile != ContextProfile::Unknown); + MOZ_ASSERT(mProfile != ContextProfile::Unknown); - uint32_t version = 0; - ParseGLVersion(this, &version); + uint32_t version = 0; + ParseGLVersion(this, &version); - mShadingLanguageVersion = 100; - ParseGLSLVersion(this, &mShadingLanguageVersion); + mShadingLanguageVersion = 100; + ParseGLSLVersion(this, &mShadingLanguageVersion); - if (ShouldSpew()) { - printf_stderr("OpenGL version detected: %u\n", version); - printf_stderr("OpenGL shading language version detected: %u\n", mShadingLanguageVersion); - printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR)); - printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER)); - } - - if (version >= mVersion) { - mVersion = version; - } - // Don't fail if version < mVersion, see bug 999445, - // Mac OSX 10.6/10.7 machines with Intel GPUs claim only OpenGL 1.4 but - // have all the GL2+ extensions that we need. + if (ShouldSpew()) { + printf_stderr("OpenGL version detected: %u\n", version); + printf_stderr("OpenGL shading language version detected: %u\n", mShadingLanguageVersion); + printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR)); + printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER)); } + if (version >= mVersion) { + mVersion = version; + } + // Don't fail if version < mVersion, see bug 999445, + // Mac OSX 10.6/10.7 machines with Intel GPUs claim only OpenGL 1.4 but + // have all the GL2+ extensions that we need. + + //////////////// + // Load OpenGL ES 2.0 symbols, or desktop if we aren't using ES 2. - if (mInitialized) { - if (IsGLES()) { - SymLoadStruct symbols_ES2[] = { - { (PRFuncPtr*) &mSymbols.fGetShaderPrecisionFormat, { "GetShaderPrecisionFormat", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClearDepthf, { "ClearDepthf", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDepthRangef, { "DepthRangef", nullptr } }, - END_SYMBOLS - }; + if (IsGLES()) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetShaderPrecisionFormat, { "GetShaderPrecisionFormat", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClearDepthf, { "ClearDepthf", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDepthRangef, { "DepthRangef", nullptr } }, + END_SYMBOLS + }; - if (!LoadSymbols(&symbols_ES2[0], trygl, prefix)) { - NS_ERROR("OpenGL ES 2.0 supported, but symbols could not be loaded."); - mInitialized = false; - } + if (!LoadGLSymbols(this, prefix, trygl, symbols, "OpenGL ES")) + return false; + } else { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fClearDepth, { "ClearDepth", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDepthRange, { "DepthRange", nullptr } }, + { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } }, + { (PRFuncPtr*) &mSymbols.fMapBuffer, { "MapBuffer", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } }, + { (PRFuncPtr*) &mSymbols.fPointParameterf, { "PointParameterf", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDrawBuffer, { "DrawBuffer", nullptr } }, + // The following functions are only used by Skia/GL in desktop mode. + // Other parts of Gecko should avoid using these + { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClientActiveTexture, { "ClientActiveTexture", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDisableClientState, { "DisableClientState", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEnableClientState, { "EnableClientState", nullptr } }, + { (PRFuncPtr*) &mSymbols.fLoadIdentity, { "LoadIdentity", nullptr } }, + { (PRFuncPtr*) &mSymbols.fLoadMatrixf, { "LoadMatrixf", nullptr } }, + { (PRFuncPtr*) &mSymbols.fMatrixMode, { "MatrixMode", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexGeni, { "TexGeni", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexGenf, { "TexGenf", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexGenfv, { "TexGenfv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexPointer, { "VertexPointer", nullptr } }, + END_SYMBOLS + }; + + if (!LoadGLSymbols(this, prefix, trygl, symbols, "Desktop OpenGL")) + return false; + } + + //////////////// + + const char* glVendorString = (const char*)fGetString(LOCAL_GL_VENDOR); + const char* glRendererString = (const char*)fGetString(LOCAL_GL_RENDERER); + if (!glVendorString || !glRendererString) + return false; + + // The order of these strings must match up with the order of the enum + // defined in GLContext.h for vendor IDs. + const char* vendorMatchStrings[size_t(GLVendor::Other)] = { + "Intel", + "NVIDIA", + "ATI", + "Qualcomm", + "Imagination", + "nouveau", + "Vivante", + "VMware, Inc.", + "ARM" + }; + + mVendor = GLVendor::Other; + for (size_t i = 0; i < size_t(GLVendor::Other); ++i) { + if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) { + mVendor = GLVendor(i); + break; + } + } + + // The order of these strings must match up with the order of the enum + // defined in GLContext.h for renderer IDs. + const char* rendererMatchStrings[size_t(GLRenderer::Other)] = { + "Adreno 200", + "Adreno 205", + "Adreno (TM) 200", + "Adreno (TM) 205", + "Adreno (TM) 320", + "Adreno (TM) 420", + "PowerVR SGX 530", + "PowerVR SGX 540", + "NVIDIA Tegra", + "Android Emulator", + "Gallium 0.4 on llvmpipe", + "Intel HD Graphics 3000 OpenGL Engine", + "Microsoft Basic Render Driver" + }; + + mRenderer = GLRenderer::Other; + for (size_t i = 0; i < size_t(GLRenderer::Other); ++i) { + if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) { + mRenderer = GLRenderer(i); + break; + } + } + + if (ShouldSpew()) { + const char* vendors[size_t(GLVendor::Other)] = { + "Intel", + "NVIDIA", + "ATI", + "Qualcomm" + }; + + MOZ_ASSERT(glVendorString); + if (mVendor < GLVendor::Other) { + printf_stderr("OpenGL vendor ('%s') recognized as: %s\n", + glVendorString, vendors[size_t(mVendor)]); } else { - SymLoadStruct symbols_desktop[] = { - { (PRFuncPtr*) &mSymbols.fClearDepth, { "ClearDepth", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDepthRange, { "DepthRange", nullptr } }, - { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } }, - { (PRFuncPtr*) &mSymbols.fMapBuffer, { "MapBuffer", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } }, - { (PRFuncPtr*) &mSymbols.fPointParameterf, { "PointParameterf", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDrawBuffer, { "DrawBuffer", nullptr } }, - // These functions are only used by Skia/GL in desktop mode. - // Other parts of Gecko should avoid using these - { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClientActiveTexture, { "ClientActiveTexture", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDisableClientState, { "DisableClientState", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEnableClientState, { "EnableClientState", nullptr } }, - { (PRFuncPtr*) &mSymbols.fLoadIdentity, { "LoadIdentity", nullptr } }, - { (PRFuncPtr*) &mSymbols.fLoadMatrixf, { "LoadMatrixf", nullptr } }, - { (PRFuncPtr*) &mSymbols.fMatrixMode, { "MatrixMode", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexGeni, { "TexGeni", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexGenf, { "TexGenf", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexGenfv, { "TexGenfv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexPointer, { "VertexPointer", nullptr } }, + printf_stderr("OpenGL vendor ('%s') not recognized.\n", glVendorString); + } + } + + //////////////// + + // We need this for retrieving the list of extensions on Core profiles. + if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } }, + END_SYMBOLS + }; + + if (!LoadGLSymbols(this, prefix, trygl, symbols, "get_string_indexed")) { + MOZ_RELEASE_ASSERT(false, "get_string_indexed is required!"); + return false; + } + } + + InitExtensions(); + InitFeatures(); + + // Disable extensions with partial or incorrect support. + if (WorkAroundDriverBugs()) { + if (Renderer() == GLRenderer::AdrenoTM320) { + MarkUnsupported(GLFeature::standard_derivatives); + } + + if (Vendor() == GLVendor::Vivante) { + // bug 958256 + MarkUnsupported(GLFeature::standard_derivatives); + } + + if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) { + // Bug 978966: on Microsoft's "Basic Render Driver" (software renderer) + // multisampling hardcodes blending with the default blendfunc, which breaks WebGL. + MarkUnsupported(GLFeature::framebuffer_multisample); + } + +#ifdef XP_MACOSX + // The Mac Nvidia driver, for versions up to and including 10.8, + // don't seem to properly support this. See 814839 + // this has been fixed in Mac OS X 10.9. See 907946 + // and it also works in 10.8.3 and higher. See 1094338. + if (Vendor() == gl::GLVendor::NVIDIA && + !nsCocoaFeatures::IsAtLeastVersion(10,8,3)) + { + MarkUnsupported(GLFeature::depth_texture); + } +#endif + } + + if (IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) { + MOZ_ASSERT((mSymbols.fMapBuffer && mSymbols.fUnmapBuffer), + "ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer" + " being available!"); + } + + //////////////////////////////////////////////////////////////////////////// + + const auto fnLoadForFeature = [this, prefix, trygl](const SymLoadStruct* list, + GLFeature feature) + { + return this->LoadFeatureSymbols(prefix, trygl, list, feature); + }; + + // Check for ARB_framebuffer_objects + if (IsSupported(GLFeature::framebuffer_object)) { + // https://www.opengl.org/registry/specs/ARB/framebuffer_object.txt + const SymLoadStruct symbols[] = { + CORE_SYMBOL(IsRenderbuffer), + CORE_SYMBOL(BindRenderbuffer), + CORE_SYMBOL(DeleteRenderbuffers), + CORE_SYMBOL(GenRenderbuffers), + CORE_SYMBOL(RenderbufferStorage), + CORE_SYMBOL(RenderbufferStorageMultisample), + CORE_SYMBOL(GetRenderbufferParameteriv), + CORE_SYMBOL(IsFramebuffer), + CORE_SYMBOL(BindFramebuffer), + CORE_SYMBOL(DeleteFramebuffers), + CORE_SYMBOL(GenFramebuffers), + CORE_SYMBOL(CheckFramebufferStatus), + CORE_SYMBOL(FramebufferTexture2D), + CORE_SYMBOL(FramebufferTextureLayer), + CORE_SYMBOL(FramebufferRenderbuffer), + CORE_SYMBOL(GetFramebufferAttachmentParameteriv), + CORE_SYMBOL(BlitFramebuffer), + CORE_SYMBOL(GenerateMipmap), + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::framebuffer_object); + } + + if (!IsSupported(GLFeature::framebuffer_object)) { + // Check for aux symbols based on extensions + if (IsSupported(GLFeature::framebuffer_object_EXT_OES)) { + const SymLoadStruct symbols[] = { + CORE_EXT_SYMBOL2(IsRenderbuffer, EXT, OES), + CORE_EXT_SYMBOL2(BindRenderbuffer, EXT, OES), + CORE_EXT_SYMBOL2(DeleteRenderbuffers, EXT, OES), + CORE_EXT_SYMBOL2(GenRenderbuffers, EXT, OES), + CORE_EXT_SYMBOL2(RenderbufferStorage, EXT, OES), + CORE_EXT_SYMBOL2(GetRenderbufferParameteriv, EXT, OES), + CORE_EXT_SYMBOL2(IsFramebuffer, EXT, OES), + CORE_EXT_SYMBOL2(BindFramebuffer, EXT, OES), + CORE_EXT_SYMBOL2(DeleteFramebuffers, EXT, OES), + CORE_EXT_SYMBOL2(GenFramebuffers, EXT, OES), + CORE_EXT_SYMBOL2(CheckFramebufferStatus, EXT, OES), + CORE_EXT_SYMBOL2(FramebufferTexture2D, EXT, OES), + CORE_EXT_SYMBOL2(FramebufferRenderbuffer, EXT, OES), + CORE_EXT_SYMBOL2(GetFramebufferAttachmentParameteriv, EXT, OES), + CORE_EXT_SYMBOL2(GenerateMipmap, EXT, OES), END_SYMBOLS }; - - if (!LoadSymbols(&symbols_desktop[0], trygl, prefix)) { - NS_ERROR("Desktop symbols failed to load."); - mInitialized = false; - } - } - } - - const char *glVendorString = nullptr; - const char *glRendererString = nullptr; - - if (mInitialized) { - // The order of these strings must match up with the order of the enum - // defined in GLContext.h for vendor IDs - glVendorString = (const char *)fGetString(LOCAL_GL_VENDOR); - if (!glVendorString) - mInitialized = false; - - const char *vendorMatchStrings[size_t(GLVendor::Other)] = { - "Intel", - "NVIDIA", - "ATI", - "Qualcomm", - "Imagination", - "nouveau", - "Vivante", - "VMware, Inc.", - "ARM" - }; - - mVendor = GLVendor::Other; - for (size_t i = 0; i < size_t(GLVendor::Other); ++i) { - if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) { - mVendor = GLVendor(i); - break; - } + fnLoadForFeature(symbols, GLFeature::framebuffer_object_EXT_OES); } - // The order of these strings must match up with the order of the enum - // defined in GLContext.h for renderer IDs - glRendererString = (const char *)fGetString(LOCAL_GL_RENDERER); - if (!glRendererString) - mInitialized = false; - - const char *rendererMatchStrings[size_t(GLRenderer::Other)] = { - "Adreno 200", - "Adreno 205", - "Adreno (TM) 200", - "Adreno (TM) 205", - "Adreno (TM) 320", - "Adreno (TM) 420", - "PowerVR SGX 530", - "PowerVR SGX 540", - "NVIDIA Tegra", - "Android Emulator", - "Gallium 0.4 on llvmpipe", - "Intel HD Graphics 3000 OpenGL Engine", - "Microsoft Basic Render Driver" - }; - - mRenderer = GLRenderer::Other; - for (size_t i = 0; i < size_t(GLRenderer::Other); ++i) { - if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) { - mRenderer = GLRenderer(i); - break; - } - } - } - - -#ifdef MOZ_GL_DEBUG - if (gfxEnv::GlDebug()) - sDebugMode |= DebugEnabled; - - // enables extra verbose output, informing of the start and finish of every GL call. - // useful e.g. to record information to investigate graphics system crashes/lockups - if (gfxEnv::GlDebugVerbose()) - sDebugMode |= DebugTrace; - - // aborts on GL error. Can be useful to debug quicker code that is known not to generate any GL error in principle. - if (gfxEnv::GlDebugAbortOnError()) - sDebugMode |= DebugAbortOnError; -#endif - - if (mInitialized) { - if (ShouldSpew()) { - const char* vendors[size_t(GLVendor::Other)] = { - "Intel", - "NVIDIA", - "ATI", - "Qualcomm" + if (IsSupported(GLFeature::framebuffer_blit)) { + const SymLoadStruct symbols[] = { + EXT_SYMBOL3(BlitFramebuffer, ANGLE, EXT, NV), + END_SYMBOLS }; + fnLoadForFeature(symbols, GLFeature::framebuffer_blit); + } - MOZ_ASSERT(glVendorString); - if (mVendor < GLVendor::Other) { - printf_stderr("OpenGL vendor ('%s') recognized as: %s\n", - glVendorString, vendors[size_t(mVendor)]); + if (IsSupported(GLFeature::framebuffer_multisample)) { + const SymLoadStruct symbols[] = { + EXT_SYMBOL3(RenderbufferStorageMultisample, ANGLE, APPLE, EXT), + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::framebuffer_multisample); + } + + if (IsExtensionSupported(GLContext::ARB_geometry_shader4) || + IsExtensionSupported(GLContext::NV_geometry_program4)) + { + const SymLoadStruct symbols[] = { + EXT_SYMBOL2(FramebufferTextureLayer, ARB, EXT), + END_SYMBOLS + }; + if (!LoadGLSymbols(this, prefix, trygl, symbols, + "ARB_geometry_shader4/NV_geometry_program4")) + { + MarkExtensionUnsupported(GLContext::ARB_geometry_shader4); + MarkExtensionUnsupported(GLContext::NV_geometry_program4); + } + } + } + + if (!IsSupported(GLFeature::framebuffer_object) && + !IsSupported(GLFeature::framebuffer_object_EXT_OES)) + { + NS_ERROR("GLContext requires support for framebuffer objects."); + return false; + } + MOZ_RELEASE_ASSERT(mSymbols.fBindFramebuffer); + + //////////////// + + LoadMoreSymbols(prefix, trygl); + + //////////////////////////////////////////////////////////////////////////// + + raw_fGetIntegerv(LOCAL_GL_VIEWPORT, mViewportRect); + raw_fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mScissorRect); + raw_fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); + raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize); + raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); + raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); + +#ifdef XP_MACOSX + if (mWorkAroundDriverBugs) { + if (mVendor == GLVendor::Intel) { + // see bug 737182 for 2D textures, bug 684882 for cube map textures. + mMaxTextureSize = std::min(mMaxTextureSize, 4096); + mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 512); + // for good measure, we align renderbuffers on what we do for 2D textures + mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096); + mNeedsTextureSizeChecks = true; + } else if (mVendor == GLVendor::NVIDIA) { + if (nsCocoaFeatures::OnMountainLionOrLater()) { + // See bug 879656. 8192 fails, 8191 works. + mMaxTextureSize = std::min(mMaxTextureSize, 8191); + mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191); } else { - printf_stderr("OpenGL vendor ('%s') unrecognized\n", glVendorString); + // See bug 877949. + mMaxTextureSize = std::min(mMaxTextureSize, 4096); + mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096); } + + // Part of the bug 879656, but it also doesn't hurt the 877949 + mNeedsTextureSizeChecks = true; } - - if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) { - SymLoadStruct moreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } }, - END_SYMBOLS - }; - - MOZ_ALWAYS_TRUE(LoadSymbols(moreSymbols, trygl, prefix)); - } - - InitExtensions(); - InitFeatures(); - - // Disable extensions with partial or incorrect support. - if (WorkAroundDriverBugs()) { - if (Renderer() == GLRenderer::AdrenoTM320) { - MarkUnsupported(GLFeature::standard_derivatives); - } - - if (Vendor() == GLVendor::Vivante) { - // bug 958256 - MarkUnsupported(GLFeature::standard_derivatives); - } - - if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) { - // Bug 978966: on Microsoft's "Basic Render Driver" (software renderer) - // multisampling hardcodes blending with the default blendfunc, which breaks WebGL. - MarkUnsupported(GLFeature::framebuffer_multisample); - } - -#ifdef XP_MACOSX - // The Mac Nvidia driver, for versions up to and including 10.8, - // don't seem to properly support this. See 814839 - // this has been fixed in Mac OS X 10.9. See 907946 - // and it also works in 10.8.3 and higher. See 1094338. - if (Vendor() == gl::GLVendor::NVIDIA && - !nsCocoaFeatures::IsAtLeastVersion(10,8,3)) - { - MarkUnsupported(GLFeature::depth_texture); - } -#endif - } - - NS_ASSERTION(!IsExtensionSupported(GLContext::ARB_pixel_buffer_object) || - (mSymbols.fMapBuffer && mSymbols.fUnmapBuffer), - "ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer being available!"); - - if (SupportsRobustness()) { - mHasRobustness = false; - - if (IsExtensionSupported(ARB_robustness)) { - SymLoadStruct robustnessSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports ARB_robustness without supplying GetGraphicsResetStatusARB."); - - mSymbols.fGetGraphicsResetStatus = nullptr; - } else { - mHasRobustness = true; - } - } - if (!IsExtensionSupported(ARB_robustness) && - IsExtensionSupported(EXT_robustness)) { - SymLoadStruct robustnessSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports EXT_robustness without supplying GetGraphicsResetStatusEXT."); - - mSymbols.fGetGraphicsResetStatus = nullptr; - } else { - mHasRobustness = true; - } - } - - if (!mHasRobustness) { - MarkUnsupported(GLFeature::robustness); - } - } - - // Check for ARB_framebuffer_objects - if (IsSupported(GLFeature::framebuffer_object)) { - // https://www.opengl.org/registry/specs/ARB/framebuffer_object.txt - SymLoadStruct coreSymbols[] = { - CORE_SYMBOL(IsRenderbuffer), - CORE_SYMBOL(BindRenderbuffer), - CORE_SYMBOL(DeleteRenderbuffers), - CORE_SYMBOL(GenRenderbuffers), - CORE_SYMBOL(RenderbufferStorage), - CORE_SYMBOL(RenderbufferStorageMultisample), - CORE_SYMBOL(GetRenderbufferParameteriv), - CORE_SYMBOL(IsFramebuffer), - CORE_SYMBOL(BindFramebuffer), - CORE_SYMBOL(DeleteFramebuffers), - CORE_SYMBOL(GenFramebuffers), - CORE_SYMBOL(CheckFramebufferStatus), - CORE_SYMBOL(FramebufferTexture2D), - CORE_SYMBOL(FramebufferTextureLayer), - CORE_SYMBOL(FramebufferRenderbuffer), - CORE_SYMBOL(GetFramebufferAttachmentParameteriv), - CORE_SYMBOL(BlitFramebuffer), - CORE_SYMBOL(GenerateMipmap), - END_SYMBOLS - }; - - if (!LoadSymbols(coreSymbols, trygl, prefix)) { - NS_ERROR("GL supports framebuffer_object without supplying its functions."); - MarkUnsupported(GLFeature::framebuffer_object); - } - } - - if (!IsSupported(GLFeature::framebuffer_object)) { - // Check for aux symbols based on extensions - if (IsSupported(GLFeature::framebuffer_object_EXT_OES)) - { - SymLoadStruct extSymbols[] = { - CORE_EXT_SYMBOL2(IsRenderbuffer, EXT, OES), - CORE_EXT_SYMBOL2(BindRenderbuffer, EXT, OES), - CORE_EXT_SYMBOL2(DeleteRenderbuffers, EXT, OES), - CORE_EXT_SYMBOL2(GenRenderbuffers, EXT, OES), - CORE_EXT_SYMBOL2(RenderbufferStorage, EXT, OES), - CORE_EXT_SYMBOL2(GetRenderbufferParameteriv, EXT, OES), - CORE_EXT_SYMBOL2(IsFramebuffer, EXT, OES), - CORE_EXT_SYMBOL2(BindFramebuffer, EXT, OES), - CORE_EXT_SYMBOL2(DeleteFramebuffers, EXT, OES), - CORE_EXT_SYMBOL2(GenFramebuffers, EXT, OES), - CORE_EXT_SYMBOL2(CheckFramebufferStatus, EXT, OES), - CORE_EXT_SYMBOL2(FramebufferTexture2D, EXT, OES), - CORE_EXT_SYMBOL2(FramebufferRenderbuffer, EXT, OES), - CORE_EXT_SYMBOL2(GetFramebufferAttachmentParameteriv, EXT, OES), - CORE_EXT_SYMBOL2(GenerateMipmap, EXT, OES), - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports framebuffer_object without supplying its functions."); - } - } - - if (IsSupported(GLFeature::framebuffer_blit)) { - SymLoadStruct extSymbols[] = { - EXT_SYMBOL3(BlitFramebuffer, ANGLE, EXT, NV), - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports framebuffer_blit without supplying its functions."); - } - } - - if (IsSupported(GLFeature::framebuffer_multisample)) { - SymLoadStruct extSymbols[] = { - EXT_SYMBOL3(RenderbufferStorageMultisample, ANGLE, APPLE, EXT), - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports framebuffer_multisample without supplying its functions."); - } - } - - if (IsExtensionSupported(GLContext::ARB_geometry_shader4) || - IsExtensionSupported(GLContext::NV_geometry_program4)) - { - SymLoadStruct extSymbols[] = { - EXT_SYMBOL2(FramebufferTextureLayer, ARB, EXT), - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports geometry_shader4 withot supplying its functions."); - } - } - } - - if (IsSupported(GLFeature::sync)) { - SymLoadStruct syncSymbols[] = { - { (PRFuncPtr*) &mSymbols.fFenceSync, { "FenceSync", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsSync, { "IsSync", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteSync, { "DeleteSync", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nullptr } }, - { (PRFuncPtr*) &mSymbols.fWaitSync, { "WaitSync", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetInteger64v, { "GetInteger64v", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetSynciv, { "GetSynciv", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&syncSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports sync without supplying its functions."); - - MarkExtensionUnsupported(ARB_sync); - ClearSymbols(syncSymbols); - } - } - - if (IsExtensionSupported(OES_EGL_image)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fEGLImageTargetTexture2D, { "EGLImageTargetTexture2DOES", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEGLImageTargetRenderbufferStorage, { "EGLImageTargetRenderbufferStorageOES", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports OES_EGL_image without supplying its functions."); - - MarkExtensionUnsupported(OES_EGL_image); - ClearSymbols(extSymbols); - } - } - - if (IsExtensionSupported(APPLE_texture_range)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTextureRangeAPPLE, { "TextureRangeAPPLE", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(extSymbols, trygl, prefix)) { - NS_ERROR("GL supports APPLE_texture_range without supplying its functions."); - - ClearSymbols(extSymbols); - } - } - - if (IsSupported(GLFeature::vertex_array_object)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArray", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArrays", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArray", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArrays", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArrayARB", "IsVertexArrayOES", "IsVertexArrayAPPLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArraysARB", "GenVertexArraysOES", "GenVertexArraysAPPLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArrayARB", "BindVertexArrayOES", "BindVertexArrayAPPLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArraysARB", "DeleteVertexArraysOES", "DeleteVertexArraysAPPLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::vertex_array_object); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports Vertex Array Object without supplying its functions."); - - MarkUnsupported(GLFeature::vertex_array_object); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::draw_instanced)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstanced", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstanced", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstancedARB", "DrawArraysInstancedEXT", "DrawArraysInstancedNV", "DrawArraysInstancedANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstancedARB", "DrawElementsInstancedEXT", "DrawElementsInstancedNV", "DrawElementsInstancedANGLE", nullptr } - }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::draw_instanced); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports instanced draws without supplying its functions."); - - MarkUnsupported(GLFeature::draw_instanced); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::instanced_arrays)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisor", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisorARB", "VertexAttribDivisorNV", "VertexAttribDivisorANGLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::instanced_arrays); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports array instanced without supplying it function."); - - MarkUnsupported(GLFeature::instanced_arrays); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::texture_storage)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2DEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3DEXT", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::texture_storage); - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports texture storage without supplying its functions."); - - MarkUnsupported(GLFeature::texture_storage); - MarkExtensionSupported(useCore ? ARB_texture_storage : EXT_texture_storage); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::sampler_objects)) { - SymLoadStruct samplerObjectsSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGenSamplers, { "GenSamplers", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteSamplers, { "DeleteSamplers", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsSampler, { "IsSampler", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindSampler, { "BindSampler", nullptr } }, - { (PRFuncPtr*) &mSymbols.fSamplerParameteri, { "SamplerParameteri", nullptr } }, - { (PRFuncPtr*) &mSymbols.fSamplerParameteriv, { "SamplerParameteriv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fSamplerParameterf, { "SamplerParameterf", nullptr } }, - { (PRFuncPtr*) &mSymbols.fSamplerParameterfv, { "SamplerParameterfv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetSamplerParameteriv, { "GetSamplerParameteriv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetSamplerParameterfv, { "GetSamplerParameterfv", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(samplerObjectsSymbols, trygl, prefix)) { - NS_ERROR("GL supports sampler objects without supplying its functions."); - - MarkUnsupported(GLFeature::sampler_objects); - ClearSymbols(samplerObjectsSymbols); - } - } - - if (IsSupported(GLFeature::texture_storage)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(coreSymbols, trygl, prefix)) { - NS_ERROR("GL supports texture storage without supplying its functions."); - - MarkUnsupported(GLFeature::texture_storage); - MarkExtensionUnsupported(ARB_texture_storage); - ClearSymbols(coreSymbols); - } - } - - // ARB_transform_feedback2/NV_transform_feedback2 is a - // superset of EXT_transform_feedback/NV_transform_feedback - // and adds glPauseTransformFeedback & - // glResumeTransformFeedback, which are required for WebGL2. - if (IsSupported(GLFeature::transform_feedback2)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBase", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRange", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacks", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedback", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacks", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedback", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedback", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedback", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryings", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVarying", nullptr } }, - { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedback", nullptr } }, - { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedback", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBaseEXT", "BindBufferBaseNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRangeEXT", "BindBufferRangeNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacksNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedbackNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacksNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedbackNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedbackEXT", "BeginTransformFeedbackNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedbackEXT", "EndTransformFeedbackNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryingsEXT", "TransformFeedbackVaryingsNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVaryingEXT", "GetTransformFeedbackVaryingNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedbackNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedbackNV", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::transform_feedback2); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports transform feedback without supplying its functions."); - - MarkUnsupported(GLFeature::transform_feedback2); - MarkUnsupported(GLFeature::bind_buffer_offset); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::bind_buffer_offset)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBindBufferOffset, { "BindBufferOffset", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBindBufferOffset, - { "BindBufferOffsetEXT", "BindBufferOffsetNV", nullptr } - }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::bind_buffer_offset); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports BindBufferOffset without supplying its function."); - - MarkUnsupported(GLFeature::bind_buffer_offset); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::query_counter)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounter", nullptr } }, - END_SYMBOLS - }; - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounterEXT", "QueryCounterANGLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::query_counter); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports query counters without supplying its functions."); - - MarkUnsupported(GLFeature::query_counter); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::query_objects)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQueryEXT", "BeginQueryANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueriesEXT", "GenQueriesANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueriesEXT", "DeleteQueriesANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQueryEXT", "EndQueryANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryivEXT", "GetQueryivANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuivEXT", "GetQueryObjectuivANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQueryEXT", "IsQueryANGLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::query_objects); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports query objects without supplying its functions."); - - MarkUnsupported(GLFeature::query_objects); - MarkUnsupported(GLFeature::get_query_object_i64v); - MarkUnsupported(GLFeature::get_query_object_iv); - MarkUnsupported(GLFeature::occlusion_query); - MarkUnsupported(GLFeature::occlusion_query_boolean); - MarkUnsupported(GLFeature::occlusion_query2); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::get_query_object_i64v)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64v", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64v", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64vEXT", "GetQueryObjecti64vANGLE", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64vEXT", "GetQueryObjectui64vANGLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::get_query_object_i64v); - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports 64 bit query object getters without supplying its functions."); - - MarkUnsupported(GLFeature::get_query_object_i64v); - MarkUnsupported(GLFeature::query_counter); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::get_query_object_iv)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectivEXT", "GetQueryObjectivANGLE", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::get_query_object_iv); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports query objects iv getter without supplying its function."); - - MarkUnsupported(GLFeature::get_query_object_iv); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::clear_buffers)) { - SymLoadStruct clearBuffersSymbols[] = { - { (PRFuncPtr*) &mSymbols.fClearBufferfi, { "ClearBufferfi", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClearBufferfv, { "ClearBufferfv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClearBufferiv, { "ClearBufferiv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fClearBufferuiv, { "ClearBufferuiv", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(clearBuffersSymbols, trygl, prefix)) { - NS_ERROR("GL supports clear_buffers without supplying its functions."); - - MarkUnsupported(GLFeature::clear_buffers); - ClearSymbols(clearBuffersSymbols); - } - } - - if (IsSupported(GLFeature::copy_buffer)) { - SymLoadStruct copyBufferSymbols[] = { - { (PRFuncPtr*) &mSymbols.fCopyBufferSubData, { "CopyBufferSubData", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(copyBufferSymbols, trygl, prefix)) { - NS_ERROR("GL supports copy_buffer without supplying its function."); - - MarkUnsupported(GLFeature::copy_buffer); - ClearSymbols(copyBufferSymbols); - } - } - - if (IsSupported(GLFeature::draw_buffers)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffersARB", "DrawBuffersEXT", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::draw_buffers); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports draw_buffers without supplying its functions."); - - MarkUnsupported(GLFeature::draw_buffers); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::draw_range_elements)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElements", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElementsEXT", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::draw_range_elements); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports draw_range_elements without supplying its functions."); - - MarkUnsupported(GLFeature::draw_range_elements); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::get_integer_indexed)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegeri_v", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] ={ - { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegerIndexedvEXT", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::get_integer_indexed); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports get_integer_indexed without supplying its functions."); - - MarkUnsupported(GLFeature::get_integer_indexed); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::get_integer64_indexed)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetInteger64i_v, { "GetInteger64i_v", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(coreSymbols, trygl, prefix)) { - NS_ERROR("GL supports get_integer64_indexed without supplying its functions."); - - MarkUnsupported(GLFeature::get_integer64_indexed); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::gpu_shader4)) { - SymLoadStruct gpuShader4Symbols[] = { - { (PRFuncPtr*) &mSymbols.fGetVertexAttribIiv, { "GetVertexAttribIiv", "GetVertexAttribIivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetVertexAttribIuiv, { "GetVertexAttribIuiv", "GetVertexAttribIuivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexAttribI4i, { "VertexAttribI4i", "VertexAttribI4iEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexAttribI4iv, { "VertexAttribI4iv","VertexAttribI4ivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexAttribI4ui, { "VertexAttribI4ui", "VertexAttribI4uiEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexAttribI4uiv, { "VertexAttribI4uiv", "VertexAttribI4uivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fVertexAttribIPointer, { "VertexAttribIPointer", "VertexAttribIPointerEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform1ui, { "Uniform1ui", "Uniform1uiEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform2ui, { "Uniform2ui", "Uniform2uiEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform3ui, { "Uniform3ui", "Uniform3uiEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform4ui, { "Uniform4ui", "Uniform4uiEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform1uiv, { "Uniform1uiv", "Uniform1uivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform2uiv, { "Uniform2uiv", "Uniform2uivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform3uiv, { "Uniform3uiv", "Uniform3uivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniform4uiv, { "Uniform4uiv", "Uniform4uivEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetFragDataLocation, { "GetFragDataLocation", "GetFragDataLocationEXT", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetUniformuiv, { "GetUniformuiv", "GetUniformuivEXT", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(gpuShader4Symbols, trygl, prefix)) { - NS_ERROR("GL supports gpu_shader4 without supplying its functions."); - - MarkUnsupported(GLFeature::gpu_shader4); - ClearSymbols(gpuShader4Symbols); - } - } - - if (IsSupported(GLFeature::map_buffer_range)) { - SymLoadStruct mapBufferRangeSymbols[] = { - { (PRFuncPtr*) &mSymbols.fMapBufferRange, { "MapBufferRange", nullptr } }, - { (PRFuncPtr*) &mSymbols.fFlushMappedBufferRange, { "FlushMappedBufferRange", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(mapBufferRangeSymbols, trygl, prefix)) { - NS_ERROR("GL supports map_buffer_range without supplying its functions."); - - MarkUnsupported(GLFeature::map_buffer_range); - ClearSymbols(mapBufferRangeSymbols); - } - } - - if (IsSupported(GLFeature::texture_3D)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTexImage3D, { "TexImage3D", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3DEXT", "TexSubImage3DOES", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::texture_3D); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports 3D textures without supplying functions."); - - MarkUnsupported(GLFeature::texture_3D); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::texture_3D_compressed)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3D", nullptr } }, - { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3D", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3DARB", "CompressedTexImage3DOES", nullptr } }, - { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3DARB", "CompressedTexSubImage3DOES", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::texture_3D_compressed); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports 3D textures without supplying functions."); - - MarkUnsupported(GLFeature::texture_3D_compressed); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::texture_3D_copy)) { - SymLoadStruct coreSymbols[] = { - { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3D", nullptr } }, - END_SYMBOLS - }; - - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3DEXT", "CopyTexSubImage3DOES", nullptr } }, - END_SYMBOLS - }; - - bool useCore = IsFeatureProvidedByCoreSymbols(GLFeature::texture_3D_copy); - - if (!LoadSymbols(useCore ? coreSymbols : extSymbols, trygl, prefix)) { - NS_ERROR("GL supports 3D textures without supplying functions."); - - MarkUnsupported(GLFeature::texture_3D_copy); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::uniform_buffer_object)) { - // Note: Don't query for glGetActiveUniformName because it is not - // supported by GL ES 3. - SymLoadStruct uboSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetUniformIndices, { "GetUniformIndices", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetActiveUniformsiv, { "GetActiveUniformsiv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetUniformBlockIndex, { "GetUniformBlockIndex", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockiv, { "GetActiveUniformBlockiv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockName, { "GetActiveUniformBlockName", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformBlockBinding, { "UniformBlockBinding", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&uboSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports ARB_uniform_buffer_object without supplying its functions."); - - MarkExtensionUnsupported(ARB_uniform_buffer_object); - MarkUnsupported(GLFeature::uniform_buffer_object); - ClearSymbols(uboSymbols); - } - } - - if (IsSupported(GLFeature::uniform_matrix_nonsquare)) { - SymLoadStruct umnSymbols[] = { - { (PRFuncPtr*) &mSymbols.fUniformMatrix2x3fv, { "UniformMatrix2x3fv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformMatrix2x4fv, { "UniformMatrix2x4fv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformMatrix3x2fv, { "UniformMatrix3x2fv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformMatrix3x4fv, { "UniformMatrix3x4fv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformMatrix4x2fv, { "UniformMatrix4x2fv", nullptr } }, - { (PRFuncPtr*) &mSymbols.fUniformMatrix4x3fv, { "UniformMatrix4x3fv", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&umnSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports uniform matrix with non-square dim without supplying its functions."); - - MarkUnsupported(GLFeature::uniform_matrix_nonsquare); - ClearSymbols(umnSymbols); - } - } - - if (IsSupported(GLFeature::internalformat_query)) { - SymLoadStruct coreSymbols[] = { - CORE_SYMBOL(GetInternalformativ), - END_SYMBOLS - }; - - if (!LoadSymbols(&coreSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports internalformat query without supplying its functions."); - - MarkUnsupported(GLFeature::internalformat_query); - ClearSymbols(coreSymbols); - } - } - - if (IsSupported(GLFeature::invalidate_framebuffer)) { - SymLoadStruct invSymbols[] = { - { (PRFuncPtr *) &mSymbols.fInvalidateFramebuffer, { "InvalidateFramebuffer", nullptr } }, - { (PRFuncPtr *) &mSymbols.fInvalidateSubFramebuffer, { "InvalidateSubFramebuffer", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&invSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports framebuffer invalidation without supplying its functions."); - - MarkUnsupported(GLFeature::invalidate_framebuffer); - ClearSymbols(invSymbols); - } - } - - if (IsExtensionSupported(KHR_debug)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fDebugMessageControl, { "DebugMessageControl", "DebugMessageControlKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDebugMessageInsert, { "DebugMessageInsert", "DebugMessageInsertKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDebugMessageCallback, { "DebugMessageCallback", "DebugMessageCallbackKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetDebugMessageLog, { "GetDebugMessageLog", "GetDebugMessageLogKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetPointerv, { "GetPointerv", "GetPointervKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fPushDebugGroup, { "PushDebugGroup", "PushDebugGroupKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fPopDebugGroup, { "PopDebugGroup", "PopDebugGroupKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fObjectLabel, { "ObjectLabel", "ObjectLabelKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetObjectLabel, { "GetObjectLabel", "GetObjectLabelKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fObjectPtrLabel, { "ObjectPtrLabel", "ObjectPtrLabelKHR", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetObjectPtrLabel, { "GetObjectPtrLabel", "GetObjectPtrLabelKHR", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&extSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports KHR_debug without supplying its functions."); - - MarkExtensionUnsupported(KHR_debug); - ClearSymbols(extSymbols); - } - } - - if (IsExtensionSupported(NV_fence)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGenFences, { "GenFencesNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fDeleteFences, { "DeleteFencesNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fSetFence, { "SetFenceNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fTestFence, { "TestFenceNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fFinishFence, { "FinishFenceNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fIsFence, { "IsFenceNV", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetFenceiv, { "GetFenceivNV", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&extSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports NV_fence without supplying its functions."); - - MarkExtensionUnsupported(NV_fence); - ClearSymbols(extSymbols); - } - } - - if (IsSupported(GLFeature::read_buffer)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&extSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports read_buffer without supplying its functions."); - - MarkUnsupported(GLFeature::read_buffer); - ClearSymbols(extSymbols); - } - } - - if (IsExtensionSupported(APPLE_framebuffer_multisample)) { - SymLoadStruct extSymbols[] = { - { (PRFuncPtr*) &mSymbols.fResolveMultisampleFramebufferAPPLE, { "ResolveMultisampleFramebufferAPPLE", nullptr } }, - END_SYMBOLS - }; - - if (!LoadSymbols(&extSymbols[0], trygl, prefix)) { - NS_ERROR("GL supports APPLE_framebuffer_multisample without supplying its functions."); - - MarkExtensionUnsupported(APPLE_framebuffer_multisample); - ClearSymbols(extSymbols); - } - } - - // Load developer symbols, don't fail if we can't find them. - SymLoadStruct auxSymbols[] = { - { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } }, - { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } }, - END_SYMBOLS - }; - bool warnOnFailures = DebugMode(); - LoadSymbols(&auxSymbols[0], trygl, prefix, warnOnFailures); } - - if (mInitialized) { - raw_fGetIntegerv(LOCAL_GL_VIEWPORT, mViewportRect); - raw_fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mScissorRect); - raw_fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); - raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize); - raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); - raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); - -#ifdef XP_MACOSX - if (mWorkAroundDriverBugs) { - if (mVendor == GLVendor::Intel) { - // see bug 737182 for 2D textures, bug 684882 for cube map textures. - mMaxTextureSize = std::min(mMaxTextureSize, 4096); - mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 512); - // for good measure, we align renderbuffers on what we do for 2D textures - mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096); - mNeedsTextureSizeChecks = true; - } else if (mVendor == GLVendor::NVIDIA) { - if (nsCocoaFeatures::OnMountainLionOrLater()) { - // See bug 879656. 8192 fails, 8191 works. - mMaxTextureSize = std::min(mMaxTextureSize, 8191); - mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191); - } else { - // See bug 877949. - mMaxTextureSize = std::min(mMaxTextureSize, 4096); - mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096); - } - - // Part of the bug 879656, but it also doesn't hurt the 877949 - mNeedsTextureSizeChecks = true; - } - } #endif #ifdef MOZ_X11 - if (mWorkAroundDriverBugs && - mVendor == GLVendor::Nouveau) { + if (mWorkAroundDriverBugs) { + if (mVendor == GLVendor::Nouveau) { // see bug 814716. Clamp MaxCubeMapTextureSize at 2K for Nouveau. mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 2048); mNeedsTextureSizeChecks = true; + } else if (mVendor == GLVendor::Intel) { + // Bug 1199923. Driver seems to report a larger max size than + // actually supported. + mMaxTextureSize /= 2; + mMaxRenderbufferSize /= 2; + mNeedsTextureSizeChecks = true; } + } #endif - if (mWorkAroundDriverBugs && - Renderer() == GLRenderer::AdrenoTM420) { - // see bug 1194923. Calling glFlush before glDeleteFramebuffers - // prevents occasional driver crash. - mNeedsFlushBeforeDeleteFB = true; - } - - mMaxTextureImageSize = mMaxTextureSize; - - if (IsSupported(GLFeature::framebuffer_multisample)) { - fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples); - } - - // We're ready for final setup. - fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0); - - // TODO: Remove SurfaceCaps::any. - if (mCaps.any) { - mCaps.any = false; - mCaps.color = true; - mCaps.alpha = false; - } - - UpdateGLFormats(mCaps); - - mTexGarbageBin = new TextureGarbageBin(this); - - MOZ_ASSERT(IsCurrent()); - - if (DebugMode() && IsExtensionSupported(KHR_debug)) { - fEnable(LOCAL_GL_DEBUG_OUTPUT); - fDisable(LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS); - fDebugMessageCallback(&StaticDebugCallback, (void*)this); - fDebugMessageControl(LOCAL_GL_DONT_CARE, - LOCAL_GL_DONT_CARE, - LOCAL_GL_DONT_CARE, - 0, nullptr, - true); - } - - } else { - // if initialization fails, ensure all symbols are zero, to avoid hard-to-understand bugs - mSymbols.Zero(); - NS_WARNING("InitWithPrefix failed!"); + if (mWorkAroundDriverBugs && + Renderer() == GLRenderer::AdrenoTM420) { + // see bug 1194923. Calling glFlush before glDeleteFramebuffers + // prevents occasional driver crash. + mNeedsFlushBeforeDeleteFB = true; } - mVersionString = nsPrintfCString("%u.%u.%u", mVersion / 100, (mVersion / 10) % 10, mVersion % 10); + mMaxTextureImageSize = mMaxTextureSize; - return mInitialized; + if (IsSupported(GLFeature::framebuffer_multisample)) { + fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples); + } + + //////////////////////////////////////////////////////////////////////////// + + // We're ready for final setup. + fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0); + + // TODO: Remove SurfaceCaps::any. + if (mCaps.any) { + mCaps.any = false; + mCaps.color = true; + mCaps.alpha = false; + } + + UpdateGLFormats(mCaps); + + mTexGarbageBin = new TextureGarbageBin(this); + + MOZ_ASSERT(IsCurrent()); + + if (DebugMode() && IsExtensionSupported(KHR_debug)) { + fEnable(LOCAL_GL_DEBUG_OUTPUT); + fDisable(LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS); + fDebugMessageCallback(&StaticDebugCallback, (void*)this); + fDebugMessageControl(LOCAL_GL_DONT_CARE, + LOCAL_GL_DONT_CARE, + LOCAL_GL_DONT_CARE, + 0, nullptr, + true); + } + + mVersionString = nsPrintfCString("%u.%u.%u", mVersion / 100, (mVersion / 10) % 10, + mVersion % 10); + return true; +} + +void +GLContext::LoadMoreSymbols(const char* prefix, bool trygl) +{ + const auto fnLoadForExt = [this, prefix, trygl](const SymLoadStruct* list, + GLExtensions ext) + { + return this->LoadExtSymbols(prefix, trygl, list, ext); + }; + + const auto fnLoadForFeature = [this, prefix, trygl](const SymLoadStruct* list, + GLFeature feature) + { + return this->LoadFeatureSymbols(prefix, trygl, list, feature); + }; + + const auto fnLoadFeatureByCore = [this, fnLoadForFeature](const SymLoadStruct* coreList, + const SymLoadStruct* extList, + GLFeature feature) + { + const bool useCore = this->IsFeatureProvidedByCoreSymbols(feature); + const auto list = useCore ? coreList : extList; + return fnLoadForFeature(list, feature); + }; + + bool hasRobustness = false; + if (SupportsRobustness()) { + if (IsExtensionSupported(ARB_robustness)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", nullptr } }, + END_SYMBOLS + }; + if (fnLoadForExt(symbols, ARB_robustness)) { + hasRobustness = true; + } + } + + if (!hasRobustness && IsExtensionSupported(EXT_robustness)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", nullptr } }, + END_SYMBOLS + }; + if (fnLoadForExt(symbols, EXT_robustness)) { + hasRobustness = true; + } + } + } + if (!hasRobustness) { + MarkUnsupported(GLFeature::robustness); + } + + if (IsSupported(GLFeature::sync)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fFenceSync, { "FenceSync", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsSync, { "IsSync", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteSync, { "DeleteSync", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nullptr } }, + { (PRFuncPtr*) &mSymbols.fWaitSync, { "WaitSync", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetInteger64v, { "GetInteger64v", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetSynciv, { "GetSynciv", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::sync); + } + + if (IsExtensionSupported(OES_EGL_image)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fEGLImageTargetTexture2D, { "EGLImageTargetTexture2DOES", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEGLImageTargetRenderbufferStorage, { "EGLImageTargetRenderbufferStorageOES", nullptr } }, + END_SYMBOLS + }; + fnLoadForExt(symbols, OES_EGL_image); + } + + if (IsExtensionSupported(APPLE_texture_range)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fTextureRangeAPPLE, { "TextureRangeAPPLE", nullptr } }, + END_SYMBOLS + }; + fnLoadForExt(symbols, APPLE_texture_range); + } + + if (IsSupported(GLFeature::vertex_array_object)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArray", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArrays", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArray", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArrays", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArrayARB", "IsVertexArrayOES", "IsVertexArrayAPPLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArraysARB", "GenVertexArraysOES", "GenVertexArraysAPPLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArrayARB", "BindVertexArrayOES", "BindVertexArrayAPPLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArraysARB", "DeleteVertexArraysOES", "DeleteVertexArraysAPPLE", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::vertex_array_object); + } + + if (IsSupported(GLFeature::draw_instanced)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstanced", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstanced", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstancedARB", "DrawArraysInstancedEXT", "DrawArraysInstancedNV", "DrawArraysInstancedANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstancedARB", "DrawElementsInstancedEXT", "DrawElementsInstancedNV", "DrawElementsInstancedANGLE", nullptr } + }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_instanced); + } + + if (IsSupported(GLFeature::instanced_arrays)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisor", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisorARB", "VertexAttribDivisorNV", "VertexAttribDivisorANGLE", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::instanced_arrays); + } + + if (IsSupported(GLFeature::texture_storage)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2DEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3DEXT", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_storage); + } + + if (IsSupported(GLFeature::sampler_objects)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGenSamplers, { "GenSamplers", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteSamplers, { "DeleteSamplers", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsSampler, { "IsSampler", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindSampler, { "BindSampler", nullptr } }, + { (PRFuncPtr*) &mSymbols.fSamplerParameteri, { "SamplerParameteri", nullptr } }, + { (PRFuncPtr*) &mSymbols.fSamplerParameteriv, { "SamplerParameteriv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fSamplerParameterf, { "SamplerParameterf", nullptr } }, + { (PRFuncPtr*) &mSymbols.fSamplerParameterfv, { "SamplerParameterfv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetSamplerParameteriv, { "GetSamplerParameteriv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetSamplerParameterfv, { "GetSamplerParameterfv", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::sampler_objects); + } + + // ARB_transform_feedback2/NV_transform_feedback2 is a + // superset of EXT_transform_feedback/NV_transform_feedback + // and adds glPauseTransformFeedback & + // glResumeTransformFeedback, which are required for WebGL2. + if (IsSupported(GLFeature::transform_feedback2)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBase", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRange", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacks", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedback", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacks", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedback", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedback", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedback", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryings", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVarying", nullptr } }, + { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedback", nullptr } }, + { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedback", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBaseEXT", "BindBufferBaseNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRangeEXT", "BindBufferRangeNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacksNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedbackNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacksNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedbackNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedbackEXT", "BeginTransformFeedbackNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedbackEXT", "EndTransformFeedbackNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryingsEXT", "TransformFeedbackVaryingsNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVaryingEXT", "GetTransformFeedbackVaryingNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedbackNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedbackNV", nullptr } }, + END_SYMBOLS + }; + if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_storage)) { + // Also mark bind_buffer_offset as unsupported. + MarkUnsupported(GLFeature::bind_buffer_offset); + } + } + + if (IsSupported(GLFeature::bind_buffer_offset)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferOffset, { "BindBufferOffset", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferOffset, + { "BindBufferOffsetEXT", "BindBufferOffsetNV", nullptr } + }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::bind_buffer_offset); + } + + if (IsSupported(GLFeature::query_counter)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounter", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounterEXT", "QueryCounterANGLE", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::query_counter); + } + + if (IsSupported(GLFeature::query_objects)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQueryEXT", "BeginQueryANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueriesEXT", "GenQueriesANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueriesEXT", "DeleteQueriesANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQueryEXT", "EndQueryANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryivEXT", "GetQueryivANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuivEXT", "GetQueryObjectuivANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQueryEXT", "IsQueryANGLE", nullptr } }, + END_SYMBOLS + }; + if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::query_objects)) { + MarkUnsupported(GLFeature::get_query_object_i64v); + MarkUnsupported(GLFeature::get_query_object_iv); + MarkUnsupported(GLFeature::occlusion_query); + MarkUnsupported(GLFeature::occlusion_query_boolean); + MarkUnsupported(GLFeature::occlusion_query2); + } + } + + if (IsSupported(GLFeature::get_query_object_i64v)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64v", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64v", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64vEXT", "GetQueryObjecti64vANGLE", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64vEXT", "GetQueryObjectui64vANGLE", nullptr } }, + END_SYMBOLS + }; + if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_query_object_i64v)) { + MarkUnsupported(GLFeature::query_counter); + } + } + + if (IsSupported(GLFeature::get_query_object_iv)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectivEXT", "GetQueryObjectivANGLE", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_query_object_iv); + } + + if (IsSupported(GLFeature::clear_buffers)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fClearBufferfi, { "ClearBufferfi", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClearBufferfv, { "ClearBufferfv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClearBufferiv, { "ClearBufferiv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fClearBufferuiv, { "ClearBufferuiv", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::clear_buffers); + } + + if (IsSupported(GLFeature::copy_buffer)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fCopyBufferSubData, { "CopyBufferSubData", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::copy_buffer); + } + + if (IsSupported(GLFeature::draw_buffers)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffersARB", "DrawBuffersEXT", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_buffers); + } + + if (IsSupported(GLFeature::draw_range_elements)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElements", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElementsEXT", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_range_elements); + } + + if (IsSupported(GLFeature::get_integer_indexed)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegeri_v", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] ={ + { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegerIndexedvEXT", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_integer_indexed); + } + + if (IsSupported(GLFeature::get_integer64_indexed)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetInteger64i_v, { "GetInteger64i_v", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::get_integer64_indexed); + } + + if (IsSupported(GLFeature::gpu_shader4)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetVertexAttribIiv, { "GetVertexAttribIiv", "GetVertexAttribIivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetVertexAttribIuiv, { "GetVertexAttribIuiv", "GetVertexAttribIuivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexAttribI4i, { "VertexAttribI4i", "VertexAttribI4iEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexAttribI4iv, { "VertexAttribI4iv","VertexAttribI4ivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexAttribI4ui, { "VertexAttribI4ui", "VertexAttribI4uiEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexAttribI4uiv, { "VertexAttribI4uiv", "VertexAttribI4uivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fVertexAttribIPointer, { "VertexAttribIPointer", "VertexAttribIPointerEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform1ui, { "Uniform1ui", "Uniform1uiEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform2ui, { "Uniform2ui", "Uniform2uiEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform3ui, { "Uniform3ui", "Uniform3uiEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform4ui, { "Uniform4ui", "Uniform4uiEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform1uiv, { "Uniform1uiv", "Uniform1uivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform2uiv, { "Uniform2uiv", "Uniform2uivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform3uiv, { "Uniform3uiv", "Uniform3uivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniform4uiv, { "Uniform4uiv", "Uniform4uivEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetFragDataLocation, { "GetFragDataLocation", "GetFragDataLocationEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetUniformuiv, { "GetUniformuiv", "GetUniformuivEXT", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::gpu_shader4); + } + + if (IsSupported(GLFeature::map_buffer_range)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fMapBufferRange, { "MapBufferRange", nullptr } }, + { (PRFuncPtr*) &mSymbols.fFlushMappedBufferRange, { "FlushMappedBufferRange", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::map_buffer_range); + } + + if (IsSupported(GLFeature::texture_3D)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fTexImage3D, { "TexImage3D", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3DEXT", "TexSubImage3DOES", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D); + } + + if (IsSupported(GLFeature::texture_3D_compressed)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3D", nullptr } }, + { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3D", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3DARB", "CompressedTexImage3DOES", nullptr } }, + { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3DARB", "CompressedTexSubImage3DOES", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D_compressed); + } + + if (IsSupported(GLFeature::texture_3D_copy)) { + const SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3D", nullptr } }, + END_SYMBOLS + }; + const SymLoadStruct extSymbols[] = { + { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3DEXT", "CopyTexSubImage3DOES", nullptr } }, + END_SYMBOLS + }; + fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D_copy); + } + + if (IsSupported(GLFeature::uniform_buffer_object)) { + // Note: Don't query for glGetActiveUniformName because it is not + // supported by GL ES 3. + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGetUniformIndices, { "GetUniformIndices", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetActiveUniformsiv, { "GetActiveUniformsiv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetUniformBlockIndex, { "GetUniformBlockIndex", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockiv, { "GetActiveUniformBlockiv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockName, { "GetActiveUniformBlockName", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformBlockBinding, { "UniformBlockBinding", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::uniform_buffer_object); + } + + if (IsSupported(GLFeature::uniform_matrix_nonsquare)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fUniformMatrix2x3fv, { "UniformMatrix2x3fv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformMatrix2x4fv, { "UniformMatrix2x4fv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformMatrix3x2fv, { "UniformMatrix3x2fv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformMatrix3x4fv, { "UniformMatrix3x4fv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformMatrix4x2fv, { "UniformMatrix4x2fv", nullptr } }, + { (PRFuncPtr*) &mSymbols.fUniformMatrix4x3fv, { "UniformMatrix4x3fv", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::uniform_matrix_nonsquare); + } + + if (IsSupported(GLFeature::internalformat_query)) { + const SymLoadStruct symbols[] = { + CORE_SYMBOL(GetInternalformativ), + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::internalformat_query); + } + + if (IsSupported(GLFeature::invalidate_framebuffer)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr *) &mSymbols.fInvalidateFramebuffer, { "InvalidateFramebuffer", nullptr } }, + { (PRFuncPtr *) &mSymbols.fInvalidateSubFramebuffer, { "InvalidateSubFramebuffer", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::invalidate_framebuffer); + } + + if (IsExtensionSupported(KHR_debug)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fDebugMessageControl, { "DebugMessageControl", "DebugMessageControlKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDebugMessageInsert, { "DebugMessageInsert", "DebugMessageInsertKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDebugMessageCallback, { "DebugMessageCallback", "DebugMessageCallbackKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetDebugMessageLog, { "GetDebugMessageLog", "GetDebugMessageLogKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetPointerv, { "GetPointerv", "GetPointervKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fPushDebugGroup, { "PushDebugGroup", "PushDebugGroupKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fPopDebugGroup, { "PopDebugGroup", "PopDebugGroupKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fObjectLabel, { "ObjectLabel", "ObjectLabelKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetObjectLabel, { "GetObjectLabel", "GetObjectLabelKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fObjectPtrLabel, { "ObjectPtrLabel", "ObjectPtrLabelKHR", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetObjectPtrLabel, { "GetObjectPtrLabel", "GetObjectPtrLabelKHR", nullptr } }, + END_SYMBOLS + }; + fnLoadForExt(symbols, KHR_debug); + } + + if (IsExtensionSupported(NV_fence)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fGenFences, { "GenFencesNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fDeleteFences, { "DeleteFencesNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fSetFence, { "SetFenceNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTestFence, { "TestFenceNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fFinishFence, { "FinishFenceNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fIsFence, { "IsFenceNV", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetFenceiv, { "GetFenceivNV", nullptr } }, + END_SYMBOLS + }; + fnLoadForExt(symbols, NV_fence); + } + + if (IsSupported(GLFeature::read_buffer)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } }, + END_SYMBOLS + }; + fnLoadForFeature(symbols, GLFeature::read_buffer); + } + + if (IsExtensionSupported(APPLE_framebuffer_multisample)) { + const SymLoadStruct symbols[] = { + { (PRFuncPtr*) &mSymbols.fResolveMultisampleFramebufferAPPLE, { "ResolveMultisampleFramebufferAPPLE", nullptr } }, + END_SYMBOLS + }; + fnLoadForExt(symbols, APPLE_framebuffer_multisample); + } + + // Load developer symbols, don't fail if we can't find them. + const SymLoadStruct devSymbols[] = { + { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } }, + END_SYMBOLS + }; + const bool warnOnFailures = DebugMode(); + LoadSymbols(devSymbols, trygl, prefix, warnOnFailures); } #undef CORE_SYMBOL diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 8a0dc6777d..d18480649d 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -126,6 +126,7 @@ enum class GLFeature { sRGB_framebuffer, sRGB_texture, sampler_objects, + seamless_cube_map_opt_in, split_framebuffer, standard_derivatives, sync, @@ -340,7 +341,6 @@ public: } protected: - bool mInitialized; bool mIsOffscreen; bool mContextLost; @@ -358,8 +358,8 @@ protected: GLRenderer mRenderer; void SetProfileVersion(ContextProfile profile, uint32_t version) { - MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before" - " initialization!"); + MOZ_ASSERT(!mSymbols.fBindFramebuffer, + "SetProfileVersion can only be called before initialization!"); MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion"); @@ -421,6 +421,7 @@ public: ARB_pixel_buffer_object, ARB_robustness, ARB_sampler_objects, + ARB_seamless_cube_map, ARB_sync, ARB_texture_compression, ARB_texture_float, @@ -552,23 +553,16 @@ private: // ----------------------------------------------------------------------------- // Robustness handling -public: - bool HasRobustness() const { - return mHasRobustness; - } - +private: /** * The derived class is expected to provide information on whether or not it * supports robustness. */ virtual bool SupportsRobustness() const = 0; -private: - bool mHasRobustness; - +public: // ----------------------------------------------------------------------------- // Error handling -public: static const char* GLErrorToString(GLenum aError) { switch (aError) { case LOCAL_GL_INVALID_ENUM: @@ -2219,8 +2213,6 @@ public: } GLenum fGetGraphicsResetStatus() { - MOZ_ASSERT(mHasRobustness); - BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus); GLenum ret = mSymbols.fGetGraphicsResetStatus(); @@ -3506,8 +3498,17 @@ public: bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const; protected: - bool InitWithPrefix(const char *prefix, bool trygl); + bool InitWithPrefix(const char* prefix, bool trygl); +private: + bool InitWithPrefixImpl(const char* prefix, bool trygl); + void LoadMoreSymbols(const char* prefix, bool trygl); + bool LoadExtSymbols(const char* prefix, bool trygl, const SymLoadStruct* list, + GLExtensions ext); + bool LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruct* list, + GLFeature feature); + +protected: void InitExtensions(); GLint mViewportRect[4]; @@ -3640,7 +3641,7 @@ void SplitByChar(const nsACString& str, const char delim, template bool -MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N], +MarkBitfieldByString(const nsACString& str, const char* const (&markStrList)[N], std::bitset* const out_markList) { for (size_t i = 0; i < N; i++) { @@ -3655,7 +3656,7 @@ MarkBitfieldByString(const nsACString& str, const char* (&markStrList)[N], template void MarkBitfieldByStrings(const std::vector& strList, - bool dumpStrings, const char* (&markStrList)[N], + bool dumpStrings, const char* const (&markStrList)[N], std::bitset* const out_markList) { for (auto itr = strList.begin(); itr != strList.end(); ++itr) { diff --git a/gfx/gl/GLContextCGL.h b/gfx/gl/GLContextCGL.h index f7416b334c..48efb1c077 100644 --- a/gfx/gl/GLContextCGL.h +++ b/gfx/gl/GLContextCGL.h @@ -55,7 +55,7 @@ public: virtual bool IsDoubleBuffered() const override; - virtual bool SupportsRobustness() const override; + virtual bool SupportsRobustness() const override { return false; } virtual bool SwapBuffers() override; }; diff --git a/gfx/gl/GLContextEAGL.h b/gfx/gl/GLContextEAGL.h index 29588781f1..fd669c47e4 100644 --- a/gfx/gl/GLContextEAGL.h +++ b/gfx/gl/GLContextEAGL.h @@ -52,7 +52,7 @@ public: virtual bool IsDoubleBuffered() const override; - virtual bool SupportsRobustness() const override; + virtual bool SupportsRobustness() const override { return false; } virtual bool SwapBuffers() override; diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index b67249d12d..d328e9f164 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -547,6 +547,15 @@ static const FeatureInfo sFeatureInfoArr[] = { GLContext::Extensions_End } }, + { + "seamless_cube_map_opt_in", + GLVersion::GL3_2, + GLESVersion::NONE, + GLContext::ARB_seamless_cube_map, + { + GLContext::Extensions_End + } + }, { // Do we have separate DRAW and READ framebuffer bind points? "split_framebuffer", diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm index beae43ec13..161d2c7b40 100644 --- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -154,12 +154,6 @@ GLContextCGL::IsDoubleBuffered() const return sCGLLibrary.UseDoubleBufferedWindows(); } -bool -GLContextCGL::SupportsRobustness() const -{ - return false; -} - bool GLContextCGL::SwapBuffers() { @@ -364,20 +358,16 @@ static RefPtr gGlobalContext; GLContext* GLContextProviderCGL::GetGlobalContext() { - if (!sCGLLibrary.EnsureInitialized()) { - return nullptr; - } + static bool triedToCreateContext = false; + if (!triedToCreateContext) { + triedToCreateContext = true; - if (!gGlobalContext) { - // There are bugs in some older drivers with pbuffers less - // than 16x16 in size; also 16x16 is POT so that we can do - // a FBO with it on older video cards. A FBO context for - // sharing is preferred since it has no associated target. - gGlobalContext = CreateOffscreenFBOContext(CreateContextFlags::NONE); - if (!gGlobalContext || !static_cast(gGlobalContext.get())->Init()) { + MOZ_RELEASE_ASSERT(!gGlobalContext); + RefPtr temp = CreateHeadless(CreateContextFlags::NONE); + gGlobalContext = temp; + + if (!gGlobalContext) { NS_WARNING("Couldn't init gGlobalContext."); - gGlobalContext = nullptr; - return nullptr; } } diff --git a/gfx/gl/GLContextProviderEAGL.mm b/gfx/gl/GLContextProviderEAGL.mm index efc934c910..f6a288c73c 100644 --- a/gfx/gl/GLContextProviderEAGL.mm +++ b/gfx/gl/GLContextProviderEAGL.mm @@ -142,12 +142,6 @@ GLContextEAGL::IsDoubleBuffered() const return true; } -bool -GLContextEAGL::SupportsRobustness() const -{ - return false; -} - bool GLContextEAGL::SwapBuffers() { @@ -249,11 +243,15 @@ static RefPtr gGlobalContext; GLContext* GLContextProviderEAGL::GetGlobalContext() { - if (!gGlobalContext) { - gGlobalContext = CreateEAGLContext(true, nullptr); - if (!gGlobalContext || - !static_cast(gGlobalContext.get())->Init()) - { + static bool triedToCreateContext = false; + if (!triedToCreateContext) { + triedToCreateContext = true; + + MOZ_RELEASE_ASSERT(!gGlobalContext); + RefPtr temp = CreateHeadless(CreateContextFlags::NONE); + gGlobalContext = temp; + + if (!gGlobalContext) { MOZ_CRASH("Failed to create global context"); } } diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index f197c1bdee..1fa149e55c 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -928,6 +928,10 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags, const mozilla::gfx::IntSize& size, const SurfaceCaps& minCaps) { + bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE); + if (!sEGLLibrary.EnsureInitialized(forceEnableHardware)) + return nullptr; + SurfaceCaps configCaps; EGLConfig config = ChooseConfig(&sEGLLibrary, flags, minCaps, &configCaps); if (config == EGL_NO_CONFIG) { @@ -935,8 +939,9 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags, return nullptr; } - if (GLContext::ShouldSpew()) + if (GLContext::ShouldSpew()) { sEGLLibrary.DumpEGLConfig(config); + } mozilla::gfx::IntSize pbSize(size); EGLSurface surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config, @@ -947,7 +952,6 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags, return nullptr; } - RefPtr gl = GLContextEGL::CreateGLContext(flags, configCaps, nullptr, true, config, surface); if (!gl) { @@ -956,22 +960,12 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags, return nullptr; } - if (!gl->Init()) { - NS_WARNING("Failed to initialize GLContext!"); - // GLContextEGL::dtor will destroy |surface| for us. - return nullptr; - } - return gl.forget(); } /*static*/ already_AddRefed GLContextProviderEGL::CreateHeadless(CreateContextFlags flags) { - bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE); - if (!sEGLLibrary.EnsureInitialized(forceEnableHardware)) - return nullptr; - mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16); SurfaceCaps dummyCaps = SurfaceCaps::Any(); return GLContextEGL::CreateEGLPBufferOffscreenContext(flags, dummySize, dummyCaps); @@ -985,7 +979,7 @@ GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size, CreateContextFlags flags) { bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE); - if (!sEGLLibrary.EnsureInitialized(forceEnableHardware)) + if (!sEGLLibrary.EnsureInitialized(forceEnableHardware)) // Needed for IsANGLE(). return nullptr; bool canOffscreenUseHeadless = true; diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp index 8f72f1f6ee..6a3b1b129c 100644 --- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -1322,22 +1322,16 @@ GLContextProviderGLX::CreateOffscreen(const IntSize& size, GLContextProviderGLX::GetGlobalContext() { // TODO: get GLX context sharing to work well with multiple threads - if (gfxEnv::DisableContextSharingGlx()) { + if (gfxEnv::DisableContextSharingGlx()) return nullptr; - } static bool triedToCreateContext = false; - if (!triedToCreateContext && !gGlobalContext) { + if (!triedToCreateContext) { triedToCreateContext = true; - IntSize dummySize = IntSize(16, 16); - SurfaceCaps dummyCaps = SurfaceCaps::Any(); - // StaticPtr doesn't support assignments from already_AddRefed, - // so use a temporary nsRefPtr to make the reference counting - // fall out correctly. - RefPtr holder; - holder = CreateOffscreenPixmapContext(dummySize, dummyCaps); - gGlobalContext = holder; + MOZ_RELEASE_ASSERT(!gGlobalContext); + RefPtr temp = CreateHeadless(CreateContextFlags::NONE); + gGlobalContext = temp; } return gGlobalContext; diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index e9a2bb11ab..8b921837ce 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -14,6 +14,7 @@ #include "prenv.h" #include "mozilla/Preferences.h" +#include "mozilla/StaticPtr.h" namespace mozilla { namespace gl { @@ -682,31 +683,18 @@ GLContextProviderWGL::CreateOffscreen(const IntSize& size, return gl.forget(); } -static RefPtr gGlobalContext; +static StaticRefPtr gGlobalContext; /*static*/ GLContext* GLContextProviderWGL::GetGlobalContext() { - if (!sWGLLib.EnsureInitialized()) { - return nullptr; - } - static bool triedToCreateContext = false; - - if (!triedToCreateContext && !gGlobalContext) { + if (!triedToCreateContext) { triedToCreateContext = true; - // conveniently, we already have what we need... - SurfaceCaps dummyCaps = SurfaceCaps::Any(); - gGlobalContext = new GLContextWGL(dummyCaps, - nullptr, true, - sWGLLib.GetWindowDC(), - sWGLLib.GetWindowGLContext()); - if (!gGlobalContext->Init()) { - NS_WARNING("Global context GLContext initialization failed?"); - gGlobalContext = nullptr; - return nullptr; - } + MOZ_RELEASE_ASSERT(!gGlobalContext); + RefPtr temp = CreateHeadless(CreateContextFlags::NONE); + gGlobalContext = temp; } return static_cast(gGlobalContext); diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index 100034266e..ca1a2e396a 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -456,14 +456,17 @@ public: } EGLDisplay Display() { + MOZ_ASSERT(mInitialized); return mEGLDisplay; } bool IsANGLE() const { + MOZ_ASSERT(mInitialized); return mIsANGLE; } bool IsWARP() const { + MOZ_ASSERT(mInitialized); return mIsWARP; } diff --git a/gfx/gl/GLLibraryLoader.cpp b/gfx/gl/GLLibraryLoader.cpp index 1f0eeec2b8..26d759a0b3 100644 --- a/gfx/gl/GLLibraryLoader.cpp +++ b/gfx/gl/GLLibraryLoader.cpp @@ -24,7 +24,7 @@ GLLibraryLoader::OpenLibrary(const char *library) } bool -GLLibraryLoader::LoadSymbols(SymLoadStruct *firstStruct, +GLLibraryLoader::LoadSymbols(const SymLoadStruct *firstStruct, bool tryplatform, const char *prefix, bool warnOnFailure) @@ -64,7 +64,7 @@ GLLibraryLoader::LookupSymbol(PRLibrary *lib, bool GLLibraryLoader::LoadSymbols(PRLibrary *lib, - SymLoadStruct *firstStruct, + const SymLoadStruct *firstStruct, PlatformLookupFunction lookupFunction, const char *prefix, bool warnOnFailure) @@ -72,7 +72,7 @@ GLLibraryLoader::LoadSymbols(PRLibrary *lib, char sbuf[MAX_SYMBOL_LENGTH * 2]; int failCount = 0; - SymLoadStruct *ss = firstStruct; + const SymLoadStruct *ss = firstStruct; while (ss->symPointer) { *ss->symPointer = 0; diff --git a/gfx/gl/GLLibraryLoader.h b/gfx/gl/GLLibraryLoader.h index 0d18a1428d..5893363ce3 100644 --- a/gfx/gl/GLLibraryLoader.h +++ b/gfx/gl/GLLibraryLoader.h @@ -35,7 +35,7 @@ public: const char *symNames[MAX_SYMBOL_NAMES]; } SymLoadStruct; - bool LoadSymbols(SymLoadStruct *firstStruct, + bool LoadSymbols(const SymLoadStruct *firstStruct, bool tryplatform = false, const char *prefix = nullptr, bool warnOnFailure = true); @@ -47,7 +47,7 @@ public: const char *symname, PlatformLookupFunction lookupFunction = nullptr); static bool LoadSymbols(PRLibrary *lib, - SymLoadStruct *firstStruct, + const SymLoadStruct *firstStruct, PlatformLookupFunction lookupFunction = nullptr, const char *prefix = nullptr, bool warnOnFailure = true); diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index a8873065db..15ada3a230 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -232,6 +232,10 @@ public: void SetReadBuffer(GLenum userMode); void SetDrawBuffer(GLenum userMode); + GLenum GetReadBufferMode() const { + return mUserReadBufferMode; + } + /** * Attempts to read pixels from the current bound framebuffer, if * it is backed by a SharedSurface. diff --git a/intl/locale/nsLanguageAtomService.cpp b/intl/locale/nsLanguageAtomService.cpp index 5675d70f5e..9002a03f78 100644 --- a/intl/locale/nsLanguageAtomService.cpp +++ b/intl/locale/nsLanguageAtomService.cpp @@ -15,7 +15,7 @@ using namespace mozilla; -static const char* const kLangGroups[][3] = { +static const nsUConvProp kLangGroups[] = { #include "langGroups.properties.h" }; diff --git a/intl/locale/nsLanguageAtomService.h b/intl/locale/nsLanguageAtomService.h index 1abe2b9e45..83f6e70961 100644 --- a/intl/locale/nsLanguageAtomService.h +++ b/intl/locale/nsLanguageAtomService.h @@ -8,6 +8,7 @@ #include "nsIStringBundle.h" #include "nsInterfaceHashtable.h" #include "nsIAtom.h" +#include "nsUConvPropertySearch.h" #include "mozilla/Attributes.h" #define NS_LANGUAGEATOMSERVICE_CID \ diff --git a/intl/locale/nsUConvPropertySearch.cpp b/intl/locale/nsUConvPropertySearch.cpp index 59b4aed81f..934244516a 100644 --- a/intl/locale/nsUConvPropertySearch.cpp +++ b/intl/locale/nsUConvPropertySearch.cpp @@ -13,8 +13,8 @@ struct PropertyComparator { const nsCString& mKey; explicit PropertyComparator(const nsCString& aKey) : mKey(aKey) {} - int operator()(const char* const (&aProperty)[3]) const { - return mKey.Compare(aProperty[0]); + int operator()(const nsUConvProp& aProperty) const { + return mKey.Compare(aProperty.mKey); } }; @@ -22,7 +22,7 @@ struct PropertyComparator // static nsresult -nsUConvPropertySearch::SearchPropertyValue(const char* const aProperties[][3], +nsUConvPropertySearch::SearchPropertyValue(const nsUConvProp aProperties[], int32_t aNumberOfProperties, const nsACString& aKey, nsACString& aValue) @@ -33,8 +33,8 @@ nsUConvPropertySearch::SearchPropertyValue(const char* const aProperties[][3], size_t index; if (BinarySearchIf(aProperties, 0, aNumberOfProperties, PropertyComparator(flat), &index)) { - nsDependentCString val(aProperties[index][1], - NS_PTR_TO_UINT32(aProperties[index][2])); + nsDependentCString val(aProperties[index].mValue, + aProperties[index].mValueLength); aValue.Assign(val); return NS_OK; } diff --git a/intl/locale/nsUConvPropertySearch.h b/intl/locale/nsUConvPropertySearch.h index 1330aa5b12..b27faa85b9 100644 --- a/intl/locale/nsUConvPropertySearch.h +++ b/intl/locale/nsUConvPropertySearch.h @@ -7,6 +7,13 @@ #include "nsStringFwd.h" +struct nsUConvProp +{ + const char* const mKey; + const char* const mValue; + const uint32_t mValueLength; +}; + class nsUConvPropertySearch { public: @@ -21,7 +28,7 @@ class nsUConvPropertySearch * the return value (empty string if not found) * @return NS_OK if found or NS_ERROR_FAILURE if not found */ - static nsresult SearchPropertyValue(const char* const aProperties[][3], + static nsresult SearchPropertyValue(const nsUConvProp aProperties[], int32_t aNumberOfProperties, const nsACString& aKey, nsACString& aValue); diff --git a/intl/locale/props2arrays.py b/intl/locale/props2arrays.py index 042db129e0..510e0d51a0 100644 --- a/intl/locale/props2arrays.py +++ b/intl/locale/props2arrays.py @@ -21,7 +21,7 @@ def main(header, propFile): header.write("// This is a generated file. Please do not edit.\n") header.write("// Please edit the corresponding .properties file instead.\n") - entries = ['{ "%s", "%s", (const char*)NS_INT32_TO_PTR(%d) }' + entries = ['{ "%s", "%s", %d }' % (key, mappings[key], len(mappings[key])) for key in keys] header.write(',\n'.join(entries) + '\n') diff --git a/intl/locale/unix/nsUNIXCharset.cpp b/intl/locale/unix/nsUNIXCharset.cpp index 43d36d9941..2bdde1a063 100644 --- a/intl/locale/unix/nsUNIXCharset.cpp +++ b/intl/locale/unix/nsUNIXCharset.cpp @@ -29,7 +29,7 @@ using mozilla::dom::EncodingUtils; using namespace mozilla; -static const char* const kUnixCharsets[][3] = { +static const nsUConvProp kUnixCharsets[] = { #include "unixcharset.properties.h" }; @@ -44,11 +44,8 @@ ConvertLocaleToCharsetUsingDeprecatedConfig(const nsACString& locale, nsACString& oResult) { if (!(locale.IsEmpty())) { - nsAutoCString localeKey; - localeKey.AssignLiteral("locale.all."); - localeKey.Append(locale); if (NS_SUCCEEDED(nsUConvPropertySearch::SearchPropertyValue(kUnixCharsets, - ArrayLength(kUnixCharsets), localeKey, oResult))) { + ArrayLength(kUnixCharsets), locale, oResult))) { return NS_OK; } } diff --git a/intl/locale/unix/unixcharset.properties b/intl/locale/unix/unixcharset.properties index 9ff094a6c3..1376b49d6a 100644 --- a/intl/locale/unix/unixcharset.properties +++ b/intl/locale/unix/unixcharset.properties @@ -13,524 +13,524 @@ ## charset, put the least common one in the platform specific section ## This section have lower priority than the platform specific section ## -## The key is "locale.all." + locale name +## The key is the locale name # AIX -locale.all.ar_AA=ISO-8859-6 +ar_AA=ISO-8859-6 # Solaris -locale.all.Ar_ARM=ISO-8859-6 -locale.all.american.iso88591=ISO-8859-1 -locale.all.bulgarian=ISO-8859-2 -locale.all.bg_BG.ISO8859-5=ISO-8859-5 +Ar_ARM=ISO-8859-6 +american.iso88591=ISO-8859-1 +bulgarian=ISO-8859-2 +bg_BG.ISO8859-5=ISO-8859-5 # AIX -locale.all.bg_BG=ISO-8859-5 -locale.all.C=ISO-8859-1 +bg_BG=ISO-8859-5 +C=ISO-8859-1 # HP -locale.all.C.iso885915=ISO-8859-15 -locale.all.c-french.iso88591=ISO-8859-1 -locale.all.chinese=gb18030 -locale.all.chinese-s=gb18030 -locale.all.chinese-t.big5=Big5 -locale.all.cs=ISO-8859-2 -locale.all.cs_CZ=ISO-8859-2 -locale.all.cs_CZ.ISO8859-2=ISO-8859-2 -locale.all.cs_CZ.88592=ISO-8859-2 -locale.all.czech=ISO-8859-2 -locale.all.da=ISO-8859-1 +C.iso885915=ISO-8859-15 +c-french.iso88591=ISO-8859-1 +chinese=gb18030 +chinese-s=gb18030 +chinese-t.big5=Big5 +cs=ISO-8859-2 +cs_CZ=ISO-8859-2 +cs_CZ.ISO8859-2=ISO-8859-2 +cs_CZ.88592=ISO-8859-2 +czech=ISO-8859-2 +da=ISO-8859-1 # Solaris -locale.all.da.ISO8859-15=ISO-8859-15 -locale.all.da_DK.ISO8859-15=ISO-8859-15 -locale.all.da_DK.ISO8859-15@euro=ISO-8859-15 +da.ISO8859-15=ISO-8859-15 +da_DK.ISO8859-15=ISO-8859-15 +da_DK.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.da.ISO8859-15@euro=ISO-8859-15 -locale.all.da_DK.88591=ISO-8859-1 +da.ISO8859-15@euro=ISO-8859-15 +da_DK.88591=ISO-8859-1 # HP -locale.all.da_DK.iso885915@euro=ISO-8859-15 -locale.all.da_DK.ISO8859-1=ISO-8859-1 -locale.all.da_DK=ISO-8859-1 +da_DK.iso885915@euro=ISO-8859-15 +da_DK.ISO8859-1=ISO-8859-1 +da_DK=ISO-8859-1 # AIX -#locale.all.Da_DK=IBM-850 -locale.all.danish.iso88591=ISO-8859-1 -locale.all.dutch.iso88591=ISO-8859-1 -locale.all.de=ISO-8859-1 +#Da_DK=IBM-850 +danish.iso88591=ISO-8859-1 +dutch.iso88591=ISO-8859-1 +de=ISO-8859-1 # Solaris -locale.all.de.ISO8859-15=ISO-8859-15 +de.ISO8859-15=ISO-8859-15 # Solaris -locale.all.de.ISO8859-15@euro=ISO-8859-15 +de.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.de.UTF-8=UTF-8 +de.UTF-8=UTF-8 # Solaris -locale.all.de.UTF-8@euro=UTF-8 -locale.all.de_AT=ISO-8859-1 +de.UTF-8@euro=UTF-8 +de_AT=ISO-8859-1 # Solaris -locale.all.de_AT.ISO8859-15=ISO-8859-15 +de_AT.ISO8859-15=ISO-8859-15 # Solaris -locale.all.de_AT.ISO8859-15@euro=ISO-8859-15 -locale.all.de_CH=ISO-8859-1 -locale.all.de_CH.88591=ISO-8859-1 -locale.all.de_CH.ISO8859-1=ISO-8859-1 -locale.all.de_DE.ISO8859-15=ISO-8859-15 -locale.all.de_DE.ISO8859-15@euro=ISO-8859-15 +de_AT.ISO8859-15@euro=ISO-8859-15 +de_CH=ISO-8859-1 +de_CH.88591=ISO-8859-1 +de_CH.ISO8859-1=ISO-8859-1 +de_DE.ISO8859-15=ISO-8859-15 +de_DE.ISO8859-15@euro=ISO-8859-15 # AIX -#locale.all.De_CH=IBM-850 -locale.all.de_DE=ISO-8859-1 -locale.all.de_DE.88591=ISO-8859-1 +#De_CH=IBM-850 +de_DE=ISO-8859-1 +de_DE.88591=ISO-8859-1 # HP -locale.all.de_DE.iso885915=ISO-8859-15 +de_DE.iso885915=ISO-8859-15 # HP -locale.all.de_DE.iso885915@euro=ISO-8859-15 -locale.all.de_DE.ISO8859-1=ISO-8859-1 +de_DE.iso885915@euro=ISO-8859-15 +de_DE.ISO8859-1=ISO-8859-1 # AIX -#locale.all.De_DE=IBM-850 +#De_DE=IBM-850 # Solaris -locale.all.el_GR.ISO8859-7=ISO-8859-7 -locale.all.el_GR.ISO8859-7@euro=ISO-8859-7 -locale.all.en_AU.ISO8859-1=ISO-8859-1 -locale.all.en_CA.ISO8859-1=ISO-8859-1 +el_GR.ISO8859-7=ISO-8859-7 +el_GR.ISO8859-7@euro=ISO-8859-7 +en_AU.ISO8859-1=ISO-8859-1 +en_CA.ISO8859-1=ISO-8859-1 # AIX -locale.all.el_GR=ISO-8859-7 -locale.all.en=ISO-8859-1 -locale.all.en_AU=ISO-8859-1 -locale.all.en_CA=ISO-8859-1 -locale.all.en_GB=ISO-8859-1 +el_GR=ISO-8859-7 +en=ISO-8859-1 +en_AU=ISO-8859-1 +en_CA=ISO-8859-1 +en_GB=ISO-8859-1 # Solaris -locale.all.en_GB.ISO8859-15=ISO-8859-15 +en_GB.ISO8859-15=ISO-8859-15 # Solaris -locale.all.en_GB.ISO8859-15@euro=ISO-8859-15 -locale.all.en_GB.88591=ISO-8859-1 -locale.all.en_GB.ISO8859-1=ISO-8859-1 +en_GB.ISO8859-15@euro=ISO-8859-15 +en_GB.88591=ISO-8859-1 +en_GB.ISO8859-1=ISO-8859-1 # HP -locale.all.en_GB.iso885915@euro=ISO-8859-15 +en_GB.iso885915@euro=ISO-8859-15 # AIX -#locale.all.En_GB=IBM-850 +#En_GB=IBM-850 # Solaris -locale.all.en_IE.ISO8859-1=ISO-8859-1 -locale.all.en_IE.ISO8859-15=ISO-8859-15 +en_IE.ISO8859-1=ISO-8859-1 +en_IE.ISO8859-15=ISO-8859-15 # Solaris -locale.all.en_IE.ISO8859-15@euro=ISO-8859-15 -locale.all.en_JP=EUC-JP -locale.all.en_JP.IBM-eucJP=EUC-JP -locale.all.En_JP.IBM-932=Shift_JIS -locale.all.En_JP=Shift_JIS -locale.all.en_KR=EUC-KR -locale.all.en_KR.IBM-eucKR=EUC-KR -locale.all.en_TH=ISO-8859-1 -locale.all.en_US=ISO-8859-1 -locale.all.en_US.88591=ISO-8859-1 -locale.all.en_US.ISO8859-1=ISO-8859-1 +en_IE.ISO8859-15@euro=ISO-8859-15 +en_JP=EUC-JP +en_JP.IBM-eucJP=EUC-JP +En_JP.IBM-932=Shift_JIS +En_JP=Shift_JIS +en_KR=EUC-KR +en_KR.IBM-eucKR=EUC-KR +en_TH=ISO-8859-1 +en_US=ISO-8859-1 +en_US.88591=ISO-8859-1 +en_US.ISO8859-1=ISO-8859-1 #FreeBSD -locale.all.en_US.ISO_8859-1=ISO-8859-1 -locale.all.da_DK.ISO_8859-1=ISO-8859-1 -locale.all.de_AT.ISO_8859-1=ISO-8859-1 -locale.all.de_CH.ISO_8859-1=ISO-8859-1 -locale.all.de_DE.ISO_8859-1=ISO-8859-1 -locale.all.en_AU.ISO_8859-1=ISO-8859-1 -locale.all.en_CA.ISO_8859-1=ISO-8859-1 -locale.all.en_GB.ISO_8859-1=ISO-8859-1 -locale.all.es_ES.ISO_8859-1=ISO-8859-1 -locale.all.fi_FI.ISO_8859-1=ISO-8859-1 -locale.all.fr_BE.ISO_8859-1=ISO-8859-1 -locale.all.fr_CA.ISO_8859-1=ISO-8859-1 -locale.all.fr_CH.ISO_8859-1=ISO-8859-1 -locale.all.fr_FR.ISO_8859-1=ISO-8859-1 -locale.all.is_IS.ISO_8859-1=ISO-8859-1 -locale.all.it_CH.ISO_8859-1=ISO-8859-1 -locale.all.it_IT.ISO_8859-1=ISO-8859-1 -locale.all.la_LN.ISO_8859-1=ISO-8859-1 -locale.all.nl_BE.ISO_8859-1=ISO-8859-1 -locale.all.nl_NL.ISO_8859-1=ISO-8859-1 -locale.all.no_NO.ISO_8859-1=ISO-8859-1 -locale.all.pt_PT.ISO_8859-1=ISO-8859-1 -locale.all.sv_SE.ISO_8859-1=ISO-8859-1 +en_US.ISO_8859-1=ISO-8859-1 +da_DK.ISO_8859-1=ISO-8859-1 +de_AT.ISO_8859-1=ISO-8859-1 +de_CH.ISO_8859-1=ISO-8859-1 +de_DE.ISO_8859-1=ISO-8859-1 +en_AU.ISO_8859-1=ISO-8859-1 +en_CA.ISO_8859-1=ISO-8859-1 +en_GB.ISO_8859-1=ISO-8859-1 +es_ES.ISO_8859-1=ISO-8859-1 +fi_FI.ISO_8859-1=ISO-8859-1 +fr_BE.ISO_8859-1=ISO-8859-1 +fr_CA.ISO_8859-1=ISO-8859-1 +fr_CH.ISO_8859-1=ISO-8859-1 +fr_FR.ISO_8859-1=ISO-8859-1 +is_IS.ISO_8859-1=ISO-8859-1 +it_CH.ISO_8859-1=ISO-8859-1 +it_IT.ISO_8859-1=ISO-8859-1 +la_LN.ISO_8859-1=ISO-8859-1 +nl_BE.ISO_8859-1=ISO-8859-1 +nl_NL.ISO_8859-1=ISO-8859-1 +no_NO.ISO_8859-1=ISO-8859-1 +pt_PT.ISO_8859-1=ISO-8859-1 +sv_SE.ISO_8859-1=ISO-8859-1 # FreeBSD 8859-15 -locale.all.da_DK.DIS_8859-15=ISO-8859-15 -locale.all.de_AT.DIS_8859-15=ISO-8859-15 -locale.all.de_CH.DIS_8859-15=ISO-8859-15 -locale.all.de_DE.DIS_8859-15=ISO-8859-15 -locale.all.en_AU.DIS_8859-15=ISO-8859-15 -locale.all.en_CA.DIS_8859-15=ISO-8859-15 -locale.all.en_GB.DIS_8859-15=ISO-8859-15 -locale.all.en_US.DIS_8859-15=ISO-8859-15 -locale.all.es_ES.DIS_8859-15=ISO-8859-15 -locale.all.fi_FI.DIS_8859-15=ISO-8859-15 -locale.all.fr_BE.DIS_8859-15=ISO-8859-15 -locale.all.fr_CA.DIS_8859-15=ISO-8859-15 -locale.all.fr_CH.DIS_8859-15=ISO-8859-15 -locale.all.fr_FR.DIS_8859-15=ISO-8859-15 -locale.all.is_IS.DIS_8859-15=ISO-8859-15 -locale.all.it_CH.DIS_8859-15=ISO-8859-15 -locale.all.it_IT.DIS_8859-15=ISO-8859-15 -locale.all.la_LN.DIS_8859-15=ISO-8859-15 -locale.all.nl_BE.DIS_8859-15=ISO-8859-15 -locale.all.nl_NL.DIS_8859-15=ISO-8859-15 -locale.all.no_NO.DIS_8859-15=ISO-8859-15 -locale.all.pt_PT.DIS_8859-15=ISO-8859-15 -locale.all.sv_SE.DIS_8859-15=ISO-8859-15 +da_DK.DIS_8859-15=ISO-8859-15 +de_AT.DIS_8859-15=ISO-8859-15 +de_CH.DIS_8859-15=ISO-8859-15 +de_DE.DIS_8859-15=ISO-8859-15 +en_AU.DIS_8859-15=ISO-8859-15 +en_CA.DIS_8859-15=ISO-8859-15 +en_GB.DIS_8859-15=ISO-8859-15 +en_US.DIS_8859-15=ISO-8859-15 +es_ES.DIS_8859-15=ISO-8859-15 +fi_FI.DIS_8859-15=ISO-8859-15 +fr_BE.DIS_8859-15=ISO-8859-15 +fr_CA.DIS_8859-15=ISO-8859-15 +fr_CH.DIS_8859-15=ISO-8859-15 +fr_FR.DIS_8859-15=ISO-8859-15 +is_IS.DIS_8859-15=ISO-8859-15 +it_CH.DIS_8859-15=ISO-8859-15 +it_IT.DIS_8859-15=ISO-8859-15 +la_LN.DIS_8859-15=ISO-8859-15 +nl_BE.DIS_8859-15=ISO-8859-15 +nl_NL.DIS_8859-15=ISO-8859-15 +no_NO.DIS_8859-15=ISO-8859-15 +pt_PT.DIS_8859-15=ISO-8859-15 +sv_SE.DIS_8859-15=ISO-8859-15 # FreeBSD 8859-2 -locale.all.cs_CZ.ISO_8859-2=ISO-8859-2 -locale.all.hr_HR.ISO_8859-2=ISO-8859-2 -locale.all.hu_HU.ISO_8859-2=ISO-8859-2 -locale.all.la_LN.ISO_8859-2=ISO-8859-2 -locale.all.pl_PL.ISO_8859-2=ISO-8859-2 -locale.all.sl_SI.ISO_8859-2=ISO-8859-2 +cs_CZ.ISO_8859-2=ISO-8859-2 +hr_HR.ISO_8859-2=ISO-8859-2 +hu_HU.ISO_8859-2=ISO-8859-2 +la_LN.ISO_8859-2=ISO-8859-2 +pl_PL.ISO_8859-2=ISO-8859-2 +sl_SI.ISO_8859-2=ISO-8859-2 # FreeBSD 8859-4 -locale.all.la_LN.ISO_8859-4=ISO-8859-4 -locale.all.lt_LT.ISO_8859-4=ISO-8859-4 +la_LN.ISO_8859-4=ISO-8859-4 +lt_LT.ISO_8859-4=ISO-8859-4 # FreeBSD 8859-5 -locale.all.ru_RU.ISO_8859-5=ISO-8859-5 -locale.all.ru_SU.ISO_8859-5=ISO-8859-5 +ru_RU.ISO_8859-5=ISO-8859-5 +ru_SU.ISO_8859-5=ISO-8859-5 # FreeBSD Russian -locale.all.ru_SU.KOI8-R=KOI8-R +ru_SU.KOI8-R=KOI8-R # FreeBSD Ukrainian -locale.all.uk_UA.KOI8-U=KOI8-U +uk_UA.KOI8-U=KOI8-U # Solaris -locale.all.en_US.UTF-8=UTF-8 +en_US.UTF-8=UTF-8 # Solaris -locale.all.en_US.UTF-8@euro=UTF-8 +en_US.UTF-8@euro=UTF-8 # AIX -#locale.all.En_US=IBM-850 -locale.all.english.iso88591=ISO-8859-1 -locale.all.es=ISO-8859-1 +#En_US=IBM-850 +english.iso88591=ISO-8859-1 +es=ISO-8859-1 # Solaris -locale.all.es.ISO8859-15=ISO-8859-15 +es.ISO8859-15=ISO-8859-15 # Solaris -locale.all.es.ISO8859-15@euro=ISO-8859-15 +es.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.es.UTF-8=UTF-8 +es.UTF-8=UTF-8 # Solaris -locale.all.es.UTF-8@euro=UTF-8 -locale.all.es_ES=ISO-8859-1 -locale.all.es_ES.ISO8859-15=ISO-8859-15 -locale.all.es_ES.ISO8859-15@euro=ISO-8859-15 -locale.all.es_AR.ISO8859-1=ISO-8859-1 -locale.all.es_BO.ISO8859-1=ISO-8859-1 -locale.all.es_CL.ISO8859-1=ISO-8859-1 -locale.all.es_CO.ISO8859-1=ISO-8859-1 -locale.all.es_CR.ISO8859-1=ISO-8859-1 -locale.all.es_EC.ISO8859-1=ISO-8859-1 -locale.all.es_GT.ISO8859-1=ISO-8859-1 -locale.all.es_MX.ISO8859-1=ISO-8859-1 -locale.all.es_NI.ISO8859-1=ISO-8859-1 -locale.all.es_PA.ISO8859-1=ISO-8859-1 -locale.all.es_PE.ISO8859-1=ISO-8859-1 -locale.all.es_PY.ISO8859-1=ISO-8859-1 -locale.all.es_SV.ISO8859-1=ISO-8859-1 -locale.all.es_UY.ISO8859-1=ISO-8859-1 -locale.all.es_VE.ISO8859-1=ISO-8859-1 +es.UTF-8@euro=UTF-8 +es_ES=ISO-8859-1 +es_ES.ISO8859-15=ISO-8859-15 +es_ES.ISO8859-15@euro=ISO-8859-15 +es_AR.ISO8859-1=ISO-8859-1 +es_BO.ISO8859-1=ISO-8859-1 +es_CL.ISO8859-1=ISO-8859-1 +es_CO.ISO8859-1=ISO-8859-1 +es_CR.ISO8859-1=ISO-8859-1 +es_EC.ISO8859-1=ISO-8859-1 +es_GT.ISO8859-1=ISO-8859-1 +es_MX.ISO8859-1=ISO-8859-1 +es_NI.ISO8859-1=ISO-8859-1 +es_PA.ISO8859-1=ISO-8859-1 +es_PE.ISO8859-1=ISO-8859-1 +es_PY.ISO8859-1=ISO-8859-1 +es_SV.ISO8859-1=ISO-8859-1 +es_UY.ISO8859-1=ISO-8859-1 +es_VE.ISO8859-1=ISO-8859-1 # HP -locale.all.es_ES.iso885915=ISO-8859-15 +es_ES.iso885915=ISO-8859-15 # HP -locale.all.es_ES.iso885915@euro=ISO-8859-15 -locale.all.es_ES.88591=ISO-8859-1 -locale.all.es_ES.ISO8859-1=ISO-8859-1 +es_ES.iso885915@euro=ISO-8859-15 +es_ES.88591=ISO-8859-1 +es_ES.ISO8859-1=ISO-8859-1 # AIX -#locale.all.En_ES=IBM-850 +#En_ES=IBM-850 # Solaris -locale.all.et_EE.ISO8859-15=ISO-8859-15 +et_EE.ISO8859-15=ISO-8859-15 # AIX -#locale.all.Et_ET=IBM-922 +#Et_ET=IBM-922 # AIX -locale.all.ET_ET=UTF-8 -locale.all.fi=ISO-8859-1 +ET_ET=UTF-8 +fi=ISO-8859-1 # Solaris -locale.all.fi.ISO8859-15=ISO-8859-15 +fi.ISO8859-15=ISO-8859-15 # Solaris -locale.all.fi.ISO8859-15@euro=ISO-8859-15 -locale.all.fi_FI=ISO-8859-1 -locale.all.fi_FI.88591=ISO-8859-1 -locale.all.fi_FI.ISO8859-1=ISO-8859-1 -locale.all.fi_FI.ISO8859-15=ISO-8859-15 -locale.all.fi_FI.ISO8859-15@euro=ISO-8859-15 +fi.ISO8859-15@euro=ISO-8859-15 +fi_FI=ISO-8859-1 +fi_FI.88591=ISO-8859-1 +fi_FI.ISO8859-1=ISO-8859-1 +fi_FI.ISO8859-15=ISO-8859-15 +fi_FI.ISO8859-15@euro=ISO-8859-15 # HP -locale.all.fi_FI.iso885915@euro=ISO-8859-15 +fi_FI.iso885915@euro=ISO-8859-15 # AIX -#locale.all.Fi_ES=IBM-850 -locale.all.finnish.iso88591=ISO-8859-1 -locale.all.fr=ISO-8859-1 +#Fi_ES=IBM-850 +finnish.iso88591=ISO-8859-1 +fr=ISO-8859-1 # Solaris -locale.all.fr.ISO8859-15=ISO-8859-15 +fr.ISO8859-15=ISO-8859-15 # Solaris -locale.all.fr.ISO8859-15@euro=ISO-8859-15 +fr.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.fr.UTF-8=UTF-8 +fr.UTF-8=UTF-8 # Solaris -locale.all.fr.UTF-8@euro=UTF-8 -locale.all.fr_BE=ISO-8859-1 +fr.UTF-8@euro=UTF-8 +fr_BE=ISO-8859-1 # Solaris -locale.all.fr_BE.ISO8859-15=ISO-8859-15 +fr_BE.ISO8859-15=ISO-8859-15 # Solaris -locale.all.fr_BE.ISO8859-15@euro=ISO-8859-15 -locale.all.fr_BE.88591=ISO-8859-1 -locale.all.fr_BE.ISO8859-1=ISO-8859-1 -locale.all.fr_BE.iso8859=ISO-8859-1 +fr_BE.ISO8859-15@euro=ISO-8859-15 +fr_BE.88591=ISO-8859-1 +fr_BE.ISO8859-1=ISO-8859-1 +fr_BE.iso8859=ISO-8859-1 # AIX -#locale.all.Fr_BE=IBM-850 -locale.all.fr_CA=ISO-8859-1 -locale.all.fr_CA.88591=ISO-8859-1 -locale.all.fr_CA.iso8859=ISO-8859-1 +#Fr_BE=IBM-850 +fr_CA=ISO-8859-1 +fr_CA.88591=ISO-8859-1 +fr_CA.iso8859=ISO-8859-1 # HP -locale.all.fr_CA.iso885915@euro=ISO-8859-15 -locale.all.fr_CA.ISO8859-1=ISO-8859-1 +fr_CA.iso885915@euro=ISO-8859-15 +fr_CA.ISO8859-1=ISO-8859-1 # AIX -#locale.all.Fr_CA=IBM-850 -locale.all.fr_CH=ISO-8859-1 -locale.all.fr_CH.88591=ISO-8859-1 -locale.all.fr_CH.iso8859=ISO-8859-1 -locale.all.fr_CH.ISO8859-1=ISO-8859-1 +#Fr_CA=IBM-850 +fr_CH=ISO-8859-1 +fr_CH.88591=ISO-8859-1 +fr_CH.iso8859=ISO-8859-1 +fr_CH.ISO8859-1=ISO-8859-1 # Solaris -locale.all.fr_FR.ISO8859-15=ISO-8859-15 -locale.all.fr_FR.ISO8859-15@euro=ISO-8859-15 +fr_FR.ISO8859-15=ISO-8859-15 +fr_FR.ISO8859-15@euro=ISO-8859-15 # AIX -#locale.all.Fr_CH=IBM-850 -locale.all.fr_FR=ISO-8859-1 -locale.all.fr_FR.88591=ISO-8859-1 -locale.all.fr_FR.iso8859=ISO-8859-1 +#Fr_CH=IBM-850 +fr_FR=ISO-8859-1 +fr_FR.88591=ISO-8859-1 +fr_FR.iso8859=ISO-8859-1 # HP -locale.all.fr_FR.iso885915=ISO-8859-15 +fr_FR.iso885915=ISO-8859-15 # HP -locale.all.fr_FR.iso885915@euro=ISO-8859-15 -locale.all.fr_FR.ISO8859-1=ISO-8859-1 +fr_FR.iso885915@euro=ISO-8859-15 +fr_FR.ISO8859-1=ISO-8859-1 # AIX -#locale.all.Fr_FR=IBM-850 -locale.all.french.iso88591=ISO-8859-1 -locale.all.german.iso88591=ISO-8859-1 +#Fr_FR=IBM-850 +french.iso88591=ISO-8859-1 +german.iso88591=ISO-8859-1 # Solaris -locale.all.he_HE=ISO-8859-8 -locale.all.he_IL=ISO-8859-8 -locale.all.hr_HR.ISO8859-2=ISO-8859-2 +he_HE=ISO-8859-8 +he_IL=ISO-8859-8 +hr_HR.ISO8859-2=ISO-8859-2 # AIX -locale.all.hr_HR=ISO-8859-2 -locale.all.hu_HU=ISO-8859-2 -locale.all.hu_HU.88592=ISO-8859-2 -locale.all.hu_HU.ISO8859-2=ISO-8859-2 -locale.all.hungarian=ISO-8859-2 -locale.all.icelandic.iso88591=ISO-8859-1 -locale.all.iso_8859_1=ISO-8859-1 -locale.all.is=ISO-8859-1 -locale.all.is_IS=ISO-8859-1 -locale.all.is_IS.88591=ISO-8859-1 -locale.all.is_IS.ISO8859-1=ISO-8859-1 +hr_HR=ISO-8859-2 +hu_HU=ISO-8859-2 +hu_HU.88592=ISO-8859-2 +hu_HU.ISO8859-2=ISO-8859-2 +hungarian=ISO-8859-2 +icelandic.iso88591=ISO-8859-1 +iso_8859_1=ISO-8859-1 +is=ISO-8859-1 +is_IS=ISO-8859-1 +is_IS.88591=ISO-8859-1 +is_IS.ISO8859-1=ISO-8859-1 # HP -locale.all.is_IS.iso885915@euro=ISO-8859-15 +is_IS.iso885915@euro=ISO-8859-15 # AIX -#locale.all.Is_IS=IBM-850 -locale.all.it=ISO-8859-1 +#Is_IS=IBM-850 +it=ISO-8859-1 # Solaris -locale.all.it.ISO8859-15=ISO-8859-15 +it.ISO8859-15=ISO-8859-15 # Solaris -locale.all.it.ISO8859-15@euro=ISO-8859-15 +it.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.it.UTF-8=UTF-8 +it.UTF-8=UTF-8 # Solaris -locale.all.it.UTF-8@euro=UTF-8 -locale.all.it_IT.ISO8859-15=ISO-8859-15 -locale.all.it_IT.ISO8859-15@euro=ISO-8859-15 +it.UTF-8@euro=UTF-8 +it_IT.ISO8859-15=ISO-8859-15 +it_IT.ISO8859-15@euro=ISO-8859-15 # AIX -#locale.all.It_IT=IBM-850 -locale.all.italian.iso8859-1=ISO-8859-1 -locale.all.it_CH=ISO-8859-1 -locale.all.it_IT=ISO-8859-1 -locale.all.it_IT.88591=ISO-8859-1 -locale.all.it_IT.ISO8859-1=ISO-8859-1 +#It_IT=IBM-850 +italian.iso8859-1=ISO-8859-1 +it_CH=ISO-8859-1 +it_IT=ISO-8859-1 +it_IT.88591=ISO-8859-1 +it_IT.ISO8859-1=ISO-8859-1 # HP -locale.all.it_IT.iso885915=ISO-8859-15 +it_IT.iso885915=ISO-8859-15 # HP -locale.all.it_IT.iso885915@euro=ISO-8859-15 +it_IT.iso885915@euro=ISO-8859-15 # AIX -locale.all.iw_IL=ISO-8859-8 +iw_IL=ISO-8859-8 # AIX -#locale.all.Iw_IL=IBM-856 -locale.all.ja=EUC-JP -locale.all.Ja_JP.IBM-932=Shift_JIS -locale.all.Ja_JP=Shift_JIS -locale.all.japanese=EUC-JP -locale.all.japanese.euc=EUC-JP -locale.all.ja_JP=EUC-JP +#Iw_IL=IBM-856 +ja=EUC-JP +Ja_JP.IBM-932=Shift_JIS +Ja_JP=Shift_JIS +japanese=EUC-JP +japanese.euc=EUC-JP +ja_JP=EUC-JP # Solaris -locale.all.ja_JP.UTF-8=UTF-8 +ja_JP.UTF-8=UTF-8 # Solaris -locale.all.ja_JP.UTF-8@euro=UTF-8 -locale.all.ja_JP.EUC=EUC-JP -locale.all.ja_JP.eucJP=EUC-JP -locale.all.ja_JP.SJIS=Shift_JIS -locale.all.ja_JP.PCK=Shift_JIS -locale.all.ja_JP.IBM-eucJP=EUC-JP -locale.all.ja_JP.mscode=Shift_JIS -locale.all.ja_JP.ujis=EUC-JP -locale.all.katakana=Shift_JIS -locale.all.ko=EUC-KR -locale.all.ko_KR=EUC-KR +ja_JP.UTF-8@euro=UTF-8 +ja_JP.EUC=EUC-JP +ja_JP.eucJP=EUC-JP +ja_JP.SJIS=Shift_JIS +ja_JP.PCK=Shift_JIS +ja_JP.IBM-eucJP=EUC-JP +ja_JP.mscode=Shift_JIS +ja_JP.ujis=EUC-JP +katakana=Shift_JIS +ko=EUC-KR +ko_KR=EUC-KR # Solaris -locale.all.ko_KR.UTF-8=UTF-8 +ko_KR.UTF-8=UTF-8 # Solaris -locale.all.ko_KR.UTF-8@euro=UTF-8 -locale.all.ko_KR.euc=EUC-KR -locale.all.ko_KR.euckr=EUC-KR -locale.all.ko_KR.eucKR=EUC-KR -locale.all.ko_KR.IBM-eucKR=EUC-KR -locale.all.ko_KR.EUC=EUC-KR -locale.all.ko.UTF-8=UTF-8 -locale.all.korean=EUC-KR +ko_KR.UTF-8@euro=UTF-8 +ko_KR.euc=EUC-KR +ko_KR.euckr=EUC-KR +ko_KR.eucKR=EUC-KR +ko_KR.IBM-eucKR=EUC-KR +ko_KR.EUC=EUC-KR +ko.UTF-8=UTF-8 +korean=EUC-KR # Solaris -locale.all.lt_LT.ISO8859-13=ISO-8859-13 +lt_LT.ISO8859-13=ISO-8859-13 # AIX -#locale.all.Lt_LT=IBM-921 +#Lt_LT=IBM-921 # AIX -locale.all.LT_LT=UTF-8 +LT_LT=UTF-8 # Solaris -locale.all.lv_LV.ISO8859-13=ISO-8859-13 +lv_LV.ISO8859-13=ISO-8859-13 # AIX -#locale.all.Lt_LV=IBM-921 +#Lt_LV=IBM-921 # AIX -locale.all.LT_LV=UTF-8 +LT_LV=UTF-8 # Solaris -locale.all.mk_MK.ISO8859-5=ISO-8859-5 +mk_MK.ISO8859-5=ISO-8859-5 # AIX -locale.all.mk_MK=ISO-8859-5 -locale.all.nl=ISO-8859-1 +mk_MK=ISO-8859-5 +nl=ISO-8859-1 # Solaris -locale.all.nl.ISO8859-15=ISO-8859-15 +nl.ISO8859-15=ISO-8859-15 # Solaris -locale.all.nl.ISO8859-15@euro=ISO-8859-15 -locale.all.nl_BE=ISO-8859-1 +nl.ISO8859-15@euro=ISO-8859-15 +nl_BE=ISO-8859-1 # Solaris -locale.all.nl_BE.ISO8859-15=ISO-8859-15 +nl_BE.ISO8859-15=ISO-8859-15 # Solaris -locale.all.nl_BE.ISO8859-15@euro=ISO-8859-15 -locale.all.nl_BE.88591=ISO-8859-1 -locale.all.nl_BE.ISO8859-1=ISO-8859-1 +nl_BE.ISO8859-15@euro=ISO-8859-15 +nl_BE.88591=ISO-8859-1 +nl_BE.ISO8859-1=ISO-8859-1 # Solaris -locale.all.nl_NL.ISO8859-15=ISO-8859-15 -locale.all.nl_NL.ISO8859-15@euro=ISO-8859-15 +nl_NL.ISO8859-15=ISO-8859-15 +nl_NL.ISO8859-15@euro=ISO-8859-15 # AIX -#locale.all.NL_BE=IBM-850 -locale.all.nl_NL=ISO-8859-1 -locale.all.nl_NL.88591=ISO-8859-1 -locale.all.nl_NL.ISO8859-1=ISO-8859-1 +#NL_BE=IBM-850 +nl_NL=ISO-8859-1 +nl_NL.88591=ISO-8859-1 +nl_NL.ISO8859-1=ISO-8859-1 # HP -locale.all.nl_NL.iso885915@euro=ISO-8859-15 +nl_NL.iso885915@euro=ISO-8859-15 # AIX -#locale.all.NL_NL=IBM-850 -locale.all.no=ISO-8859-1 -locale.all.no_NO=ISO-8859-1 -locale.all.no_NO.88591=ISO-8859-1 -locale.all.no_NO.ISO8859-1=ISO-8859-1 +#NL_NL=IBM-850 +no=ISO-8859-1 +no_NO=ISO-8859-1 +no_NO.88591=ISO-8859-1 +no_NO.ISO8859-1=ISO-8859-1 # Solaris -locale.all.no_NO.ISO8859-1@bokmal=ISO-8859-1 -locale.all.no_NO.ISO8859-1@nynorsk=ISO-8859-1 +no_NO.ISO8859-1@bokmal=ISO-8859-1 +no_NO.ISO8859-1@nynorsk=ISO-8859-1 # HP -locale.all.no_NO.iso885915@euro=ISO-8859-15 +no_NO.iso885915@euro=ISO-8859-15 # AIX -#locale.all.No_NO=IBM-850 -locale.all.norwegian.iso88591=ISO-8859-1 -locale.all.pl=ISO-8859-2 -locale.all.pl_PL=ISO-8859-2 -locale.all.pl_PL.88592=ISO-8859-2 -locale.all.pl_PL.ISO8859-2=ISO-8859-2 -locale.all.polish=ISO-8859-2 -locale.all.portuguese.iso88591=ISO-8859-1 -locale.all.pt=ISO-8859-1 +#No_NO=IBM-850 +norwegian.iso88591=ISO-8859-1 +pl=ISO-8859-2 +pl_PL=ISO-8859-2 +pl_PL.88592=ISO-8859-2 +pl_PL.ISO8859-2=ISO-8859-2 +polish=ISO-8859-2 +portuguese.iso88591=ISO-8859-1 +pt=ISO-8859-1 # Solaris -locale.all.pt.ISO8859-15=ISO-8859-15 +pt.ISO8859-15=ISO-8859-15 # Solaris -locale.all.pt.ISO8859-15@euro=ISO-8859-15 +pt.ISO8859-15@euro=ISO-8859-15 # Solaris -locale.all.pt_BR.ISO8859-1=ISO-8859-1 -locale.all.pt_PT.ISO8859-15=ISO-8859-15 -locale.all.pt_PT.ISO8859-15@euro=ISO-8859-15 +pt_BR.ISO8859-1=ISO-8859-1 +pt_PT.ISO8859-15=ISO-8859-15 +pt_PT.ISO8859-15@euro=ISO-8859-15 # AIX -#locale.all.Pt.PT=IBM-850 -locale.all.pt_PT=ISO-8859-1 -locale.all.pt_PT.88591=ISO-8859-1 +#Pt.PT=IBM-850 +pt_PT=ISO-8859-1 +pt_PT.88591=ISO-8859-1 # HP -locale.all.pt_PT.iso885915@euro=ISO-8859-15 -locale.all.pt_PT.ISO8859-1=ISO-8859-1 +pt_PT.iso885915@euro=ISO-8859-15 +pt_PT.ISO8859-1=ISO-8859-1 # Solaris -locale.all.ro_RO.ISO8859-2=ISO-8859-2 +ro_RO.ISO8859-2=ISO-8859-2 # AIX -locale.all.ro_RO=ISO-8859-5 +ro_RO=ISO-8859-5 # Solaris -#locale.all.ru_RU.ANSI1251= ??? ANSI-1251 ??? -locale.all.ru_RU.ISO8859-5=ISO-8859-5 +#ru_RU.ANSI1251= ??? ANSI-1251 ??? +ru_RU.ISO8859-5=ISO-8859-5 # AIX -locale.all.ru_RU=ISO-8859-5 -locale.all.ru_RU.KOI8-R=KOI8-R +ru_RU=ISO-8859-5 +ru_RU.KOI8-R=KOI8-R # RedHat 7 reported by Garaschenko Slava diff.txt +# +# Step 2: edit diff.txt +# - when a function has been renamed, get the - and + lines adjacent and mark the - line with [renamed] at the end +# - when a function has been replaced, do the same (replacements behave differently) +# - for anything that isn't a simple addition, deletion, rename, or replace, tag with [other] +# (things tagged [other] will be put in a separate section for manual fixup) +# +# Step 3: run release-notes < diff.txt > changes.txt +# - this will group changes into sections and annotate them with bug numbers +# - the bugs chosen are just the bug that last touched each line, and are unlikely to be entirely accurate +# +# Step 4: run release-notes mdn < changes.txt > final.txt +# - this will add an MDN link to every list item, first checking whether such a link is valid +# +# Step 5: paste into the MDN page, eg https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Releases/45 + +# Upcoming: basing everything off of jsapi.h is probably not going to work for +# much longer, given that more stuff is moving into js/public. Scan +# js/public/*.h too and record where everything comes from (to automate header +# changes in the notes)? +# +# This is only looking at C style APIs. Dump out all methods too? +# +# The enbuggification should be split out into a separate phase because it is +# wrong a fair amount of the time (whitespace changes, parameter changes, +# etc.), and should have a way of running repeatedly so you can incrementally +# fix stuff up. +# +# It would be very nice to have an example program that links against mozjs, +# tested in CI, so we can diff that for release notes. + +use strict; +use warnings; + +if (@ARGV && $ARGV[0] eq 'diff') { + my ($orig_file, $new_file) = @ARGV[1..2]; + my $orig_api = grab_api($orig_file); + my $new_api = grab_api($new_file); + diff_apis($orig_api, $new_api); + exit 0; +} + +my $path = "/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference"; +my $url_prefix = "https://developer.mozilla.org$path"; + +if (@ARGV && $ARGV[0] eq 'mdn') { + shift(@ARGV); + while(<>) { + if (/
  • ([\w:]+)/) { + print STDERR "Checking $1...\n"; + system("wget", "-q", "$url_prefix/$1"); + if ($? == 0) { + s!
  • ([\w:]+)!
  • $1!; + } + } + print; + } + exit 0; +} + +sub grab_api { + my ($file) = @_; + open(my $fh, "<", $file) or die "open $file: $!"; + my $grabbing; + my @api; + while(<$fh>) { + if ($grabbing && /^(\w+)/) { + push @api, $1; + } + $grabbing = /JS_PUBLIC_API/; + } + return \@api; +} + +sub diff_apis { + my ($old, $new) = @_; + my %old; + @old{@$old} = (); + my %new; + @new{@$new} = (); + + open(my $ofh, ">", "/tmp/r-c.diff.1"); + print $ofh "$_\n" foreach (@$old); + close $ofh; + open(my $nfh, ">", "/tmp/r-c.diff.2"); + print $nfh "$_\n" foreach (@$new); + close $nfh; + open(my $diff, "diff -u /tmp/r-c.diff.1 /tmp/r-c.diff.2 |"); + while(<$diff>) { + if (/^-(\w+)/) { + next if exists $new{$1}; # Still exists, so skip it + } elsif (/^\+(\w+)/) { + next if exists $old{$1}; # It was already there, skip it + } + print; + } +} + +my @added; +my @renamed; +my @replaced; +my @deleted; +my @other; + +my %N; + +my $renaming; +my $replacing; +while (<>) { + my $name; + if (/^[ +-](\w+)/) { + $name = $1; + $N{$name} = $name =~ /^JS_/ ? $name : "JS::$name"; + } + + if (/^-/) { + die if ! $name; + if (/\[rename\]/) { + $renaming = $name; + } elsif (/\[replace\]/) { + $replacing = $name; + } elsif (/\[other\]/) { + push @other, $name; + } else { + push @deleted, $name; + } + } elsif (/^\+/) { + die if ! $name; + if ($renaming) { + push @renamed, [ $renaming, $name ]; + undef $renaming; + } elsif ($replacing) { + push @replaced, [ $replacing, $name ]; + undef $replacing; + } elsif (/\[other\]/) { + push @other, $name; + } else { + push @added, $name; + } + } +} + +open(my $fh, "<", "jsapi.blame") or die "open jsapi.blame: $!"; +my $grabbing; +my %changerev; +my %revs; +while(<$fh>) { + if ($grabbing && /^\s*(\d+): (\w+)/ ) { + $changerev{$2} = $1; + $revs{$1} = 1; + } + $grabbing = /JS_PUBLIC_API/; +} + +my %bug; +for my $rev (keys %revs) { + open(my $fh, "hg log -r $rev -T '{desc}' |"); + while(<$fh>) { + if (/[bB]ug (\d+)/) { + $bug{$rev} = $1; + } + } +} + +sub get_bug_suffix { + my ($api) = @_; + $DB::single = 1 if ! $changerev{$api}; + my $bug = $bug{$changerev{$api}}; + return $bug ? " {{{bug($bug)}}}" : ""; +} + +print "(new apis)\n"; +print "
      \n"; +print "
    • $N{$_}" . get_bug_suffix($_) . "
    • \n" foreach @added; +print "
    • $N{$_->[0]} renamed to $N{$_->[1]}" . get_bug_suffix($_->[1]) . "
    • \n" foreach @renamed; +print "
    • $N{$_->[0]} replaced with $N{$_->[1]}" . get_bug_suffix($_->[1]) . "
    • \n" foreach @replaced; +print "
    \n"; +print "\n"; + +print qq(

    Deleted APIs

    \n); +print "
      \n"; +print "
    • $N{$_}
    • \n" foreach @deleted; +print "
    \n"; +print "\n"; + +print qq(

    Changed APIs

    \n); +print "
      \n"; +print "
    • $N{$_}" . get_bug_suffix($_) . "
    • \n" foreach @other; +print "
    \n"; +print "\n"; diff --git a/js/src/make-source-package.sh b/js/src/make-source-package.sh index 3c9251a48d..ea51f078b3 100755 --- a/js/src/make-source-package.sh +++ b/js/src/make-source-package.sh @@ -79,6 +79,7 @@ case $cmd in # put in js itself cp -pPR ${TOPSRCDIR}/mfbt ${tgtpath} cp -pPR ${SRCDIR}/../public ${tgtpath}/js + cp -pPR ${SRCDIR}/../examples ${tgtpath}/js find ${SRCDIR} -mindepth 1 -maxdepth 1 -not -path ${DIST} -a -not -name ${pkg} \ -exec cp -pPR {} ${tgtpath}/js/src \; diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index dbc3bf7c3d..deac75a994 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -631,6 +631,10 @@ public: { return NSAppUnitsToFloatPixels(aAppUnits, float(AppUnitsPerCSSPixel())); } + static double AppUnitsToDoubleCSSPixels(nscoord aAppUnits) + { return NSAppUnitsToDoublePixels(aAppUnits, + double(AppUnitsPerCSSPixel())); } + nscoord DevPixelsToAppUnits(int32_t aPixels) const { return NSIntPixelsToAppUnits(aPixels, AppUnitsPerDevPixel()); } diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 912c4fd982..834623e146 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -4098,14 +4098,14 @@ ScrollFrameHelper::FireScrollPortEvent() // DOM event. bool both = vertChanged && horizChanged && newVerticalOverflow == newHorizontalOverflow; - InternalScrollPortEvent::orientType orient; + InternalScrollPortEvent::OrientType orient; if (both) { - orient = InternalScrollPortEvent::both; + orient = InternalScrollPortEvent::eBoth; mHorizontalOverflow = newHorizontalOverflow; mVerticalOverflow = newVerticalOverflow; } else if (vertChanged) { - orient = InternalScrollPortEvent::vertical; + orient = InternalScrollPortEvent::eVertical; mVerticalOverflow = newVerticalOverflow; if (horizChanged) { // We need to dispatch a separate horizontal DOM event. Do that the next @@ -4115,15 +4115,15 @@ ScrollFrameHelper::FireScrollPortEvent() } } else { - orient = InternalScrollPortEvent::horizontal; + orient = InternalScrollPortEvent::eHorizontal; mHorizontalOverflow = newHorizontalOverflow; } InternalScrollPortEvent event(true, - (orient == InternalScrollPortEvent::horizontal ? mHorizontalOverflow : - mVerticalOverflow) ? + (orient == InternalScrollPortEvent::eHorizontal ? mHorizontalOverflow : + mVerticalOverflow) ? eScrollPortOverflow : eScrollPortUnderflow, nullptr); - event.orient = orient; + event.mOrient = orient; return EventDispatcher::Dispatch(mOuter->GetContent(), mOuter->PresContext(), &event); } diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 8dd5cf4afe..823a97dfbf 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -921,7 +921,7 @@ nsTreeBodyFrame::CheckOverflow(const ScrollParts& aParts) InternalScrollPortEvent event(true, mVerticalOverflow ? eScrollPortOverflow : eScrollPortUnderflow, nullptr); - event.orient = InternalScrollPortEvent::vertical; + event.mOrient = InternalScrollPortEvent::eVertical; EventDispatcher::Dispatch(content, presContext, &event); } @@ -929,7 +929,7 @@ nsTreeBodyFrame::CheckOverflow(const ScrollParts& aParts) InternalScrollPortEvent event(true, mHorizontalOverflow ? eScrollPortOverflow : eScrollPortUnderflow, nullptr); - event.orient = InternalScrollPortEvent::horizontal; + event.mOrient = InternalScrollPortEvent::eHorizontal; EventDispatcher::Dispatch(content, presContext, &event); } diff --git a/memory/mozalloc/throw_gcc.h b/memory/mozalloc/throw_gcc.h index 9385185640..db81d4f936 100644 --- a/memory/mozalloc/throw_gcc.h +++ b/memory/mozalloc/throw_gcc.h @@ -74,52 +74,41 @@ __throw_bad_typeid(void) } // used by -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_THROW_INLINE void -__throw_bad_function_call(void) { - mozalloc_abort("fatal: STL threw bad_function_call"); +__throw_bad_function_call(void) +{ + mozalloc_abort("fatal: STL threw bad_function_call"); } -#endif -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_logic_error(const char* msg) { mozalloc_abort(msg); } -#endif -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_domain_error(const char* msg) { mozalloc_abort(msg); } -#endif -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_invalid_argument(const char* msg) { mozalloc_abort(msg); } -#endif -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_length_error(const char* msg) { mozalloc_abort(msg); } -#endif -#if !defined(_LIBCPP_VERSION) MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_out_of_range(const char* msg) { mozalloc_abort(msg); } -#endif MOZ_THROW_NORETURN MOZ_THROW_EXPORT MOZ_ALWAYS_INLINE void __throw_runtime_error(const char* msg) diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html.ini index 858defada4..865150c6d8 100644 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html.ini +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html.ini @@ -1,711 +1,745 @@ [parse-a-sizes-attribute.html] type: testharness - disabled: investigating intermittent failures in bug 1134120 - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="100vw" (standards mode)] - expected: FAIL - - [ ref sizes="100vw" (standards mode)] - expected: FAIL - - [ ref sizes="100vw" (standards mode)] - expected: FAIL - - [ ref sizes="100vw" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (quirks mode)] - expected: FAIL - - [ ref sizes="100vw" (quirks mode)] - expected: FAIL - - [ ref sizes="100vw" (quirks mode)] - expected: FAIL - - [ ref sizes="100vw" (quirks mode)] - expected: FAIL - - [ ref sizes="100vw" (quirks mode)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="1px" (display:none)] - expected: FAIL - - [ ref sizes="100vw" (display:none)] - expected: FAIL - - [ ref sizes="100vw" (display:none)] - expected: FAIL - - [ ref sizes="100vw" (display:none)] - expected: FAIL - - [ ref sizes="100vw" (display:none)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (width:1000px)] - expected: FAIL - - [ ref sizes="100vw" (width:1000px)] - expected: FAIL - - [ ref sizes="100vw" (width:1000px)] - expected: FAIL - - [ ref sizes="100vw" (width:1000px)] - expected: FAIL - - [ ref sizes="100vw" (width:1000px)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] - expected: FAIL - - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="100vw" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="100vw" (standards mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (standards mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="100vw" (standards mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] expected: FAIL [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="100vw" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="100vw" (quirks mode)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (quirks mode)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="100vw" (quirks mode)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] expected: FAIL [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="100vw" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="100vw" (display:none)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (display:none)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="1px" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="100vw" (display:none)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] expected: FAIL [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="1px" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="100vw" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL - [ ref sizes="100vw" (width:1000px)] + [ ref sizes="1px" (width:1000px)] expected: FAIL + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="1px" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL + + [ ref sizes="100vw" (width:1000px)] + expected: FAIL \ No newline at end of file diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini deleted file mode 100644 index 9e26da876c..0000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[parse-a-srcset-attribute.html] - type: testharness - ["data:,a 1.x"] - expected: FAIL - - ["data:,a +1x"] - expected: FAIL - - ["data:,a \xe2\x80\x891x" (leading U+2009)] - expected: FAIL - - ["data:,a \xe2\x80\x8a1x" (leading U+200A)] - expected: FAIL - - ["data:,a \xe2\x80\x8c1x" (leading U+200C)] - expected: FAIL - - ["data:,a \xe2\x80\x8d1x" (leading U+200D)] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini index 5fef8053ba..4b7bfe91be 100644 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini @@ -1,11 +1,5 @@ [update-the-source-set.html] type: testharness - [] - expected: FAIL - - [] - expected: FAIL - [] expected: FAIL diff --git a/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/content.html.ini b/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/content.html.ini index 734be982ca..2d2b29bf28 100644 --- a/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/content.html.ini +++ b/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/content.html.ini @@ -1,35 +1,14 @@ [content.html] type: testharness - [an empty url argument should throw SYNTAX_ERR] - expected: FAIL - [%s instead of domain name should throw SYNTAX_ERR] expected: FAIL [%s instead of subdomain name should throw syntax_err] expected: FAIL - [a url argument without %s should throw SYNTAX_ERR] - expected: FAIL - [a url argument pointing to a different domain name, without %s should throw SYNTAX_ERR] expected: FAIL - [a url argument without %s (but with %) should throw SYNTAX_ERR] - expected: FAIL - - [a url argument without %s (but with %a) should throw SYNTAX_ERR] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR (2)] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR (3)] - expected: FAIL - [attempting to override the image/jpeg MIME type should throw SECURITY_ERR] expected: FAIL diff --git a/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.html.ini b/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.html.ini index 625791aa65..962ba34346 100644 --- a/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.html.ini +++ b/testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.html.ini @@ -1,98 +1,20 @@ [protocol.html] type: testharness - [an empty url argument should throw SYNTAX_ERR] - expected: FAIL - [%s instead of domain name should throw SYNTAX_ERR] expected: FAIL [%s instead of subdomain name should throw SYNTAX_ERR] expected: FAIL - [a url argument without %s should throw SYNTAX_ERR] - expected: FAIL - [a url argument pointing to a different domain name, without %s should throw SYNTAX_ERR] expected: FAIL - [a url argument without %s (but with %) should throw SYNTAX_ERR] - expected: FAIL - - [a url argument without %s (but with %a) should throw SYNTAX_ERR] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR (2)] - expected: FAIL - - [a url argument pointing to a different domain name should throw SECURITY_ERR (3)] - expected: FAIL - - [looping handlers should throw SECURITY_ERR] - expected: FAIL - - [a url argument pointing to a non-http[s\] scheme should throw SECURITY_ERR due to not being of the same origin] - expected: FAIL - - [a protocol argument containing an unrecognized scheme should throw SECURITY_ERR] - expected: FAIL - - [a protocol argument containing : should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing :// should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing http:// should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing a null character should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing a backspace character should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing a LF character should throw SYNTAX_ERR] - expected: FAIL - - [a protocol argument containing non-alphanumeric characters (like a cyrillic “а”) should throw SYNTAX_ERR] - expected: FAIL - - [attempting to override the about protocol should throw SECURITY_ERR] - expected: FAIL - [attempting to override the attachment protocol should throw SECURITY_ERR] expected: FAIL - [attempting to override the blob protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the chrome protocol should throw SECURITY_ERR] - expected: FAIL - [attempting to override the cid protocol should throw SECURITY_ERR] expected: FAIL - [attempting to override the data protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the file protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the ftp protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the http protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the https protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the javascript protocol should throw SECURITY_ERR] - expected: FAIL - [attempting to override the livescript protocol should throw SECURITY_ERR] expected: FAIL @@ -111,27 +33,9 @@ [attempting to override the res protocol should throw SECURITY_ERR] expected: FAIL - [attempting to override the resource protocol should throw SECURITY_ERR] - expected: FAIL - [attempting to override the shttp protocol should throw SECURITY_ERR] expected: FAIL [attempting to override the tcl protocol should throw SECURITY_ERR] expected: FAIL - [attempting to override the vbscript protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the view-source protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the ws protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the wss protocol should throw SECURITY_ERR] - expected: FAIL - - [attempting to override the wyciwyg protocol should throw SECURITY_ERR] - expected: FAIL - diff --git a/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization.html b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization.html index b78ad45053..e47de1238f 100644 --- a/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization.html +++ b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization.html @@ -282,6 +282,7 @@ var encodingMap = { ], "shift_jis": [ "csshiftjis", + "ms932", "ms_kanji", "shift-jis", "shift_jis", diff --git a/testing/web-platform/tests/encoding/resources/encodings.js b/testing/web-platform/tests/encoding/resources/encodings.js index 6771a44967..1cdf585eec 100644 --- a/testing/web-platform/tests/encoding/resources/encodings.js +++ b/testing/web-platform/tests/encoding/resources/encodings.js @@ -419,6 +419,7 @@ var encodings_table = { "labels": [ "csshiftjis", + "ms932", "ms_kanji", "shift-jis", "shift_jis", diff --git a/testing/web-platform/tests/service-workers/service-worker/navigate-window.https.html b/testing/web-platform/tests/service-workers/service-worker/navigate-window.https.html index 4a0e51d3d8..e3aaf4c5cd 100644 --- a/testing/web-platform/tests/service-workers/service-worker/navigate-window.https.html +++ b/testing/web-platform/tests/service-workers/service-worker/navigate-window.https.html @@ -29,6 +29,11 @@ function navigate_window(win, url) { return wait_for_message('LOADED').then(_ => win); } +function reload_window(win) { + win.location.reload(); + return wait_for_message('LOADED').then(_ => win); +} + function go_back(win) { win.history.back(); return wait_for_message('PAGESHOW').then(_ => win); @@ -61,24 +66,39 @@ function validate_window(win, url, opts) { // opened window in this case. assert_equals(win.navigator.serviceWorker.controller, reg.active, 'window should be controlled by service worker'); - return get_clients(win, reg.active); + return get_clients(win, reg.active, opts); }) .then(resultList => { - assert_equals(resultList.length, 1, 'there should only be one client'); - assert_equals(resultList[0].url, url, - 'client should be our opened window'); - assert_equals(resultList[0].frameType, 'auxiliary', - 'window.open() should create a client with an auxiliary frame type'); + // We should always see our controlled window. + var expected = [ + { url: url, frameType: 'auxiliary' } + ]; + // If we are including uncontrolled windows, then we might see the + // test window itself and the test harness. + if (opts.includeUncontrolled) { + expected.push({ url: BASE_URL + 'navigate-window.https.html', + frameType: 'auxiliary' }); + expected.push({ url: host_info['HTTPS_ORIGIN'] + '/testharness_runner.html', + frameType: 'top-level' }); + } + assert_equals(resultList.length, expected.length, + 'expected number of clients'); + for (var i = 0; i < resultList.length; ++i) { + assert_equals(resultList[i].url, expected[i].url, + 'client should have expected url'); + assert_equals(resultList[i].frameType, expected[i].frameType, + ' client should have expected frame type'); + } return win; }) } -async_test(function(t) { +promise_test(function(t) { var worker = BASE_URL + 'resources/navigate-window-worker.js'; - var scope = BASE_URL + 'resources/loaded.html?navigate-window'; + var scope = BASE_URL + 'resources/loaded.html?navigate-window-controlled'; var url1 = scope + '&q=1'; var url2 = scope + '&q=2'; - service_worker_unregister_and_register(t, worker, scope) + return service_worker_unregister_and_register(t, worker, scope) .then(reg => wait_for_state(t, reg.installing, 'activated') ) .then(___ => with_window(url1)) .then(win => validate_window(win, url1, { includeUncontrolled: false })) @@ -88,10 +108,34 @@ async_test(function(t) { .then(win => validate_window(win, url1, { includeUncontrolled: false })) .then(win => go_forward(win)) .then(win => validate_window(win, url2, { includeUncontrolled: false })) + .then(win => reload_window(win)) + .then(win => validate_window(win, url2, { includeUncontrolled: false })) .then(win => win.close()) .catch(unreached_rejection(t)) - .then(___ => service_worker_unregister_and_done(t, scope)) + .then(___ => service_worker_unregister(t, scope)) }, 'Clients.matchAll() should not show an old window as controlled after ' + 'it navigates.'); + +promise_test(function(t) { + var worker = BASE_URL + 'resources/navigate-window-worker.js'; + var scope = BASE_URL + 'resources/loaded.html?navigate-window-uncontrolled'; + var url1 = scope + '&q=1'; + var url2 = scope + '&q=2'; + return service_worker_unregister_and_register(t, worker, scope) + .then(reg => wait_for_state(t, reg.installing, 'activated') ) + .then(___ => with_window(url1)) + .then(win => validate_window(win, url1, { includeUncontrolled: true })) + .then(win => navigate_window(win, url2)) + .then(win => validate_window(win, url2, { includeUncontrolled: true })) + .then(win => go_back(win)) + .then(win => validate_window(win, url1, { includeUncontrolled: true })) + .then(win => go_forward(win)) + .then(win => validate_window(win, url2, { includeUncontrolled: true })) + .then(win => reload_window(win)) + .then(win => validate_window(win, url2, { includeUncontrolled: true })) + .then(win => win.close()) + .catch(unreached_rejection(t)) + .then(___ => service_worker_unregister(t, scope)) + }, 'Clients.matchAll() should not show an old window after it navigates.'); diff --git a/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js b/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js index e6f1c608ab..adccd8fb78 100644 --- a/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js +++ b/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js @@ -481,24 +481,6 @@ function* test_push_cleared() const channelID = '0ef2ad4a-6c49-41ad-af6e-95d2425276bf'; let db = PushServiceWebSocket.newPushDB(); - do_register_cleanup(() => {return db.drop().then(_ => db.close());}); - - PushService.init({ - serverURI: "wss://push.example.org/", - networkInfo: new MockDesktopNetworkInfo(), - db, - makeWebSocket(uri) { - return new MockWebSocket(uri, { - onHello(request) { - this.serverSendMsg(JSON.stringify({ - messageType: 'hello', - status: 200, - uaid: userAgentID, - })); - }, - }); - } - }); function push_registration_exists(aURL, ps) { @@ -516,20 +498,44 @@ function* test_push_cleared() }); } - const TEST_URL = "https://www.mozilla.org/scope/"; - do_check_false(yield push_registration_exists(TEST_URL, ps)); - yield db.put({ - channelID, - pushEndpoint: 'https://example.org/update/clear-success', - scope: TEST_URL, - version: 1, - originAttributes: '', - quota: Infinity, - }); - do_check_true(yield push_registration_exists(TEST_URL, ps)); - ForgetAboutSite.removeDataFromDomain("mozilla.org"); - yield waitForPurgeNotification(); - do_check_false(yield push_registration_exists(TEST_URL, ps)); + try { + PushService.init({ + serverURI: "wss://push.example.org/", + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID, + })); + }, + }); + } + }); + + const TEST_URL = "https://www.mozilla.org/scope/"; + do_check_false(yield push_registration_exists(TEST_URL, ps)); + yield db.put({ + channelID, + pushEndpoint: 'https://example.org/update/clear-success', + scope: TEST_URL, + version: 1, + originAttributes: '', + quota: Infinity, + }); + do_check_true(yield push_registration_exists(TEST_URL, ps)); + + let promisePurgeNotification = waitForPurgeNotification(); + yield ForgetAboutSite.removeDataFromDomain("mozilla.org"); + yield promisePurgeNotification; + + do_check_false(yield push_registration_exists(TEST_URL, ps)); + } finally { + yield PushService._shutdownService(); + } } // Cache diff --git a/widget/ContentEvents.h b/widget/ContentEvents.h index 542974cf70..fe979c7c73 100644 --- a/widget/ContentEvents.h +++ b/widget/ContentEvents.h @@ -31,17 +31,17 @@ public: return this; } - enum orientType + enum OrientType { - vertical = 0, - horizontal = 1, - both = 2 + eVertical, + eHorizontal, + eBoth }; InternalScrollPortEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget) : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eScrollPortEventClass) - , orient(vertical) + , mOrient(eVertical) { } @@ -57,14 +57,14 @@ public: return result; } - orientType orient; + OrientType mOrient; void AssignScrollPortEventData(const InternalScrollPortEvent& aEvent, bool aCopyTargets) { AssignGUIEventData(aEvent, aCopyTargets); - orient = aEvent.orient; + mOrient = aEvent.mOrient; } }; diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index d7c0cf3ecd..f59eb899cd 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -988,7 +988,7 @@ PuppetWidget::SetCursor(imgIContainer* aCursor, mozilla::UniquePtr surfaceData = nsContentUtils::GetSurfaceData(dataSurface, &length, &stride); - nsCString cursorData = nsCString(surfaceData.get(), length); + nsDependentCString cursorData(surfaceData.get(), length); mozilla::gfx::IntSize size = dataSurface->GetSize(); if (!mTabChild->SendSetCustomCursor(cursorData, size.width, size.height, stride, static_cast(dataSurface->GetFormat()), diff --git a/widget/tests/test_imestate.html b/widget/tests/test_imestate.html index 077cf2da88..b3fc5ce54a 100644 --- a/widget/tests/test_imestate.html +++ b/widget/tests/test_imestate.html @@ -1232,6 +1232,9 @@ function runEditorFlagChangeTests() var container = document.getElementById("display"); + // Reset selection from previous tests. + window.getSelection().collapse(container, 0); + // the editor has focus directly. container.setAttribute("contenteditable", "true"); container.focus(); @@ -1252,9 +1255,6 @@ function runEditorFlagChangeTests() editor.QueryInterface(Components.interfaces.nsIEditorIMESupport); var flags = editor.flags; - // Reset selection from previous tests. - editor.selection.collapse(container, 0); - // input characters synthesizeCompositionChange( { "composition":