зеркало из 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]]
|
||||
name = "gleam"
|
||||
version = "0.6.15"
|
||||
version = "0.6.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3315,7 +3315,7 @@ dependencies = [
|
|||
"dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3366,7 +3366,7 @@ dependencies = [
|
|||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nsstring 0.1.0",
|
||||
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3624,7 +3624,7 @@ dependencies = [
|
|||
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
||||
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
"checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd"
|
||||
"checksum gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "43edfa3a4321024d7dac1625cf154ef0c16996a6a384d066480e306ebd39fecc"
|
||||
"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2"
|
||||
"checksum guid_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87261686cc5e35b6584f4c2a430c2b153d8a92ab1ef820c16be34c1df8f5f58b"
|
||||
|
|
|
@ -4301,6 +4301,13 @@ static void NotifyActivityChanged(nsISupports* aSupports, void* aUnused) {
|
|||
do_QueryInterface(aSupports));
|
||||
if (objectDocumentActivity) {
|
||||
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, "responseText is only available if responseType is '' or 'text'.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_WRONG_RESPONSETYPE_FOR_RESPONSETEXT)
|
||||
DOM4_MSG_DEF(InvalidAccessError, "synchronous XMLHttpRequests do not support timeout and responseType.", NS_ERROR_DOM_INVALID_ACCESS_XHR_TIMEOUT_AND_RESPONSETYPE_UNSUPPORTED_FOR_SYNC)
|
||||
|
||||
/* Image decode errors. */
|
||||
DOM4_MSG_DEF(EncodingError, "Node bound to inactive document.", NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT)
|
||||
DOM4_MSG_DEF(EncodingError, "Invalid image request.", NS_ERROR_DOM_IMAGE_INVALID_REQUEST)
|
||||
DOM4_MSG_DEF(EncodingError, "Invalid encoded image data.", NS_ERROR_DOM_IMAGE_BROKEN)
|
||||
|
|
|
@ -95,6 +95,8 @@ nsImageLoadingContent::nsImageLoadingContent()
|
|||
: mCurrentRequestFlags(0),
|
||||
mPendingRequestFlags(0),
|
||||
mObserverList(nullptr),
|
||||
mOutstandingDecodePromises(0),
|
||||
mRequestGeneration(0),
|
||||
mImageBlockingStatus(nsIContentPolicy::ACCEPT),
|
||||
mLoadingEnabled(true),
|
||||
mIsImageStateForced(false),
|
||||
|
@ -120,17 +122,21 @@ nsImageLoadingContent::nsImageLoadingContent()
|
|||
void nsImageLoadingContent::DestroyImageLoadingContent() {
|
||||
// Cancel our requests so they won't hold stale refs to us
|
||||
// NB: Don't ask to discard the images here.
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST);
|
||||
ClearCurrentRequest(NS_BINDING_ABORTED);
|
||||
ClearPendingRequest(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
nsImageLoadingContent::~nsImageLoadingContent() {
|
||||
NS_ASSERTION(!mCurrentRequest && !mPendingRequest,
|
||||
"DestroyImageLoadingContent not called");
|
||||
NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext,
|
||||
"Observers still registered?");
|
||||
NS_ASSERTION(mScriptedObservers.IsEmpty(),
|
||||
"Scripted observers still registered?");
|
||||
MOZ_ASSERT(!mCurrentRequest && !mPendingRequest,
|
||||
"DestroyImageLoadingContent not called");
|
||||
MOZ_ASSERT(!mObserverList.mObserver && !mObserverList.mNext,
|
||||
"Observers still registered?");
|
||||
MOZ_ASSERT(mScriptedObservers.IsEmpty(),
|
||||
"Scripted observers still registered?");
|
||||
MOZ_ASSERT(mOutstandingDecodePromises == 0,
|
||||
"Decode promises still unfulfilled?");
|
||||
MOZ_ASSERT(mDecodePromises.IsEmpty(), "Decode promises still unfulfilled?");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -204,6 +210,11 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, int32_t aType,
|
|||
return OnLoadComplete(aRequest, status);
|
||||
}
|
||||
|
||||
if (aType == imgINotificationObserver::FRAME_COMPLETE &&
|
||||
mCurrentRequest == aRequest) {
|
||||
MaybeResolveDecodePromises();
|
||||
}
|
||||
|
||||
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
aRequest->GetImage(getter_AddRefs(container));
|
||||
|
@ -260,6 +271,7 @@ nsresult nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest,
|
|||
nsCOMPtr<nsINode> thisNode =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
SVGObserverUtils::InvalidateDirectRenderingObservers(thisNode->AsElement());
|
||||
MaybeResolveDecodePromises();
|
||||
|
||||
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) {
|
||||
if (mSyncDecodingHint == aHint) {
|
||||
return;
|
||||
|
@ -786,6 +958,15 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
|
|||
// Shouldn't that be done before the start of the load?
|
||||
// XXX what about shouldProcess?
|
||||
|
||||
// If we have a current request without a size, we know we will replace it
|
||||
// with the PrepareNextRequest below. If the new current request is for a
|
||||
// different URI, then we need to reject any outstanding promises.
|
||||
if (mCurrentRequest && !HaveSize(mCurrentRequest)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetOriginalURI(getter_AddRefs(uri));
|
||||
MaybeAgeRequestGeneration(uri);
|
||||
}
|
||||
|
||||
// Our state might change. Watch it.
|
||||
AutoStateChanger changer(this, true);
|
||||
|
||||
|
@ -944,6 +1125,13 @@ nsresult nsImageLoadingContent::LoadImage(nsIURI* aNewURI, bool aForce,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have a current request without a size, we know we will replace it
|
||||
// with the PrepareNextRequest below. If the new current request is for a
|
||||
// different URI, then we need to reject any outstanding promises.
|
||||
if (mCurrentRequest && !HaveSize(mCurrentRequest)) {
|
||||
MaybeAgeRequestGeneration(aNewURI);
|
||||
}
|
||||
|
||||
// From this point on, our image state could change. Watch it.
|
||||
AutoStateChanger changer(this, aNotify);
|
||||
|
||||
|
@ -1120,11 +1308,13 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) {
|
|||
} else if (!mCurrentRequest) {
|
||||
// No current request means error, since we weren't disabled or suppressed
|
||||
mBroken = true;
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN);
|
||||
} else {
|
||||
uint32_t currentLoadStatus;
|
||||
nsresult rv = mCurrentRequest->GetImageStatus(¤tLoadStatus);
|
||||
if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) {
|
||||
mBroken = true;
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_BROKEN);
|
||||
} else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
mLoading = true;
|
||||
}
|
||||
|
@ -1135,6 +1325,7 @@ void nsImageLoadingContent::UpdateImageState(bool aNotify) {
|
|||
}
|
||||
|
||||
void nsImageLoadingContent::CancelImageRequests(bool aNotify) {
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INVALID_REQUEST);
|
||||
AutoStateChanger changer(this, aNotify);
|
||||
ClearPendingRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES));
|
||||
ClearCurrentRequest(NS_BINDING_ABORTED, Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
@ -1183,6 +1374,7 @@ nsresult nsImageLoadingContent::FireEvent(const nsAString& aEventType,
|
|||
bool aIsCancelable) {
|
||||
if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) {
|
||||
// Don't bother to fire any events, especially error events.
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1315,6 +1507,13 @@ class ImageRequestAutoLock {
|
|||
void nsImageLoadingContent::MakePendingRequestCurrent() {
|
||||
MOZ_ASSERT(mPendingRequest);
|
||||
|
||||
// If we have a pending request, we know that there is an existing current
|
||||
// request with size information. If the pending request is for a different
|
||||
// URI, then we need to reject any outstanding promises.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mPendingRequest->GetURI(getter_AddRefs(uri));
|
||||
MaybeAgeRequestGeneration(uri);
|
||||
|
||||
// Lock mCurrentRequest for the duration of this method. We do this because
|
||||
// PrepareCurrentRequest() might unlock mCurrentRequest. If mCurrentRequest
|
||||
// and mPendingRequest are both requests for the same image, unlocking
|
||||
|
@ -1408,6 +1607,12 @@ bool nsImageLoadingContent::HaveSize(imgIRequest* aImage) {
|
|||
return (NS_SUCCEEDED(rv) && (status & imgIRequest::STATUS_SIZE_AVAILABLE));
|
||||
}
|
||||
|
||||
void nsImageLoadingContent::NotifyOwnerDocumentActivityChanged() {
|
||||
if (!GetOurOwnerDoc()->IsCurrentActiveDocument()) {
|
||||
RejectDecodePromises(NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
void nsImageLoadingContent::BindToTree(Document* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent) {
|
||||
// We may be getting connected, if so our image should be tracked,
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "nsAttrValue.h"
|
||||
|
||||
|
@ -82,6 +83,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
|
|||
*/
|
||||
void SetSyncDecodingHint(bool aHint);
|
||||
|
||||
/**
|
||||
* Notify us that the document state has changed. Called by nsDocument so that
|
||||
* we may reject any promises which require the document to be active.
|
||||
*/
|
||||
void NotifyOwnerDocumentActivityChanged();
|
||||
|
||||
protected:
|
||||
enum ImageLoadType {
|
||||
// Most normal image loads
|
||||
|
@ -230,6 +237,18 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
|
|||
uint32_t NaturalWidth();
|
||||
uint32_t NaturalHeight();
|
||||
|
||||
/**
|
||||
* Create a promise and queue a microtask which will ensure the current
|
||||
* request (after any pending loads are applied) has requested a full decode.
|
||||
* The promise is fulfilled once the request has a fully decoded surface that
|
||||
* is available for drawing, or an error condition occurrs (e.g. broken image,
|
||||
* current request is updated, etc).
|
||||
*
|
||||
* https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode
|
||||
*/
|
||||
already_AddRefed<mozilla::dom::Promise> QueueDecodeAsync(
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
enum class ImageDecodingType : uint8_t {
|
||||
Auto,
|
||||
Async,
|
||||
|
@ -240,6 +259,38 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
|
|||
static const nsAttrValue::EnumTable* kDecodingTableDefault;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Enqueue and/or fulfill a promise created by QueueDecodeAsync.
|
||||
*/
|
||||
void DecodeAsync(RefPtr<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.
|
||||
*/
|
||||
|
@ -483,6 +534,12 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
|
|||
*/
|
||||
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
|
||||
* return in ImageState().
|
||||
|
@ -491,6 +548,23 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
|
|||
|
||||
mozilla::TimeStamp mMostRecentRequestChange;
|
||||
|
||||
/**
|
||||
* Total number of outstanding decode promises, including those stored in
|
||||
* mDecodePromises and those embedded in runnables waiting to be enqueued.
|
||||
* This is used to determine whether we need to register as an observer for
|
||||
* document activity notifications.
|
||||
*/
|
||||
size_t mOutstandingDecodePromises;
|
||||
|
||||
/**
|
||||
* An incrementing counter representing the current request generation;
|
||||
* Each time mCurrentRequest is modified with a different URI, this will
|
||||
* be incremented. Each QueueDecodeAsync call will cache the generation
|
||||
* of the current request so that when it is processed, it knows if it
|
||||
* should have rejected because the request changed.
|
||||
*/
|
||||
uint32_t mRequestGeneration;
|
||||
|
||||
int16_t mImageBlockingStatus;
|
||||
bool mLoadingEnabled : 1;
|
||||
|
||||
|
|
|
@ -499,6 +499,16 @@ already_AddRefed<nsINode> nsNodeUtils::CloneAndAdopt(
|
|||
nsObjectLoadingContent* olc =
|
||||
static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
|
||||
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) {
|
||||
QueueCheckPluginStopEvent();
|
||||
}
|
||||
nsImageLoadingContent::NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
|
||||
// nsIRequestObserver
|
||||
|
|
|
@ -191,6 +191,10 @@ void HTMLImageElement::GetDecoding(nsAString& 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,
|
||||
const nsAString& aValue,
|
||||
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
|
|
|
@ -180,6 +180,8 @@ class HTMLImageElement final : public nsGenericHTMLElement,
|
|||
}
|
||||
void GetDecoding(nsAString& aValue);
|
||||
|
||||
already_AddRefed<Promise> Decode(ErrorResult& aRv);
|
||||
|
||||
net::ReferrerPolicy GetImageReferrerPolicy() override {
|
||||
return GetReferrerPolicyAsEnum();
|
||||
}
|
||||
|
|
|
@ -2170,8 +2170,12 @@ class LSRequestBase : public DatastoreOperationBase,
|
|||
private:
|
||||
void SendReadyMessage();
|
||||
|
||||
nsresult SendReadyMessageInternal();
|
||||
|
||||
void Finish();
|
||||
|
||||
void FinishInternal();
|
||||
|
||||
void SendResults();
|
||||
|
||||
protected:
|
||||
|
@ -5703,27 +5707,49 @@ void LSRequestBase::SendReadyMessage() {
|
|||
MaybeSetFailureCode(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (MayProceed()) {
|
||||
Unused << SendReady();
|
||||
nsresult rv = SendReadyMessageInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MaybeSetFailureCode(rv);
|
||||
|
||||
mState = State::WaitingForFinish;
|
||||
|
||||
mWaitingForFinish = true;
|
||||
} else {
|
||||
Cleanup();
|
||||
|
||||
mState = State::Completed;
|
||||
FinishInternal();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult LSRequestBase::SendReadyMessageInternal() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::SendingReadyMessage);
|
||||
|
||||
if (!MayProceed()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!SendReady())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mState = State::WaitingForFinish;
|
||||
|
||||
mWaitingForFinish = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void LSRequestBase::Finish() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::WaitingForFinish);
|
||||
|
||||
mState = State::SendingResults;
|
||||
|
||||
mWaitingForFinish = false;
|
||||
|
||||
FinishInternal();
|
||||
}
|
||||
|
||||
void LSRequestBase::FinishInternal() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::SendingReadyMessage ||
|
||||
mState == State::WaitingForFinish);
|
||||
|
||||
mState = State::SendingResults;
|
||||
|
||||
// This LSRequestBase can only be held alive by the IPDL. Run() can end up
|
||||
// with clearing that last reference. So we need to add a self reference here.
|
||||
RefPtr<LSRequestBase> kungFuDeathGrip = this;
|
||||
|
|
|
@ -101,6 +101,10 @@ void SVGImageElement::GetDecoding(nsAString& 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) {
|
||||
|
|
|
@ -93,6 +93,8 @@ class SVGImageElement : public SVGImageElementBase,
|
|||
}
|
||||
void GetDecoding(nsAString& aValue);
|
||||
|
||||
already_AddRefed<Promise> Decode(ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
nsresult LoadSVGImage(bool aForce, bool aNotify);
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ interface HTMLImageElement : HTMLElement {
|
|||
readonly attribute unsigned long naturalWidth;
|
||||
readonly attribute unsigned long naturalHeight;
|
||||
readonly attribute boolean complete;
|
||||
[NewObject]
|
||||
Promise<void> decode();
|
||||
};
|
||||
|
||||
// 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;
|
||||
[CEReactions, SetterThrows]
|
||||
attribute DOMString decoding;
|
||||
[NewObject]
|
||||
Promise<void> decode();
|
||||
};
|
||||
|
||||
SVGImageElement implements MozImageLoadingContent;
|
||||
|
|
|
@ -143,7 +143,7 @@ name = "cgl"
|
|||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -370,7 +370,7 @@ name = "direct-composition"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.60.0",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -569,7 +569,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gleam"
|
||||
version = "0.6.15"
|
||||
version = "0.6.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1640,7 +1640,7 @@ dependencies = [
|
|||
"dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1676,7 +1676,7 @@ dependencies = [
|
|||
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.60.0",
|
||||
|
@ -1793,7 +1793,7 @@ dependencies = [
|
|||
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1940,7 +1940,7 @@ dependencies = [
|
|||
"checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c"
|
||||
"checksum gl_generator 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39a23d5e872a275135d66895d954269cf5e8661d234eb1c2480f4ce0d586acbd"
|
||||
"checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
|
||||
"checksum gleam 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "43edfa3a4321024d7dac1625cf154ef0c16996a6a384d066480e306ebd39fecc"
|
||||
"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"
|
||||
"checksum glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70c5fe78efbd5a3b243a804ea1032053c584510f8822819f94cfb29b2100317"
|
||||
"checksum half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d5c5f71a723d10dfc58927cbed37c3071a50afc7f073d86fd7d3e5727db890f"
|
||||
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
|
||||
|
|
|
@ -29,7 +29,7 @@ byteorder = "1.0"
|
|||
cfg-if = "0.1.2"
|
||||
cstr = "0.1.2"
|
||||
fxhash = "0.2.1"
|
||||
gleam = "0.6.14"
|
||||
gleam = "0.6.16"
|
||||
image = { optional = true, version = "0.21" }
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
|
|
|
@ -8,6 +8,12 @@ use std::rc::Rc;
|
|||
|
||||
use device::GpuFrameId;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum GpuDebugMethod {
|
||||
None,
|
||||
MarkerEXT,
|
||||
KHR,
|
||||
}
|
||||
|
||||
pub trait NamedTag {
|
||||
fn get_label(&self) -> &str;
|
||||
|
@ -69,18 +75,18 @@ pub struct GpuFrameProfile<T> {
|
|||
samplers: QuerySet<GpuSampler<T>>,
|
||||
frame_id: GpuFrameId,
|
||||
inside_frame: bool,
|
||||
ext_debug_marker: bool
|
||||
debug_method: GpuDebugMethod,
|
||||
}
|
||||
|
||||
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 {
|
||||
gl,
|
||||
timers: QuerySet::new(),
|
||||
samplers: QuerySet::new(),
|
||||
frame_id: GpuFrameId::new(0),
|
||||
inside_frame: false,
|
||||
ext_debug_marker
|
||||
debug_method
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +146,7 @@ impl<T: NamedTag> GpuFrameProfile<T> {
|
|||
fn start_timer(&mut self, tag: T) -> GpuTimeQuery {
|
||||
self.finish_timer();
|
||||
|
||||
let marker = GpuMarker::new(&self.gl, tag.get_label(), self.ext_debug_marker);
|
||||
let marker = GpuMarker::new(&self.gl, tag.get_label(), self.debug_method);
|
||||
|
||||
if let Some(query) = self.timers.add(GpuTimer { tag, time_ns: 0 }) {
|
||||
self.gl.begin_query(gl::TIME_ELAPSED, query);
|
||||
|
@ -186,21 +192,21 @@ pub struct GpuProfiler<T> {
|
|||
gl: Rc<gl::Gl>,
|
||||
frames: Vec<GpuFrameProfile<T>>,
|
||||
next_frame: usize,
|
||||
ext_debug_marker: bool
|
||||
debug_method: GpuDebugMethod
|
||||
}
|
||||
|
||||
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;
|
||||
let frames = (0 .. MAX_PROFILE_FRAMES)
|
||||
.map(|_| GpuFrameProfile::new(Rc::clone(&gl), ext_debug_marker))
|
||||
.map(|_| GpuFrameProfile::new(Rc::clone(&gl), debug_method))
|
||||
.collect();
|
||||
|
||||
GpuProfiler {
|
||||
gl,
|
||||
next_frame: 0,
|
||||
frames,
|
||||
ext_debug_marker
|
||||
debug_method
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,41 +269,52 @@ impl<T: NamedTag> GpuProfiler<T> {
|
|||
}
|
||||
|
||||
pub fn start_marker(&mut self, label: &str) -> GpuMarker {
|
||||
GpuMarker::new(&self.gl, label, self.ext_debug_marker)
|
||||
GpuMarker::new(&self.gl, label, self.debug_method)
|
||||
}
|
||||
|
||||
pub fn place_marker(&mut self, label: &str) {
|
||||
GpuMarker::fire(&self.gl, label, self.ext_debug_marker)
|
||||
GpuMarker::fire(&self.gl, label, self.debug_method)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub struct GpuMarker {
|
||||
gl: Option<Rc<gl::Gl>>
|
||||
gl: Option<(Rc<gl::Gl>, GpuDebugMethod)>,
|
||||
}
|
||||
|
||||
impl GpuMarker {
|
||||
fn new(gl: &Rc<gl::Gl>, message: &str, ext_debug_marker: bool) -> Self {
|
||||
let gl = if ext_debug_marker {
|
||||
gl.push_group_marker_ext(message);
|
||||
Some(Rc::clone(gl))
|
||||
} else {
|
||||
None
|
||||
fn new(gl: &Rc<gl::Gl>, message: &str, debug_method: GpuDebugMethod) -> Self {
|
||||
let gl = match debug_method {
|
||||
GpuDebugMethod::KHR => {
|
||||
gl.push_debug_group_khr(gl::DEBUG_SOURCE_APPLICATION, 0, message);
|
||||
Some((Rc::clone(gl), debug_method))
|
||||
},
|
||||
GpuDebugMethod::MarkerEXT => {
|
||||
gl.push_group_marker_ext(message);
|
||||
Some((Rc::clone(gl), debug_method))
|
||||
},
|
||||
GpuDebugMethod::None => None,
|
||||
};
|
||||
GpuMarker { gl }
|
||||
}
|
||||
|
||||
fn fire(gl: &Rc<gl::Gl>, message: &str, ext_debug_marker: bool) {
|
||||
if ext_debug_marker {
|
||||
gl.insert_event_marker_ext(message);
|
||||
}
|
||||
fn fire(gl: &Rc<gl::Gl>, message: &str, debug_method: GpuDebugMethod) {
|
||||
match debug_method {
|
||||
GpuDebugMethod::KHR => gl.debug_message_insert_khr(gl::DEBUG_SOURCE_APPLICATION, gl::DEBUG_TYPE_MARKER, 0, gl::DEBUG_SEVERITY_NOTIFICATION, message),
|
||||
GpuDebugMethod::MarkerEXT => gl.insert_event_marker_ext(message),
|
||||
GpuDebugMethod::None => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GpuMarker {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref gl) = self.gl {
|
||||
gl.pop_group_marker_ext();
|
||||
if let Some((ref gl, debug_method)) = self.gl {
|
||||
match debug_method {
|
||||
GpuDebugMethod::KHR => gl.pop_debug_group_khr(),
|
||||
GpuDebugMethod::MarkerEXT => gl.pop_group_marker_ext(),
|
||||
GpuDebugMethod::None => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ use prim_store::DeferredResolve;
|
|||
use profiler::{BackendProfileCounters, FrameProfileCounters, TimeProfileCounter,
|
||||
GpuProfileTag, RendererProfileCounters, RendererProfileTimers};
|
||||
use profiler::{Profiler, ChangeIndicator};
|
||||
use device::query::GpuProfiler;
|
||||
use device::query::{GpuProfiler, GpuDebugMethod};
|
||||
use rayon::{ThreadPool, ThreadPoolBuilder};
|
||||
use record::ApiRecordingReceiver;
|
||||
use render_backend::{FrameId, RenderBackend};
|
||||
|
@ -2339,8 +2339,17 @@ impl Renderer {
|
|||
}
|
||||
})?;
|
||||
|
||||
let ext_debug_marker = device.supports_extension("GL_EXT_debug_marker");
|
||||
let gpu_profile = GpuProfiler::new(Rc::clone(device.rc_gl()), ext_debug_marker);
|
||||
let debug_support = if device.supports_extension("GL_KHR_debug") {
|
||||
GpuDebugMethod::KHR
|
||||
} else if device.supports_extension("GL_EXT_debug_marker") {
|
||||
GpuDebugMethod::MarkerEXT
|
||||
} else {
|
||||
GpuDebugMethod::None
|
||||
};
|
||||
|
||||
info!("using {:?}", debug_support);
|
||||
|
||||
let gpu_profile = GpuProfiler::new(Rc::clone(device.rc_gl()), debug_support);
|
||||
#[cfg(feature = "capture")]
|
||||
let read_fbo = device.create_fbo();
|
||||
|
||||
|
|
|
@ -225,6 +225,8 @@ DynamicImage::StartDecoding(uint32_t aFlags) { return NS_OK; }
|
|||
|
||||
bool DynamicImage::StartDecodingWithResult(uint32_t aFlags) { return true; }
|
||||
|
||||
bool DynamicImage::RequestDecodeWithResult(uint32_t aFlags) { return true; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
|
||||
return NS_OK;
|
||||
|
|
|
@ -202,6 +202,10 @@ bool ImageWrapper::StartDecodingWithResult(uint32_t aFlags) {
|
|||
return mInnerImage->StartDecodingWithResult(aFlags);
|
||||
}
|
||||
|
||||
bool ImageWrapper::RequestDecodeWithResult(uint32_t aFlags) {
|
||||
return mInnerImage->RequestDecodeWithResult(aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
|
||||
return mInnerImage->RequestDecodeForSize(aSize, aFlags);
|
||||
|
|
|
@ -339,9 +339,12 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags,
|
|||
return LookupResult(MatchType::NOT_FOUND);
|
||||
}
|
||||
|
||||
const bool syncDecode = aFlags & FLAG_SYNC_DECODE;
|
||||
const bool avoidRedecode = aFlags & FLAG_AVOID_REDECODE_FOR_SIZE;
|
||||
if (result.Type() == MatchType::NOT_FOUND ||
|
||||
result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND ||
|
||||
((aFlags & FLAG_SYNC_DECODE) && !result)) {
|
||||
(result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND &&
|
||||
!avoidRedecode) ||
|
||||
(syncDecode && !avoidRedecode && !result)) {
|
||||
// We don't have a copy of this frame, and there's no decoder working on
|
||||
// one. (Or we're sync decoding and the existing decoder hasn't even started
|
||||
// yet.) Trigger decoding so it'll be available next time.
|
||||
|
@ -353,15 +356,14 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags,
|
|||
// The surface cache may suggest the preferred size we are supposed to
|
||||
// decode at. This should only happen if we accept substitutions.
|
||||
if (!result.SuggestedSize().IsEmpty()) {
|
||||
MOZ_ASSERT(!(aFlags & FLAG_SYNC_DECODE) &&
|
||||
(aFlags & FLAG_HIGH_QUALITY_SCALING));
|
||||
MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
|
||||
requestedSize = result.SuggestedSize();
|
||||
}
|
||||
|
||||
bool ranSync = Decode(requestedSize, aFlags, aPlaybackType);
|
||||
|
||||
// If we can or did sync decode, we should already have the frame.
|
||||
if (ranSync || (aFlags & FLAG_SYNC_DECODE)) {
|
||||
if (ranSync || syncDecode) {
|
||||
result =
|
||||
LookupFrameInternal(requestedSize, aFlags, aPlaybackType, aMarkUsed);
|
||||
}
|
||||
|
@ -375,7 +377,7 @@ LookupResult RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags,
|
|||
// Sync decoding guarantees that we got the frame, but if it's owned by an
|
||||
// async decoder that's currently running, the contents of the frame may not
|
||||
// be available yet. Make sure we get everything.
|
||||
if (mAllSourceData && (aFlags & FLAG_SYNC_DECODE)) {
|
||||
if (mAllSourceData && syncDecode) {
|
||||
result.Surface()->WaitUntilFinished();
|
||||
}
|
||||
|
||||
|
@ -1078,6 +1080,18 @@ bool RasterImage::StartDecodingWithResult(uint32_t aFlags) {
|
|||
return surface && surface->IsFinished();
|
||||
}
|
||||
|
||||
bool RasterImage::RequestDecodeWithResult(uint32_t aFlags) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t flags = aFlags | FLAG_ASYNC_NOTIFY;
|
||||
DrawableSurface surface = RequestDecodeForSizeInternal(mSize, flags);
|
||||
return surface && surface->IsFinished();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
|
|
@ -1236,6 +1236,11 @@ bool VectorImage::StartDecodingWithResult(uint32_t aFlags) {
|
|||
return mIsFullyLoaded;
|
||||
}
|
||||
|
||||
bool VectorImage::RequestDecodeWithResult(uint32_t aFlags) {
|
||||
// SVG images are ready to draw when they are loaded
|
||||
return mIsFullyLoaded;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags) {
|
||||
// Nothing to do for SVG images, though in theory we could rasterize to the
|
||||
|
|
|
@ -209,6 +209,10 @@ interface imgIContainer : nsISupports
|
|||
* (a "window into SVG space") based on the border image area, and we need to
|
||||
* be sure we don't subsequently scale that viewport in a way that distorts
|
||||
* its contents by stretching them more in one dimension than the other.
|
||||
*
|
||||
* FLAG_AVOID_REDECODE_FOR_SIZE: If there is already a raster surface
|
||||
* available for this image, but it is not the same size as requested, skip
|
||||
* starting a new decode for said size.
|
||||
*/
|
||||
const unsigned long FLAG_NONE = 0x0;
|
||||
const unsigned long FLAG_SYNC_DECODE = 0x1;
|
||||
|
@ -222,6 +226,7 @@ interface imgIContainer : nsISupports
|
|||
const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x100;
|
||||
const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x200;
|
||||
const unsigned long FLAG_FORCE_UNIFORM_SCALING = 0x400;
|
||||
const unsigned long FLAG_AVOID_REDECODE_FOR_SIZE = 0x800;
|
||||
|
||||
/**
|
||||
* A constant specifying the default set of decode flags (i.e., the default
|
||||
|
@ -472,6 +477,17 @@ interface imgIContainer : nsISupports
|
|||
*/
|
||||
[noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags);
|
||||
|
||||
/*
|
||||
* This method triggers decoding for an image, but unlike startDecoding() it
|
||||
* enables the caller to provide more detailed information about the decode
|
||||
* request.
|
||||
*
|
||||
* @param aFlags Flags of the FLAG_* variety.
|
||||
* @return True there is a surface that satisfies the request and it is
|
||||
* fully decoded, else false.
|
||||
*/
|
||||
[noscript, notxpcom] boolean requestDecodeWithResult(in uint32_t aFlags);
|
||||
|
||||
/*
|
||||
* This method triggers decoding for an image, but unlike startDecoding() it
|
||||
* enables the caller to provide more detailed information about the decode
|
||||
|
|
|
@ -163,9 +163,23 @@ interface imgIRequest : nsIRequest
|
|||
/**
|
||||
* Exactly like startDecoding above except returns whether the current frame
|
||||
* of the image is complete or not.
|
||||
*
|
||||
* @param aFlags Flags of the FLAG_* variety. Only FLAG_ASYNC_NOTIFY
|
||||
* is accepted; all others are ignored.
|
||||
*/
|
||||
[noscript, notxpcom] boolean startDecodingWithResult(in uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* This method triggers decoding for an image, but unlike startDecoding() it
|
||||
* enables the caller to provide more detailed information about the decode
|
||||
* request.
|
||||
*
|
||||
* @param aFlags Flags of the FLAG_* variety.
|
||||
* @return True there is a surface that satisfies the request and it is
|
||||
* fully decoded, else false.
|
||||
*/
|
||||
[noscript, notxpcom] boolean requestDecodeWithResult(in uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Locks an image. If the image does not exist yet, locks it once it becomes
|
||||
* available. The lock persists for the lifetime of the imgIRequest (until
|
||||
|
|
|
@ -543,6 +543,24 @@ bool imgRequestProxy::StartDecodingWithResult(uint32_t aFlags) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool imgRequestProxy::RequestDecodeWithResult(uint32_t aFlags) {
|
||||
if (IsValidating()) {
|
||||
mDecodeRequested = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<Image> image = GetImage();
|
||||
if (image) {
|
||||
return image->RequestDecodeWithResult(aFlags);
|
||||
}
|
||||
|
||||
if (GetOwner()) {
|
||||
GetOwner()->StartDecoding();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
imgRequestProxy::LockImage() {
|
||||
mLockCount++;
|
||||
|
|
|
@ -42,11 +42,14 @@ nsEffectiveTLDService::nsEffectiveTLDService()
|
|||
: mIDNService(), mGraph(etld_dafsa::kDafsa) {}
|
||||
|
||||
nsresult nsEffectiveTLDService::Init() {
|
||||
if (gService) {
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
MOZ_ASSERT(!gService);
|
||||
gService = this;
|
||||
RegisterWeakMemoryReporter(this);
|
||||
|
||||
|
@ -55,7 +58,10 @@ nsresult nsEffectiveTLDService::Init() {
|
|||
|
||||
nsEffectiveTLDService::~nsEffectiveTLDService() {
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
gService = nullptr;
|
||||
if (mIDNService) {
|
||||
// Only clear gService if Init() finished successfully.
|
||||
gService = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -5,6 +5,7 @@ support-files =
|
|||
redirect.sjs
|
||||
|
||||
[browser_about_cache.js]
|
||||
[browser_bug1535877.js]
|
||||
[browser_NetUtil.js]
|
||||
[browser_child_resource.js]
|
||||
skip-if = !crashreporter || (e10s && debug && os == "linux" && bits == 64) || debug # Bug 1370783
|
||||
|
|
|
@ -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)
|
||||
rustup = self.which('rustup', cargo_bin)
|
||||
if rustup:
|
||||
self.ensure_rust_targets(rustup, version)
|
||||
self.ensure_rust_targets(rustup)
|
||||
return
|
||||
|
||||
if version:
|
||||
|
@ -697,7 +697,7 @@ class BaseBootstrapper(object):
|
|||
print('Will try to install Rust.')
|
||||
self.install_rust()
|
||||
|
||||
def ensure_rust_targets(self, rustup, rust_version):
|
||||
def ensure_rust_targets(self, rustup):
|
||||
"""Make sure appropriate cross target libraries are installed."""
|
||||
target_list = subprocess.check_output([rustup, 'target', 'list'])
|
||||
targets = [line.split()[0] for line in target_list.splitlines()
|
||||
|
@ -712,11 +712,7 @@ class BaseBootstrapper(object):
|
|||
|
||||
if 'mobile_android' in self.application:
|
||||
# Let's add the most common targets.
|
||||
if LooseVersion(rust_version) < '1.33':
|
||||
arm_target = 'armv7-linux-androideabi'
|
||||
else:
|
||||
arm_target = 'thumbv7neon-linux-androideabi'
|
||||
android_targets = (arm_target,
|
||||
android_targets = ('thumbv7neon-linux-androideabi',
|
||||
'aarch64-linux-android',
|
||||
'i686-linux-android',
|
||||
'x86_64-linux-android', )
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
|
||||
[fetch.any.serviceworker.html]
|
||||
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1540914
|
||||
[Valid cross-origin no-cors fetch with a 'Cross-Origin-Resource-Policy: same-site' response header.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -477,15 +477,6 @@ prefs: [dom.security.featurePolicy.enabled:true]
|
|||
[HTMLBodyElement interface: document.createElement("body") must inherit property "onunhandledrejection" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: operation decode()]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: document.createElement("img") must inherit property "decode()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement interface: new Image() must inherit property "decode()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: attribute allowUserMedia]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
[image-decode-iframe.html]
|
||||
expected:
|
||||
ERROR
|
||||
[(misc) Decode from removed iframe fails (loaded img)]
|
||||
expected: TIMEOUT
|
||||
|
||||
[(misc) Decode from removed iframe fails (img not loaded)]
|
||||
expected: NOTRUN
|
||||
|
||||
[(misc) Decode from iframe, later removed, fails (img not loaded)]
|
||||
expected: NOTRUN
|
||||
|
||||
[HTMLImageElement.prototype.decode(), iframe tests. Decode from removed iframe fails (loaded img)]
|
||||
expected: TIMEOUT
|
||||
expected: TIMEOUT
|
||||
|
||||
[HTMLImageElement.prototype.decode(), iframe tests. Decode from removed iframe fails (img not loaded)]
|
||||
expected: NOTRUN
|
||||
expected: TIMEOUT
|
||||
|
||||
[HTMLImageElement.prototype.decode(), iframe tests. Decode from iframe, later removed, fails (img not loaded)]
|
||||
expected: NOTRUN
|
||||
|
|
|
@ -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
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
# to registry (e.g. crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
[package]
|
||||
name = "gleam"
|
||||
version = "0.6.15"
|
||||
version = "0.6.16"
|
||||
authors = ["The Servo Project Developers"]
|
||||
build = "build.rs"
|
||||
description = "Generated OpenGL bindings and wrapper for Servo."
|
||||
|
|
|
@ -553,6 +553,9 @@ declare_gl_apis! {
|
|||
fn insert_event_marker_ext(&self, message: &str);
|
||||
fn push_group_marker_ext(&self, message: &str);
|
||||
fn pop_group_marker_ext(&self);
|
||||
fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str);
|
||||
fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str);
|
||||
fn pop_debug_group_khr(&self);
|
||||
fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync;
|
||||
fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
|
||||
fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
|
||||
|
|
|
@ -1946,6 +1946,32 @@ impl Gl for GlFns {
|
|||
}
|
||||
}
|
||||
|
||||
fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) {
|
||||
if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_
|
||||
.DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) {
|
||||
if self.ffi_gl_.PushDebugGroupKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_
|
||||
.PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_debug_group_khr(&self) {
|
||||
if self.ffi_gl_.PopDebugGroupKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_.PopDebugGroupKHR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
|
||||
unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ }
|
||||
}
|
||||
|
|
|
@ -1952,6 +1952,32 @@ impl Gl for GlesFns {
|
|||
}
|
||||
}
|
||||
|
||||
fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) {
|
||||
if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_
|
||||
.DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) {
|
||||
if self.ffi_gl_.PushDebugGroupKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_
|
||||
.PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_debug_group_khr(&self) {
|
||||
if self.ffi_gl_.PopDebugGroupKHR.is_loaded() {
|
||||
unsafe {
|
||||
self.ffi_gl_.PopDebugGroupKHR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
|
||||
unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ }
|
||||
}
|
||||
|
|
|
@ -642,6 +642,11 @@ with modules["DOM"]:
|
|||
# decoding process.
|
||||
errors["NS_ERROR_DOM_JS_DECODING_ERROR"] = FAILURE(1026)
|
||||
|
||||
# Image decode errors.
|
||||
errors["NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT"] = FAILURE(1027)
|
||||
errors["NS_ERROR_DOM_IMAGE_INVALID_REQUEST"] = FAILURE(1028)
|
||||
errors["NS_ERROR_DOM_IMAGE_BROKEN"] = FAILURE(1029)
|
||||
|
||||
# May be used to indicate when e.g. setting a property value didn't
|
||||
# actually change the value, like for obj.foo = "bar"; obj.foo = "bar";
|
||||
# the second assignment throws NS_SUCCESS_DOM_NO_OPERATION.
|
||||
|
|
Загрузка…
Ссылка в новой задаче