зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
fcac8589b7
|
@ -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(¤tLoadStatus);
|
nsresult rv = mCurrentRequest->GetImageStatus(¤tLoadStatus);
|
||||||
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;
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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"}
|
|
@ -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."
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 _ }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче