Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Daniel Varga 2019-04-03 09:15:08 +03:00
Родитель a4e3aa46bf 14dc5b7d8a
Коммит fcac8589b7
45 изменённых файлов: 593 добавлений и 313 удалений

8
Cargo.lock сгенерированный
Просмотреть файл

@ -1284,7 +1284,7 @@ dependencies = [
[[package]] [[package]]
name = "gleam" name = "gleam"
version = "0.6.15" version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"nsstring 0.1.0", "nsstring 0.1.0",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "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.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 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 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 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 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" "checksum guid_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87261686cc5e35b6584f4c2a430c2b153d8a92ab1ef820c16be34c1df8f5f58b"

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

@ -4301,6 +4301,13 @@ static void NotifyActivityChanged(nsISupports* aSupports, void* aUnused) {
do_QueryInterface(aSupports)); do_QueryInterface(aSupports));
if (objectDocumentActivity) { if (objectDocumentActivity) {
objectDocumentActivity->NotifyOwnerDocumentActivityChanged(); objectDocumentActivity->NotifyOwnerDocumentActivityChanged();
} else {
nsCOMPtr<nsIImageLoadingContent> imageLoadingContent(
do_QueryInterface(aSupports));
if (imageLoadingContent) {
auto ilc = static_cast<nsImageLoadingContent*>(imageLoadingContent.get());
ilc->NotifyOwnerDocumentActivityChanged();
}
} }
} }

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

@ -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, "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(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) 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)

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

