diff --git a/Cargo.lock b/Cargo.lock index 1b46032347de..5acdf10aef62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1284,7 +1284,7 @@ dependencies = [ [[package]] name = "gleam" -version = "0.6.15" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3315,7 +3315,7 @@ dependencies = [ "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3366,7 +3366,7 @@ dependencies = [ "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "nsstring 0.1.0", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3624,7 +3624,7 @@ dependencies = [ "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd" -"checksum gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "43edfa3a4321024d7dac1625cf154ef0c16996a6a384d066480e306ebd39fecc" +"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2" "checksum guid_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87261686cc5e35b6584f4c2a430c2b153d8a92ab1ef820c16be34c1df8f5f58b" diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 8aaf72e3ea7d..58c96a048d85 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -4301,6 +4301,13 @@ static void NotifyActivityChanged(nsISupports* aSupports, void* aUnused) { do_QueryInterface(aSupports)); if (objectDocumentActivity) { objectDocumentActivity->NotifyOwnerDocumentActivityChanged(); + } else { + nsCOMPtr imageLoadingContent( + do_QueryInterface(aSupports)); + if (imageLoadingContent) { + auto ilc = static_cast(imageLoadingContent.get()); + ilc->NotifyOwnerDocumentActivityChanged(); + } } } diff --git a/dom/base/domerr.msg b/dom/base/domerr.msg index d011f9dfde53..078a1362efa4 100644 --- a/dom/base/domerr.msg +++ b/dom/base/domerr.msg @@ -163,3 +163,8 @@ DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest state must not be LOADING or DON DOM4_MSG_DEF(InvalidStateError, "responseXML is only available if responseType is '' or 'document'.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_WRONG_RESPONSETYPE_FOR_RESPONSEXML) DOM4_MSG_DEF(InvalidStateError, "responseText is only available if responseType is '' or 'text'.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_WRONG_RESPONSETYPE_FOR_RESPONSETEXT) DOM4_MSG_DEF(InvalidAccessError, "synchronous XMLHttpRequests do not support timeout and responseType.", NS_ERROR_DOM_INVALID_ACCESS_XHR_TIMEOUT_AND_RESPONSETYPE_UNSUPPORTED_FOR_SYNC) + +/* Image decode errors. */ +DOM4_MSG_DEF(EncodingError, "Node bound to inactive document.", NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT) +DOM4_MSG_DEF(EncodingError, "Invalid image request.", NS_ERROR_DOM_IMAGE_INVALID_REQUEST) +DOM4_MSG_DEF(EncodingError, "Invalid encoded image data.", NS_ERROR_DOM_IMAGE_BROKEN) diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index d3f19748eb37..e187d793c086 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -95,6 +95,8 @@ nsImageLoadingContent::nsImageLoadingContent() : mCurrentRequestFlags(0), mPendingRequestFlags(0), mObserverList(nullptr), + mOutstandingDecodePromises(0), + mRequestGeneration(0), mImageBlockingStatus(nsIContentPolicy::ACCEPT), mLoadingEnabled(true), mIsImageStateForced(false), @@ -120,17 +122,21 @@ nsImageLoadingContent::nsImageLoadingContent() void nsImageLoadingContent::DestroyImageLoadingContent() { // Cancel our requests so they won't hold stale refs to us // NB: Don't ask to discard the images here. + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST); ClearCurrentRequest(NS_BINDING_ABORTED); ClearPendingRequest(NS_BINDING_ABORTED); } nsImageLoadingContent::~nsImageLoadingContent() { - NS_ASSERTION(!mCurrentRequest && !mPendingRequest, - "DestroyImageLoadingContent not called"); - NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext, - "Observers still registered?"); - NS_ASSERTION(mScriptedObservers.IsEmpty(), - "Scripted observers still registered?"); + MOZ_ASSERT(!mCurrentRequest && !mPendingRequest, + "DestroyImageLoadingContent not called"); + MOZ_ASSERT(!mObserverList.mObserver && !mObserverList.mNext, + "Observers still registered?"); + MOZ_ASSERT(mScriptedObservers.IsEmpty(), + "Scripted observers still registered?"); + MOZ_ASSERT(mOutstandingDecodePromises == 0, + "Decode promises still unfulfilled?"); + MOZ_ASSERT(mDecodePromises.IsEmpty(), "Decode promises still unfulfilled?"); } /* @@ -204,6 +210,11 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, int32_t aType, return OnLoadComplete(aRequest, status); } + if (aType == imgINotificationObserver::FRAME_COMPLETE && + mCurrentRequest == aRequest) { + MaybeResolveDecodePromises(); + } + if (aType == imgINotificationObserver::DECODE_COMPLETE) { nsCOMPtr container; aRequest->GetImage(getter_AddRefs(container)); @@ -260,6 +271,7 @@ nsresult nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsCOMPtr thisNode = do_QueryInterface(static_cast(this)); SVGObserverUtils::InvalidateDirectRenderingObservers(thisNode->AsElement()); + MaybeResolveDecodePromises(); return NS_OK; } @@ -334,6 +346,166 @@ void nsImageLoadingContent::SetLoadingEnabled(bool aLoadingEnabled) { } } +already_AddRefed nsImageLoadingContent::QueueDecodeAsync( + ErrorResult& aRv) { + Document* doc = GetOurOwnerDoc(); + RefPtr promise = Promise::Create(doc->GetScopeObject(), aRv); + if (aRv.Failed()) { + return nullptr; + } + + class QueueDecodeTask final : public Runnable { + public: + QueueDecodeTask(nsImageLoadingContent* aOwner, Promise* aPromise, + uint32_t aRequestGeneration) + : Runnable("nsImageLoadingContent::QueueDecodeTask"), + mOwner(aOwner), + mPromise(aPromise), + mRequestGeneration(aRequestGeneration) {} + + NS_IMETHOD Run() override { + mOwner->DecodeAsync(std::move(mPromise), mRequestGeneration); + return NS_OK; + } + + private: + RefPtr mOwner; + RefPtr mPromise; + uint32_t mRequestGeneration; + }; + + if (++mOutstandingDecodePromises == 1) { + MOZ_ASSERT(mDecodePromises.IsEmpty()); + doc->RegisterActivityObserver(this); + } + + auto task = MakeRefPtr(this, promise, mRequestGeneration); + nsContentUtils::RunInStableState(task.forget()); + return promise.forget(); +} + +void nsImageLoadingContent::DecodeAsync(RefPtr&& aPromise, + uint32_t aRequestGeneration) { + MOZ_ASSERT(nsContentUtils::IsInStableOrMetaStableState()); + MOZ_ASSERT(aPromise); + MOZ_ASSERT(mOutstandingDecodePromises > mDecodePromises.Length()); + + // The request may have gotten updated since the decode call was issued. + if (aRequestGeneration != mRequestGeneration) { + aPromise->MaybeReject(NS_ERROR_DOM_IMAGE_INVALID_REQUEST); + // We never got placed in mDecodePromises, so we must ensure we decrement + // the counter explicitly. + --mOutstandingDecodePromises; + MaybeDeregisterActivityObserver(); + return; + } + + bool wasEmpty = mDecodePromises.IsEmpty(); + mDecodePromises.AppendElement(std::move(aPromise)); + if (wasEmpty) { + MaybeResolveDecodePromises(); + } +} + +void nsImageLoadingContent::MaybeResolveDecodePromises() { + if (mDecodePromises.IsEmpty()) { + return; + } + + if (!mCurrentRequest) { + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST); + return; + } + + // Only can resolve if our document is the active document. If not we are + // supposed to reject the promise, even if it was fulfilled successfully. + if (!GetOurOwnerDoc()->IsCurrentActiveDocument()) { + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT); + return; + } + + // If any error occurred while decoding, we need to reject first. + uint32_t status = imgIRequest::STATUS_NONE; + mCurrentRequest->GetImageStatus(&status); + if (status & imgIRequest::STATUS_ERROR) { + RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN); + return; + } + + // We need the size to bother with requesting a decode, as we are either + // blocked on validation or metadata decoding. + if (!(status & imgIRequest::STATUS_SIZE_AVAILABLE)) { + return; + } + + // Check the surface cache status and/or request decoding begin. We do this + // before LOAD_COMPLETE because we want to start as soon as possible. + uint32_t flags = imgIContainer::FLAG_HIGH_QUALITY_SCALING | + imgIContainer::FLAG_AVOID_REDECODE_FOR_SIZE; + if (!mCurrentRequest->RequestDecodeWithResult(flags)) { + return; + } + + // We can only fulfill the promises once we have all the data. + if (!(status & imgIRequest::STATUS_LOAD_COMPLETE)) { + return; + } + + for (auto& promise : mDecodePromises) { + promise->MaybeResolveWithUndefined(); + } + + MOZ_ASSERT(mOutstandingDecodePromises >= mDecodePromises.Length()); + mOutstandingDecodePromises -= mDecodePromises.Length(); + mDecodePromises.Clear(); + MaybeDeregisterActivityObserver(); +} + +void nsImageLoadingContent::RejectDecodePromises(nsresult aStatus) { + if (mDecodePromises.IsEmpty()) { + return; + } + + for (auto& promise : mDecodePromises) { + promise->MaybeReject(aStatus); + } + + MOZ_ASSERT(mOutstandingDecodePromises >= mDecodePromises.Length()); + mOutstandingDecodePromises -= mDecodePromises.Length(); + mDecodePromises.Clear(); + MaybeDeregisterActivityObserver(); +} + +void nsImageLoadingContent::MaybeAgeRequestGeneration(nsIURI* aNewURI) { + MOZ_ASSERT(mCurrentRequest); + + // If the current request is about to change, we need to verify if the new + // URI matches the existing current request's URI. If it doesn't, we need to + // reject any outstanding promises due to the current request mutating as per + // step 2.2 of the decode API requirements. + // + // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode + if (aNewURI) { + nsCOMPtr currentURI; + mCurrentRequest->GetURI(getter_AddRefs(currentURI)); + + bool equal = false; + if (NS_SUCCEEDED(aNewURI->Equals(currentURI, &equal)) && equal) { + return; + } + } + + ++mRequestGeneration; + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST); +} + +void nsImageLoadingContent::MaybeDeregisterActivityObserver() { + if (mOutstandingDecodePromises == 0) { + MOZ_ASSERT(mDecodePromises.IsEmpty()); + GetOurOwnerDoc()->UnregisterActivityObserver(this); + } +} + void nsImageLoadingContent::SetSyncDecodingHint(bool aHint) { if (mSyncDecodingHint == aHint) { return; @@ -786,6 +958,15 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel, // Shouldn't that be done before the start of the load? // XXX what about shouldProcess? + // If we have a current request without a size, we know we will replace it + // with the PrepareNextRequest below. If the new current request is for a + // different URI, then we need to reject any outstanding promises. + if (mCurrentRequest && !HaveSize(mCurrentRequest)) { + nsCOMPtr uri; + aChannel->GetOriginalURI(getter_AddRefs(uri)); + MaybeAgeRequestGeneration(uri); + } + // Our state might change. Watch it. AutoStateChanger changer(this, true); @@ -944,6 +1125,13 @@ nsresult nsImageLoadingContent::LoadImage(nsIURI* aNewURI, bool aForce, } } + // If we have a current request without a size, we know we will replace it + // with the PrepareNextRequest below. If the new current request is for a + // different URI, then we need to reject any outstanding promises. + if (mCurrentRequest && !HaveSize(mCurrentRequest)) { + MaybeAgeRequestGeneration(aNewURI); + } + // From this point on, our image state could change. Watch it. AutoStateChanger changer(this, aNotify); @@ -1120,11 +1308,13 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) { } else if (!mCurrentRequest) { // No current request means error, since we weren't disabled or suppressed mBroken = true; + RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN); } else { uint32_t currentLoadStatus; nsresult rv = mCurrentRequest->GetImageStatus(¤tLoadStatus); if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) { mBroken = true; + RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN); } else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) { mLoading = true; } @@ -1135,6 +1325,7 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) { } void nsImageLoadingContent::CancelImageRequests(bool aNotify) { + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST); AutoStateChanger changer(this, aNotify); ClearPendingRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES)); ClearCurrentRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES)); @@ -1183,6 +1374,7 @@ nsresult nsImageLoadingContent::FireEvent(const nsAString& aEventType, bool aIsCancelable) { if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) { // Don't bother to fire any events, especially error events. + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT); return NS_OK; } @@ -1315,6 +1507,13 @@ class ImageRequestAutoLock { void nsImageLoadingContent::MakePendingRequestCurrent() { MOZ_ASSERT(mPendingRequest); + // If we have a pending request, we know that there is an existing current + // request with size information. If the pending request is for a different + // URI, then we need to reject any outstanding promises. + nsCOMPtr uri; + mPendingRequest->GetURI(getter_AddRefs(uri)); + MaybeAgeRequestGeneration(uri); + // Lock mCurrentRequest for the duration of this method. We do this because // PrepareCurrentRequest() might unlock mCurrentRequest. If mCurrentRequest // and mPendingRequest are both requests for the same image, unlocking @@ -1408,6 +1607,12 @@ bool nsImageLoadingContent::HaveSize(imgIRequest* aImage) { return (NS_SUCCEEDED(rv) && (status & imgIRequest::STATUS_SIZE_AVAILABLE)); } +void nsImageLoadingContent::NotifyOwnerDocumentActivityChanged() { + if (!GetOurOwnerDoc()->IsCurrentActiveDocument()) { + RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT); + } +} + void nsImageLoadingContent::BindToTree(Document* aDocument, nsIContent* aParent, nsIContent* aBindingParent) { // We may be getting connected, if so our image should be tracked, diff --git a/dom/base/nsImageLoadingContent.h b/dom/base/nsImageLoadingContent.h index e422dab9244b..6f02cffaf775 100644 --- a/dom/base/nsImageLoadingContent.h +++ b/dom/base/nsImageLoadingContent.h @@ -23,6 +23,7 @@ #include "mozilla/ErrorResult.h" #include "nsIContentPolicy.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/Promise.h" #include "mozilla/net/ReferrerPolicy.h" #include "nsAttrValue.h" @@ -82,6 +83,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent { */ void SetSyncDecodingHint(bool aHint); + /** + * Notify us that the document state has changed. Called by nsDocument so that + * we may reject any promises which require the document to be active. + */ + void NotifyOwnerDocumentActivityChanged(); + protected: enum ImageLoadType { // Most normal image loads @@ -230,6 +237,18 @@ class nsImageLoadingContent : public nsIImageLoadingContent { uint32_t NaturalWidth(); uint32_t NaturalHeight(); + /** + * Create a promise and queue a microtask which will ensure the current + * request (after any pending loads are applied) has requested a full decode. + * The promise is fulfilled once the request has a fully decoded surface that + * is available for drawing, or an error condition occurrs (e.g. broken image, + * current request is updated, etc). + * + * https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode + */ + already_AddRefed QueueDecodeAsync( + mozilla::ErrorResult& aRv); + enum class ImageDecodingType : uint8_t { Auto, Async, @@ -240,6 +259,38 @@ class nsImageLoadingContent : public nsIImageLoadingContent { static const nsAttrValue::EnumTable* kDecodingTableDefault; private: + /** + * Enqueue and/or fulfill a promise created by QueueDecodeAsync. + */ + void DecodeAsync(RefPtr&& aPromise, + uint32_t aRequestGeneration); + + /** + * Attempt to resolve all queued promises based on the state of the current + * request. If the current request does not yet have all of the encoded data, + * or the decoding has not yet completed, it will return without changing the + * promise states. + */ + void MaybeResolveDecodePromises(); + + /** + * Reject all queued promises with the given status. + */ + void RejectDecodePromises(nsresult aStatus); + + /** + * Age the generation counter if we have a new current request with a + * different URI. If the generation counter is aged, then all queued promises + * will also be rejected. + */ + void MaybeAgeRequestGeneration(nsIURI* aNewURI); + + /** + * Deregister as an observer for the owner document's activity notifications + * if we have no outstanding decode promises. + */ + void MaybeDeregisterActivityObserver(); + /** * Struct used to manage the native image observers. */ @@ -483,6 +534,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent { */ nsTArray> mScriptedObservers; + /** + * Promises created by QueueDecodeAsync that are still waiting to be + * fulfilled by the image being fully decoded. + */ + nsTArray> mDecodePromises; + /** * When mIsImageStateForced is true, this holds the ImageState that we'll * return in ImageState(). @@ -491,6 +548,23 @@ class nsImageLoadingContent : public nsIImageLoadingContent { mozilla::TimeStamp mMostRecentRequestChange; + /** + * Total number of outstanding decode promises, including those stored in + * mDecodePromises and those embedded in runnables waiting to be enqueued. + * This is used to determine whether we need to register as an observer for + * document activity notifications. + */ + size_t mOutstandingDecodePromises; + + /** + * An incrementing counter representing the current request generation; + * Each time mCurrentRequest is modified with a different URI, this will + * be incremented. Each QueueDecodeAsync call will cache the generation + * of the current request so that when it is processed, it knows if it + * should have rejected because the request changed. + */ + uint32_t mRequestGeneration; + int16_t mImageBlockingStatus; bool mLoadingEnabled : 1; diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index 2e2ede74dca2..811a607a0152 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -499,6 +499,16 @@ already_AddRefed nsNodeUtils::CloneAndAdopt( nsObjectLoadingContent* olc = static_cast(objectLoadingContent.get()); olc->NotifyOwnerDocumentActivityChanged(); + } else { + // HTMLImageElement::FromNode is insufficient since we need this for + // as well. + nsCOMPtr imageLoadingContent( + do_QueryInterface(aNode)); + if (imageLoadingContent) { + auto ilc = + static_cast(imageLoadingContent.get()); + ilc->NotifyOwnerDocumentActivityChanged(); + } } } diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index f15d358c36a2..38b2fc5ac946 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -927,6 +927,7 @@ void nsObjectLoadingContent::NotifyOwnerDocumentActivityChanged() { if (mInstanceOwner || mInstantiating) { QueueCheckPluginStopEvent(); } + nsImageLoadingContent::NotifyOwnerDocumentActivityChanged(); } // nsIRequestObserver diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index b4c8d758da78..8dc7ee96aeec 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -191,6 +191,10 @@ void HTMLImageElement::GetDecoding(nsAString& aValue) { GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue); } +already_AddRefed HTMLImageElement::Decode(ErrorResult& aRv) { + return nsImageLoadingContent::QueueDecodeAsync(aRv); +} + bool HTMLImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, const nsAString& aValue, nsIPrincipal* aMaybeScriptedPrincipal, diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h index d6acf914218b..dc96a64163d1 100644 --- a/dom/html/HTMLImageElement.h +++ b/dom/html/HTMLImageElement.h @@ -180,6 +180,8 @@ class HTMLImageElement final : public nsGenericHTMLElement, } void GetDecoding(nsAString& aValue); + already_AddRefed Decode(ErrorResult& aRv); + net::ReferrerPolicy GetImageReferrerPolicy() override { return GetReferrerPolicyAsEnum(); } diff --git a/dom/localstorage/ActorsParent.cpp b/dom/localstorage/ActorsParent.cpp index c1afc10c32f9..f5e1a8411ce2 100644 --- a/dom/localstorage/ActorsParent.cpp +++ b/dom/localstorage/ActorsParent.cpp @@ -2170,8 +2170,12 @@ class LSRequestBase : public DatastoreOperationBase, private: void SendReadyMessage(); + nsresult SendReadyMessageInternal(); + void Finish(); + void FinishInternal(); + void SendResults(); protected: @@ -5703,27 +5707,49 @@ void LSRequestBase::SendReadyMessage() { MaybeSetFailureCode(NS_ERROR_FAILURE); } - if (MayProceed()) { - Unused << SendReady(); + nsresult rv = SendReadyMessageInternal(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MaybeSetFailureCode(rv); - mState = State::WaitingForFinish; - - mWaitingForFinish = true; - } else { - Cleanup(); - - mState = State::Completed; + FinishInternal(); } } +nsresult LSRequestBase::SendReadyMessageInternal() { + AssertIsOnOwningThread(); + MOZ_ASSERT(mState == State::SendingReadyMessage); + + if (!MayProceed()) { + return NS_ERROR_FAILURE; + } + + if (NS_WARN_IF(!SendReady())) { + return NS_ERROR_FAILURE; + } + + mState = State::WaitingForFinish; + + mWaitingForFinish = true; + + return NS_OK; +} + void LSRequestBase::Finish() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::WaitingForFinish); - mState = State::SendingResults; - mWaitingForFinish = false; + FinishInternal(); +} + +void LSRequestBase::FinishInternal() { + AssertIsOnOwningThread(); + MOZ_ASSERT(mState == State::SendingReadyMessage || + mState == State::WaitingForFinish); + + mState = State::SendingResults; + // This LSRequestBase can only be held alive by the IPDL. Run() can end up // with clearing that last reference. So we need to add a self reference here. RefPtr kungFuDeathGrip = this; diff --git a/dom/svg/SVGImageElement.cpp b/dom/svg/SVGImageElement.cpp index 82b978e683cf..8d64e5c54892 100644 --- a/dom/svg/SVGImageElement.cpp +++ b/dom/svg/SVGImageElement.cpp @@ -101,6 +101,10 @@ void SVGImageElement::GetDecoding(nsAString& aValue) { GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue); } +already_AddRefed SVGImageElement::Decode(ErrorResult& aRv) { + return nsImageLoadingContent::QueueDecodeAsync(aRv); +} + //---------------------------------------------------------------------- nsresult SVGImageElement::LoadSVGImage(bool aForce, bool aNotify) { diff --git a/dom/svg/SVGImageElement.h b/dom/svg/SVGImageElement.h index 0702eaffff21..989efcd2118b 100644 --- a/dom/svg/SVGImageElement.h +++ b/dom/svg/SVGImageElement.h @@ -93,6 +93,8 @@ class SVGImageElement : public SVGImageElementBase, } void GetDecoding(nsAString& aValue); + already_AddRefed Decode(ErrorResult& aRv); + protected: nsresult LoadSVGImage(bool aForce, bool aNotify); diff --git a/dom/webidl/HTMLImageElement.webidl b/dom/webidl/HTMLImageElement.webidl index 4899f32f3e11..4b73f77eb24b 100644 --- a/dom/webidl/HTMLImageElement.webidl +++ b/dom/webidl/HTMLImageElement.webidl @@ -42,6 +42,8 @@ interface HTMLImageElement : HTMLElement { readonly attribute unsigned long naturalWidth; readonly attribute unsigned long naturalHeight; readonly attribute boolean complete; + [NewObject] + Promise decode(); }; // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis diff --git a/dom/webidl/SVGImageElement.webidl b/dom/webidl/SVGImageElement.webidl index 4ba236bed470..eeaf66f1a90f 100644 --- a/dom/webidl/SVGImageElement.webidl +++ b/dom/webidl/SVGImageElement.webidl @@ -23,6 +23,8 @@ interface SVGImageElement : SVGGraphicsElement { readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; [CEReactions, SetterThrows] attribute DOMString decoding; + [NewObject] + Promise decode(); }; SVGImageElement implements MozImageLoadingContent; diff --git a/gfx/wr/Cargo.lock b/gfx/wr/Cargo.lock index b271b8f9c1cb..e18c6ddd7d67 100644 --- a/gfx/wr/Cargo.lock +++ b/gfx/wr/Cargo.lock @@ -143,7 +143,7 @@ name = "cgl" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -370,7 +370,7 @@ name = "direct-composition" version = "0.1.0" dependencies = [ "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "webrender 0.60.0", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -569,7 +569,7 @@ dependencies = [ [[package]] name = "gleam" -version = "0.6.15" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1640,7 +1640,7 @@ dependencies = [ "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1676,7 +1676,7 @@ dependencies = [ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender 0.60.0", @@ -1793,7 +1793,7 @@ dependencies = [ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", "font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1940,7 +1940,7 @@ dependencies = [ "checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c" "checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd" "checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a" -"checksum gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "43edfa3a4321024d7dac1625cf154ef0c16996a6a384d066480e306ebd39fecc" +"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5" "checksum glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70c5fe78efbd5a3b243a804ea1032053c584510f8822819f94cfb29b2100317" "checksum half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d5c5f71a723d10dfc58927cbed37c3071a50afc7f073d86fd7d3e5727db890f" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" diff --git a/gfx/wr/webrender/Cargo.toml b/gfx/wr/webrender/Cargo.toml index c9a647f182d3..fa72e784f48a 100644 --- a/gfx/wr/webrender/Cargo.toml +++ b/gfx/wr/webrender/Cargo.toml @@ -29,7 +29,7 @@ byteorder = "1.0" cfg-if = "0.1.2" cstr = "0.1.2" fxhash = "0.2.1" -gleam = "0.6.14" +gleam = "0.6.16" image = { optional = true, version = "0.21" } lazy_static = "1" log = "0.4" diff --git a/gfx/wr/webrender/src/device/query_gl.rs b/gfx/wr/webrender/src/device/query_gl.rs index 1ed30c8b6189..f770bb92bce0 100644 --- a/gfx/wr/webrender/src/device/query_gl.rs +++ b/gfx/wr/webrender/src/device/query_gl.rs @@ -8,6 +8,12 @@ use std::rc::Rc; use device::GpuFrameId; +#[derive(Copy, Clone, Debug)] +pub enum GpuDebugMethod { + None, + MarkerEXT, + KHR, +} pub trait NamedTag { fn get_label(&self) -> &str; @@ -69,18 +75,18 @@ pub struct GpuFrameProfile { samplers: QuerySet>, frame_id: GpuFrameId, inside_frame: bool, - ext_debug_marker: bool + debug_method: GpuDebugMethod, } impl GpuFrameProfile { - fn new(gl: Rc, ext_debug_marker: bool) -> Self { + fn new(gl: Rc, debug_method: GpuDebugMethod) -> Self { GpuFrameProfile { gl, timers: QuerySet::new(), samplers: QuerySet::new(), frame_id: GpuFrameId::new(0), inside_frame: false, - ext_debug_marker + debug_method } } @@ -140,7 +146,7 @@ impl GpuFrameProfile { fn start_timer(&mut self, tag: T) -> GpuTimeQuery { self.finish_timer(); - let marker = GpuMarker::new(&self.gl, tag.get_label(), self.ext_debug_marker); + let marker = GpuMarker::new(&self.gl, tag.get_label(), self.debug_method); if let Some(query) = self.timers.add(GpuTimer { tag, time_ns: 0 }) { self.gl.begin_query(gl::TIME_ELAPSED, query); @@ -186,21 +192,21 @@ pub struct GpuProfiler { gl: Rc, frames: Vec>, next_frame: usize, - ext_debug_marker: bool + debug_method: GpuDebugMethod } impl GpuProfiler { - pub fn new(gl: Rc, ext_debug_marker: bool) -> Self { + pub fn new(gl: Rc, debug_method: GpuDebugMethod) -> Self { const MAX_PROFILE_FRAMES: usize = 4; let frames = (0 .. MAX_PROFILE_FRAMES) - .map(|_| GpuFrameProfile::new(Rc::clone(&gl), ext_debug_marker)) + .map(|_| GpuFrameProfile::new(Rc::clone(&gl), debug_method)) .collect(); GpuProfiler { gl, next_frame: 0, frames, - ext_debug_marker + debug_method } } @@ -263,41 +269,52 @@ impl GpuProfiler { } pub fn start_marker(&mut self, label: &str) -> GpuMarker { - GpuMarker::new(&self.gl, label, self.ext_debug_marker) + GpuMarker::new(&self.gl, label, self.debug_method) } pub fn place_marker(&mut self, label: &str) { - GpuMarker::fire(&self.gl, label, self.ext_debug_marker) + GpuMarker::fire(&self.gl, label, self.debug_method) } } #[must_use] pub struct GpuMarker { - gl: Option> + gl: Option<(Rc, GpuDebugMethod)>, } impl GpuMarker { - fn new(gl: &Rc, message: &str, ext_debug_marker: bool) -> Self { - let gl = if ext_debug_marker { - gl.push_group_marker_ext(message); - Some(Rc::clone(gl)) - } else { - None + fn new(gl: &Rc, message: &str, debug_method: GpuDebugMethod) -> Self { + let gl = match debug_method { + GpuDebugMethod::KHR => { + gl.push_debug_group_khr(gl::DEBUG_SOURCE_APPLICATION, 0, message); + Some((Rc::clone(gl), debug_method)) + }, + GpuDebugMethod::MarkerEXT => { + gl.push_group_marker_ext(message); + Some((Rc::clone(gl), debug_method)) + }, + GpuDebugMethod::None => None, }; GpuMarker { gl } } - fn fire(gl: &Rc, message: &str, ext_debug_marker: bool) { - if ext_debug_marker { - gl.insert_event_marker_ext(message); - } + fn fire(gl: &Rc, message: &str, debug_method: GpuDebugMethod) { + match debug_method { + GpuDebugMethod::KHR => gl.debug_message_insert_khr(gl::DEBUG_SOURCE_APPLICATION, gl::DEBUG_TYPE_MARKER, 0, gl::DEBUG_SEVERITY_NOTIFICATION, message), + GpuDebugMethod::MarkerEXT => gl.insert_event_marker_ext(message), + GpuDebugMethod::None => {} + }; } } impl Drop for GpuMarker { fn drop(&mut self) { - if let Some(ref gl) = self.gl { - gl.pop_group_marker_ext(); + if let Some((ref gl, debug_method)) = self.gl { + match debug_method { + GpuDebugMethod::KHR => gl.pop_debug_group_khr(), + GpuDebugMethod::MarkerEXT => gl.pop_group_marker_ext(), + GpuDebugMethod::None => {} + }; } } } diff --git a/gfx/wr/webrender/src/renderer.rs b/gfx/wr/webrender/src/renderer.rs index fb594fb51b92..c5b3cad1b1cb 100644 --- a/gfx/wr/webrender/src/renderer.rs +++ b/gfx/wr/webrender/src/renderer.rs @@ -75,7 +75,7 @@ use prim_store::DeferredResolve; use profiler::{BackendProfileCounters, FrameProfileCounters, TimeProfileCounter, GpuProfileTag, RendererProfileCounters, RendererProfileTimers}; use profiler::{Profiler, ChangeIndicator}; -use device::query::GpuProfiler; +use device::query::{GpuProfiler, GpuDebugMethod}; use rayon::{ThreadPool, ThreadPoolBuilder}; use record::ApiRecordingReceiver; use render_backend::{FrameId, RenderBackend}; @@ -2339,8 +2339,17 @@ impl Renderer { } })?; - let ext_debug_marker = device.supports_extension("GL_EXT_debug_marker"); - let gpu_profile = GpuProfiler::new(Rc::clone(device.rc_gl()), ext_debug_marker); + let debug_support = if device.supports_extension("GL_KHR_debug") { + GpuDebugMethod::KHR + } else if device.supports_extension("GL_EXT_debug_marker") { + GpuDebugMethod::MarkerEXT + } else { + GpuDebugMethod::None + }; + + info!("using {:?}", debug_support); + + let gpu_profile = GpuProfiler::new(Rc::clone(device.rc_gl()), debug_support); #[cfg(feature = "capture")] let read_fbo = device.create_fbo(); diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp index 4de8e96f2446..3881846ec513 100644 --- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -225,6 +225,8 @@ DynamicImage::StartDecoding(uint32_t aFlags) { return NS_OK; } bool DynamicImage::StartDecodingWithResult(uint32_t aFlags) { return true; } +bool DynamicImage::RequestDecodeWithResult(uint32_t aFlags) { return true; } + NS_IMETHODIMP DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { return NS_OK; diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp index ee9d26ba398d..04a21db02840 100644 --- a/image/ImageWrapper.cpp +++ b/image/ImageWrapper.cpp @@ -202,6 +202,10 @@ bool ImageWrapper::StartDecodingWithResult(uint32_t aFlags) { return mInnerImage->StartDecodingWithResult(aFlags); } +bool ImageWrapper::RequestDecodeWithResult(uint32_t aFlags) { + return mInnerImage->RequestDecodeWithResult(aFlags); +} + NS_IMETHODIMP ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { return mInnerImage->RequestDecodeForSize(aSize, aFlags); diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 8466f4622783..ab293ed99e2e 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -339,9 +339,12 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags, return LookupResult(MatchType::NOT_FOUND); } + const bool syncDecode = aFlags & FLAG_SYNC_DECODE; + const bool avoidRedecode = aFlags & FLAG_AVOID_REDECODE_FOR_SIZE; if (result.Type() == MatchType::NOT_FOUND || - result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND || - ((aFlags & FLAG_SYNC_DECODE) && !result)) { + (result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND && + !avoidRedecode) || + (syncDecode && !avoidRedecode && !result)) { // We don't have a copy of this frame, and there's no decoder working on // one. (Or we're sync decoding and the existing decoder hasn't even started // yet.) Trigger decoding so it'll be available next time. @@ -353,15 +356,14 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags, // The surface cache may suggest the preferred size we are supposed to // decode at. This should only happen if we accept substitutions. if (!result.SuggestedSize().IsEmpty()) { - MOZ_ASSERT(!(aFlags & FLAG_SYNC_DECODE) && - (aFlags & FLAG_HIGH_QUALITY_SCALING)); + MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING)); requestedSize = result.SuggestedSize(); } bool ranSync = Decode(requestedSize, aFlags, aPlaybackType); // If we can or did sync decode, we should already have the frame. - if (ranSync || (aFlags & FLAG_SYNC_DECODE)) { + if (ranSync || syncDecode) { result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed); } @@ -375,7 +377,7 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags, // Sync decoding guarantees that we got the frame, but if it's owned by an // async decoder that's currently running, the contents of the frame may not // be available yet. Make sure we get everything. - if (mAllSourceData && (aFlags & FLAG_SYNC_DECODE)) { + if (mAllSourceData && syncDecode) { result.Surface()->WaitUntilFinished(); } @@ -1078,6 +1080,18 @@ bool RasterImage::StartDecodingWithResult(uint32_t aFlags) { return surface && surface->IsFinished(); } +bool RasterImage::RequestDecodeWithResult(uint32_t aFlags) { + MOZ_ASSERT(NS_IsMainThread()); + + if (mError) { + return false; + } + + uint32_t flags = aFlags | FLAG_ASYNC_NOTIFY; + DrawableSurface surface = RequestDecodeForSizeInternal(mSize, flags); + return surface && surface->IsFinished(); +} + NS_IMETHODIMP RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) { MOZ_ASSERT(NS_IsMainThread()); diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 6f5506194963..e0689485f239 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -1236,6 +1236,11 @@ bool VectorImage::StartDecodingWithResult(uint32_t aFlags) { return mIsFullyLoaded; } +bool VectorImage::RequestDecodeWithResult(uint32_t aFlags) { + // SVG images are ready to draw when they are loaded + return mIsFullyLoaded; +} + NS_IMETHODIMP VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { // Nothing to do for SVG images, though in theory we could rasterize to the diff --git a/image/imgIContainer.idl b/image/imgIContainer.idl index 7ab8ae63a419..e7e75adf2a3e 100644 --- a/image/imgIContainer.idl +++ b/image/imgIContainer.idl @@ -209,6 +209,10 @@ interface imgIContainer : nsISupports * (a "window into SVG space") based on the border image area, and we need to * be sure we don't subsequently scale that viewport in a way that distorts * its contents by stretching them more in one dimension than the other. + * + * FLAG_AVOID_REDECODE_FOR_SIZE: If there is already a raster surface + * available for this image, but it is not the same size as requested, skip + * starting a new decode for said size. */ const unsigned long FLAG_NONE = 0x0; const unsigned long FLAG_SYNC_DECODE = 0x1; @@ -222,6 +226,7 @@ interface imgIContainer : nsISupports const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x100; const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x200; const unsigned long FLAG_FORCE_UNIFORM_SCALING = 0x400; + const unsigned long FLAG_AVOID_REDECODE_FOR_SIZE = 0x800; /** * A constant specifying the default set of decode flags (i.e., the default @@ -472,6 +477,17 @@ interface imgIContainer : nsISupports */ [noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags); + /* + * This method triggers decoding for an image, but unlike startDecoding() it + * enables the caller to provide more detailed information about the decode + * request. + * + * @param aFlags Flags of the FLAG_* variety. + * @return True there is a surface that satisfies the request and it is + * fully decoded, else false. + */ + [noscript, notxpcom] boolean requestDecodeWithResult(in uint32_t aFlags); + /* * This method triggers decoding for an image, but unlike startDecoding() it * enables the caller to provide more detailed information about the decode diff --git a/image/imgIRequest.idl b/image/imgIRequest.idl index cebe9ad749cb..9f683ea47dcd 100644 --- a/image/imgIRequest.idl +++ b/image/imgIRequest.idl @@ -163,9 +163,23 @@ interface imgIRequest : nsIRequest /** * Exactly like startDecoding above except returns whether the current frame * of the image is complete or not. + * + * @param aFlags Flags of the FLAG_* variety. Only FLAG_ASYNC_NOTIFY + * is accepted; all others are ignored. */ [noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags); + /** + * This method triggers decoding for an image, but unlike startDecoding() it + * enables the caller to provide more detailed information about the decode + * request. + * + * @param aFlags Flags of the FLAG_* variety. + * @return True there is a surface that satisfies the request and it is + * fully decoded, else false. + */ + [noscript, notxpcom] boolean requestDecodeWithResult(in uint32_t aFlags); + /** * Locks an image. If the image does not exist yet, locks it once it becomes * available. The lock persists for the lifetime of the imgIRequest (until diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp index fc35b3cd47c6..3f1a1ebb5d0f 100644 --- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -543,6 +543,24 @@ bool imgRequestProxy::StartDecodingWithResult(uint32_t aFlags) { return false; } +bool imgRequestProxy::RequestDecodeWithResult(uint32_t aFlags) { + if (IsValidating()) { + mDecodeRequested = true; + return false; + } + + RefPtr image = GetImage(); + if (image) { + return image->RequestDecodeWithResult(aFlags); + } + + if (GetOwner()) { + GetOwner()->StartDecoding(); + } + + return false; +} + NS_IMETHODIMP imgRequestProxy::LockImage() { mLockCount++; diff --git a/netwerk/dns/nsEffectiveTLDService.cpp b/netwerk/dns/nsEffectiveTLDService.cpp index 27a2d4a90960..463179037d55 100644 --- a/netwerk/dns/nsEffectiveTLDService.cpp +++ b/netwerk/dns/nsEffectiveTLDService.cpp @@ -42,11 +42,14 @@ nsEffectiveTLDService::nsEffectiveTLDService() : mIDNService(), mGraph(etld_dafsa::kDafsa) {} nsresult nsEffectiveTLDService::Init() { + if (gService) { + return NS_ERROR_ALREADY_INITIALIZED; + } + nsresult rv; mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; - MOZ_ASSERT(!gService); gService = this; RegisterWeakMemoryReporter(this); @@ -55,7 +58,10 @@ nsresult nsEffectiveTLDService::Init() { nsEffectiveTLDService::~nsEffectiveTLDService() { UnregisterWeakMemoryReporter(this); - gService = nullptr; + if (mIDNService) { + // Only clear gService if Init() finished successfully. + gService = nullptr; + } } // static diff --git a/netwerk/test/browser/browser.ini b/netwerk/test/browser/browser.ini index 6eb2acdebd52..ea7c51ef4f8c 100644 --- a/netwerk/test/browser/browser.ini +++ b/netwerk/test/browser/browser.ini @@ -5,6 +5,7 @@ support-files = redirect.sjs [browser_about_cache.js] +[browser_bug1535877.js] [browser_NetUtil.js] [browser_child_resource.js] skip-if = !crashreporter || (e10s && debug && os == "linux" && bits == 64) || debug # Bug 1370783 diff --git a/netwerk/test/browser/browser_bug1535877.js b/netwerk/test/browser/browser_bug1535877.js new file mode 100644 index 000000000000..5af97e2886c1 --- /dev/null +++ b/netwerk/test/browser/browser_bug1535877.js @@ -0,0 +1,11 @@ +"use strict"; + +add_task(_ => { + try { + Cc["@mozilla.org/network/effective-tld-service;1"] + .createInstance(Ci.nsISupports); + } catch (e) { + is(e.result, Cr.NS_ERROR_XPC_CI_RETURNED_FAILURE, + "Component creation as an instance fails with expected code"); + } +}); diff --git a/python/mozboot/mozboot/base.py b/python/mozboot/mozboot/base.py index 1f5316d62f8d..630b0472ef62 100644 --- a/python/mozboot/mozboot/base.py +++ b/python/mozboot/mozboot/base.py @@ -673,7 +673,7 @@ class BaseBootstrapper(object): print('Your version of Rust (%s) is new enough.' % version) rustup = self.which('rustup', cargo_bin) if rustup: - self.ensure_rust_targets(rustup, version) + self.ensure_rust_targets(rustup) return if version: @@ -697,7 +697,7 @@ class BaseBootstrapper(object): print('Will try to install Rust.') self.install_rust() - def ensure_rust_targets(self, rustup, rust_version): + def ensure_rust_targets(self, rustup): """Make sure appropriate cross target libraries are installed.""" target_list = subprocess.check_output([rustup, 'target', 'list']) targets = [line.split()[0] for line in target_list.splitlines() @@ -712,11 +712,7 @@ class BaseBootstrapper(object): if 'mobile_android' in self.application: # Let's add the most common targets. - if LooseVersion(rust_version) < '1.33': - arm_target = 'armv7-linux-androideabi' - else: - arm_target = 'thumbv7neon-linux-androideabi' - android_targets = (arm_target, + android_targets = ('thumbv7neon-linux-androideabi', 'aarch64-linux-android', 'i686-linux-android', 'x86_64-linux-android', ) diff --git a/testing/web-platform/meta/fetch/cross-origin-resource-policy/fetch.any.js.ini b/testing/web-platform/meta/fetch/cross-origin-resource-policy/fetch.any.js.ini index c6ad5b558690..c55217a2cc8d 100644 --- a/testing/web-platform/meta/fetch/cross-origin-resource-policy/fetch.any.js.ini +++ b/testing/web-platform/meta/fetch/cross-origin-resource-policy/fetch.any.js.ini @@ -45,6 +45,7 @@ [fetch.any.serviceworker.html] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1540914 [Valid cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.] expected: FAIL diff --git a/testing/web-platform/meta/html/dom/interfaces.https.html.ini b/testing/web-platform/meta/html/dom/interfaces.https.html.ini index 392a5fb6eca3..073a88fb68c7 100644 --- a/testing/web-platform/meta/html/dom/interfaces.https.html.ini +++ b/testing/web-platform/meta/html/dom/interfaces.https.html.ini @@ -477,15 +477,6 @@ prefs: [dom.security.featurePolicy.enabled:true] [HTMLBodyElement interface: document.createElement("body") must inherit property "onunhandledrejection" with the proper type] expected: FAIL - [HTMLImageElement interface: operation decode()] - expected: FAIL - - [HTMLImageElement interface: document.createElement("img") must inherit property "decode()" with the proper type] - expected: FAIL - - [HTMLImageElement interface: new Image() must inherit property "decode()" with the proper type] - expected: FAIL - [HTMLIFrameElement interface: attribute allowUserMedia] expected: FAIL diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-iframe.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-iframe.html.ini index d2289ddcbda6..48c489728cac 100644 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-iframe.html.ini +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-iframe.html.ini @@ -1,20 +1,8 @@ [image-decode-iframe.html] - expected: - ERROR - [(misc) Decode from removed iframe fails (loaded img)] - expected: TIMEOUT - - [(misc) Decode from removed iframe fails (img not loaded)] - expected: NOTRUN - - [(misc) Decode from iframe, later removed, fails (img not loaded)] - expected: NOTRUN - - [HTMLImageElement.prototype.decode(), iframe tests. Decode from removed iframe fails (loaded img)] - expected: TIMEOUT + expected: TIMEOUT [HTMLImageElement.prototype.decode(), iframe tests. Decode from removed iframe fails (img not loaded)] - expected: NOTRUN + expected: TIMEOUT [HTMLImageElement.prototype.decode(), iframe tests. Decode from iframe, later removed, fails (img not loaded)] expected: NOTRUN diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html.ini deleted file mode 100644 index c6ccbbea7362..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html.ini +++ /dev/null @@ -1,19 +0,0 @@ -[image-decode-path-changes-svg.tentative.html] - [SVGImageElement.prototype.decode(), href mutation tests. xlink:href changes fail decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), href mutation tests. href changes fail decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), href mutation tests. xlink:href changes fail decode; following good decode succeeds.] - expected: FAIL - - [SVGImageElement.prototype.decode(), href mutation tests. href changes fail decode; following good decode succeeds.] - expected: FAIL - - [SVGImageElement.prototype.decode(), href mutation tests. xlink:href changes fail decode; following bad decode fails.] - expected: FAIL - - [SVGImageElement.prototype.decode(), href mutation tests. href changes fail decode; following bad decode fails.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes.html.ini deleted file mode 100644 index d8bf52762725..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes.html.ini +++ /dev/null @@ -1,49 +0,0 @@ -[image-decode-path-changes.html] - [(src) Path changes fail decode.] - expected: FAIL - - [(src) Path changes fail decode; following good decode succeeds.] - expected: FAIL - - [(src) Path changes fail decode; following bad decode fails.] - expected: FAIL - - [(src) Path changes to the same path succeed.] - expected: FAIL - - [(srcset) Path changes fail decode.] - expected: FAIL - - [(srcset) Path changes fail decode; following good decode succeeds.] - expected: FAIL - - [(srcset) Path changes fail decode; following bad decode fails.] - expected: FAIL - - [(srcset) Path changes to the same path succeed.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode; following good png decode succeeds.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode; following good svg decode succeeds.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode; following bad decode fails.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes to the same path succeed.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. srcset changes fail decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. srcset changes fail decode; following good decode succeeds.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), src/srcset mutation tests. srcset changes fail decode; following bad decode fails.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-picture.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-picture.html.ini deleted file mode 100644 index 3e10b4957e4d..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-picture.html.ini +++ /dev/null @@ -1,25 +0,0 @@ -[image-decode-picture.html] - [HTMLImageElement.prototype.decode(), picture tests. Image with PNG source decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Image with multiple sources decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Image with PNG data URL source decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Image with SVG source decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Non-existent source fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Corrupt image in src fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Image without srcset fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), picture tests. Multiple decodes for images with src succeed.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-svg.tentative.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-svg.tentative.html.ini deleted file mode 100644 index be82788fa59d..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-svg.tentative.html.ini +++ /dev/null @@ -1,40 +0,0 @@ -[image-decode-svg.tentative.html] - [SVGImageElement.prototype.decode(), basic tests. Image with PNG xlink:href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image with PNG href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image with PNG data URL xlink:href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image with PNG data URL href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image with SVG xlink:href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image with SVG href decodes with undefined.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Non-existent xlink:href fails decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Non-existent href fails decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Corrupt image in xlink:href fails decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Corrupt image in href fails decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Image without xlink:href or href fails decode.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Multiple decodes with a xlink:href succeed.] - expected: FAIL - - [SVGImageElement.prototype.decode(), basic tests. Multiple decodes with a href succeed.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html.ini deleted file mode 100644 index 07344310126b..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[image-decode-with-quick-attach-svg.tentative.html] - [SVGImageElement.prototype.decode(), attach to DOM before promise resolves.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html.ini deleted file mode 100644 index 27790990a427..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[image-decode-with-quick-attach.html] - [HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode.html.ini deleted file mode 100644 index 1abe9869734a..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/decode/image-decode.html.ini +++ /dev/null @@ -1,76 +0,0 @@ -[image-decode.html] - [(src) PNG image decodes with undefined.] - expected: FAIL - - [(src) PNG url image decodes with undefined.] - expected: FAIL - - [(src) SVG image decodes with undefined.] - expected: FAIL - - [(src) Non-existent path fails decode.] - expected: FAIL - - [(src) Corrupt image fails decode.] - expected: FAIL - - [(src) Path-less image fails decode.] - expected: FAIL - - [(src) Multiple decodes succeed.] - expected: FAIL - - [(srcset) PNG image decodes with undefined.] - expected: FAIL - - [(srcset) SVG image decodes with undefined.] - expected: FAIL - - [(srcset) Non-existent path fails decode.] - expected: FAIL - - [(srcset) Multiple decodes succeed.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image with PNG src decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image with PNG data URL src decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image with SVG src decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Non-existent src fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Inactive document fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Adopted active image into inactive document fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Adopted inactive image into active document succeeds.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Corrupt image in src fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image without src/srcset fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Multiple decodes for images with src succeed.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image with PNG srcset decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Image with SVG srcset decodes with undefined.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Non-existent srcset fails decode.] - expected: FAIL - - [HTMLImageElement.prototype.decode(), basic tests. Multiple decodes for images with srcset succeed.] - expected: FAIL - diff --git a/third_party/rust/gleam/.cargo-checksum.json b/third_party/rust/gleam/.cargo-checksum.json index c912964f7684..1e2b6e94ce29 100644 --- a/third_party/rust/gleam/.cargo-checksum.json +++ b/third_party/rust/gleam/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"5e823cb4a829b626b7b9b603dac4d3a98debf5e83b91897ab9f186eed8f49d61","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"6ee689b1edfcd469dea669b0dc11ca89e0172c3b58bb82ff7a58acc94e1f7e88","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"e659b099df9c2ae39fc311aa649bbb8b96dfc7df8eba8f98b2eab34d5a368442","src/gl_fns.rs":"99693ea60d5867fea7d6f092e9fae6f2ff3d0be3c6f533257618261ccdfc6341","src/gles_fns.rs":"e28eadc5907dd963765574b21f68eb308674c7ec799b26896b86de9fee8c8eac","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"43edfa3a4321024d7dac1625cf154ef0c16996a6a384d066480e306ebd39fecc"} \ No newline at end of file +{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"6bf850af90d5a3828cf26170a161f2ed06fa3cf3783dce79d28fe6444654408e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"6ee689b1edfcd469dea669b0dc11ca89e0172c3b58bb82ff7a58acc94e1f7e88","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"2663b598573f7521d06f878229eee65434c831cf9fd4b543b4fcdd3bb1b281aa","src/gl_fns.rs":"239ace5607ee8dd4bcad35db0c4908469d7deb4841c162f736e404e1403980f7","src/gles_fns.rs":"51f25388f092242fb25bfe4861e70690006f4ac28e854d709ebb440cbef3df03","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"} \ No newline at end of file diff --git a/third_party/rust/gleam/Cargo.toml b/third_party/rust/gleam/Cargo.toml index f5a9ca84c5ce..463fc70ee9ab 100644 --- a/third_party/rust/gleam/Cargo.toml +++ b/third_party/rust/gleam/Cargo.toml @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "gleam" -version = "0.6.15" +version = "0.6.16" authors = ["The Servo Project Developers"] build = "build.rs" description = "Generated OpenGL bindings and wrapper for Servo." diff --git a/third_party/rust/gleam/src/gl.rs b/third_party/rust/gleam/src/gl.rs index 252ccfd51189..854b94abebaa 100644 --- a/third_party/rust/gleam/src/gl.rs +++ b/third_party/rust/gleam/src/gl.rs @@ -553,6 +553,9 @@ declare_gl_apis! { fn insert_event_marker_ext(&self, message: &str); fn push_group_marker_ext(&self, message: &str); fn pop_group_marker_ext(&self); + fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str); + fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str); + fn pop_debug_group_khr(&self); fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync; fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64); fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64); diff --git a/third_party/rust/gleam/src/gl_fns.rs b/third_party/rust/gleam/src/gl_fns.rs index 62a3de0b73a4..851f6f639cc3 100644 --- a/third_party/rust/gleam/src/gl_fns.rs +++ b/third_party/rust/gleam/src/gl_fns.rs @@ -1946,6 +1946,32 @@ impl Gl for GlFns { } } + fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) { + if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() { + unsafe { + self.ffi_gl_ + .DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _); + } + } + } + + fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) { + if self.ffi_gl_.PushDebugGroupKHR.is_loaded() { + unsafe { + self.ffi_gl_ + .PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _); + } + } + } + + fn pop_debug_group_khr(&self) { + if self.ffi_gl_.PopDebugGroupKHR.is_loaded() { + unsafe { + self.ffi_gl_.PopDebugGroupKHR(); + } + } + } + fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync { unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ } } diff --git a/third_party/rust/gleam/src/gles_fns.rs b/third_party/rust/gleam/src/gles_fns.rs index 61c7bfb1e4a0..9877e4744f70 100644 --- a/third_party/rust/gleam/src/gles_fns.rs +++ b/third_party/rust/gleam/src/gles_fns.rs @@ -1952,6 +1952,32 @@ impl Gl for GlesFns { } } + fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) { + if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() { + unsafe { + self.ffi_gl_ + .DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _); + } + } + } + + fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) { + if self.ffi_gl_.PushDebugGroupKHR.is_loaded() { + unsafe { + self.ffi_gl_ + .PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _); + } + } + } + + fn pop_debug_group_khr(&self) { + if self.ffi_gl_.PopDebugGroupKHR.is_loaded() { + unsafe { + self.ffi_gl_.PopDebugGroupKHR(); + } + } + } + fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync { unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ } } diff --git a/xpcom/base/ErrorList.py b/xpcom/base/ErrorList.py index 680a12106ecc..baf6d41dae71 100755 --- a/xpcom/base/ErrorList.py +++ b/xpcom/base/ErrorList.py @@ -642,6 +642,11 @@ with modules["DOM"]: # decoding process. errors["NS_ERROR_DOM_JS_DECODING_ERROR"] = FAILURE(1026) + # Image decode errors. + errors["NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT"] = FAILURE(1027) + errors["NS_ERROR_DOM_IMAGE_INVALID_REQUEST"] = FAILURE(1028) + errors["NS_ERROR_DOM_IMAGE_BROKEN"] = FAILURE(1029) + # May be used to indicate when e.g. setting a property value didn't # actually change the value, like for obj.foo = "bar"; obj.foo = "bar"; # the second assignment throws NS_SUCCESS_DOM_NO_OPERATION.