gecko-dev/image/SourceBuffer.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

501 lines
18 KiB
C
Raw Normal View History

/* -*- 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/. */
/**
* SourceBuffer is a single producer, multiple consumer data structure used for
* storing image source (compressed) data.
*/
Bug 1038536 - Flatten image/src/ directory. r=seth --HG-- rename : image/src/BMPFileHeaders.h => image/BMPFileHeaders.h rename : image/src/ClippedImage.cpp => image/ClippedImage.cpp rename : image/src/ClippedImage.h => image/ClippedImage.h rename : image/src/DecodePool.cpp => image/DecodePool.cpp rename : image/src/DecodePool.h => image/DecodePool.h rename : image/src/Decoder.cpp => image/Decoder.cpp rename : image/src/Decoder.h => image/Decoder.h rename : image/src/Downscaler.cpp => image/Downscaler.cpp rename : image/src/Downscaler.h => image/Downscaler.h rename : image/src/DynamicImage.cpp => image/DynamicImage.cpp rename : image/src/DynamicImage.h => image/DynamicImage.h rename : image/src/FrameAnimator.cpp => image/FrameAnimator.cpp rename : image/src/FrameAnimator.h => image/FrameAnimator.h rename : image/src/FrozenImage.cpp => image/FrozenImage.cpp rename : image/src/FrozenImage.h => image/FrozenImage.h rename : image/src/ICOFileHeaders.h => image/ICOFileHeaders.h rename : image/src/IProgressObserver.h => image/IProgressObserver.h rename : image/src/Image.cpp => image/Image.cpp rename : image/src/Image.h => image/Image.h rename : image/src/ImageFactory.cpp => image/ImageFactory.cpp rename : image/src/ImageFactory.h => image/ImageFactory.h rename : image/src/ImageMetadata.cpp => image/ImageMetadata.cpp rename : image/src/ImageMetadata.h => image/ImageMetadata.h rename : image/src/ImageOps.cpp => image/ImageOps.cpp rename : image/src/ImageOps.h => image/ImageOps.h rename : image/src/ImageRegion.h => image/ImageRegion.h rename : image/src/ImageURL.h => image/ImageURL.h rename : image/src/ImageWrapper.cpp => image/ImageWrapper.cpp rename : image/src/ImageWrapper.h => image/ImageWrapper.h rename : image/src/MultipartImage.cpp => image/MultipartImage.cpp rename : image/src/MultipartImage.h => image/MultipartImage.h rename : image/src/Orientation.h => image/Orientation.h rename : image/src/OrientedImage.cpp => image/OrientedImage.cpp rename : image/src/OrientedImage.h => image/OrientedImage.h rename : image/src/ProgressTracker.cpp => image/ProgressTracker.cpp rename : image/src/ProgressTracker.h => image/ProgressTracker.h rename : image/src/RasterImage.cpp => image/RasterImage.cpp rename : image/src/RasterImage.h => image/RasterImage.h rename : image/src/SVGDocumentWrapper.cpp => image/SVGDocumentWrapper.cpp rename : image/src/SVGDocumentWrapper.h => image/SVGDocumentWrapper.h rename : image/src/ScriptedNotificationObserver.cpp => image/ScriptedNotificationObserver.cpp rename : image/src/ScriptedNotificationObserver.h => image/ScriptedNotificationObserver.h rename : image/src/ShutdownTracker.cpp => image/ShutdownTracker.cpp rename : image/src/ShutdownTracker.h => image/ShutdownTracker.h rename : image/src/SourceBuffer.cpp => image/SourceBuffer.cpp rename : image/src/SourceBuffer.h => image/SourceBuffer.h rename : image/src/SurfaceCache.cpp => image/SurfaceCache.cpp rename : image/src/SurfaceCache.h => image/SurfaceCache.h rename : image/src/VectorImage.cpp => image/VectorImage.cpp rename : image/src/VectorImage.h => image/VectorImage.h rename : image/src/imgFrame.cpp => image/imgFrame.cpp rename : image/src/imgFrame.h => image/imgFrame.h rename : image/src/imgLoader.cpp => image/imgLoader.cpp rename : image/src/imgLoader.h => image/imgLoader.h rename : image/src/imgRequest.cpp => image/imgRequest.cpp rename : image/src/imgRequest.h => image/imgRequest.h rename : image/src/imgRequestProxy.cpp => image/imgRequestProxy.cpp rename : image/src/imgRequestProxy.h => image/imgRequestProxy.h rename : image/src/imgTools.cpp => image/imgTools.cpp rename : image/src/imgTools.h => image/imgTools.h
2015-05-15 03:52:05 +00:00
#ifndef mozilla_image_sourcebuffer_h
#define mozilla_image_sourcebuffer_h
#include <algorithm>
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Mutex.h"
#include "mozilla/Move.h"
#include "mozilla/MemoryReporting.h"
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
#include "mozilla/UniquePtr.h"
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
#include "mozilla/RefPtr.h"
#include "nsTArray.h"
class nsIInputStream;
namespace mozilla {
namespace image {
class SourceBuffer;
/**
* IResumable is an interface for classes that can schedule themselves to resume
* their work later. An implementation of IResumable generally should post a
* runnable to some event target which continues the work of the task.
*/
struct IResumable {
MOZ_DECLARE_REFCOUNTED_TYPENAME(IResumable)
// Subclasses may or may not be XPCOM classes, so we just require that they
// implement AddRef and Release.
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
virtual void Resume() = 0;
protected:
virtual ~IResumable() {}
};
/**
* SourceBufferIterator is a class that allows consumers of image source data to
* read the contents of a SourceBuffer sequentially.
*
* Consumers can advance through the SourceBuffer by calling
* AdvanceOrScheduleResume() repeatedly. After every advance, they should call
* check the return value, which will tell them the iterator's new state.
*
* If WAITING is returned, AdvanceOrScheduleResume() has arranged
* to call the consumer's Resume() method later, so the consumer should save its
* state if needed and stop running.
*
* If the iterator's new state is READY, then the consumer can call Data() and
* Length() to read new data from the SourceBuffer.
*
* Finally, in the COMPLETE state the consumer can call CompletionStatus() to
* get the status passed to SourceBuffer::Complete().
*/
class SourceBufferIterator final {
public:
enum State {
START, // The iterator is at the beginning of the buffer.
READY, // The iterator is pointing to new data.
WAITING, // The iterator is blocked and the caller must yield.
COMPLETE // The iterator is pointing to the end of the buffer.
};
explicit SourceBufferIterator(SourceBuffer* aOwner, size_t aReadLimit)
: mOwner(aOwner),
mState(START),
mChunkCount(0),
mByteCount(0),
mRemainderToRead(aReadLimit) {
MOZ_ASSERT(aOwner);
mData.mIterating.mChunk = 0;
mData.mIterating.mData = nullptr;
mData.mIterating.mOffset = 0;
mData.mIterating.mAvailableLength = 0;
mData.mIterating.mNextReadLength = 0;
}
SourceBufferIterator(SourceBufferIterator&& aOther)
: mOwner(std::move(aOther.mOwner)),
mState(aOther.mState),
mData(aOther.mData),
mChunkCount(aOther.mChunkCount),
mByteCount(aOther.mByteCount),
mRemainderToRead(aOther.mRemainderToRead) {}
~SourceBufferIterator();
SourceBufferIterator& operator=(SourceBufferIterator&& aOther);
/**
* Returns true if there are no more than @aBytes remaining in the
* SourceBuffer. If the SourceBuffer is not yet complete, returns false.
*/
bool RemainingBytesIsNoMoreThan(size_t aBytes) const;
/**
* Advances the iterator through the SourceBuffer if possible. Advances no
* more than @aRequestedBytes bytes. (Use SIZE_MAX to advance as much as
* possible.)
*
* This is a wrapper around AdvanceOrScheduleResume() that makes it clearer at
* the callsite when the no resuming is intended.
*
* @return State::READY if the iterator was successfully advanced.
* State::WAITING if the iterator could not be advanced because it's
* at the end of the underlying SourceBuffer, but the SourceBuffer
* may still receive additional data.
* State::COMPLETE if the iterator could not be advanced because it's
* at the end of the underlying SourceBuffer and the SourceBuffer is
* marked complete (i.e., it will never receive any additional
* data).
*/
State Advance(size_t aRequestedBytes) {
return AdvanceOrScheduleResume(aRequestedBytes, nullptr);
}
/**
* Advances the iterator through the SourceBuffer if possible. Advances no
* more than @aRequestedBytes bytes. (Use SIZE_MAX to advance as much as
* possible.) If advancing is not possible and @aConsumer is not null,
* arranges to call the @aConsumer's Resume() method when more data is
* available.
*
* @return State::READY if the iterator was successfully advanced.
* State::WAITING if the iterator could not be advanced because it's
* at the end of the underlying SourceBuffer, but the SourceBuffer
* may still receive additional data. @aConsumer's Resume() method
* will be called when additional data is available.
* State::COMPLETE if the iterator could not be advanced because it's
* at the end of the underlying SourceBuffer and the SourceBuffer is
* marked complete (i.e., it will never receive any additional
* data).
*/
State AdvanceOrScheduleResume(size_t aRequestedBytes, IResumable* aConsumer);
/// If at the end, returns the status passed to SourceBuffer::Complete().
nsresult CompletionStatus() const {
MOZ_ASSERT(mState == COMPLETE,
"Calling CompletionStatus() in the wrong state");
return mState == COMPLETE ? mData.mAtEnd.mStatus : NS_OK;
}
/// If we're ready to read, returns a pointer to the new data.
const char* Data() const {
MOZ_ASSERT(mState == READY, "Calling Data() in the wrong state");
return mState == READY ? mData.mIterating.mData + mData.mIterating.mOffset
: nullptr;
}
/// If we're ready to read, returns the length of the new data.
size_t Length() const {
MOZ_ASSERT(mState == READY, "Calling Length() in the wrong state");
return mState == READY ? mData.mIterating.mNextReadLength : 0;
}
/// If we're ready to read, returns whether or not everything available thus
/// far has been in the same contiguous buffer.
bool IsContiguous() const {
MOZ_ASSERT(mState == READY, "Calling IsContiguous() in the wrong state");
return mState == READY ? mData.mIterating.mChunk == 0 : false;
}
/// @return a count of the chunks we've advanced through.
uint32_t ChunkCount() const { return mChunkCount; }
/// @return a count of the bytes in all chunks we've advanced through.
size_t ByteCount() const { return mByteCount; }
/// @return the source buffer which owns the iterator.
SourceBuffer* Owner() const {
MOZ_ASSERT(mOwner);
return mOwner;
}
/// @return the current offset from the beginning of the buffer.
size_t Position() const {
return mByteCount - mData.mIterating.mAvailableLength;
}
private:
friend class SourceBuffer;
SourceBufferIterator(const SourceBufferIterator&) = delete;
SourceBufferIterator& operator=(const SourceBufferIterator&) = delete;
bool HasMore() const { return mState != COMPLETE; }
State AdvanceFromLocalBuffer(size_t aRequestedBytes) {
MOZ_ASSERT(mState == READY, "Advancing in the wrong state");
MOZ_ASSERT(mData.mIterating.mAvailableLength > 0,
"The local buffer shouldn't be empty");
MOZ_ASSERT(mData.mIterating.mNextReadLength == 0,
"Advancing without consuming previous data");
mData.mIterating.mNextReadLength =
std::min(mData.mIterating.mAvailableLength, aRequestedBytes);
return READY;
}
State SetReady(uint32_t aChunk, const char* aData, size_t aOffset,
size_t aAvailableLength, size_t aRequestedBytes) {
MOZ_ASSERT(mState != COMPLETE);
mState = READY;
// Prevent the iterator from reporting more data than it is allowed to read.
if (aAvailableLength > mRemainderToRead) {
aAvailableLength = mRemainderToRead;
}
// Update state.
mData.mIterating.mChunk = aChunk;
mData.mIterating.mData = aData;
mData.mIterating.mOffset = aOffset;
mData.mIterating.mAvailableLength = aAvailableLength;
// Update metrics.
mChunkCount++;
mByteCount += aAvailableLength;
// Attempt to advance by the requested number of bytes.
return AdvanceFromLocalBuffer(aRequestedBytes);
}
State SetWaiting(bool aHasConsumer) {
MOZ_ASSERT(mState != COMPLETE);
// Without a consumer, we won't know when to wake up precisely. Caller
// convention should mean that we don't try to advance unless we have
// written new data, but that doesn't mean we got enough.
MOZ_ASSERT(mState != WAITING || !aHasConsumer,
"Did we get a spurious wakeup somehow?");
return mState = WAITING;
}
State SetComplete(nsresult aStatus) {
mData.mAtEnd.mStatus = aStatus;
return mState = COMPLETE;
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<SourceBuffer> mOwner;
State mState;
/**
* This union contains our iteration state if we're still iterating (for
* states START, READY, and WAITING) and the status the SourceBuffer was
* completed with if we're in state COMPLETE.
*/
union {
struct {
uint32_t mChunk; // Index of the chunk in SourceBuffer.
const char* mData; // Pointer to the start of the chunk.
size_t mOffset; // Current read position of the iterator relative to
// mData.
size_t mAvailableLength; // How many bytes remain unread in the chunk,
// relative to mOffset.
size_t
mNextReadLength; // How many bytes the last iterator advance
// requested to be read, so that we know much
// to increase mOffset and reduce mAvailableLength
// by when the next advance is requested.
} mIterating; // Cached info of the chunk currently iterating over.
struct {
nsresult mStatus; // Status code indicating if we read all the data.
} mAtEnd; // State info after iterator is complete.
} mData;
uint32_t mChunkCount; // Count of chunks observed, including current chunk.
size_t mByteCount; // Count of readable bytes observed, including unread
// bytes from the current chunk.
size_t mRemainderToRead; // Count of bytes left to read if there is a maximum
// imposed by the caller. SIZE_MAX if unlimited.
};
/**
* SourceBuffer is a parallel data structure used for storing image source
* (compressed) data.
*
* SourceBuffer is a single producer, multiple consumer data structure. The
* single producer calls Append() to append data to the buffer. In parallel,
* multiple consumers can call Iterator(), which returns a SourceBufferIterator
* that they can use to iterate through the buffer. The SourceBufferIterator
* returns a series of pointers which remain stable for lifetime of the
* SourceBuffer, and the data they point to is immutable, ensuring that the
* producer never interferes with the consumers.
*
* In order to avoid blocking, SourceBuffer works with SourceBufferIterator to
* keep a list of consumers which are waiting for new data, and to resume them
* when the producer appends more. All consumers must implement the IResumable
* interface to make this possible.
*/
class SourceBuffer final {
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(image::SourceBuffer)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(image::SourceBuffer)
SourceBuffer();
//////////////////////////////////////////////////////////////////////////////
// Producer methods.
//////////////////////////////////////////////////////////////////////////////
/**
* If the producer knows how long the source data will be, it should call
* ExpectLength, which enables SourceBuffer to preallocate its buffer.
*/
nsresult ExpectLength(size_t aExpectedLength);
/// Append the provided data to the buffer.
nsresult Append(const char* aData, size_t aLength);
/// Append the data available on the provided nsIInputStream to the buffer.
nsresult AppendFromInputStream(nsIInputStream* aInputStream, uint32_t aCount);
/**
* Mark the buffer complete, with a status that will be available to
* consumers. Further calls to Append() are forbidden after Complete().
*/
void Complete(nsresult aStatus);
/// Returns true if the buffer is complete.
bool IsComplete();
/// Memory reporting.
size_t SizeOfIncludingThisWithComputedFallback(MallocSizeOf) const;
//////////////////////////////////////////////////////////////////////////////
// Consumer methods.
//////////////////////////////////////////////////////////////////////////////
/**
* Returns an iterator to this SourceBuffer, which cannot read more than the
* given length.
*/
SourceBufferIterator Iterator(size_t aReadLength = SIZE_MAX);
//////////////////////////////////////////////////////////////////////////////
// Consumer methods.
//////////////////////////////////////////////////////////////////////////////
/**
* The minimum chunk capacity we'll allocate, if we don't know the correct
* capacity (which would happen because ExpectLength() wasn't called or gave
* us the wrong value). This is only exposed for use by tests; if normal code
* is using this, it's doing something wrong.
*/
static const size_t MIN_CHUNK_CAPACITY = 4096;
/**
* The maximum chunk capacity we'll allocate. This was historically the
* maximum we would preallocate based on the network size. We may adjust it
* in the future based on the IMAGE_DECODE_CHUNKS telemetry to ensure most
* images remain in a single chunk.
*/
static const size_t MAX_CHUNK_CAPACITY = 20 * 1024 * 1024;
private:
friend class SourceBufferIterator;
~SourceBuffer();
//////////////////////////////////////////////////////////////////////////////
// Chunk type and chunk-related methods.
//////////////////////////////////////////////////////////////////////////////
class Chunk final {
public:
explicit Chunk(size_t aCapacity) : mCapacity(aCapacity), mLength(0) {
MOZ_ASSERT(aCapacity > 0, "Creating zero-capacity chunk");
mData = static_cast<char*>(malloc(mCapacity));
}
~Chunk() { free(mData); }
Chunk(Chunk&& aOther)
: mCapacity(aOther.mCapacity),
mLength(aOther.mLength),
mData(aOther.mData) {
aOther.mCapacity = aOther.mLength = 0;
aOther.mData = nullptr;
}
Chunk& operator=(Chunk&& aOther) {
free(mData);
mCapacity = aOther.mCapacity;
mLength = aOther.mLength;
mData = aOther.mData;
aOther.mCapacity = aOther.mLength = 0;
aOther.mData = nullptr;
return *this;
}
bool AllocationFailed() const { return !mData; }
size_t Capacity() const { return mCapacity; }
size_t Length() const { return mLength; }
char* Data() const {
MOZ_ASSERT(mData, "Allocation failed but nobody checked for it");
return mData;
}
void AddLength(size_t aAdditionalLength) {
MOZ_ASSERT(mLength + aAdditionalLength <= mCapacity);
mLength += aAdditionalLength;
}
bool SetCapacity(size_t aCapacity) {
MOZ_ASSERT(mData, "Allocation failed but nobody checked for it");
char* data = static_cast<char*>(realloc(mData, aCapacity));
if (!data) {
return false;
}
mData = data;
mCapacity = aCapacity;
return true;
}
private:
Chunk(const Chunk&) = delete;
Chunk& operator=(const Chunk&) = delete;
size_t mCapacity;
size_t mLength;
char* mData;
};
nsresult AppendChunk(Maybe<Chunk>&& aChunk);
Maybe<Chunk> CreateChunk(size_t aCapacity, size_t aExistingCapacity = 0,
bool aRoundUp = true);
nsresult Compact();
static size_t RoundedUpCapacity(size_t aCapacity);
size_t FibonacciCapacityWithMinimum(size_t aMinCapacity);
//////////////////////////////////////////////////////////////////////////////
// Iterator / consumer methods.
//////////////////////////////////////////////////////////////////////////////
void AddWaitingConsumer(IResumable* aConsumer);
void ResumeWaitingConsumers();
typedef SourceBufferIterator::State State;
State AdvanceIteratorOrScheduleResume(SourceBufferIterator& aIterator,
size_t aRequestedBytes,
IResumable* aConsumer);
bool RemainingBytesIsNoMoreThan(const SourceBufferIterator& aIterator,
size_t aBytes) const;
void OnIteratorRelease();
//////////////////////////////////////////////////////////////////////////////
// Helper methods.
//////////////////////////////////////////////////////////////////////////////
nsresult HandleError(nsresult aError);
bool IsEmpty();
bool IsLastChunk(uint32_t aChunk);
//////////////////////////////////////////////////////////////////////////////
// Member variables.
//////////////////////////////////////////////////////////////////////////////
/// All private members are protected by mMutex.
mutable Mutex mMutex;
/// The data in this SourceBuffer, stored as a series of Chunks.
AutoTArray<Chunk, 1> mChunks;
/// Consumers which are waiting to be notified when new data is available.
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
nsTArray<RefPtr<IResumable>> mWaitingConsumers;
/// If present, marks this SourceBuffer complete with the given final status.
Maybe<nsresult> mStatus;
/// Count of active consumers.
uint32_t mConsumerCount;
/// True if compacting has been performed.
bool mCompacted;
};
} // namespace image
} // namespace mozilla
Bug 1038536 - Flatten image/src/ directory. r=seth --HG-- rename : image/src/BMPFileHeaders.h => image/BMPFileHeaders.h rename : image/src/ClippedImage.cpp => image/ClippedImage.cpp rename : image/src/ClippedImage.h => image/ClippedImage.h rename : image/src/DecodePool.cpp => image/DecodePool.cpp rename : image/src/DecodePool.h => image/DecodePool.h rename : image/src/Decoder.cpp => image/Decoder.cpp rename : image/src/Decoder.h => image/Decoder.h rename : image/src/Downscaler.cpp => image/Downscaler.cpp rename : image/src/Downscaler.h => image/Downscaler.h rename : image/src/DynamicImage.cpp => image/DynamicImage.cpp rename : image/src/DynamicImage.h => image/DynamicImage.h rename : image/src/FrameAnimator.cpp => image/FrameAnimator.cpp rename : image/src/FrameAnimator.h => image/FrameAnimator.h rename : image/src/FrozenImage.cpp => image/FrozenImage.cpp rename : image/src/FrozenImage.h => image/FrozenImage.h rename : image/src/ICOFileHeaders.h => image/ICOFileHeaders.h rename : image/src/IProgressObserver.h => image/IProgressObserver.h rename : image/src/Image.cpp => image/Image.cpp rename : image/src/Image.h => image/Image.h rename : image/src/ImageFactory.cpp => image/ImageFactory.cpp rename : image/src/ImageFactory.h => image/ImageFactory.h rename : image/src/ImageMetadata.cpp => image/ImageMetadata.cpp rename : image/src/ImageMetadata.h => image/ImageMetadata.h rename : image/src/ImageOps.cpp => image/ImageOps.cpp rename : image/src/ImageOps.h => image/ImageOps.h rename : image/src/ImageRegion.h => image/ImageRegion.h rename : image/src/ImageURL.h => image/ImageURL.h rename : image/src/ImageWrapper.cpp => image/ImageWrapper.cpp rename : image/src/ImageWrapper.h => image/ImageWrapper.h rename : image/src/MultipartImage.cpp => image/MultipartImage.cpp rename : image/src/MultipartImage.h => image/MultipartImage.h rename : image/src/Orientation.h => image/Orientation.h rename : image/src/OrientedImage.cpp => image/OrientedImage.cpp rename : image/src/OrientedImage.h => image/OrientedImage.h rename : image/src/ProgressTracker.cpp => image/ProgressTracker.cpp rename : image/src/ProgressTracker.h => image/ProgressTracker.h rename : image/src/RasterImage.cpp => image/RasterImage.cpp rename : image/src/RasterImage.h => image/RasterImage.h rename : image/src/SVGDocumentWrapper.cpp => image/SVGDocumentWrapper.cpp rename : image/src/SVGDocumentWrapper.h => image/SVGDocumentWrapper.h rename : image/src/ScriptedNotificationObserver.cpp => image/ScriptedNotificationObserver.cpp rename : image/src/ScriptedNotificationObserver.h => image/ScriptedNotificationObserver.h rename : image/src/ShutdownTracker.cpp => image/ShutdownTracker.cpp rename : image/src/ShutdownTracker.h => image/ShutdownTracker.h rename : image/src/SourceBuffer.cpp => image/SourceBuffer.cpp rename : image/src/SourceBuffer.h => image/SourceBuffer.h rename : image/src/SurfaceCache.cpp => image/SurfaceCache.cpp rename : image/src/SurfaceCache.h => image/SurfaceCache.h rename : image/src/VectorImage.cpp => image/VectorImage.cpp rename : image/src/VectorImage.h => image/VectorImage.h rename : image/src/imgFrame.cpp => image/imgFrame.cpp rename : image/src/imgFrame.h => image/imgFrame.h rename : image/src/imgLoader.cpp => image/imgLoader.cpp rename : image/src/imgLoader.h => image/imgLoader.h rename : image/src/imgRequest.cpp => image/imgRequest.cpp rename : image/src/imgRequest.h => image/imgRequest.h rename : image/src/imgRequestProxy.cpp => image/imgRequestProxy.cpp rename : image/src/imgRequestProxy.h => image/imgRequestProxy.h rename : image/src/imgTools.cpp => image/imgTools.cpp rename : image/src/imgTools.h => image/imgTools.h
2015-05-15 03:52:05 +00:00
#endif // mozilla_image_sourcebuffer_h