@ -95,6 +95,8 @@ nsImageLoadingContent::nsImageLoadingContent()
: mCurrentRequestFlags(0), : mCurrentRequestFlags(0),
mPendingRequestFlags(0), mPendingRequestFlags(0),
mObserverList(nullptr), mObserverList(nullptr),
mOutstandingDecodePromises(0),
mRequestGeneration(0),
mImageBlockingStatus(nsIContentPolicy::ACCEPT), mImageBlockingStatus(nsIContentPolicy::ACCEPT),
mLoadingEnabled(true), mLoadingEnabled(true),
mIsImageStateForced(false), mIsImageStateForced(false),
@ -120,17 +122,21 @@ nsImageLoadingContent::nsImageLoadingContent()
void nsImageLoadingContent::DestroyImageLoadingContent() { void nsImageLoadingContent::DestroyImageLoadingContent() {
// Cancel our requests so they won't hold stale refs to us // Cancel our requests so they won't hold stale refs to us
// NB: Don't ask to discard the images here. // NB: Don't ask to discard the images here.
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST);
ClearCurrentRequest(NS_BINDING_ABORTED); ClearCurrentRequest(NS_BINDING_ABORTED);
ClearPendingRequest(NS_BINDING_ABORTED); ClearPendingRequest(NS_BINDING_ABORTED);
} }
nsImageLoadingContent::~nsImageLoadingContent() { nsImageLoadingContent::~nsImageLoadingContent() {
NS_ASSERTION(!mCurrentRequest && !mPendingRequest, MOZ_ASSERT(!mCurrentRequest && !mPendingRequest,
"DestroyImageLoadingContent not called"); "DestroyImageLoadingContent not called");
NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext, MOZ_ASSERT(!mObserverList.mObserver && !mObserverList.mNext,
"Observers still registered?"); "Observers still registered?");
NS_ASSERTION(mScriptedObservers.IsEmpty(), MOZ_ASSERT(mScriptedObservers.IsEmpty(),
"Scripted observers still registered?"); "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); return OnLoadComplete(aRequest, status);
} }
if (aType == imgINotificationObserver::FRAME_COMPLETE &&
mCurrentRequest == aRequest) {
MaybeResolveDecodePromises();
}
if (aType == imgINotificationObserver::DECODE_COMPLETE) { if (aType == imgINotificationObserver::DECODE_COMPLETE) {
nsCOMPtr<imgIContainer> container; nsCOMPtr<imgIContainer> container;
aRequest->GetImage(getter_AddRefs(container)); aRequest->GetImage(getter_AddRefs(container));
@ -260,6 +271,7 @@ nsresult nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest,
nsCOMPtr<nsINode> thisNode = nsCOMPtr<nsINode> thisNode =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this)); do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
SVGObserverUtils::InvalidateDirectRenderingObservers(thisNode->AsElement()); SVGObserverUtils::InvalidateDirectRenderingObservers(thisNode->AsElement());
MaybeResolveDecodePromises();
return NS_OK; return NS_OK;
} }
@ -334,6 +346,166 @@ void nsImageLoadingContent::SetLoadingEnabled(bool aLoadingEnabled) {
} }
} }
already_AddRefed<Promise> nsImageLoadingContent::QueueDecodeAsync(
ErrorResult& aRv) {
Document* doc = GetOurOwnerDoc();
RefPtr<Promise> 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<nsImageLoadingContent> mOwner;
RefPtr<Promise> mPromise;
uint32_t mRequestGeneration;
};
if (++mOutstandingDecodePromises == 1) {
MOZ_ASSERT(mDecodePromises.IsEmpty());
doc->RegisterActivityObserver(this);
}
auto task = MakeRefPtr<QueueDecodeTask>(this, promise, mRequestGeneration);
nsContentUtils::RunInStableState(task.forget());
return promise.forget();
}
void nsImageLoadingContent::DecodeAsync(RefPtr<Promise>&& 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<nsIURI> 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) { void nsImageLoadingContent::SetSyncDecodingHint(bool aHint) {
if (mSyncDecodingHint == aHint) { if (mSyncDecodingHint == aHint) {
return; return;
@ -786,6 +958,15 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
// Shouldn't that be done before the start of the load? // Shouldn't that be done before the start of the load?
// XXX what about shouldProcess? // 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<nsIURI> uri;
aChannel->GetOriginalURI(getter_AddRefs(uri));
MaybeAgeRequestGeneration(uri);
}
// Our state might change. Watch it. // Our state might change. Watch it.
AutoStateChanger changer(this, true); 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. // From this point on, our image state could change. Watch it.
AutoStateChanger changer(this, aNotify); AutoStateChanger changer(this, aNotify);
@ -1120,11 +1308,13 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) {
} else if (!mCurrentRequest) { } else if (!mCurrentRequest) {
// No current request means error, since we weren't disabled or suppressed // No current request means error, since we weren't disabled or suppressed
mBroken = true; mBroken = true;
RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN);
} else { } else {
uint32_t currentLoadStatus; uint32_t currentLoadStatus;
nsresult rv = mCurrentRequest->GetImageStatus(&currentLoadStatus); nsresult rv = mCurrentRequest->GetImageStatus(&currentLoadStatus);
if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) { if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) {
mBroken = true; mBroken = true;
RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN);
} else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) { } else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
mLoading = true; mLoading = true;
} }
@ -1135,6 +1325,7 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) {
} }
void nsImageLoadingContent::CancelImageRequests(bool aNotify) { void nsImageLoadingContent::CancelImageRequests(bool aNotify) {
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST);
AutoStateChanger changer(this, aNotify); AutoStateChanger changer(this, aNotify);
ClearPendingRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES)); ClearPendingRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES));
ClearCurrentRequest(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) { bool aIsCancelable) {
if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) { if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) {
// Don't bother to fire any events, especially error events. // Don't bother to fire any events, especially error events.
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT);
return NS_OK; return NS_OK;
} }
@ -1315,6 +1507,13 @@ class ImageRequestAutoLock {
void nsImageLoadingContent::MakePendingRequestCurrent() { void nsImageLoadingContent::MakePendingRequestCurrent() {
MOZ_ASSERT(mPendingRequest); 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<nsIURI> uri;
mPendingRequest->GetURI(getter_AddRefs(uri));
MaybeAgeRequestGeneration(uri);
// Lock mCurrentRequest for the duration of this method. We do this because // Lock mCurrentRequest for the duration of this method. We do this because
// PrepareCurrentRequest() might unlock mCurrentRequest. If mCurrentRequest // PrepareCurrentRequest() might unlock mCurrentRequest. If mCurrentRequest
// and mPendingRequest are both requests for the same image, unlocking // 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)); 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, void nsImageLoadingContent::BindToTree(Document* aDocument, nsIContent* aParent,
nsIContent* aBindingParent) { nsIContent* aBindingParent) {
// We may be getting connected, if so our image should be tracked, // We may be getting connected, if so our image should be tracked,

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

@ -23,6 +23,7 @@
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "nsIContentPolicy.h" #include "nsIContentPolicy.h"
#include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/net/ReferrerPolicy.h" #include "mozilla/net/ReferrerPolicy.h"
#include "nsAttrValue.h" #include "nsAttrValue.h"
@ -82,6 +83,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
*/ */
void SetSyncDecodingHint(bool aHint); 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: protected:
enum ImageLoadType { enum ImageLoadType {
// Most normal image loads // Most normal image loads
@ -230,6 +237,18 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
uint32_t NaturalWidth(); uint32_t NaturalWidth();
uint32_t NaturalHeight(); 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<mozilla::dom::Promise> QueueDecodeAsync(
mozilla::ErrorResult& aRv);
enum class ImageDecodingType : uint8_t { enum class ImageDecodingType : uint8_t {
Auto, Auto,
Async, Async,
@ -240,6 +259,38 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
static const nsAttrValue::EnumTable* kDecodingTableDefault; static const nsAttrValue::EnumTable* kDecodingTableDefault;
private: private:
/**
* Enqueue and/or fulfill a promise created by QueueDecodeAsync.
*/
void DecodeAsync(RefPtr<mozilla::dom::Promise>&& 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. * Struct used to manage the native image observers.
*/ */
@ -483,6 +534,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
*/ */
nsTArray<RefPtr<ScriptedImageObserver>> mScriptedObservers; nsTArray<RefPtr<ScriptedImageObserver>> mScriptedObservers;
/**
* Promises created by QueueDecodeAsync that are still waiting to be
* fulfilled by the image being fully decoded.
*/
nsTArray<RefPtr<mozilla::dom::Promise>> mDecodePromises;
/** /**
* When mIsImageStateForced is true, this holds the ImageState that we'll * When mIsImageStateForced is true, this holds the ImageState that we'll
* return in ImageState(). * return in ImageState().
@ -491,6 +548,23 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
mozilla::TimeStamp mMostRecentRequestChange; 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; int16_t mImageBlockingStatus;
bool mLoadingEnabled : 1; bool mLoadingEnabled : 1;

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

@ -499,6 +499,16 @@ already_AddRefed<nsINode> nsNodeUtils::CloneAndAdopt(
nsObjectLoadingContent* olc = nsObjectLoadingContent* olc =
static_cast<nsObjectLoadingContent*>(objectLoadingContent.get()); static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
olc->NotifyOwnerDocumentActivityChanged(); olc->NotifyOwnerDocumentActivityChanged();
} else {
// HTMLImageElement::FromNode is insufficient since we need this for
// <svg:image> as well.
nsCOMPtr<nsIImageLoadingContent> imageLoadingContent(
do_QueryInterface(aNode));
if (imageLoadingContent) {
auto ilc =
static_cast<nsImageLoadingContent*>(imageLoadingContent.get());
ilc->NotifyOwnerDocumentActivityChanged();
}
} }
} }

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

@ -927,6 +927,7 @@ void nsObjectLoadingContent::NotifyOwnerDocumentActivityChanged() {
if (mInstanceOwner || mInstantiating) { if (mInstanceOwner || mInstantiating) {
QueueCheckPluginStopEvent(); QueueCheckPluginStopEvent();
} }
nsImageLoadingContent::NotifyOwnerDocumentActivityChanged();
} }
// nsIRequestObserver // nsIRequestObserver

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

@ -191,6 +191,10 @@ void HTMLImageElement::GetDecoding(nsAString& aValue) {
GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue); GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue);
} }
already_AddRefed<Promise> HTMLImageElement::Decode(ErrorResult& aRv) {
return nsImageLoadingContent::QueueDecodeAsync(aRv);
}
bool HTMLImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, bool HTMLImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal, nsIPrincipal* aMaybeScriptedPrincipal,

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

@ -180,6 +180,8 @@ class HTMLImageElement final : public nsGenericHTMLElement,
} }
void GetDecoding(nsAString& aValue); void GetDecoding(nsAString& aValue);
already_AddRefed<Promise> Decode(ErrorResult& aRv);
net::ReferrerPolicy GetImageReferrerPolicy() override { net::ReferrerPolicy GetImageReferrerPolicy() override {
return GetReferrerPolicyAsEnum(); return GetReferrerPolicyAsEnum();
} }

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

@ -2170,8 +2170,12 @@ class LSRequestBase : public DatastoreOperationBase,
private: private:
void SendReadyMessage(); void SendReadyMessage();
nsresult SendReadyMessageInternal();
void Finish(); void Finish();
void FinishInternal();
void SendResults(); void SendResults();
protected: protected:
@ -5703,27 +5707,49 @@ void LSRequestBase::SendReadyMessage() {
MaybeSetFailureCode(NS_ERROR_FAILURE); MaybeSetFailureCode(NS_ERROR_FAILURE);
} }
if (MayProceed()) { nsresult rv = SendReadyMessageInternal();
Unused << SendReady(); if (NS_WARN_IF(NS_FAILED(rv))) {
MaybeSetFailureCode(rv);
mState = State::WaitingForFinish; FinishInternal();
mWaitingForFinish = true;
} else {
Cleanup();
mState = State::Completed;
} }
} }
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() { void LSRequestBase::Finish() {
AssertIsOnOwningThread(); AssertIsOnOwningThread();
MOZ_ASSERT(mState == State::WaitingForFinish); MOZ_ASSERT(mState == State::WaitingForFinish);
mState = State::SendingResults;
mWaitingForFinish = false; 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 // 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. // with clearing that last reference. So we need to add a self reference here.
RefPtr<LSRequestBase> kungFuDeathGrip = this; RefPtr<LSRequestBase> kungFuDeathGrip = this;

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

@ -101,6 +101,10 @@ void SVGImageElement::GetDecoding(nsAString& aValue) {
GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue); GetEnumAttr(nsGkAtoms::decoding, kDecodingTableDefault->tag, aValue);
} }
already_AddRefed<Promise> SVGImageElement::Decode(ErrorResult& aRv) {
return nsImageLoadingContent::QueueDecodeAsync(aRv);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
nsresult SVGImageElement::LoadSVGImage(bool aForce, bool aNotify) { nsresult SVGImageElement::LoadSVGImage(bool aForce, bool aNotify) {

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

@ -93,6 +93,8 @@ class SVGImageElement : public SVGImageElementBase,
} }
void GetDecoding(nsAString& aValue); void GetDecoding(nsAString& aValue);
already_AddRefed<Promise> Decode(ErrorResult& aRv);
protected: protected:
nsresult LoadSVGImage(bool aForce, bool aNotify); nsresult LoadSVGImage(bool aForce, bool aNotify);

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

@ -42,6 +42,8 @@ interface HTMLImageElement : HTMLElement {
readonly attribute unsigned long naturalWidth; readonly attribute unsigned long naturalWidth;
readonly attribute unsigned long naturalHeight; readonly attribute unsigned long naturalHeight;
readonly attribute boolean complete; readonly attribute boolean complete;
[NewObject]
Promise<void> decode();
}; };
// http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis

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

@ -23,6 +23,8 @@ interface SVGImageElement : SVGGraphicsElement {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
[CEReactions, SetterThrows] [CEReactions, SetterThrows]
attribute DOMString decoding; attribute DOMString decoding;
[NewObject]
Promise<void> decode();
}; };
SVGImageElement implements MozImageLoadingContent; SVGImageElement implements MozImageLoadingContent;

14
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -143,7 +143,7 @@ name = "cgl"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -370,7 +370,7 @@ name = "direct-composition"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"euclid 0.19.5 (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)",
"mozangle 0.1.6 (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", "webrender 0.60.0",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -569,7 +569,7 @@ dependencies = [
[[package]] [[package]]
name = "gleam" name = "gleam"
version = "0.6.15" version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender 0.60.0", "webrender 0.60.0",
@ -1793,7 +1793,7 @@ dependencies = [
"env_logger 0.5.10 (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)", "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)", "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)", "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)", "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)", "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 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.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 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 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 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" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"

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

@ -29,7 +29,7 @@ byteorder = "1.0"
cfg-if = "0.1.2" cfg-if = "0.1.2"
cstr = "0.1.2" cstr = "0.1.2"
fxhash = "0.2.1" fxhash = "0.2.1"
gleam = "0.6.14" gleam = "0.6.16"
image = { optional = true, version = "0.21" } image = { optional = true, version = "0.21" }
lazy_static = "1" lazy_static = "1"
log = "0.4" log = "0.4"

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

@ -8,6 +8,12 @@ use std::rc::Rc;
use device::GpuFrameId; use device::GpuFrameId;
#[derive(Copy, Clone, Debug)]
pub enum GpuDebugMethod {
None,
MarkerEXT,
KHR,
}
pub trait NamedTag { pub trait NamedTag {
fn get_label(&self) -> &str; fn get_label(&self) -> &str;
@ -69,18 +75,18 @@ pub struct GpuFrameProfile<T> {
samplers: QuerySet<GpuSampler<T>>, samplers: QuerySet<GpuSampler<T>>,
frame_id: GpuFrameId, frame_id: GpuFrameId,
inside_frame: bool, inside_frame: bool,
ext_debug_marker: bool debug_method: GpuDebugMethod,
} }
impl<T> GpuFrameProfile<T> { impl<T> GpuFrameProfile<T> {
fn new(gl: Rc<gl::Gl>, ext_debug_marker: bool) -> Self { fn new(gl: Rc<gl::Gl>, debug_method: GpuDebugMethod) -> Self {
GpuFrameProfile { GpuFrameProfile {
gl, gl,
timers: QuerySet::new(), timers: QuerySet::new(),
samplers: QuerySet::new(), samplers: QuerySet::new(),
frame_id: GpuFrameId::new(0), frame_id: GpuFrameId::new(0),
inside_frame: false, inside_frame: false,
ext_debug_marker debug_method
} }
} }
@ -140,7 +146,7 @@ impl<T: NamedTag> GpuFrameProfile<T> {
fn start_timer(&mut self, tag: T) -> GpuTimeQuery { fn start_timer(&mut self, tag: T) -> GpuTimeQuery {
self.finish_timer(); 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 }) { if let Some(query) = self.timers.add(GpuTimer { tag, time_ns: 0 }) {
self.gl.begin_query(gl::TIME_ELAPSED, query); self.gl.begin_query(gl::TIME_ELAPSED, query);
@ -186,21 +192,21 @@ pub struct GpuProfiler<T> {
gl: Rc<gl::Gl>, gl: Rc<gl::Gl>,
frames: Vec<GpuFrameProfile<T>>, frames: Vec<GpuFrameProfile<T>>,
next_frame: usize, next_frame: usize,
ext_debug_marker: bool debug_method: GpuDebugMethod
} }
impl<T> GpuProfiler<T> { impl<T> GpuProfiler<T> {
pub fn new(gl: Rc<gl::Gl>, ext_debug_marker: bool) -> Self { pub fn new(gl: Rc<gl::Gl>, debug_method: GpuDebugMethod) -> Self {
const MAX_PROFILE_FRAMES: usize = 4; const MAX_PROFILE_FRAMES: usize = 4;
let frames = (0 .. MAX_PROFILE_FRAMES) let frames = (0 .. MAX_PROFILE_FRAMES)
.map(|_| GpuFrameProfile::new(Rc::clone(&gl), ext_debug_marker)) .map(|_| GpuFrameProfile::new(Rc::clone(&gl), debug_method))
.collect(); .collect();
GpuProfiler { GpuProfiler {
gl, gl,
next_frame: 0, next_frame: 0,
frames, frames,
ext_debug_marker debug_method
} }
} }
@ -263,41 +269,52 @@ impl<T: NamedTag> GpuProfiler<T> {
} }
pub fn start_marker(&mut self, label: &str) -> GpuMarker { 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) { 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] #[must_use]
pub struct GpuMarker { pub struct GpuMarker {
gl: Option<Rc<gl::Gl>> gl: Option<(Rc<gl::Gl>, GpuDebugMethod)>,
} }
impl GpuMarker { impl GpuMarker {
fn new(gl: &Rc<gl::Gl>, message: &str, ext_debug_marker: bool) -> Self { fn new(gl: &Rc<gl::Gl>, message: &str, debug_method: GpuDebugMethod) -> Self {
let gl = if ext_debug_marker { let gl = match debug_method {
gl.push_group_marker_ext(message); GpuDebugMethod::KHR => {
Some(Rc::clone(gl)) gl.push_debug_group_khr(gl::DEBUG_SOURCE_APPLICATION, 0, message);
} else { Some((Rc::clone(gl), debug_method))
None },
GpuDebugMethod::MarkerEXT => {
gl.push_group_marker_ext(message);
Some((Rc::clone(gl), debug_method))
},
GpuDebugMethod::None => None,
}; };
GpuMarker { gl } GpuMarker { gl }
} }
fn fire(gl: &Rc<gl::Gl>, message: &str, ext_debug_marker: bool) { fn fire(gl: &Rc<gl::Gl>, message: &str, debug_method: GpuDebugMethod) {
if ext_debug_marker { match debug_method {
gl.insert_event_marker_ext(message); 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 { impl Drop for GpuMarker {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(ref gl) = self.gl { if let Some((ref gl, debug_method)) = self.gl {
gl.pop_group_marker_ext(); match debug_method {
GpuDebugMethod::KHR => gl.pop_debug_group_khr(),
GpuDebugMethod::MarkerEXT => gl.pop_group_marker_ext(),
GpuDebugMethod::None => {}
};
} }
} }
} }

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

@ -75,7 +75,7 @@ use prim_store::DeferredResolve;
use profiler::{BackendProfileCounters, FrameProfileCounters, TimeProfileCounter, use profiler::{BackendProfileCounters, FrameProfileCounters, TimeProfileCounter,
GpuProfileTag, RendererProfileCounters, RendererProfileTimers}; GpuProfileTag, RendererProfileCounters, RendererProfileTimers};
use profiler::{Profiler, ChangeIndicator}; use profiler::{Profiler, ChangeIndicator};
use device::query::GpuProfiler; use device::query::{GpuProfiler, GpuDebugMethod};
use rayon::{ThreadPool, ThreadPoolBuilder}; use rayon::{ThreadPool, ThreadPoolBuilder};
use record::ApiRecordingReceiver; use record::ApiRecordingReceiver;
use render_backend::{FrameId, RenderBackend}; use render_backend::{FrameId, RenderBackend};
@ -2339,8 +2339,17 @@ impl Renderer {
} }
})?; })?;
let ext_debug_marker = device.supports_extension("GL_EXT_debug_marker"); let debug_support = if device.supports_extension("GL_KHR_debug") {
let gpu_profile = GpuProfiler::new(Rc::clone(device.rc_gl()), ext_debug_marker); 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")] #[cfg(feature = "capture")]
let read_fbo = device.create_fbo(); let read_fbo = device.create_fbo();

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

@ -225,6 +225,8 @@ DynamicImage::StartDecoding(uint32_t aFlags) { return NS_OK; }
bool DynamicImage::StartDecodingWithResult(uint32_t aFlags) { return true; } bool DynamicImage::StartDecodingWithResult(uint32_t aFlags) { return true; }
bool DynamicImage::RequestDecodeWithResult(uint32_t aFlags) { return true; }
NS_IMETHODIMP NS_IMETHODIMP
DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
return NS_OK; return NS_OK;

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

@ -202,6 +202,10 @@ bool ImageWrapper::StartDecodingWithResult(uint32_t aFlags) {
return mInnerImage->StartDecodingWithResult(aFlags); return mInnerImage->StartDecodingWithResult(aFlags);
} }
bool ImageWrapper::RequestDecodeWithResult(uint32_t aFlags) {
return mInnerImage->RequestDecodeWithResult(aFlags);
}
NS_IMETHODIMP NS_IMETHODIMP
ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
return mInnerImage->RequestDecodeForSize(aSize, aFlags); return mInnerImage->RequestDecodeForSize(aSize, aFlags);

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

@ -339,9 +339,12 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags,
return LookupResult(MatchType::NOT_FOUND); 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 || if (result.Type() == MatchType::NOT_FOUND ||
result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND || (result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND &&
((aFlags & FLAG_SYNC_DECODE) && !result)) { !avoidRedecode) ||
(syncDecode && !avoidRedecode && !result)) {
// We don't have a copy of this frame, and there's no decoder working on // 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 // one. (Or we're sync decoding and the existing decoder hasn't even started
// yet.) Trigger decoding so it'll be available next time. // 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 // The surface cache may suggest the preferred size we are supposed to
// decode at. This should only happen if we accept substitutions. // decode at. This should only happen if we accept substitutions.
if (!result.SuggestedSize().IsEmpty()) { if (!result.SuggestedSize().IsEmpty()) {
MOZ_ASSERT(!(aFlags & FLAG_SYNC_DECODE) && MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
(aFlags & FLAG_HIGH_QUALITY_SCALING));
requestedSize = result.SuggestedSize(); requestedSize = result.SuggestedSize();
} }
bool ranSync = Decode(requestedSize, aFlags, aPlaybackType); bool ranSync = Decode(requestedSize, aFlags, aPlaybackType);
// If we can or did sync decode, we should already have the frame. // If we can or did sync decode, we should already have the frame.
if (ranSync || (aFlags & FLAG_SYNC_DECODE)) { if (ranSync || syncDecode) {
result = result =
LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed); 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 // 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 // async decoder that's currently running, the contents of the frame may not
// be available yet. Make sure we get everything. // be available yet. Make sure we get everything.
if (mAllSourceData && (aFlags & FLAG_SYNC_DECODE)) { if (mAllSourceData && syncDecode) {
result.Surface()->WaitUntilFinished(); result.Surface()->WaitUntilFinished();
} }
@ -1078,6 +1080,18 @@ bool RasterImage::StartDecodingWithResult(uint32_t aFlags) {
return surface && surface->IsFinished(); 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 NS_IMETHODIMP
RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) { RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());

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

@ -1236,6 +1236,11 @@ bool VectorImage::StartDecodingWithResult(uint32_t aFlags) {
return mIsFullyLoaded; return mIsFullyLoaded;
} }
bool VectorImage::RequestDecodeWithResult(uint32_t aFlags) {
// SVG images are ready to draw when they are loaded
return mIsFullyLoaded;
}
NS_IMETHODIMP NS_IMETHODIMP
VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) { VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
// Nothing to do for SVG images, though in theory we could rasterize to the // Nothing to do for SVG images, though in theory we could rasterize to the

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

@ -209,6 +209,10 @@ interface imgIContainer : nsISupports
* (a "window into SVG space") based on the border image area, and we need to * (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 * 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. * 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_NONE = 0x0;
const unsigned long FLAG_SYNC_DECODE = 0x1; 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_BYPASS_SURFACE_CACHE = 0x100;
const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x200; const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x200;
const unsigned long FLAG_FORCE_UNIFORM_SCALING = 0x400; 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 * 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); [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 * This method triggers decoding for an image, but unlike startDecoding() it
* enables the caller to provide more detailed information about the decode * enables the caller to provide more detailed information about the decode

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

@ -163,9 +163,23 @@ interface imgIRequest : nsIRequest
/** /**
* Exactly like startDecoding above except returns whether the current frame * Exactly like startDecoding above except returns whether the current frame
* of the image is complete or not. * 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); [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 * 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 * available. The lock persists for the lifetime of the imgIRequest (until

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

@ -543,6 +543,24 @@ bool imgRequestProxy::StartDecodingWithResult(uint32_t aFlags) {
return false; return false;
} }
bool imgRequestProxy::RequestDecodeWithResult(uint32_t aFlags) {
if (IsValidating()) {
mDecodeRequested = true;
return false;
}
RefPtr<Image> image = GetImage();
if (image) {
return image->RequestDecodeWithResult(aFlags);
}
if (GetOwner()) {
GetOwner()->StartDecoding();
}
return false;
}
NS_IMETHODIMP NS_IMETHODIMP
imgRequestProxy::LockImage() { imgRequestProxy::LockImage() {
mLockCount++; mLockCount++;

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

@ -42,11 +42,14 @@ nsEffectiveTLDService::nsEffectiveTLDService()
: mIDNService(), mGraph(etld_dafsa::kDafsa) {} : mIDNService(), mGraph(etld_dafsa::kDafsa) {}
nsresult nsEffectiveTLDService::Init() { nsresult nsEffectiveTLDService::Init() {
if (gService) {
return NS_ERROR_ALREADY_INITIALIZED;
}
nsresult rv; nsresult rv;
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
MOZ_ASSERT(!gService);
gService = this; gService = this;
RegisterWeakMemoryReporter(this); RegisterWeakMemoryReporter(this);
@ -55,7 +58,10 @@ nsresult nsEffectiveTLDService::Init() {
nsEffectiveTLDService::~nsEffectiveTLDService() { nsEffectiveTLDService::~nsEffectiveTLDService() {
UnregisterWeakMemoryReporter(this); UnregisterWeakMemoryReporter(this);
gService = nullptr; if (mIDNService) {
// Only clear gService if Init() finished successfully.
gService = nullptr;
}
} }
// static // static

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

@ -5,6 +5,7 @@ support-files =
redirect.sjs redirect.sjs
[browser_about_cache.js] [browser_about_cache.js]
[browser_bug1535877.js]
[browser_NetUtil.js] [browser_NetUtil.js]
[browser_child_resource.js] [browser_child_resource.js]
skip-if = !crashreporter || (e10s && debug && os == "linux" && bits == 64) || debug # Bug 1370783 skip-if = !crashreporter || (e10s && debug && os == "linux" && bits == 64) || debug # Bug 1370783

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

@ -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");
}
});

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

@ -673,7 +673,7 @@ class BaseBootstrapper(object):
print('Your version of Rust (%s) is new enough.' % version) print('Your version of Rust (%s) is new enough.' % version)
rustup = self.which('rustup', cargo_bin) rustup = self.which('rustup', cargo_bin)
if rustup: if rustup:
self.ensure_rust_targets(rustup, version) self.ensure_rust_targets(rustup)
return return
if version: if version:
@ -697,7 +697,7 @@ class BaseBootstrapper(object):
print('Will try to install Rust.') print('Will try to install Rust.')
self.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.""" """Make sure appropriate cross target libraries are installed."""
target_list = subprocess.check_output([rustup, 'target', 'list']) target_list = subprocess.check_output([rustup, 'target', 'list'])
targets = [line.split()[0] for line in target_list.splitlines() targets = [line.split()[0] for line in target_list.splitlines()
@ -712,11 +712,7 @@ class BaseBootstrapper(object):
if 'mobile_android' in self.application: if 'mobile_android' in self.application:
# Let's add the most common targets. # Let's add the most common targets.
if LooseVersion(rust_version) < '1.33': android_targets = ('thumbv7neon-linux-androideabi',
arm_target = 'armv7-linux-androideabi'
else:
arm_target = 'thumbv7neon-linux-androideabi'
android_targets = (arm_target,
'aarch64-linux-android', 'aarch64-linux-android',
'i686-linux-android', 'i686-linux-android',
'x86_64-linux-android', ) 'x86_64-linux-android', )

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

@ -45,6 +45,7 @@
[fetch.any.serviceworker.html] [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.] [Valid cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.]
expected: FAIL expected: FAIL

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

@ -477,15 +477,6 @@ prefs: [dom.security.featurePolicy.enabled:true]
[HTMLBodyElement interface: document.createElement("body") must inherit property "onunhandledrejection" with the proper type] [HTMLBodyElement interface: document.createElement("body") must inherit property "onunhandledrejection" with the proper type]
expected: FAIL 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] [HTMLIFrameElement interface: attribute allowUserMedia]
expected: FAIL expected: FAIL

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

@ -1,20 +1,8 @@
[image-decode-iframe.html] [image-decode-iframe.html]
expected: expected: TIMEOUT
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
[HTMLImageElement.prototype.decode(), iframe tests. Decode from removed iframe fails (img not loaded)] [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)] [HTMLImageElement.prototype.decode(), iframe tests. Decode from iframe, later removed, fails (img not loaded)]
expected: NOTRUN expected: NOTRUN

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

@ -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

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

@ -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

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

@ -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

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

@ -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

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

@ -1,4 +0,0 @@
[image-decode-with-quick-attach-svg.tentative.html]
[SVGImageElement.prototype.decode(), attach to DOM before promise resolves.]
expected: FAIL

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

@ -1,4 +0,0 @@
[image-decode-with-quick-attach.html]
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.]
expected: FAIL

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

@ -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

2
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"} {"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"}

4
third_party/rust/gleam/Cargo.toml поставляемый
Просмотреть файл

@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically # When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility # "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies # 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 # If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're # issue against the rust-lang/cargo repository. If you're
@ -12,7 +12,7 @@
[package] [package]
name = "gleam" name = "gleam"
version = "0.6.15" version = "0.6.16"
authors = ["The Servo Project Developers"] authors = ["The Servo Project Developers"]
build = "build.rs" build = "build.rs"
description = "Generated OpenGL bindings and wrapper for Servo." description = "Generated OpenGL bindings and wrapper for Servo."

3
third_party/rust/gleam/src/gl.rs поставляемый
Просмотреть файл

@ -553,6 +553,9 @@ declare_gl_apis! {
fn insert_event_marker_ext(&self, message: &str); fn insert_event_marker_ext(&self, message: &str);
fn push_group_marker_ext(&self, message: &str); fn push_group_marker_ext(&self, message: &str);
fn pop_group_marker_ext(&self); 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 fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync;
fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64); fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64); fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);

26
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 { fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ } unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ }
} }

26
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 { fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ } unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ }
} }

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

@ -642,6 +642,11 @@ with modules["DOM"]:
# decoding process. # decoding process.
errors["NS_ERROR_DOM_JS_DECODING_ERROR"] = FAILURE(1026) 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 # 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"; # actually change the value, like for obj.foo = "bar"; obj.foo = "bar";
# the second assignment throws NS_SUCCESS_DOM_NO_OPERATION. # the second assignment throws NS_SUCCESS_DOM_NO_OPERATION.