mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
9af8eeaf15
- Bug 1125514 - Use jemalloc's metadata statistics to compute bookkeeping. r=glandium (541dbcfc6f) - Bug 1201462 - Don't count arena allocated metadata once per bin. r=glandium (57e7c31081) - back some warnings (377df69d65) - Bug 1219501. In imagelib, initialize the number of cores to at least 1 in case of error. r=seth (3d7d1635f0) - Bug 1219501. Limit total number of image decoding threads to 32 regardless of number asked for. r=seth (829a7a623d) - Bug 1213744 (Part 1) - Support zero-size frame rects and detecting the end of the frame in Downscaler. r=tn (05e29075cc) - Bug 1213744 (Part 2) - Clamp the GIF frame rect to the visible rect for DDD and don't decode outside it. r=tn (8a25e10a3e) - Bug 1194837. Don't use the inverse orientation matrix when computing the image space invalidate rect. r=seth (cb5e4c2643) - Bug 1214054 - Don't fire DECODE_COMPLETE in VectorImage::OnSVGDocumetError(). r=dholbert (bb7c34e46f) - Bug 1195878 - If we detect animation during a full decode, drop the results of the full decode on the floor. r=tn (a765af2b68) - Bug 1210553 - Remove the alternate flags arguments from SurfaceCache's Lookup functions. r=dholbert (15c6124f98) - Bug 1217320 - Remove more XPIDL signature comments in .cpp files. r=froydnj (411ac93047) - Bug 1186796 - Replace nsBaseHashtable::EnumerateRead() calls in image/ with iterators r=njn (665773ae6d) - Bug 1186792 - Replace nsBaseHashtable::EnumerateRead() calls in hal/ with iterators. r=dhylands. (d57c6b11da) - Bug 1187142 - Replace nsBaseHashtable::Enumerate() calls in hal/ with iterators. r=dhylands. (ec05c5b125) - Bug 1186793 - Replace nsBaseHashtable::EnumerateRead() calls in gfx/ with iterators r=njn (9b3cdd92ce) - Bug 1215900 - Fix clang's -Wimplicit-fallthrough warnings in gfx/ipc/ GfxMessageUtils.h. r=mstange (f55605f1fe) - Bug 618898 - Part 1: Add WGL_NV_DX_interop. r=jgilbert (73390398ed) - Bug 618898 - Add D3D11SharedSurfaceInterop. r=jgilbert (3dde956b85) - Bug 1208513 - Resurrect SharedSurface_GLTexture for use on iOS r=jgilbert (b0fdc90414) - Bug 1150760 - Don't call workaround unless necessary. - r=kamidphish (9bdd135931) - Bug 1151106 - let debugger stop on each iteration of a "for(;;)" loop; r=jimb (b1b921c3a7) - Bug 1223652 - Remove redundant else block after return statement in CGBlockScopeList::findEnclosingScope. r=arai (f1368bfc73) - Bug 1219515 - IonMonkey: Fix ThrowIfNotConstructing was not declared. r=evilpie (1d6cedad10) - Bug 1224044 - Use stable hashing in SavedFramePtrHasher r=terrence (4389cf1b70) - Bug 1206596: Change js::SavedStacks to use mozilla::FastBernoulliTrial. r=fitzgen (1c4a8d1929) - Bug 1206357: Add mfbt/FastBernoulliTrial.h, implementing efficient random sampling. r=waldo (7143e53dba) - No bug: Fix comment in mfbt/FastBernoulliTrial.h. DONTBUILD r=me (e3343f8d9d) - Bug 1217919 - Separate dynamic module scopes from those of function calls r=shu (521f6826e5) - Bug 1202568 - Cherry-pick warning fixes from upstream double-conversion. r=Ms2ger (ef738f753b) - add back some disabled android stuff (0351b0c518) - Bug 1135261 - return new window from window.open in desktop runtime; r=marco,smaug,junior,wesj (fa4d8f2468) - Bug 898075 - Remove the mozbrowserasyncscroll event from Gecko. r=botond,kanru,sicking (b1fdcb7630) - namespace (91374d2db8)
235 lines
7.9 KiB
C++
235 lines
7.9 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_image_ProgressTracker_h
|
|
#define mozilla_image_ProgressTracker_h
|
|
|
|
#include "CopyOnWrite.h"
|
|
#include "mozilla/Mutex.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "mozilla/WeakPtr.h"
|
|
#include "nsDataHashtable.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsTObserverArray.h"
|
|
#include "nsThreadUtils.h"
|
|
#include "nsRect.h"
|
|
#include "IProgressObserver.h"
|
|
|
|
class nsIRunnable;
|
|
|
|
namespace mozilla {
|
|
namespace image {
|
|
|
|
class AsyncNotifyRunnable;
|
|
class AsyncNotifyCurrentStateRunnable;
|
|
class Image;
|
|
|
|
/**
|
|
* Image progress bitflags.
|
|
*
|
|
* See CheckProgressConsistency() for the invariants we enforce about the
|
|
* ordering dependencies betweeen these flags.
|
|
*/
|
|
enum {
|
|
FLAG_SIZE_AVAILABLE = 1u << 0, // STATUS_SIZE_AVAILABLE
|
|
FLAG_DECODE_COMPLETE = 1u << 1, // STATUS_DECODE_COMPLETE
|
|
FLAG_FRAME_COMPLETE = 1u << 2, // STATUS_FRAME_COMPLETE
|
|
FLAG_LOAD_COMPLETE = 1u << 3, // STATUS_LOAD_COMPLETE
|
|
FLAG_ONLOAD_BLOCKED = 1u << 4,
|
|
FLAG_ONLOAD_UNBLOCKED = 1u << 5,
|
|
FLAG_IS_ANIMATED = 1u << 6, // STATUS_IS_ANIMATED
|
|
FLAG_HAS_TRANSPARENCY = 1u << 7, // STATUS_HAS_TRANSPARENCY
|
|
FLAG_LAST_PART_COMPLETE = 1u << 8,
|
|
FLAG_HAS_ERROR = 1u << 9 // STATUS_ERROR
|
|
};
|
|
|
|
typedef uint32_t Progress;
|
|
|
|
const uint32_t NoProgress = 0;
|
|
|
|
inline Progress LoadCompleteProgress(bool aLastPart,
|
|
bool aError,
|
|
nsresult aStatus)
|
|
{
|
|
Progress progress = FLAG_LOAD_COMPLETE;
|
|
if (aLastPart) {
|
|
progress |= FLAG_LAST_PART_COMPLETE;
|
|
}
|
|
if (NS_FAILED(aStatus) || aError) {
|
|
progress |= FLAG_HAS_ERROR;
|
|
}
|
|
return progress;
|
|
}
|
|
|
|
/**
|
|
* ProgressTracker stores its observers in an ObserverTable, which is a hash
|
|
* table mapping raw pointers to WeakPtr's to the same objects. This sounds like
|
|
* unnecessary duplication of information, but it's necessary for stable hash
|
|
* values since WeakPtr's lose the knowledge of which object they used to point
|
|
* to when that object is destroyed.
|
|
*
|
|
* ObserverTable subclasses nsDataHashtable to add reference counting support
|
|
* and a copy constructor, both of which are needed for use with CopyOnWrite<T>.
|
|
*/
|
|
class ObserverTable
|
|
: public nsDataHashtable<nsPtrHashKey<IProgressObserver>,
|
|
WeakPtr<IProgressObserver>>
|
|
{
|
|
public:
|
|
NS_INLINE_DECL_REFCOUNTING(ObserverTable);
|
|
|
|
ObserverTable() = default;
|
|
|
|
ObserverTable(const ObserverTable& aOther)
|
|
{
|
|
NS_WARNING("Forced to copy ObserverTable due to nested notifications");
|
|
for (auto iter = aOther.ConstIter(); !iter.Done(); iter.Next()) {
|
|
this->Put(iter.Key(), iter.Data());
|
|
}
|
|
}
|
|
|
|
private:
|
|
~ObserverTable() { }
|
|
};
|
|
|
|
/**
|
|
* ProgressTracker is a class that records an Image's progress through the
|
|
* loading and decoding process, and makes it possible to send notifications to
|
|
* IProgressObservers, both synchronously and asynchronously.
|
|
*
|
|
* When a new observer needs to be notified of the current progress of an image,
|
|
* call the Notify() method on this class with the relevant observer as its
|
|
* argument, and the notifications will be replayed to the observer
|
|
* asynchronously.
|
|
*/
|
|
class ProgressTracker : public mozilla::SupportsWeakPtr<ProgressTracker>
|
|
{
|
|
virtual ~ProgressTracker() { }
|
|
|
|
public:
|
|
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ProgressTracker)
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProgressTracker)
|
|
|
|
ProgressTracker()
|
|
: mImageMutex("ProgressTracker::mImage")
|
|
, mImage(nullptr)
|
|
, mObservers(new ObserverTable)
|
|
, mProgress(NoProgress)
|
|
{ }
|
|
|
|
bool HasImage() const { MutexAutoLock lock(mImageMutex); return mImage; }
|
|
already_AddRefed<Image> GetImage() const
|
|
{
|
|
MutexAutoLock lock(mImageMutex);
|
|
RefPtr<Image> image = mImage;
|
|
return image.forget();
|
|
}
|
|
|
|
// Get the current image status (as in imgIRequest).
|
|
uint32_t GetImageStatus() const;
|
|
|
|
// Get the current Progress.
|
|
Progress GetProgress() const { return mProgress; }
|
|
|
|
// Schedule an asynchronous "replaying" of all the notifications that would
|
|
// have to happen to put us in the current state.
|
|
// We will also take note of any notifications that happen between the time
|
|
// Notify() is called and when we call SyncNotify on |aObserver|, and replay
|
|
// them as well.
|
|
// Should be called on the main thread only, since observers and GetURI are
|
|
// not threadsafe.
|
|
void Notify(IProgressObserver* aObserver);
|
|
|
|
// Schedule an asynchronous "replaying" of all the notifications that would
|
|
// have to happen to put us in the state we are in right now.
|
|
// Unlike Notify(), does *not* take into account future notifications.
|
|
// This is only useful if you do not have an imgRequest, e.g., if you are a
|
|
// static request returned from imgIRequest::GetStaticRequest().
|
|
// Should be called on the main thread only, since observers and GetURI are
|
|
// not threadsafe.
|
|
void NotifyCurrentState(IProgressObserver* aObserver);
|
|
|
|
// "Replay" all of the notifications that would have to happen to put us in
|
|
// the state we're currently in.
|
|
// Only use this if you're already servicing an asynchronous call (e.g.
|
|
// OnStartRequest).
|
|
// Should be called on the main thread only, since observers and GetURI are
|
|
// not threadsafe.
|
|
void SyncNotify(IProgressObserver* aObserver);
|
|
|
|
// Get this ProgressTracker ready for a new request. This resets all the
|
|
// state that doesn't persist between requests.
|
|
void ResetForNewRequest();
|
|
|
|
// Stateless notifications. These are dispatched and immediately forgotten
|
|
// about. All of these notifications are main thread only.
|
|
void OnDiscard();
|
|
void OnUnlockedDraw();
|
|
void OnImageAvailable();
|
|
|
|
// Compute the difference between this our progress and aProgress. This allows
|
|
// callers to predict whether SyncNotifyProgress will send any notifications.
|
|
Progress Difference(Progress aProgress) const
|
|
{
|
|
return ~mProgress & aProgress;
|
|
}
|
|
|
|
// Update our state to incorporate the changes in aProgress and synchronously
|
|
// notify our observers.
|
|
//
|
|
// Because this may result in recursive notifications, no decoding locks may
|
|
// be held. Called on the main thread only.
|
|
void SyncNotifyProgress(Progress aProgress,
|
|
const nsIntRect& aInvalidRect = nsIntRect());
|
|
|
|
// We manage a set of observers that are using an image and thus concerned
|
|
// with its loading progress. Weak pointers.
|
|
void AddObserver(IProgressObserver* aObserver);
|
|
bool RemoveObserver(IProgressObserver* aObserver);
|
|
uint32_t ObserverCount() const;
|
|
|
|
// Resets our weak reference to our image. Image subclasses should call this
|
|
// in their destructor.
|
|
void ResetImage();
|
|
|
|
private:
|
|
friend class AsyncNotifyRunnable;
|
|
friend class AsyncNotifyCurrentStateRunnable;
|
|
friend class ImageFactory;
|
|
|
|
ProgressTracker(const ProgressTracker& aOther) = delete;
|
|
|
|
// Sets our weak reference to our image. Only ImageFactory should call this.
|
|
void SetImage(Image* aImage);
|
|
|
|
// Send some notifications that would be necessary to make |aObserver| believe
|
|
// the request is finished downloading and decoding. We only send
|
|
// FLAG_LOAD_COMPLETE and FLAG_ONLOAD_UNBLOCKED, and only if necessary.
|
|
void EmulateRequestFinished(IProgressObserver* aObserver);
|
|
|
|
// Main thread only because it deals with the observer service.
|
|
void FireFailureNotification();
|
|
|
|
// The runnable, if any, that we've scheduled to deliver async notifications.
|
|
nsCOMPtr<nsIRunnable> mRunnable;
|
|
|
|
// mImage is a weak ref; it should be set to null when the image goes out of
|
|
// scope. mImageMutex protects mImage.
|
|
mutable Mutex mImageMutex;
|
|
Image* mImage;
|
|
|
|
// Hashtable of observers attached to the image. Each observer represents a
|
|
// consumer using the image. Main thread only.
|
|
CopyOnWrite<ObserverTable> mObservers;
|
|
|
|
Progress mProgress;
|
|
};
|
|
|
|
} // namespace image
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_image_ProgressTracker_h
|