forked from mirrors/gecko-dev
Bug 1732115 - Part 3. Refactor decoder pipeline to partially use Unoriented/OrientedPixel. r=tnikkel
Rather than change every use of IntSize/Rect/Point in image/, this patch attempts to draw the line at the relevant parts of the decoding pipeline to prevent confusion about which size and orientation we are working with. Differential Revision: https://phabricator.services.mozilla.com/D126381
This commit is contained in:
parent
e2050d4c94
commit
09266efcbc
30 changed files with 294 additions and 307 deletions
|
|
@ -266,12 +266,12 @@ void Decoder::CompleteDecode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Decoder::SetOutputSize(const gfx::IntSize& aSize) {
|
void Decoder::SetOutputSize(const OrientedIntSize& aSize) {
|
||||||
mOutputSize = Some(aSize);
|
mOutputSize = Some(aSize);
|
||||||
mHaveExplicitOutputSize = true;
|
mHaveExplicitOutputSize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<gfx::IntSize> Decoder::ExplicitOutputSize() const {
|
Maybe<OrientedIntSize> Decoder::ExplicitOutputSize() const {
|
||||||
MOZ_ASSERT_IF(mHaveExplicitOutputSize, mOutputSize);
|
MOZ_ASSERT_IF(mHaveExplicitOutputSize, mOutputSize);
|
||||||
return mHaveExplicitOutputSize ? mOutputSize : Nothing();
|
return mHaveExplicitOutputSize ? mOutputSize : Nothing();
|
||||||
}
|
}
|
||||||
|
|
@ -448,10 +448,11 @@ void Decoder::PostSize(int32_t aWidth, int32_t aHeight,
|
||||||
|
|
||||||
// Set our output size if it's not already set.
|
// Set our output size if it's not already set.
|
||||||
if (!mOutputSize) {
|
if (!mOutputSize) {
|
||||||
mOutputSize = Some(IntSize(aWidth, aHeight));
|
mOutputSize = Some(mImageMetadata.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mOutputSize->width <= aWidth && mOutputSize->height <= aHeight,
|
MOZ_ASSERT(mOutputSize->width <= mImageMetadata.GetSize().width &&
|
||||||
|
mOutputSize->height <= mImageMetadata.GetSize().height,
|
||||||
"Output size will result in upscaling");
|
"Output size will result in upscaling");
|
||||||
|
|
||||||
// Record this notification.
|
// Record this notification.
|
||||||
|
|
@ -486,7 +487,8 @@ void Decoder::PostFrameStop(Opacity aFrameOpacity) {
|
||||||
// If we're not sending partial invalidations, then we send an invalidation
|
// If we're not sending partial invalidations, then we send an invalidation
|
||||||
// here when the first frame is complete.
|
// here when the first frame is complete.
|
||||||
if (!ShouldSendPartialInvalidations()) {
|
if (!ShouldSendPartialInvalidations()) {
|
||||||
mInvalidRect.UnionRect(mInvalidRect, IntRect(IntPoint(), Size()));
|
mInvalidRect.UnionRect(mInvalidRect,
|
||||||
|
OrientedIntRect(OrientedIntPoint(), Size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we dispose of the first frame by clearing it, then the first frame's
|
// If we dispose of the first frame by clearing it, then the first frame's
|
||||||
|
|
@ -498,7 +500,7 @@ void Decoder::PostFrameStop(Opacity aFrameOpacity) {
|
||||||
case DisposalMethod::CLEAR:
|
case DisposalMethod::CLEAR:
|
||||||
case DisposalMethod::CLEAR_ALL:
|
case DisposalMethod::CLEAR_ALL:
|
||||||
case DisposalMethod::RESTORE_PREVIOUS:
|
case DisposalMethod::RESTORE_PREVIOUS:
|
||||||
mFirstFrameRefreshArea = IntRect(IntPoint(), Size());
|
mFirstFrameRefreshArea = IntRect(IntPoint(), Size().ToUnknownSize());
|
||||||
break;
|
break;
|
||||||
case DisposalMethod::KEEP:
|
case DisposalMethod::KEEP:
|
||||||
case DisposalMethod::NOT_SPECIFIED:
|
case DisposalMethod::NOT_SPECIFIED:
|
||||||
|
|
@ -512,8 +514,8 @@ void Decoder::PostFrameStop(Opacity aFrameOpacity) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Decoder::PostInvalidation(const gfx::IntRect& aRect,
|
void Decoder::PostInvalidation(const OrientedIntRect& aRect,
|
||||||
const Maybe<gfx::IntRect>& aRectAtOutputSize
|
const Maybe<OrientedIntRect>& aRectAtOutputSize
|
||||||
/* = Nothing() */) {
|
/* = Nothing() */) {
|
||||||
// We should be mid-frame
|
// We should be mid-frame
|
||||||
MOZ_ASSERT(mInFrame, "Can't invalidate when not mid-frame!");
|
MOZ_ASSERT(mInFrame, "Can't invalidate when not mid-frame!");
|
||||||
|
|
@ -523,7 +525,8 @@ void Decoder::PostInvalidation(const gfx::IntRect& aRect,
|
||||||
// or we're past the first frame.
|
// or we're past the first frame.
|
||||||
if (ShouldSendPartialInvalidations() && mFrameCount == 1) {
|
if (ShouldSendPartialInvalidations() && mFrameCount == 1) {
|
||||||
mInvalidRect.UnionRect(mInvalidRect, aRect);
|
mInvalidRect.UnionRect(mInvalidRect, aRect);
|
||||||
mCurrentFrame->ImageUpdated(aRectAtOutputSize.valueOr(aRect));
|
mCurrentFrame->ImageUpdated(
|
||||||
|
aRectAtOutputSize.valueOr(aRect).ToUnknownRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,8 +157,8 @@ class Decoder {
|
||||||
* TakeInvalidRect() returns only the invalidation region accumulated since
|
* TakeInvalidRect() returns only the invalidation region accumulated since
|
||||||
* the last call to TakeInvalidRect().
|
* the last call to TakeInvalidRect().
|
||||||
*/
|
*/
|
||||||
nsIntRect TakeInvalidRect() {
|
OrientedIntRect TakeInvalidRect() {
|
||||||
nsIntRect invalidRect = mInvalidRect;
|
OrientedIntRect invalidRect = mInvalidRect;
|
||||||
mInvalidRect.SetEmpty();
|
mInvalidRect.SetEmpty();
|
||||||
return invalidRect;
|
return invalidRect;
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +211,7 @@ class Decoder {
|
||||||
*
|
*
|
||||||
* This must be called before Init() is called.
|
* This must be called before Init() is called.
|
||||||
*/
|
*/
|
||||||
void SetOutputSize(const gfx::IntSize& aSize);
|
void SetOutputSize(const OrientedIntSize& aSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the output size of this decoder. If this is smaller than the
|
* @return the output size of this decoder. If this is smaller than the
|
||||||
|
|
@ -220,7 +220,7 @@ class Decoder {
|
||||||
*
|
*
|
||||||
* Illegal to call if HasSize() returns false.
|
* Illegal to call if HasSize() returns false.
|
||||||
*/
|
*/
|
||||||
gfx::IntSize OutputSize() const {
|
OrientedIntSize OutputSize() const {
|
||||||
MOZ_ASSERT(HasSize());
|
MOZ_ASSERT(HasSize());
|
||||||
return *mOutputSize;
|
return *mOutputSize;
|
||||||
}
|
}
|
||||||
|
|
@ -229,13 +229,13 @@ class Decoder {
|
||||||
* @return either the size passed to SetOutputSize() or Nothing(), indicating
|
* @return either the size passed to SetOutputSize() or Nothing(), indicating
|
||||||
* that SetOutputSize() was not explicitly called.
|
* that SetOutputSize() was not explicitly called.
|
||||||
*/
|
*/
|
||||||
Maybe<gfx::IntSize> ExplicitOutputSize() const;
|
Maybe<OrientedIntSize> ExplicitOutputSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the expected image size of this decoder. Decoding will fail if this
|
* Sets the expected image size of this decoder. Decoding will fail if this
|
||||||
* does not match.
|
* does not match.
|
||||||
*/
|
*/
|
||||||
void SetExpectedSize(const gfx::IntSize& aSize) {
|
void SetExpectedSize(const OrientedIntSize& aSize) {
|
||||||
mExpectedSize.emplace(aSize);
|
mExpectedSize.emplace(aSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,7 +342,7 @@ class Decoder {
|
||||||
*
|
*
|
||||||
* Illegal to call if HasSize() returns false.
|
* Illegal to call if HasSize() returns false.
|
||||||
*/
|
*/
|
||||||
gfx::IntSize Size() const {
|
OrientedIntSize Size() const {
|
||||||
MOZ_ASSERT(HasSize());
|
MOZ_ASSERT(HasSize());
|
||||||
return mImageMetadata.GetSize();
|
return mImageMetadata.GetSize();
|
||||||
}
|
}
|
||||||
|
|
@ -354,8 +354,8 @@ class Decoder {
|
||||||
*
|
*
|
||||||
* Illegal to call if HasSize() returns false.
|
* Illegal to call if HasSize() returns false.
|
||||||
*/
|
*/
|
||||||
gfx::IntRect FullFrame() const {
|
OrientedIntRect FullFrame() const {
|
||||||
return gfx::IntRect(gfx::IntPoint(), Size());
|
return OrientedIntRect(OrientedIntPoint(), Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -369,8 +369,18 @@ class Decoder {
|
||||||
*
|
*
|
||||||
* Illegal to call if HasSize() returns false.
|
* Illegal to call if HasSize() returns false.
|
||||||
*/
|
*/
|
||||||
gfx::IntRect FullOutputFrame() const {
|
OrientedIntRect FullOutputFrame() const {
|
||||||
return gfx::IntRect(gfx::IntPoint(), OutputSize());
|
return OrientedIntRect(OrientedIntPoint(), OutputSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the orientation of the image.
|
||||||
|
*
|
||||||
|
* Illegal to call if HasSize() returns false.
|
||||||
|
*/
|
||||||
|
Orientation GetOrientation() const {
|
||||||
|
MOZ_ASSERT(HasSize());
|
||||||
|
return mImageMetadata.GetOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return final status information about this decoder. Should be called
|
/// @return final status information about this decoder. Should be called
|
||||||
|
|
@ -514,8 +524,8 @@ class Decoder {
|
||||||
* be supplied if we're downscaling during decode.
|
* be supplied if we're downscaling during decode.
|
||||||
*/
|
*/
|
||||||
void PostInvalidation(
|
void PostInvalidation(
|
||||||
const gfx::IntRect& aRect,
|
const OrientedIntRect& aRect,
|
||||||
const Maybe<gfx::IntRect>& aRectAtOutputSize = Nothing());
|
const Maybe<OrientedIntRect>& aRectAtOutputSize = Nothing());
|
||||||
|
|
||||||
// Called by the decoders when they have successfully decoded the image. This
|
// Called by the decoders when they have successfully decoded the image. This
|
||||||
// may occur as the result of the decoder getting to the appropriate point in
|
// may occur as the result of the decoder getting to the appropriate point in
|
||||||
|
|
@ -586,14 +596,14 @@ class Decoder {
|
||||||
|
|
||||||
ImageMetadata mImageMetadata;
|
ImageMetadata mImageMetadata;
|
||||||
|
|
||||||
gfx::IntRect
|
OrientedIntRect
|
||||||
mInvalidRect; // Tracks new rows as the current frame is decoded.
|
mInvalidRect; // Tracks new rows as the current frame is decoded.
|
||||||
gfx::IntRect mRestoreDirtyRect; // Tracks an invalidation region between the
|
gfx::IntRect mRestoreDirtyRect; // Tracks an invalidation region between the
|
||||||
// restore frame and the previous frame.
|
// restore frame and the previous frame.
|
||||||
gfx::IntRect mRecycleRect; // Tracks an invalidation region between the
|
gfx::IntRect mRecycleRect; // Tracks an invalidation region between the
|
||||||
// recycled frame and the current frame.
|
// recycled frame and the current frame.
|
||||||
Maybe<gfx::IntSize> mOutputSize; // The size of our output surface.
|
Maybe<OrientedIntSize> mOutputSize; // The size of our output surface.
|
||||||
Maybe<gfx::IntSize> mExpectedSize; // The expected size of the image.
|
Maybe<OrientedIntSize> mExpectedSize; // The expected size of the image.
|
||||||
Progress mProgress;
|
Progress mProgress;
|
||||||
|
|
||||||
uint32_t mFrameCount; // Number of frames, including anything in-progress
|
uint32_t mFrameCount; // Number of frames, including anything in-progress
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ nsresult DecoderFactory::CreateDecoder(
|
||||||
// Initialize the decoder.
|
// Initialize the decoder.
|
||||||
decoder->SetMetadataDecode(false);
|
decoder->SetMetadataDecode(false);
|
||||||
decoder->SetIterator(aSourceBuffer->Iterator());
|
decoder->SetIterator(aSourceBuffer->Iterator());
|
||||||
decoder->SetOutputSize(aOutputSize);
|
decoder->SetOutputSize(OrientedIntSize::FromUnknownSize(aOutputSize));
|
||||||
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
|
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
|
||||||
decoder->SetSurfaceFlags(aSurfaceFlags);
|
decoder->SetSurfaceFlags(aSurfaceFlags);
|
||||||
|
|
||||||
|
|
@ -320,7 +320,8 @@ already_AddRefed<IDecodingTask> DecoderFactory::CreateMetadataDecoder(
|
||||||
already_AddRefed<Decoder> DecoderFactory::CreateDecoderForICOResource(
|
already_AddRefed<Decoder> DecoderFactory::CreateDecoderForICOResource(
|
||||||
DecoderType aType, SourceBufferIterator&& aIterator,
|
DecoderType aType, SourceBufferIterator&& aIterator,
|
||||||
NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
|
NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
|
||||||
const Maybe<IntSize>& aExpectedSize, const Maybe<uint32_t>& aDataOffset
|
const Maybe<OrientedIntSize>& aExpectedSize,
|
||||||
|
const Maybe<uint32_t>& aDataOffset
|
||||||
/* = Nothing() */) {
|
/* = Nothing() */) {
|
||||||
// Create the decoder.
|
// Create the decoder.
|
||||||
RefPtr<Decoder> decoder;
|
RefPtr<Decoder> decoder;
|
||||||
|
|
@ -389,7 +390,7 @@ already_AddRefed<Decoder> DecoderFactory::CreateAnonymousDecoder(
|
||||||
|
|
||||||
// Set an output size for downscale-during-decode if requested.
|
// Set an output size for downscale-during-decode if requested.
|
||||||
if (aOutputSize) {
|
if (aOutputSize) {
|
||||||
decoder->SetOutputSize(*aOutputSize);
|
decoder->SetOutputSize(OrientedIntSize::FromUnknownSize(*aOutputSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(decoder->Init())) {
|
if (NS_FAILED(decoder->Init())) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
#include "Orientation.h"
|
||||||
#include "SurfaceFlags.h"
|
#include "SurfaceFlags.h"
|
||||||
|
|
||||||
namespace mozilla::image {
|
namespace mozilla::image {
|
||||||
|
|
@ -154,7 +155,7 @@ class DecoderFactory {
|
||||||
static already_AddRefed<Decoder> CreateDecoderForICOResource(
|
static already_AddRefed<Decoder> CreateDecoderForICOResource(
|
||||||
DecoderType aType, SourceBufferIterator&& aIterator,
|
DecoderType aType, SourceBufferIterator&& aIterator,
|
||||||
NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
|
NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode,
|
||||||
const Maybe<gfx::IntSize>& aExpectedSize,
|
const Maybe<OrientedIntSize>& aExpectedSize,
|
||||||
const Maybe<uint32_t>& aDataOffset = Nothing());
|
const Maybe<uint32_t>& aDataOffset = Nothing());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -467,7 +467,7 @@ LookupResult FrameAnimator::GetCompositedFrame(AnimationState& aState,
|
||||||
// getting called which calls UpdateState. The reason we care about this
|
// getting called which calls UpdateState. The reason we care about this
|
||||||
// is that img.decode promises won't resolve until GetCompositedFrame
|
// is that img.decode promises won't resolve until GetCompositedFrame
|
||||||
// returns a frame.
|
// returns a frame.
|
||||||
UnorientedIntRect rect = UnorientedIntRect::FromUnknownRect(
|
OrientedIntRect rect = OrientedIntRect::FromUnknownRect(
|
||||||
aState.UpdateStateInternal(result, mSize));
|
aState.UpdateStateInternal(result, mSize));
|
||||||
|
|
||||||
if (!rect.IsEmpty()) {
|
if (!rect.IsEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,7 @@ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
|
||||||
// calls we make off-main-thread and the notifications that RasterImage
|
// calls we make off-main-thread and the notifications that RasterImage
|
||||||
// actually receives, which would cause bugs.
|
// actually receives, which would cause bugs.
|
||||||
Progress progress = aDecoder->TakeProgress();
|
Progress progress = aDecoder->TakeProgress();
|
||||||
UnorientedIntRect invalidRect =
|
OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
|
||||||
UnorientedIntRect::FromUnknownRect(aDecoder->TakeInvalidRect());
|
|
||||||
Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
|
Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
|
||||||
DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
|
DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
|
||||||
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
||||||
|
|
@ -106,8 +105,7 @@ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
|
||||||
ImageMetadata metadata = aDecoder->GetImageMetadata();
|
ImageMetadata metadata = aDecoder->GetImageMetadata();
|
||||||
DecoderTelemetry telemetry = aDecoder->Telemetry();
|
DecoderTelemetry telemetry = aDecoder->Telemetry();
|
||||||
Progress progress = aDecoder->TakeProgress();
|
Progress progress = aDecoder->TakeProgress();
|
||||||
UnorientedIntRect invalidRect =
|
OrientedIntRect invalidRect = aDecoder->TakeInvalidRect();
|
||||||
UnorientedIntRect::FromUnknownRect(aDecoder->TakeInvalidRect());
|
|
||||||
Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
|
Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount();
|
||||||
DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
|
DecoderFlags decoderFlags = aDecoder->GetDecoderFlags();
|
||||||
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
||||||
|
|
|
||||||
|
|
@ -56,21 +56,24 @@ class ImageMetadata {
|
||||||
void SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation,
|
void SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation,
|
||||||
Resolution aResolution) {
|
Resolution aResolution) {
|
||||||
if (!HasSize()) {
|
if (!HasSize()) {
|
||||||
mSize.emplace(nsIntSize(aWidth, aHeight));
|
mSize.emplace(
|
||||||
|
aOrientation.ToOriented(UnorientedIntSize(aWidth, aHeight)));
|
||||||
mOrientation.emplace(aOrientation);
|
mOrientation.emplace(aOrientation);
|
||||||
mResolution = aResolution;
|
mResolution = aResolution;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nsIntSize GetSize() const { return *mSize; }
|
OrientedIntSize GetSize() const { return *mSize; }
|
||||||
bool HasSize() const { return mSize.isSome(); }
|
bool HasSize() const { return mSize.isSome(); }
|
||||||
|
|
||||||
void AddNativeSize(const nsIntSize& aSize) {
|
void AddNativeSize(const OrientedIntSize& aSize) {
|
||||||
mNativeSizes.AppendElement(aSize);
|
mNativeSizes.AppendElement(aSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Resolution GetResolution() const { return mResolution; }
|
Resolution GetResolution() const { return mResolution; }
|
||||||
|
|
||||||
const nsTArray<nsIntSize>& GetNativeSizes() const { return mNativeSizes; }
|
const nsTArray<OrientedIntSize>& GetNativeSizes() const {
|
||||||
|
return mNativeSizes;
|
||||||
|
}
|
||||||
|
|
||||||
Orientation GetOrientation() const { return *mOrientation; }
|
Orientation GetOrientation() const { return *mOrientation; }
|
||||||
bool HasOrientation() const { return mOrientation.isSome(); }
|
bool HasOrientation() const { return mOrientation.isSome(); }
|
||||||
|
|
@ -98,11 +101,11 @@ class ImageMetadata {
|
||||||
// loops.
|
// loops.
|
||||||
Maybe<gfx::IntRect> mFirstFrameRefreshArea;
|
Maybe<gfx::IntRect> mFirstFrameRefreshArea;
|
||||||
|
|
||||||
Maybe<nsIntSize> mSize;
|
Maybe<OrientedIntSize> mSize;
|
||||||
Maybe<Orientation> mOrientation;
|
Maybe<Orientation> mOrientation;
|
||||||
|
|
||||||
// Sizes the image can natively decode to.
|
// Sizes the image can natively decode to.
|
||||||
CopyableTArray<nsIntSize> mNativeSizes;
|
CopyableTArray<OrientedIntSize> mNativeSizes;
|
||||||
|
|
||||||
bool mHasAnimation = false;
|
bool mHasAnimation = false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ RasterImage::RequestRefresh(const TimeStamp& aTime) {
|
||||||
// once for all frames that we've now passed (if AdvanceFrame() was called
|
// once for all frames that we've now passed (if AdvanceFrame() was called
|
||||||
// more than once).
|
// more than once).
|
||||||
if (!res.mDirtyRect.IsEmpty() || res.mFrameAdvanced) {
|
if (!res.mDirtyRect.IsEmpty() || res.mFrameAdvanced) {
|
||||||
auto dirtyRect = UnorientedIntRect::FromUnknownRect(res.mDirtyRect);
|
auto dirtyRect = OrientedIntRect::FromUnknownRect(res.mDirtyRect);
|
||||||
NotifyProgress(NoProgress, dirtyRect);
|
NotifyProgress(NoProgress, dirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,7 +279,7 @@ RasterImage::GetProducerId(uint32_t* aId) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult RasterImage::LookupFrameInternal(const UnorientedIntSize& aSize,
|
LookupResult RasterImage::LookupFrameInternal(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType,
|
PlaybackType aPlaybackType,
|
||||||
bool aMarkUsed) {
|
bool aMarkUsed) {
|
||||||
|
|
@ -311,7 +311,7 @@ LookupResult RasterImage::LookupFrameInternal(const UnorientedIntSize& aSize,
|
||||||
aMarkUsed);
|
aMarkUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult RasterImage::LookupFrame(const UnorientedIntSize& aSize,
|
LookupResult RasterImage::LookupFrame(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType,
|
PlaybackType aPlaybackType,
|
||||||
bool aMarkUsed) {
|
bool aMarkUsed) {
|
||||||
|
|
@ -323,8 +323,8 @@ LookupResult RasterImage::LookupFrame(const UnorientedIntSize& aSize,
|
||||||
aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
|
aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnorientedIntSize requestedSize =
|
OrientedIntSize requestedSize =
|
||||||
CanDownscaleDuringDecode(aSize, aFlags) ? aSize : ToUnoriented(mSize);
|
CanDownscaleDuringDecode(aSize, aFlags) ? aSize : mSize;
|
||||||
if (requestedSize.IsEmpty()) {
|
if (requestedSize.IsEmpty()) {
|
||||||
// Can't decode to a surface of zero size.
|
// Can't decode to a surface of zero size.
|
||||||
return LookupResult(MatchType::NOT_FOUND);
|
return LookupResult(MatchType::NOT_FOUND);
|
||||||
|
|
@ -356,8 +356,7 @@ LookupResult RasterImage::LookupFrame(const UnorientedIntSize& aSize,
|
||||||
// decode at. This should only happen if we accept substitutions.
|
// decode at. This should only happen if we accept substitutions.
|
||||||
if (!result.SuggestedSize().IsEmpty()) {
|
if (!result.SuggestedSize().IsEmpty()) {
|
||||||
MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
|
MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
|
||||||
requestedSize =
|
requestedSize = OrientedIntSize::FromUnknownSize(result.SuggestedSize());
|
||||||
UnorientedIntSize::FromUnknownSize(result.SuggestedSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ranSync = false, failed = false;
|
bool ranSync = false, failed = false;
|
||||||
|
|
@ -439,10 +438,9 @@ RasterImage::WillDrawOpaqueNow() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = ToUnoriented(mSize);
|
|
||||||
LookupResult result = SurfaceCache::LookupBestMatch(
|
LookupResult result = SurfaceCache::LookupBestMatch(
|
||||||
ImageKey(this),
|
ImageKey(this),
|
||||||
RasterSurfaceKey(size.ToUnknownSize(), DefaultSurfaceFlags(),
|
RasterSurfaceKey(mSize.ToUnknownSize(), DefaultSurfaceFlags(),
|
||||||
PlaybackType::eStatic),
|
PlaybackType::eStatic),
|
||||||
/* aMarkUsed = */ false);
|
/* aMarkUsed = */ false);
|
||||||
MatchType matchType = result.Type();
|
MatchType matchType = result.Type();
|
||||||
|
|
@ -482,10 +480,9 @@ void RasterImage::OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded) {
|
||||||
MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
|
MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
|
||||||
ReleaseImageContainer();
|
ReleaseImageContainer();
|
||||||
|
|
||||||
auto size = ToUnoriented(mSize);
|
IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
|
||||||
IntRect rect = mAnimationState->UpdateState(this, size.ToUnknownSize());
|
|
||||||
|
|
||||||
auto dirtyRect = UnorientedIntRect::FromUnknownRect(rect);
|
auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
|
||||||
NotifyProgress(NoProgress, dirtyRect);
|
NotifyProgress(NoProgress, dirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -578,9 +575,8 @@ RasterImage::GetFrameInternal(const IntSize& aSize,
|
||||||
// Get the frame. If it's not there, it's probably the caller's fault for
|
// Get the frame. If it's not there, it's probably the caller's fault for
|
||||||
// not waiting for the data to be loaded from the network or not passing
|
// not waiting for the data to be loaded from the network or not passing
|
||||||
// FLAG_SYNC_DECODE.
|
// FLAG_SYNC_DECODE.
|
||||||
LookupResult result =
|
LookupResult result = LookupFrame(size, aFlags, ToPlaybackType(aWhichFrame),
|
||||||
LookupFrame(ToUnoriented(size), aFlags, ToPlaybackType(aWhichFrame),
|
/* aMarkUsed = */ true);
|
||||||
/* aMarkUsed = */ true);
|
|
||||||
auto resultSuggestedSize =
|
auto resultSuggestedSize =
|
||||||
UnorientedIntSize::FromUnknownSize(result.SuggestedSize());
|
UnorientedIntSize::FromUnknownSize(result.SuggestedSize());
|
||||||
|
|
||||||
|
|
@ -637,7 +633,7 @@ Tuple<ImgDrawResult, IntSize> RasterImage::GetImageContainerSize(
|
||||||
}
|
}
|
||||||
|
|
||||||
auto requestedSize = OrientedIntSize::FromUnknownSize(aRequestedSize);
|
auto requestedSize = OrientedIntSize::FromUnknownSize(aRequestedSize);
|
||||||
if (!CanDownscaleDuringDecode(ToUnoriented(requestedSize), aFlags)) {
|
if (!CanDownscaleDuringDecode(requestedSize, aFlags)) {
|
||||||
return MakeTuple(ImgDrawResult::SUCCESS, mSize.ToUnknownSize());
|
return MakeTuple(ImgDrawResult::SUCCESS, mSize.ToUnknownSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,7 +684,7 @@ bool RasterImage::SetMetadata(const ImageMetadata& aMetadata,
|
||||||
mResolution = aMetadata.GetResolution();
|
mResolution = aMetadata.GetResolution();
|
||||||
|
|
||||||
if (aMetadata.HasSize()) {
|
if (aMetadata.HasSize()) {
|
||||||
auto metadataSize = UnorientedIntSize::FromUnknownSize(aMetadata.GetSize());
|
auto metadataSize = aMetadata.GetSize();
|
||||||
if (metadataSize.width < 0 || metadataSize.height < 0) {
|
if (metadataSize.width < 0 || metadataSize.height < 0) {
|
||||||
NS_WARNING("Image has negative intrinsic size");
|
NS_WARNING("Image has negative intrinsic size");
|
||||||
DoError();
|
DoError();
|
||||||
|
|
@ -700,7 +696,7 @@ bool RasterImage::SetMetadata(const ImageMetadata& aMetadata,
|
||||||
|
|
||||||
// If we already have a size, check the new size against the old one.
|
// If we already have a size, check the new size against the old one.
|
||||||
if (LoadHasSize() &&
|
if (LoadHasSize() &&
|
||||||
(metadataSize != ToUnoriented(mSize) || orientation != mOrientation)) {
|
(metadataSize != mSize || orientation != mOrientation)) {
|
||||||
NS_WARNING(
|
NS_WARNING(
|
||||||
"Image changed size or orientation on redecode! "
|
"Image changed size or orientation on redecode! "
|
||||||
"This should not happen!");
|
"This should not happen!");
|
||||||
|
|
@ -710,11 +706,10 @@ bool RasterImage::SetMetadata(const ImageMetadata& aMetadata,
|
||||||
|
|
||||||
// Set the size and flag that we have it.
|
// Set the size and flag that we have it.
|
||||||
mOrientation = orientation;
|
mOrientation = orientation;
|
||||||
mSize = ToOriented(metadataSize);
|
mSize = metadataSize;
|
||||||
mNativeSizes.Clear();
|
mNativeSizes.Clear();
|
||||||
for (const auto& nativeSize : aMetadata.GetNativeSizes()) {
|
for (const auto& nativeSize : aMetadata.GetNativeSizes()) {
|
||||||
mNativeSizes.AppendElement(
|
mNativeSizes.AppendElement(nativeSize);
|
||||||
ToOriented(UnorientedIntSize::FromUnknownSize(nativeSize)));
|
|
||||||
}
|
}
|
||||||
StoreHasSize(true);
|
StoreHasSize(true);
|
||||||
}
|
}
|
||||||
|
|
@ -722,8 +717,7 @@ bool RasterImage::SetMetadata(const ImageMetadata& aMetadata,
|
||||||
if (LoadHasSize() && aMetadata.HasAnimation() && !mAnimationState) {
|
if (LoadHasSize() && aMetadata.HasAnimation() && !mAnimationState) {
|
||||||
// We're becoming animated, so initialize animation stuff.
|
// We're becoming animated, so initialize animation stuff.
|
||||||
mAnimationState.emplace(mAnimationMode);
|
mAnimationState.emplace(mAnimationMode);
|
||||||
mFrameAnimator =
|
mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize.ToUnknownSize());
|
||||||
MakeUnique<FrameAnimator>(this, ToUnoriented(mSize).ToUnknownSize());
|
|
||||||
|
|
||||||
if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
|
if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
|
||||||
// We don't support discarding animated images (See bug 414259).
|
// We don't support discarding animated images (See bug 414259).
|
||||||
|
|
@ -846,7 +840,7 @@ RasterImage::ResetAnimation() {
|
||||||
mFrameAnimator->ResetAnimation(*mAnimationState);
|
mFrameAnimator->ResetAnimation(*mAnimationState);
|
||||||
|
|
||||||
IntRect area = mAnimationState->FirstFrameRefreshArea();
|
IntRect area = mAnimationState->FirstFrameRefreshArea();
|
||||||
NotifyProgress(NoProgress, UnorientedIntRect::FromUnknownRect(area));
|
NotifyProgress(NoProgress, OrientedIntRect::FromUnknownRect(area));
|
||||||
|
|
||||||
// Start the animation again. It may not have been running before, if
|
// Start the animation again. It may not have been running before, if
|
||||||
// mAnimationFinished was true before entering this function.
|
// mAnimationFinished was true before entering this function.
|
||||||
|
|
@ -1008,10 +1002,9 @@ void RasterImage::Discard() {
|
||||||
if (mAnimationState) {
|
if (mAnimationState) {
|
||||||
ReleaseImageContainer();
|
ReleaseImageContainer();
|
||||||
|
|
||||||
auto size = ToUnoriented(mSize);
|
IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
|
||||||
IntRect rect = mAnimationState->UpdateState(this, size.ToUnknownSize());
|
|
||||||
|
|
||||||
auto dirtyRect = UnorientedIntRect::FromUnknownRect(rect);
|
auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
|
||||||
NotifyProgress(NoProgress, dirtyRect);
|
NotifyProgress(NoProgress, dirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1057,8 +1050,7 @@ bool RasterImage::StartDecodingWithResult(uint32_t aFlags,
|
||||||
|
|
||||||
uint32_t flags = (aFlags & FLAG_ASYNC_NOTIFY) | FLAG_SYNC_DECODE_IF_FAST |
|
uint32_t flags = (aFlags & FLAG_ASYNC_NOTIFY) | FLAG_SYNC_DECODE_IF_FAST |
|
||||||
FLAG_HIGH_QUALITY_SCALING;
|
FLAG_HIGH_QUALITY_SCALING;
|
||||||
LookupResult result =
|
LookupResult result = RequestDecodeForSizeInternal(mSize, flags, aWhichFrame);
|
||||||
RequestDecodeForSizeInternal(ToUnoriented(mSize), flags, aWhichFrame);
|
|
||||||
DrawableSurface surface = std::move(result.Surface());
|
DrawableSurface surface = std::move(result.Surface());
|
||||||
return surface && surface->IsFinished();
|
return surface && surface->IsFinished();
|
||||||
}
|
}
|
||||||
|
|
@ -1072,8 +1064,7 @@ imgIContainer::DecodeResult RasterImage::RequestDecodeWithResult(
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = aFlags | FLAG_ASYNC_NOTIFY;
|
uint32_t flags = aFlags | FLAG_ASYNC_NOTIFY;
|
||||||
LookupResult result =
|
LookupResult result = RequestDecodeForSizeInternal(mSize, flags, aWhichFrame);
|
||||||
RequestDecodeForSizeInternal(ToUnoriented(mSize), flags, aWhichFrame);
|
|
||||||
DrawableSurface surface = std::move(result.Surface());
|
DrawableSurface surface = std::move(result.Surface());
|
||||||
if (surface && surface->IsFinished()) {
|
if (surface && surface->IsFinished()) {
|
||||||
return imgIContainer::DECODE_SURFACE_AVAILABLE;
|
return imgIContainer::DECODE_SURFACE_AVAILABLE;
|
||||||
|
|
@ -1093,15 +1084,14 @@ RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestDecodeForSizeInternal(
|
RequestDecodeForSizeInternal(OrientedIntSize::FromUnknownSize(aSize), aFlags,
|
||||||
ToUnoriented(OrientedIntSize::FromUnknownSize(aSize)), aFlags,
|
aWhichFrame);
|
||||||
aWhichFrame);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult RasterImage::RequestDecodeForSizeInternal(
|
LookupResult RasterImage::RequestDecodeForSizeInternal(
|
||||||
const UnorientedIntSize& aSize, uint32_t aFlags, uint32_t aWhichFrame) {
|
const OrientedIntSize& aSize, uint32_t aFlags, uint32_t aWhichFrame) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
if (aWhichFrame > FRAME_MAX_VALUE) {
|
if (aWhichFrame > FRAME_MAX_VALUE) {
|
||||||
|
|
@ -1155,7 +1145,7 @@ static bool LaunchDecodingTask(IDecodingTask* aTask, RasterImage* aImage,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterImage::Decode(const UnorientedIntSize& aSize, uint32_t aFlags,
|
void RasterImage::Decode(const OrientedIntSize& aSize, uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType, bool& aOutRanSync,
|
PlaybackType aPlaybackType, bool& aOutRanSync,
|
||||||
bool& aOutFailed) {
|
bool& aOutFailed) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
@ -1212,14 +1202,13 @@ void RasterImage::Decode(const UnorientedIntSize& aSize, uint32_t aFlags,
|
||||||
if (animated) {
|
if (animated) {
|
||||||
size_t currentFrame = mAnimationState->GetCurrentAnimationFrameIndex();
|
size_t currentFrame = mAnimationState->GetCurrentAnimationFrameIndex();
|
||||||
rv = DecoderFactory::CreateAnimationDecoder(
|
rv = DecoderFactory::CreateAnimationDecoder(
|
||||||
mDecoderType, WrapNotNull(this), mSourceBuffer,
|
mDecoderType, WrapNotNull(this), mSourceBuffer, mSize.ToUnknownSize(),
|
||||||
ToUnoriented(mSize).ToUnknownSize(), decoderFlags, surfaceFlags,
|
decoderFlags, surfaceFlags, currentFrame, getter_AddRefs(task));
|
||||||
currentFrame, getter_AddRefs(task));
|
|
||||||
} else {
|
} else {
|
||||||
rv = DecoderFactory::CreateDecoder(
|
rv = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),
|
||||||
mDecoderType, WrapNotNull(this), mSourceBuffer,
|
mSourceBuffer, mSize.ToUnknownSize(),
|
||||||
ToUnoriented(mSize).ToUnknownSize(), aSize.ToUnknownSize(),
|
aSize.ToUnknownSize(), decoderFlags,
|
||||||
decoderFlags, surfaceFlags, getter_AddRefs(task));
|
surfaceFlags, getter_AddRefs(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NS_ERROR_ALREADY_INITIALIZED) {
|
if (rv == NS_ERROR_ALREADY_INITIALIZED) {
|
||||||
|
|
@ -1238,8 +1227,7 @@ void RasterImage::Decode(const UnorientedIntSize& aSize, uint32_t aFlags,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
IntRect rect =
|
IntRect rect =
|
||||||
#endif
|
#endif
|
||||||
mAnimationState->UpdateState(this, ToUnoriented(mSize).ToUnknownSize(),
|
mAnimationState->UpdateState(this, mSize.ToUnknownSize(), false);
|
||||||
false);
|
|
||||||
MOZ_ASSERT(rect.IsEmpty());
|
MOZ_ASSERT(rect.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1279,7 +1267,7 @@ RasterImage::DecodeMetadata(uint32_t aFlags) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterImage::RecoverFromInvalidFrames(const UnorientedIntSize& aSize,
|
void RasterImage::RecoverFromInvalidFrames(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags) {
|
uint32_t aFlags) {
|
||||||
if (!LoadHasSize()) {
|
if (!LoadHasSize()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1300,8 +1288,8 @@ void RasterImage::RecoverFromInvalidFrames(const UnorientedIntSize& aSize,
|
||||||
// Animated images require some special handling, because we normally require
|
// Animated images require some special handling, because we normally require
|
||||||
// that they never be discarded.
|
// that they never be discarded.
|
||||||
if (mAnimationState) {
|
if (mAnimationState) {
|
||||||
Decode(ToUnoriented(mSize), aFlags | FLAG_SYNC_DECODE,
|
Decode(mSize, aFlags | FLAG_SYNC_DECODE, PlaybackType::eAnimated, unused1,
|
||||||
PlaybackType::eAnimated, unused1, unused2);
|
unused2);
|
||||||
ResetAnimation();
|
ResetAnimation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1298,7 @@ void RasterImage::RecoverFromInvalidFrames(const UnorientedIntSize& aSize,
|
||||||
Decode(aSize, aFlags, PlaybackType::eStatic, unused1, unused2);
|
Decode(aSize, aFlags, PlaybackType::eStatic, unused1, unused2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RasterImage::CanDownscaleDuringDecode(const UnorientedIntSize& aSize,
|
bool RasterImage::CanDownscaleDuringDecode(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags) {
|
uint32_t aFlags) {
|
||||||
// Check basic requirements: downscale-during-decode is enabled, Skia is
|
// Check basic requirements: downscale-during-decode is enabled, Skia is
|
||||||
// available, this image isn't transient, we have all the source data and know
|
// available, this image isn't transient, we have all the source data and know
|
||||||
|
|
@ -1327,8 +1315,7 @@ bool RasterImage::CanDownscaleDuringDecode(const UnorientedIntSize& aSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never upscale.
|
// Never upscale.
|
||||||
UnorientedIntSize ourSize = ToUnoriented(mSize);
|
if (aSize.width >= mSize.width || aSize.height >= mSize.height) {
|
||||||
if (aSize.width >= ourSize.width || aSize.height >= ourSize.height) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1347,7 +1334,7 @@ bool RasterImage::CanDownscaleDuringDecode(const UnorientedIntSize& aSize,
|
||||||
|
|
||||||
ImgDrawResult RasterImage::DrawInternal(DrawableSurface&& aSurface,
|
ImgDrawResult RasterImage::DrawInternal(DrawableSurface&& aSurface,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
const UnorientedIntSize& aSize,
|
const OrientedIntSize& aSize,
|
||||||
const ImageRegion& aRegion,
|
const ImageRegion& aRegion,
|
||||||
SamplingFilter aSamplingFilter,
|
SamplingFilter aSamplingFilter,
|
||||||
uint32_t aFlags, float aOpacity) {
|
uint32_t aFlags, float aOpacity) {
|
||||||
|
|
@ -1422,7 +1409,7 @@ RasterImage::Draw(gfxContext* aContext, const IntSize& aSize,
|
||||||
? aFlags
|
? aFlags
|
||||||
: aFlags & ~FLAG_HIGH_QUALITY_SCALING;
|
: aFlags & ~FLAG_HIGH_QUALITY_SCALING;
|
||||||
|
|
||||||
auto size = ToUnoriented(OrientedIntSize::FromUnknownSize(aSize));
|
auto size = OrientedIntSize::FromUnknownSize(aSize);
|
||||||
LookupResult result = LookupFrame(size, flags, ToPlaybackType(aWhichFrame),
|
LookupResult result = LookupFrame(size, flags, ToPlaybackType(aWhichFrame),
|
||||||
/* aMarkUsed = */ true);
|
/* aMarkUsed = */ true);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
@ -1436,26 +1423,9 @@ RasterImage::Draw(gfxContext* aContext, const IntSize& aSize,
|
||||||
bool shouldRecordTelemetry =
|
bool shouldRecordTelemetry =
|
||||||
!mDrawStartTime.IsNull() && result.Surface()->IsFinished();
|
!mDrawStartTime.IsNull() && result.Surface()->IsFinished();
|
||||||
|
|
||||||
ImgDrawResult drawResult;
|
ImgDrawResult drawResult =
|
||||||
{
|
DrawInternal(std::move(result.Surface()), aContext, size, aRegion,
|
||||||
gfxContextMatrixAutoSaveRestore asr;
|
aSamplingFilter, flags, aOpacity);
|
||||||
ImageRegion region(aRegion);
|
|
||||||
|
|
||||||
if (!mOrientation.IsIdentity()) {
|
|
||||||
// Apply a transform so that the unoriented image is drawn in the
|
|
||||||
// orientation expected by the caller.
|
|
||||||
gfxMatrix matrix = OrientationMatrix(size);
|
|
||||||
asr.SetContext(aContext);
|
|
||||||
aContext->Multiply(matrix);
|
|
||||||
|
|
||||||
// Convert the region to unoriented coordinates.
|
|
||||||
gfxMatrix inverseMatrix = OrientationMatrix(size, /* aInvert = */ true);
|
|
||||||
region.TransformBoundsBy(inverseMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawResult = DrawInternal(std::move(result.Surface()), aContext, size,
|
|
||||||
region, aSamplingFilter, flags, aOpacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldRecordTelemetry) {
|
if (shouldRecordTelemetry) {
|
||||||
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
|
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
|
||||||
|
|
@ -1560,7 +1530,7 @@ void RasterImage::DoError() {
|
||||||
SurfaceCache::RemoveImage(ImageKey(this));
|
SurfaceCache::RemoveImage(ImageKey(this));
|
||||||
|
|
||||||
// Invalidate to get rid of any partially-drawn image content.
|
// Invalidate to get rid of any partially-drawn image content.
|
||||||
auto dirtyRect = UnorientedIntRect({0, 0}, ToUnoriented(mSize));
|
auto dirtyRect = OrientedIntRect({0, 0}, mSize);
|
||||||
NotifyProgress(NoProgress, dirtyRect);
|
NotifyProgress(NoProgress, dirtyRect);
|
||||||
|
|
||||||
MOZ_LOG(gImgLog, LogLevel::Error,
|
MOZ_LOG(gImgLog, LogLevel::Error,
|
||||||
|
|
@ -1603,7 +1573,7 @@ RasterImage::GetFramesNotified(uint32_t* aFramesNotified) {
|
||||||
|
|
||||||
void RasterImage::NotifyProgress(
|
void RasterImage::NotifyProgress(
|
||||||
Progress aProgress,
|
Progress aProgress,
|
||||||
const UnorientedIntRect& aInvalidRect /* = UnorientedIntRect() */,
|
const OrientedIntRect& aInvalidRect /* = OrientedIntRect() */,
|
||||||
const Maybe<uint32_t>& aFrameCount /* = Nothing() */,
|
const Maybe<uint32_t>& aFrameCount /* = Nothing() */,
|
||||||
DecoderFlags aDecoderFlags /* = DefaultDecoderFlags() */,
|
DecoderFlags aDecoderFlags /* = DefaultDecoderFlags() */,
|
||||||
SurfaceFlags aSurfaceFlags /* = DefaultSurfaceFlags() */) {
|
SurfaceFlags aSurfaceFlags /* = DefaultSurfaceFlags() */) {
|
||||||
|
|
@ -1612,7 +1582,7 @@ void RasterImage::NotifyProgress(
|
||||||
// Ensure that we stay alive long enough to finish notifying.
|
// Ensure that we stay alive long enough to finish notifying.
|
||||||
RefPtr<RasterImage> image = this;
|
RefPtr<RasterImage> image = this;
|
||||||
|
|
||||||
UnorientedIntRect invalidRect = aInvalidRect;
|
OrientedIntRect invalidRect = aInvalidRect;
|
||||||
|
|
||||||
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY)) {
|
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY)) {
|
||||||
// We may have decoded new animation frames; update our animation state.
|
// We may have decoded new animation frames; update our animation state.
|
||||||
|
|
@ -1628,32 +1598,29 @@ void RasterImage::NotifyProgress(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAnimationState) {
|
if (mAnimationState) {
|
||||||
auto size = ToUnoriented(mSize);
|
IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
|
||||||
IntRect rect = mAnimationState->UpdateState(this, size.ToUnknownSize());
|
|
||||||
|
|
||||||
invalidRect.UnionRect(invalidRect,
|
invalidRect.UnionRect(invalidRect,
|
||||||
UnorientedIntRect::FromUnknownRect(rect));
|
OrientedIntRect::FromUnknownRect(rect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool wasDefaultFlags = aSurfaceFlags == DefaultSurfaceFlags();
|
const bool wasDefaultFlags = aSurfaceFlags == DefaultSurfaceFlags();
|
||||||
|
|
||||||
auto orientedInvalidRect = ToOriented(invalidRect);
|
if (!invalidRect.IsEmpty() && wasDefaultFlags) {
|
||||||
|
|
||||||
if (!orientedInvalidRect.IsEmpty() && wasDefaultFlags) {
|
|
||||||
// Update our image container since we're invalidating.
|
// Update our image container since we're invalidating.
|
||||||
UpdateImageContainer(Some(orientedInvalidRect.ToUnknownRect()));
|
UpdateImageContainer(Some(invalidRect.ToUnknownRect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the observers what happened.
|
// Tell the observers what happened.
|
||||||
image->mProgressTracker->SyncNotifyProgress(
|
image->mProgressTracker->SyncNotifyProgress(aProgress,
|
||||||
aProgress, orientedInvalidRect.ToUnknownRect());
|
invalidRect.ToUnknownRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterImage::NotifyDecodeComplete(
|
void RasterImage::NotifyDecodeComplete(
|
||||||
const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
|
const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
|
||||||
const DecoderTelemetry& aTelemetry, Progress aProgress,
|
const DecoderTelemetry& aTelemetry, Progress aProgress,
|
||||||
const UnorientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
|
const OrientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
|
||||||
DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) {
|
DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
|
@ -1668,8 +1635,7 @@ void RasterImage::NotifyDecodeComplete(
|
||||||
// This indicates a serious error that requires us to discard all existing
|
// This indicates a serious error that requires us to discard all existing
|
||||||
// surfaces and redecode to recover. We'll drop the results from this
|
// surfaces and redecode to recover. We'll drop the results from this
|
||||||
// decoder on the floor, since they aren't valid.
|
// decoder on the floor, since they aren't valid.
|
||||||
RecoverFromInvalidFrames(ToUnoriented(mSize),
|
RecoverFromInvalidFrames(mSize, FromSurfaceFlags(aSurfaceFlags));
|
||||||
FromSurfaceFlags(aSurfaceFlags));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1704,11 +1670,10 @@ void RasterImage::NotifyDecodeComplete(
|
||||||
// expect anymore.
|
// expect anymore.
|
||||||
mAnimationState->NotifyDecodeComplete();
|
mAnimationState->NotifyDecodeComplete();
|
||||||
|
|
||||||
auto size = ToUnoriented(mSize);
|
IntRect rect = mAnimationState->UpdateState(this, mSize.ToUnknownSize());
|
||||||
IntRect rect = mAnimationState->UpdateState(this, size.ToUnknownSize());
|
|
||||||
|
|
||||||
if (!rect.IsEmpty()) {
|
if (!rect.IsEmpty()) {
|
||||||
auto dirtyRect = UnorientedIntRect::FromUnknownRect(rect);
|
auto dirtyRect = OrientedIntRect::FromUnknownRect(rect);
|
||||||
NotifyProgress(NoProgress, dirtyRect);
|
NotifyProgress(NoProgress, dirtyRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1750,9 +1715,9 @@ void RasterImage::NotifyDecodeComplete(
|
||||||
// If we were a metadata decode and a full decode was requested, do it.
|
// If we were a metadata decode and a full decode was requested, do it.
|
||||||
if (LoadWantFullDecode()) {
|
if (LoadWantFullDecode()) {
|
||||||
StoreWantFullDecode(false);
|
StoreWantFullDecode(false);
|
||||||
RequestDecodeForSize(mSize.ToUnknownSize(),
|
RequestDecodeForSizeInternal(
|
||||||
DECODE_FLAGS_DEFAULT | FLAG_HIGH_QUALITY_SCALING,
|
mSize, DECODE_FLAGS_DEFAULT | FLAG_HIGH_QUALITY_SCALING,
|
||||||
FRAME_CURRENT);
|
FRAME_CURRENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1806,7 +1771,7 @@ IntSize RasterImage::OptimalImageSizeForDest(const gfxSize& aDest,
|
||||||
IntSize::Ceil(aDest.width, aDest.height));
|
IntSize::Ceil(aDest.width, aDest.height));
|
||||||
|
|
||||||
if (aSamplingFilter == SamplingFilter::GOOD &&
|
if (aSamplingFilter == SamplingFilter::GOOD &&
|
||||||
CanDownscaleDuringDecode(ToUnoriented(dest), aFlags)) {
|
CanDownscaleDuringDecode(dest, aFlags)) {
|
||||||
return dest.ToUnknownSize();
|
return dest.ToUnknownSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,11 @@ class RasterImage final : public ImageResource,
|
||||||
* these notifications, or DefaultSurfaceFlags() if the
|
* these notifications, or DefaultSurfaceFlags() if the
|
||||||
* notifications don't come from a decoder.
|
* notifications don't come from a decoder.
|
||||||
*/
|
*/
|
||||||
void NotifyProgress(
|
void NotifyProgress(Progress aProgress,
|
||||||
Progress aProgress,
|
const OrientedIntRect& aInvalidRect = OrientedIntRect(),
|
||||||
const UnorientedIntRect& aInvalidRect = UnorientedIntRect(),
|
const Maybe<uint32_t>& aFrameCount = Nothing(),
|
||||||
const Maybe<uint32_t>& aFrameCount = Nothing(),
|
DecoderFlags aDecoderFlags = DefaultDecoderFlags(),
|
||||||
DecoderFlags aDecoderFlags = DefaultDecoderFlags(),
|
SurfaceFlags aSurfaceFlags = DefaultSurfaceFlags());
|
||||||
SurfaceFlags aSurfaceFlags = DefaultSurfaceFlags());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records decoding results, sends out any final notifications, updates the
|
* Records decoding results, sends out any final notifications, updates the
|
||||||
|
|
@ -222,7 +221,7 @@ class RasterImage final : public ImageResource,
|
||||||
void NotifyDecodeComplete(
|
void NotifyDecodeComplete(
|
||||||
const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
|
const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata,
|
||||||
const DecoderTelemetry& aTelemetry, Progress aProgress,
|
const DecoderTelemetry& aTelemetry, Progress aProgress,
|
||||||
const UnorientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
|
const OrientedIntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount,
|
||||||
DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags);
|
DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags);
|
||||||
|
|
||||||
// Helper method for NotifyDecodeComplete.
|
// Helper method for NotifyDecodeComplete.
|
||||||
|
|
@ -281,16 +280,16 @@ class RasterImage final : public ImageResource,
|
||||||
* @return a drawable surface, which may be empty if the requested surface
|
* @return a drawable surface, which may be empty if the requested surface
|
||||||
* could not be found.
|
* could not be found.
|
||||||
*/
|
*/
|
||||||
LookupResult LookupFrame(const UnorientedIntSize& aSize, uint32_t aFlags,
|
LookupResult LookupFrame(const OrientedIntSize& aSize, uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType, bool aMarkUsed);
|
PlaybackType aPlaybackType, bool aMarkUsed);
|
||||||
|
|
||||||
/// Helper method for LookupFrame().
|
/// Helper method for LookupFrame().
|
||||||
LookupResult LookupFrameInternal(const UnorientedIntSize& aSize,
|
LookupResult LookupFrameInternal(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags, PlaybackType aPlaybackType,
|
uint32_t aFlags, PlaybackType aPlaybackType,
|
||||||
bool aMarkUsed);
|
bool aMarkUsed);
|
||||||
|
|
||||||
ImgDrawResult DrawInternal(DrawableSurface&& aFrameRef, gfxContext* aContext,
|
ImgDrawResult DrawInternal(DrawableSurface&& aFrameRef, gfxContext* aContext,
|
||||||
const UnorientedIntSize& aSize,
|
const OrientedIntSize& aSize,
|
||||||
const ImageRegion& aRegion,
|
const ImageRegion& aRegion,
|
||||||
gfx::SamplingFilter aSamplingFilter,
|
gfx::SamplingFilter aSamplingFilter,
|
||||||
uint32_t aFlags, float aOpacity);
|
uint32_t aFlags, float aOpacity);
|
||||||
|
|
@ -322,7 +321,7 @@ class RasterImage final : public ImageResource,
|
||||||
* aOutRanSync is set to true if the decode was run synchronously.
|
* aOutRanSync is set to true if the decode was run synchronously.
|
||||||
* aOutFailed is set to true if failed to start a decode.
|
* aOutFailed is set to true if failed to start a decode.
|
||||||
*/
|
*/
|
||||||
void Decode(const UnorientedIntSize& aSize, uint32_t aFlags,
|
void Decode(const OrientedIntSize& aSize, uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType, bool& aOutRanSync, bool& aOutFailed);
|
PlaybackType aPlaybackType, bool& aOutRanSync, bool& aOutFailed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -358,8 +357,7 @@ class RasterImage final : public ImageResource,
|
||||||
* RecoverFromInvalidFrames discards all existing frames and redecodes using
|
* RecoverFromInvalidFrames discards all existing frames and redecodes using
|
||||||
* the provided @aSize and @aFlags.
|
* the provided @aSize and @aFlags.
|
||||||
*/
|
*/
|
||||||
void RecoverFromInvalidFrames(const UnorientedIntSize& aSize,
|
void RecoverFromInvalidFrames(const OrientedIntSize& aSize, uint32_t aFlags);
|
||||||
uint32_t aFlags);
|
|
||||||
|
|
||||||
void OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded);
|
void OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded);
|
||||||
|
|
||||||
|
|
@ -463,8 +461,7 @@ class RasterImage final : public ImageResource,
|
||||||
|
|
||||||
// Determines whether we can downscale during decode with the given
|
// Determines whether we can downscale during decode with the given
|
||||||
// parameters.
|
// parameters.
|
||||||
bool CanDownscaleDuringDecode(const UnorientedIntSize& aSize,
|
bool CanDownscaleDuringDecode(const OrientedIntSize& aSize, uint32_t aFlags);
|
||||||
uint32_t aFlags);
|
|
||||||
|
|
||||||
// Error handling.
|
// Error handling.
|
||||||
void DoError();
|
void DoError();
|
||||||
|
|
@ -491,7 +488,7 @@ class RasterImage final : public ImageResource,
|
||||||
|
|
||||||
bool IsOpaque();
|
bool IsOpaque();
|
||||||
|
|
||||||
LookupResult RequestDecodeForSizeInternal(const UnorientedIntSize& aSize,
|
LookupResult RequestDecodeForSizeInternal(const OrientedIntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
uint32_t aWhichFrame);
|
uint32_t aWhichFrame);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ Maybe<SurfaceInvalidRect> AbstractSurfaceSink::TakeInvalidRect() {
|
||||||
invalidRect.mInputSpaceRect = invalidRect.mOutputSpaceRect = mInvalidRect;
|
invalidRect.mInputSpaceRect = invalidRect.mOutputSpaceRect = mInvalidRect;
|
||||||
|
|
||||||
// Forget about the invalid rect we're returning.
|
// Forget about the invalid rect we're returning.
|
||||||
mInvalidRect = IntRect();
|
mInvalidRect = OrientedIntRect();
|
||||||
|
|
||||||
return Some(invalidRect);
|
return Some(invalidRect);
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ uint8_t* AbstractSurfaceSink::DoAdvanceRow() {
|
||||||
// to change.
|
// to change.
|
||||||
int32_t invalidY = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
|
int32_t invalidY = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
|
||||||
mInvalidRect.UnionRect(mInvalidRect,
|
mInvalidRect.UnionRect(mInvalidRect,
|
||||||
IntRect(0, invalidY, InputSize().width, 1));
|
OrientedIntRect(0, invalidY, InputSize().width, 1));
|
||||||
|
|
||||||
mRow = min(uint32_t(InputSize().height), mRow + 1);
|
mRow = min(uint32_t(InputSize().height), mRow + 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "mozilla/Variant.h"
|
#include "mozilla/Variant.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
|
#include "Orientation.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
@ -47,8 +48,9 @@ class Decoder;
|
||||||
* of the output surface (after all SurfaceFilters).
|
* of the output surface (after all SurfaceFilters).
|
||||||
*/
|
*/
|
||||||
struct SurfaceInvalidRect {
|
struct SurfaceInvalidRect {
|
||||||
gfx::IntRect mInputSpaceRect; /// The invalid rect in pre-SurfacePipe space.
|
OrientedIntRect
|
||||||
gfx::IntRect
|
mInputSpaceRect; /// The invalid rect in pre-SurfacePipe space.
|
||||||
|
OrientedIntRect
|
||||||
mOutputSpaceRect; /// The invalid rect in post-SurfacePipe space.
|
mOutputSpaceRect; /// The invalid rect in post-SurfacePipe space.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -774,7 +776,7 @@ class AbstractSurfaceSink : public SurfaceFilter {
|
||||||
uint8_t* DoAdvanceRow() final;
|
uint8_t* DoAdvanceRow() final;
|
||||||
virtual uint8_t* GetRowPointer() const = 0;
|
virtual uint8_t* GetRowPointer() const = 0;
|
||||||
|
|
||||||
gfx::IntRect
|
OrientedIntRect
|
||||||
mInvalidRect; /// The region of the surface that has been written
|
mInvalidRect; /// The region of the surface that has been written
|
||||||
/// to since the last call to TakeInvalidRect().
|
/// to since the last call to TakeInvalidRect().
|
||||||
uint8_t* mImageData; /// A pointer to the beginning of the surface data.
|
uint8_t* mImageData; /// A pointer to the beginning of the surface data.
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,8 @@ class SurfacePipeFactory {
|
||||||
* initialized.
|
* initialized.
|
||||||
*/
|
*/
|
||||||
static Maybe<SurfacePipe> CreateSurfacePipe(
|
static Maybe<SurfacePipe> CreateSurfacePipe(
|
||||||
Decoder* aDecoder, const nsIntSize& aInputSize,
|
Decoder* aDecoder, const OrientedIntSize& aInputSize,
|
||||||
const nsIntSize& aOutputSize, const nsIntRect& aFrameRect,
|
const OrientedIntSize& aOutputSize, const OrientedIntRect& aFrameRect,
|
||||||
gfx::SurfaceFormat aInFormat, gfx::SurfaceFormat aOutFormat,
|
gfx::SurfaceFormat aInFormat, gfx::SurfaceFormat aOutFormat,
|
||||||
const Maybe<AnimationParams>& aAnimParams, qcms_transform* aTransform,
|
const Maybe<AnimationParams>& aAnimParams, qcms_transform* aTransform,
|
||||||
SurfacePipeFlags aFlags) {
|
SurfacePipeFlags aFlags) {
|
||||||
|
|
@ -101,7 +101,7 @@ class SurfacePipeFactory {
|
||||||
bool(aFlags & SurfacePipeFlags::PROGRESSIVE_DISPLAY);
|
bool(aFlags & SurfacePipeFlags::PROGRESSIVE_DISPLAY);
|
||||||
const bool downscale = aInputSize != aOutputSize;
|
const bool downscale = aInputSize != aOutputSize;
|
||||||
const bool removeFrameRect = !aFrameRect.IsEqualEdges(
|
const bool removeFrameRect = !aFrameRect.IsEqualEdges(
|
||||||
nsIntRect(0, 0, aInputSize.width, aInputSize.height));
|
OrientedIntRect(OrientedIntPoint(0, 0), aInputSize));
|
||||||
const bool blendAnimation = aAnimParams.isSome();
|
const bool blendAnimation = aAnimParams.isSome();
|
||||||
const bool colorManagement = aTransform != nullptr;
|
const bool colorManagement = aTransform != nullptr;
|
||||||
const bool premultiplyAlpha =
|
const bool premultiplyAlpha =
|
||||||
|
|
@ -174,13 +174,13 @@ class SurfacePipeFactory {
|
||||||
// account.
|
// account.
|
||||||
DeinterlacingConfig<uint32_t> deinterlacingConfig{progressiveDisplay};
|
DeinterlacingConfig<uint32_t> deinterlacingConfig{progressiveDisplay};
|
||||||
ADAM7InterpolatingConfig interpolatingConfig;
|
ADAM7InterpolatingConfig interpolatingConfig;
|
||||||
RemoveFrameRectConfig removeFrameRectConfig{aFrameRect};
|
RemoveFrameRectConfig removeFrameRectConfig{aFrameRect.ToUnknownRect()};
|
||||||
BlendAnimationConfig blendAnimationConfig{aDecoder};
|
BlendAnimationConfig blendAnimationConfig{aDecoder};
|
||||||
DownscalingConfig downscalingConfig{aInputSize, aOutFormat};
|
DownscalingConfig downscalingConfig{aInputSize.ToUnknownSize(), aOutFormat};
|
||||||
ColorManagementConfig colorManagementConfig{aTransform};
|
ColorManagementConfig colorManagementConfig{aTransform};
|
||||||
SwizzleConfig swizzleConfig{aInFormat, aOutFormat, premultiplyAlpha};
|
SwizzleConfig swizzleConfig{aInFormat, aOutFormat, premultiplyAlpha};
|
||||||
SurfaceConfig surfaceConfig{aDecoder, aOutputSize, aOutFormat,
|
SurfaceConfig surfaceConfig{aDecoder, aOutputSize.ToUnknownSize(),
|
||||||
flipVertically, aAnimParams};
|
aOutFormat, flipVertically, aAnimParams};
|
||||||
|
|
||||||
Maybe<SurfacePipe> pipe;
|
Maybe<SurfacePipe> pipe;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1376,8 +1376,10 @@ nsAVIFDecoder::DecodeResult nsAVIFDecoder::Decode(
|
||||||
AccumulateCategorical(LABELS_AVIF_ALPHA::absent);
|
AccumulateCategorical(LABELS_AVIF_ALPHA::absent);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntSize rgbSize = Size();
|
IntSize rgbSize = decodedData.mPicSize;
|
||||||
MOZ_ASSERT(rgbSize == decodedData.mPicSize);
|
MOZ_ASSERT(
|
||||||
|
rgbSize ==
|
||||||
|
GetImageMetadata().GetOrientation().ToUnoriented(Size()).ToUnknownSize());
|
||||||
|
|
||||||
if (parsedImg.nclx_colour_information &&
|
if (parsedImg.nclx_colour_information &&
|
||||||
parsedImg.icc_colour_information.data) {
|
parsedImg.icc_colour_information.data) {
|
||||||
|
|
@ -1553,7 +1555,7 @@ nsAVIFDecoder::DecodeResult nsAVIFDecoder::Decode(
|
||||||
MOZ_LOG(sAVIFLog, LogLevel::Debug,
|
MOZ_LOG(sAVIFLog, LogLevel::Debug,
|
||||||
("[this=%p] calling SurfacePipeFactory::CreateSurfacePipe", this));
|
("[this=%p] calling SurfacePipeFactory::CreateSurfacePipe", this));
|
||||||
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||||
this, rgbSize, OutputSize(), FullFrame(), format, format, Nothing(),
|
this, Size(), OutputSize(), FullFrame(), format, format, Nothing(),
|
||||||
mTransform, SurfacePipeFlags());
|
mTransform, SurfacePipeFlags());
|
||||||
|
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ void nsGIFDecoder2::BeginGIF() {
|
||||||
PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height);
|
PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsGIFDecoder2::CheckForTransparency(const IntRect& aFrameRect) {
|
bool nsGIFDecoder2::CheckForTransparency(const OrientedIntRect& aFrameRect) {
|
||||||
// Check if the image has a transparent color in its palette.
|
// Check if the image has a transparent color in its palette.
|
||||||
if (mGIFStruct.is_transparent) {
|
if (mGIFStruct.is_transparent) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
|
|
@ -154,7 +154,8 @@ bool nsGIFDecoder2::CheckForTransparency(const IntRect& aFrameRect) {
|
||||||
|
|
||||||
// If we need padding on the first frame, that means we don't draw into part
|
// If we need padding on the first frame, that means we don't draw into part
|
||||||
// of the image at all. Report that as transparency.
|
// of the image at all. Report that as transparency.
|
||||||
IntRect imageRect(0, 0, mGIFStruct.screen_width, mGIFStruct.screen_height);
|
OrientedIntRect imageRect(0, 0, mGIFStruct.screen_width,
|
||||||
|
mGIFStruct.screen_height);
|
||||||
if (!imageRect.IsEqualEdges(aFrameRect)) {
|
if (!imageRect.IsEqualEdges(aFrameRect)) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
mSawTransparency = true; // Make sure we don't optimize it away.
|
mSawTransparency = true; // Make sure we don't optimize it away.
|
||||||
|
|
@ -165,7 +166,7 @@ bool nsGIFDecoder2::CheckForTransparency(const IntRect& aFrameRect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
nsresult nsGIFDecoder2::BeginImageFrame(const IntRect& aFrameRect,
|
nsresult nsGIFDecoder2::BeginImageFrame(const OrientedIntRect& aFrameRect,
|
||||||
uint16_t aDepth, bool aIsInterlaced) {
|
uint16_t aDepth, bool aIsInterlaced) {
|
||||||
MOZ_ASSERT(HasSize());
|
MOZ_ASSERT(HasSize());
|
||||||
|
|
||||||
|
|
@ -176,7 +177,7 @@ nsresult nsGIFDecoder2::BeginImageFrame(const IntRect& aFrameRect,
|
||||||
|
|
||||||
Maybe<AnimationParams> animParams;
|
Maybe<AnimationParams> animParams;
|
||||||
if (!IsFirstFrameDecode()) {
|
if (!IsFirstFrameDecode()) {
|
||||||
animParams.emplace(aFrameRect,
|
animParams.emplace(aFrameRect.ToUnknownRect(),
|
||||||
FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time),
|
FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time),
|
||||||
uint32_t(mGIFStruct.images_decoded), BlendMethod::OVER,
|
uint32_t(mGIFStruct.images_decoded), BlendMethod::OVER,
|
||||||
DisposalMethod(mGIFStruct.disposal_method));
|
DisposalMethod(mGIFStruct.disposal_method));
|
||||||
|
|
@ -752,7 +753,7 @@ LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDescriptor(
|
||||||
|
|
||||||
LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishImageDescriptor(
|
LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishImageDescriptor(
|
||||||
const char* aData) {
|
const char* aData) {
|
||||||
IntRect frameRect;
|
OrientedIntRect frameRect;
|
||||||
|
|
||||||
// Get image offsets with respect to the screen origin.
|
// Get image offsets with respect to the screen origin.
|
||||||
frameRect.SetRect(
|
frameRect.SetRect(
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class nsGIFDecoder2 : public Decoder {
|
||||||
* @param aDepth The palette depth of this frame.
|
* @param aDepth The palette depth of this frame.
|
||||||
* @param aIsInterlaced If true, this frame is an interlaced frame.
|
* @param aIsInterlaced If true, this frame is an interlaced frame.
|
||||||
*/
|
*/
|
||||||
nsresult BeginImageFrame(const gfx::IntRect& aFrameRect, uint16_t aDepth,
|
nsresult BeginImageFrame(const OrientedIntRect& aFrameRect, uint16_t aDepth,
|
||||||
bool aIsInterlaced);
|
bool aIsInterlaced);
|
||||||
|
|
||||||
/// Called when we finish decoding a frame.
|
/// Called when we finish decoding a frame.
|
||||||
|
|
@ -76,7 +76,7 @@ class nsGIFDecoder2 : public Decoder {
|
||||||
|
|
||||||
/// Checks if we have transparency, either because the header indicates that
|
/// Checks if we have transparency, either because the header indicates that
|
||||||
/// there's alpha, or because the frame rect doesn't cover the entire image.
|
/// there's alpha, or because the frame rect doesn't cover the entire image.
|
||||||
bool CheckForTransparency(const gfx::IntRect& aFrameRect);
|
bool CheckForTransparency(const OrientedIntRect& aFrameRect);
|
||||||
|
|
||||||
// @return the clear code used for LZW decompression.
|
// @return the clear code used for LZW decompression.
|
||||||
int ClearCode() const {
|
int ClearCode() const {
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ LexerTransition<ICOState> nsICODecoder::ReadDirEntry(const char* aData) {
|
||||||
e.mBitCount = LittleEndian::readUint16(aData + 6);
|
e.mBitCount = LittleEndian::readUint16(aData + 6);
|
||||||
e.mBytesInRes = LittleEndian::readUint32(aData + 8);
|
e.mBytesInRes = LittleEndian::readUint32(aData + 8);
|
||||||
e.mImageOffset = offset;
|
e.mImageOffset = offset;
|
||||||
e.mSize = IntSize(e.mWidth, e.mHeight);
|
e.mSize = OrientedIntSize(e.mWidth, e.mHeight);
|
||||||
|
|
||||||
// Only accept entries with sufficient resource data to actually contain
|
// Only accept entries with sufficient resource data to actually contain
|
||||||
// some image data.
|
// some image data.
|
||||||
|
|
@ -234,7 +234,7 @@ LexerTransition<ICOState> nsICODecoder::FinishDirEntry() {
|
||||||
|
|
||||||
// If an explicit output size was specified, we'll try to select the resource
|
// If an explicit output size was specified, we'll try to select the resource
|
||||||
// that matches it best below.
|
// that matches it best below.
|
||||||
const Maybe<IntSize> desiredSize = ExplicitOutputSize();
|
const Maybe<OrientedIntSize> desiredSize = ExplicitOutputSize();
|
||||||
|
|
||||||
// Determine the biggest resource. We always use the biggest resource for the
|
// Determine the biggest resource. We always use the biggest resource for the
|
||||||
// intrinsic size, and if we don't have a specific desired size, we select it
|
// intrinsic size, and if we don't have a specific desired size, we select it
|
||||||
|
|
@ -309,7 +309,7 @@ LexerTransition<ICOState> nsICODecoder::FinishDirEntry() {
|
||||||
//
|
//
|
||||||
// TODO(aosmond): This is the last user of Downscaler. We should switch this
|
// TODO(aosmond): This is the last user of Downscaler. We should switch this
|
||||||
// to SurfacePipe as well so we can remove the code from tree.
|
// to SurfacePipe as well so we can remove the code from tree.
|
||||||
mDownscaler.emplace(OutputSize());
|
mDownscaler.emplace(OutputSize().ToUnknownSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offsetToResource = mDirEntry->mImageOffset - FirstResourceOffset();
|
size_t offsetToResource = mDirEntry->mImageOffset - FirstResourceOffset();
|
||||||
|
|
@ -348,7 +348,7 @@ LexerTransition<ICOState> nsICODecoder::SniffResource(const char* aData) {
|
||||||
|
|
||||||
// Create a PNG decoder which will do the rest of the work for us.
|
// Create a PNG decoder which will do the rest of the work for us.
|
||||||
bool metadataDecode = mReturnIterator.isSome();
|
bool metadataDecode = mReturnIterator.isSome();
|
||||||
Maybe<IntSize> expectedSize =
|
Maybe<OrientedIntSize> expectedSize =
|
||||||
metadataDecode ? Nothing() : Some(mDirEntry->mSize);
|
metadataDecode ? Nothing() : Some(mDirEntry->mSize);
|
||||||
mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
|
mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
|
||||||
DecoderType::PNG, std::move(containedIterator.ref()), WrapNotNull(this),
|
DecoderType::PNG, std::move(containedIterator.ref()), WrapNotNull(this),
|
||||||
|
|
@ -412,7 +412,7 @@ LexerTransition<ICOState> nsICODecoder::ReadBIH(const char* aData) {
|
||||||
// Create a BMP decoder which will do most of the work for us; the exception
|
// Create a BMP decoder which will do most of the work for us; the exception
|
||||||
// is the AND mask, which isn't present in standalone BMPs.
|
// is the AND mask, which isn't present in standalone BMPs.
|
||||||
bool metadataDecode = mReturnIterator.isSome();
|
bool metadataDecode = mReturnIterator.isSome();
|
||||||
Maybe<IntSize> expectedSize =
|
Maybe<OrientedIntSize> expectedSize =
|
||||||
metadataDecode ? Nothing() : Some(mDirEntry->mSize);
|
metadataDecode ? Nothing() : Some(mDirEntry->mSize);
|
||||||
mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
|
mContainedDecoder = DecoderFactory::CreateDecoderForICOResource(
|
||||||
DecoderType::BMP, std::move(containedIterator.ref()), WrapNotNull(this),
|
DecoderType::BMP, std::move(containedIterator.ref()), WrapNotNull(this),
|
||||||
|
|
@ -491,10 +491,10 @@ LexerTransition<ICOState> nsICODecoder::PrepareForMask() {
|
||||||
mDownscaler->TargetSize().width *
|
mDownscaler->TargetSize().width *
|
||||||
mDownscaler->TargetSize().height * sizeof(uint32_t));
|
mDownscaler->TargetSize().height * sizeof(uint32_t));
|
||||||
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
|
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
|
||||||
nsresult rv =
|
nsresult rv = mDownscaler->BeginFrame(mDirEntry->mSize.ToUnknownSize(),
|
||||||
mDownscaler->BeginFrame(mDirEntry->mSize, Nothing(), mMaskBuffer.get(),
|
Nothing(), mMaskBuffer.get(),
|
||||||
/* aHasAlpha = */ true,
|
/* aHasAlpha = */ true,
|
||||||
/* aFlipVertically = */ true);
|
/* aFlipVertically = */ true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return Transition::TerminateFailure();
|
return Transition::TerminateFailure();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class nsICODecoder : public Decoder {
|
||||||
LexerTransition<ICOState> FinishResource();
|
LexerTransition<ICOState> FinishResource();
|
||||||
|
|
||||||
struct IconDirEntryEx : public IconDirEntry {
|
struct IconDirEntryEx : public IconDirEntry {
|
||||||
gfx::IntSize mSize;
|
OrientedIntSize mSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
StreamingLexer<ICOState, 32> mLexer; // The lexer.
|
StreamingLexer<ICOState, 32> mLexer; // The lexer.
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
|
||||||
}
|
}
|
||||||
|
|
||||||
case JXL_DEC_FULL_IMAGE: {
|
case JXL_DEC_FULL_IMAGE: {
|
||||||
gfx::IntSize size(mInfo.xsize, mInfo.ysize);
|
OrientedIntSize size(mInfo.xsize, mInfo.ysize);
|
||||||
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||||
this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
|
this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
|
||||||
SurfaceFormat::OS_RGBA, Nothing(), nullptr, SurfacePipeFlags());
|
SurfaceFormat::OS_RGBA, Nothing(), nullptr, SurfacePipeFlags());
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ nsPNGDecoder::~nsPNGDecoder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPNGDecoder::TransparencyType nsPNGDecoder::GetTransparencyType(
|
nsPNGDecoder::TransparencyType nsPNGDecoder::GetTransparencyType(
|
||||||
const IntRect& aFrameRect) {
|
const OrientedIntRect& aFrameRect) {
|
||||||
// Check if the image has a transparent color in its palette.
|
// Check if the image has a transparent color in its palette.
|
||||||
if (HasAlphaChannel()) {
|
if (HasAlphaChannel()) {
|
||||||
return TransparencyType::eAlpha;
|
return TransparencyType::eAlpha;
|
||||||
|
|
@ -194,7 +194,7 @@ nsresult nsPNGDecoder::CreateFrame(const FrameInfo& aFrameInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
animParams.emplace(
|
animParams.emplace(
|
||||||
AnimationParams{aFrameInfo.mFrameRect,
|
AnimationParams{aFrameInfo.mFrameRect.ToUnknownRect(),
|
||||||
FrameTimeout::FromRawMilliseconds(mAnimInfo.mTimeout),
|
FrameTimeout::FromRawMilliseconds(mAnimInfo.mTimeout),
|
||||||
mNumFrames, mAnimInfo.mBlend, mAnimInfo.mDispose});
|
mNumFrames, mAnimInfo.mBlend, mAnimInfo.mDispose});
|
||||||
}
|
}
|
||||||
|
|
@ -527,7 +527,7 @@ void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) {
|
||||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||||
&interlace_type, &compression_type, &filter_type);
|
&interlace_type, &compression_type, &filter_type);
|
||||||
|
|
||||||
const IntRect frameRect(0, 0, width, height);
|
const OrientedIntRect frameRect(0, 0, width, height);
|
||||||
|
|
||||||
// Post our size to the superclass
|
// Post our size to the superclass
|
||||||
decoder->PostSize(frameRect.Width(), frameRect.Height());
|
decoder->PostSize(frameRect.Width(), frameRect.Height());
|
||||||
|
|
@ -930,10 +930,11 @@ void nsPNGDecoder::frame_info_callback(png_structp png_ptr,
|
||||||
|
|
||||||
// Save the information necessary to create the frame; we'll actually create
|
// Save the information necessary to create the frame; we'll actually create
|
||||||
// it when we return from the yield.
|
// it when we return from the yield.
|
||||||
const IntRect frameRect(png_get_next_frame_x_offset(png_ptr, decoder->mInfo),
|
const OrientedIntRect frameRect(
|
||||||
png_get_next_frame_y_offset(png_ptr, decoder->mInfo),
|
png_get_next_frame_x_offset(png_ptr, decoder->mInfo),
|
||||||
png_get_next_frame_width(png_ptr, decoder->mInfo),
|
png_get_next_frame_y_offset(png_ptr, decoder->mInfo),
|
||||||
png_get_next_frame_height(png_ptr, decoder->mInfo));
|
png_get_next_frame_width(png_ptr, decoder->mInfo),
|
||||||
|
png_get_next_frame_height(png_ptr, decoder->mInfo));
|
||||||
const bool isInterlaced = bool(decoder->interlacebuf);
|
const bool isInterlaced = bool(decoder->interlacebuf);
|
||||||
|
|
||||||
# ifndef MOZ_EMBEDDED_LIBPNG
|
# ifndef MOZ_EMBEDDED_LIBPNG
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class nsPNGDecoder : public Decoder {
|
||||||
|
|
||||||
/// The information necessary to create a frame.
|
/// The information necessary to create a frame.
|
||||||
struct FrameInfo {
|
struct FrameInfo {
|
||||||
gfx::IntRect mFrameRect;
|
OrientedIntRect mFrameRect;
|
||||||
bool mIsInterlaced;
|
bool mIsInterlaced;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ class nsPNGDecoder : public Decoder {
|
||||||
|
|
||||||
enum class TransparencyType { eNone, eAlpha, eFrameRect };
|
enum class TransparencyType { eNone, eAlpha, eFrameRect };
|
||||||
|
|
||||||
TransparencyType GetTransparencyType(const gfx::IntRect& aFrameRect);
|
TransparencyType GetTransparencyType(const OrientedIntRect& aFrameRect);
|
||||||
void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
|
void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
|
||||||
|
|
||||||
void PostInvalidationIfNeeded();
|
void PostInvalidationIfNeeded();
|
||||||
|
|
@ -92,7 +92,7 @@ class nsPNGDecoder : public Decoder {
|
||||||
public:
|
public:
|
||||||
png_structp mPNG;
|
png_structp mPNG;
|
||||||
png_infop mInfo;
|
png_infop mInfo;
|
||||||
nsIntRect mFrameRect;
|
OrientedIntRect mFrameRect;
|
||||||
uint8_t* mCMSLine;
|
uint8_t* mCMSLine;
|
||||||
uint8_t* interlacebuf;
|
uint8_t* interlacebuf;
|
||||||
gfx::SurfaceFormat mFormat;
|
gfx::SurfaceFormat mFormat;
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ LexerResult nsWebPDecoder::UpdateBuffer(SourceBufferIterator& aIterator,
|
||||||
return ReadData();
|
return ReadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsWebPDecoder::CreateFrame(const nsIntRect& aFrameRect) {
|
nsresult nsWebPDecoder::CreateFrame(const OrientedIntRect& aFrameRect) {
|
||||||
MOZ_ASSERT(HasSize());
|
MOZ_ASSERT(HasSize());
|
||||||
MOZ_ASSERT(!mDecoder);
|
MOZ_ASSERT(!mDecoder);
|
||||||
|
|
||||||
|
|
@ -257,7 +257,8 @@ nsresult nsWebPDecoder::CreateFrame(const nsIntRect& aFrameRect) {
|
||||||
|
|
||||||
Maybe<AnimationParams> animParams;
|
Maybe<AnimationParams> animParams;
|
||||||
if (!IsFirstFrameDecode()) {
|
if (!IsFirstFrameDecode()) {
|
||||||
animParams.emplace(aFrameRect, mTimeout, mCurrentFrame, mBlend, mDisposal);
|
animParams.emplace(aFrameRect.ToUnknownRect(), mTimeout, mCurrentFrame,
|
||||||
|
mBlend, mDisposal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
|
||||||
|
|
@ -430,7 +431,7 @@ LexerResult nsWebPDecoder::ReadPayload(WebPDemuxer* aDemuxer,
|
||||||
}
|
}
|
||||||
|
|
||||||
LexerResult nsWebPDecoder::ReadSingle(const uint8_t* aData, size_t aLength,
|
LexerResult nsWebPDecoder::ReadSingle(const uint8_t* aData, size_t aLength,
|
||||||
const IntRect& aFrameRect) {
|
const OrientedIntRect& aFrameRect) {
|
||||||
MOZ_ASSERT(!IsMetadataDecode());
|
MOZ_ASSERT(!IsMetadataDecode());
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(aData);
|
||||||
MOZ_ASSERT(aLength > 0);
|
MOZ_ASSERT(aLength > 0);
|
||||||
|
|
@ -560,7 +561,8 @@ LexerResult nsWebPDecoder::ReadMultiple(WebPDemuxer* aDemuxer,
|
||||||
mFormat = iter.has_alpha || mCurrentFrame > 0 ? SurfaceFormat::OS_RGBA
|
mFormat = iter.has_alpha || mCurrentFrame > 0 ? SurfaceFormat::OS_RGBA
|
||||||
: SurfaceFormat::OS_RGBX;
|
: SurfaceFormat::OS_RGBX;
|
||||||
mTimeout = FrameTimeout::FromRawMilliseconds(iter.duration);
|
mTimeout = FrameTimeout::FromRawMilliseconds(iter.duration);
|
||||||
nsIntRect frameRect(iter.x_offset, iter.y_offset, iter.width, iter.height);
|
OrientedIntRect frameRect(iter.x_offset, iter.y_offset, iter.width,
|
||||||
|
iter.height);
|
||||||
|
|
||||||
rv = ReadSingle(iter.fragment.bytes, iter.fragment.size, frameRect);
|
rv = ReadSingle(iter.fragment.bytes, iter.fragment.size, frameRect);
|
||||||
complete = complete && !WebPDemuxNextFrame(&iter);
|
complete = complete && !WebPDemuxNextFrame(&iter);
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ class nsWebPDecoder final : public Decoder {
|
||||||
LexerResult ReadHeader(WebPDemuxer* aDemuxer, bool aIsComplete);
|
LexerResult ReadHeader(WebPDemuxer* aDemuxer, bool aIsComplete);
|
||||||
LexerResult ReadPayload(WebPDemuxer* aDemuxer, bool aIsComplete);
|
LexerResult ReadPayload(WebPDemuxer* aDemuxer, bool aIsComplete);
|
||||||
|
|
||||||
nsresult CreateFrame(const nsIntRect& aFrameRect);
|
nsresult CreateFrame(const OrientedIntRect& aFrameRect);
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
|
|
||||||
LexerResult ReadSingle(const uint8_t* aData, size_t aLength,
|
LexerResult ReadSingle(const uint8_t* aData, size_t aLength,
|
||||||
const gfx::IntRect& aFrameRect);
|
const OrientedIntRect& aFrameRect);
|
||||||
|
|
||||||
LexerResult ReadMultiple(WebPDemuxer* aDemuxer, bool aIsComplete);
|
LexerResult ReadMultiple(WebPDemuxer* aDemuxer, bool aIsComplete);
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ class nsWebPDecoder final : public Decoder {
|
||||||
gfx::SurfaceFormat mFormat;
|
gfx::SurfaceFormat mFormat;
|
||||||
|
|
||||||
/// Frame rect for the current frame.
|
/// Frame rect for the current frame.
|
||||||
gfx::IntRect mFrameRect;
|
OrientedIntRect mFrameRect;
|
||||||
|
|
||||||
/// The last row of decoded pixels written to mPipe.
|
/// The last row of decoded pixels written to mPipe.
|
||||||
int mLastRow;
|
int mLastRow;
|
||||||
|
|
|
||||||
|
|
@ -277,13 +277,13 @@ already_AddRefed<Decoder> CreateTrivialDecoder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
|
void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
|
||||||
const gfx::IntRect& aInputSpaceRect,
|
const IntRect& aInputSpaceRect,
|
||||||
const gfx::IntRect& aOutputSpaceRect) {
|
const IntRect& aOutputSpaceRect) {
|
||||||
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(aInputSpaceRect, invalidRect->mInputSpaceRect);
|
EXPECT_EQ(aInputSpaceRect, invalidRect->mInputSpaceRect.ToUnknownRect());
|
||||||
EXPECT_EQ(aOutputSpaceRect, invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(aOutputSpaceRect, invalidRect->mOutputSpaceRect.ToUnknownRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckGeneratedImage(Decoder* aDecoder, const IntRect& aRect,
|
void CheckGeneratedImage(Decoder* aDecoder, const IntRect& aRect,
|
||||||
|
|
|
||||||
|
|
@ -151,21 +151,22 @@ TEST_F(ImageDecodeToSurface, ICOMultipleSizes) {
|
||||||
buffer, nsDependentCString(testCase.mMimeType), metadata);
|
buffer, nsDependentCString(testCase.mMimeType), metadata);
|
||||||
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
||||||
ASSERT_TRUE(metadata.HasSize());
|
ASSERT_TRUE(metadata.HasSize());
|
||||||
EXPECT_EQ(testCase.mSize, metadata.GetSize());
|
EXPECT_EQ(testCase.mSize, metadata.GetSize().ToUnknownSize());
|
||||||
|
|
||||||
const nsTArray<IntSize>& nativeSizes = metadata.GetNativeSizes();
|
const nsTArray<OrientedIntSize>& nativeSizes = metadata.GetNativeSizes();
|
||||||
ASSERT_EQ(6u, nativeSizes.Length());
|
ASSERT_EQ(6u, nativeSizes.Length());
|
||||||
|
|
||||||
IntSize expectedSizes[] = {
|
OrientedIntSize expectedSizes[] = {
|
||||||
IntSize(16, 16), IntSize(32, 32), IntSize(64, 64),
|
OrientedIntSize(16, 16), OrientedIntSize(32, 32),
|
||||||
IntSize(128, 128), IntSize(256, 256), IntSize(256, 128),
|
OrientedIntSize(64, 64), OrientedIntSize(128, 128),
|
||||||
|
OrientedIntSize(256, 256), OrientedIntSize(256, 128),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
|
EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
|
||||||
|
|
||||||
// Request decoding at native size
|
// Request decoding at native size
|
||||||
testCase.mOutputSize = nativeSizes[i];
|
testCase.mOutputSize = nativeSizes[i].ToUnknownSize();
|
||||||
RunDecodeToSurface(testCase, buffer);
|
RunDecodeToSurface(testCase, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ static already_AddRefed<SourceSurface> CheckDecoderState(
|
||||||
bool(progress & FLAG_IS_ANIMATED));
|
bool(progress & FLAG_IS_ANIMATED));
|
||||||
|
|
||||||
// The decoder should get the correct size.
|
// The decoder should get the correct size.
|
||||||
IntSize size = aDecoder->Size();
|
OrientedIntSize size = aDecoder->Size();
|
||||||
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
||||||
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
||||||
|
|
||||||
|
|
@ -316,7 +316,7 @@ static void CheckAnimationDecoderResults(const ImageTestCase& aTestCase,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The decoder should get the correct size.
|
// The decoder should get the correct size.
|
||||||
IntSize size = aDecoder->Size();
|
OrientedIntSize size = aDecoder->Size();
|
||||||
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
||||||
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ static void CheckDecoderState(const ImageTestCase& aTestCase,
|
||||||
bool(progress & FLAG_IS_ANIMATED));
|
bool(progress & FLAG_IS_ANIMATED));
|
||||||
|
|
||||||
// The decoder should get the correct size.
|
// The decoder should get the correct size.
|
||||||
IntSize size = aDecoder->Size();
|
OrientedIntSize size = aDecoder->Size();
|
||||||
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
EXPECT_EQ(aTestCase.mSize.width, size.width);
|
||||||
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
EXPECT_EQ(aTestCase.mSize.height, size.height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ TEST_F(ImageDeinterlacingFilter, WritePixelsOutput1_1) {
|
||||||
void WriteRowAndCheckInterlacerOutput(image::Decoder* aDecoder,
|
void WriteRowAndCheckInterlacerOutput(image::Decoder* aDecoder,
|
||||||
SurfaceFilter* aFilter, BGRAColor aColor,
|
SurfaceFilter* aFilter, BGRAColor aColor,
|
||||||
WriteState aNextState,
|
WriteState aNextState,
|
||||||
IntRect aInvalidRect,
|
OrientedIntRect aInvalidRect,
|
||||||
uint32_t aFirstHaeberliRow,
|
uint32_t aFirstHaeberliRow,
|
||||||
uint32_t aLastHaeberliRow) {
|
uint32_t aLastHaeberliRow) {
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
|
@ -474,7 +474,7 @@ TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7) {
|
||||||
// the end of the first pass.
|
// the end of the first pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 0, 4);
|
OrientedIntRect(0, 0, 7, 7), 0, 4);
|
||||||
|
|
||||||
// Second pass. Rows are positioned at 8n + 4.
|
// Second pass. Rows are positioned at 8n + 4.
|
||||||
|
|
||||||
|
|
@ -482,7 +482,7 @@ TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7) {
|
||||||
// the end of the second pass.
|
// the end of the second pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 1, 4);
|
OrientedIntRect(0, 0, 7, 7), 1, 4);
|
||||||
|
|
||||||
// Third pass. Rows are positioned at 4n + 2.
|
// Third pass. Rows are positioned at 4n + 2.
|
||||||
|
|
||||||
|
|
@ -491,13 +491,13 @@ TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7) {
|
||||||
// previous passes when seeking to the next output row (rows 4 and 5).
|
// previous passes when seeking to the next output row (rows 4 and 5).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 2, 7, 4), 2, 3);
|
OrientedIntRect(0, 2, 7, 4), 2, 3);
|
||||||
|
|
||||||
// Output row 6. The invalid rect is the entire image because this is
|
// Output row 6. The invalid rect is the entire image because this is
|
||||||
// the end of the third pass.
|
// the end of the third pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 6, 6);
|
OrientedIntRect(0, 0, 7, 7), 6, 6);
|
||||||
|
|
||||||
// Fourth pass. Rows are positioned at 2n + 1.
|
// Fourth pass. Rows are positioned at 2n + 1.
|
||||||
|
|
||||||
|
|
@ -506,21 +506,21 @@ TEST_F(ImageDeinterlacingFilter, WritePixelsIntermediateOutput7_7) {
|
||||||
// previous passes when seeking to the next output row (row 2).
|
// previous passes when seeking to the next output row (row 2).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 1, 7, 2), 1, 1);
|
OrientedIntRect(0, 1, 7, 2), 1, 1);
|
||||||
|
|
||||||
// Output row 3. The invalid rect contains the Haeberli rows for this
|
// Output row 3. The invalid rect contains the Haeberli rows for this
|
||||||
// output row (just row 3) as well as the rows that we copy from
|
// output row (just row 3) as well as the rows that we copy from
|
||||||
// previous passes when seeking to the next output row (row 4).
|
// previous passes when seeking to the next output row (row 4).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 3, 7, 2), 3, 3);
|
OrientedIntRect(0, 3, 7, 2), 3, 3);
|
||||||
|
|
||||||
// Output row 5. The invalid rect contains the Haeberli rows for this
|
// Output row 5. The invalid rect contains the Haeberli rows for this
|
||||||
// output row (just row 5) as well as the rows that we copy from
|
// output row (just row 5) as well as the rows that we copy from
|
||||||
// previous passes when seeking to the next output row (row 6).
|
// previous passes when seeking to the next output row (row 6).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::FINISHED,
|
WriteState::FINISHED,
|
||||||
IntRect(0, 5, 7, 2), 5, 5);
|
OrientedIntRect(0, 5, 7, 2), 5, 5);
|
||||||
|
|
||||||
// Assert that we're in the expected final state.
|
// Assert that we're in the expected final state.
|
||||||
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
||||||
|
|
@ -557,7 +557,7 @@ TEST_F(ImageDeinterlacingFilter,
|
||||||
// the end of the first pass.
|
// the end of the first pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 0, 0);
|
OrientedIntRect(0, 0, 7, 7), 0, 0);
|
||||||
|
|
||||||
// Second pass. Rows are positioned at 8n + 4.
|
// Second pass. Rows are positioned at 8n + 4.
|
||||||
|
|
||||||
|
|
@ -565,7 +565,7 @@ TEST_F(ImageDeinterlacingFilter,
|
||||||
// the end of the second pass.
|
// the end of the second pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 4, 4);
|
OrientedIntRect(0, 0, 7, 7), 4, 4);
|
||||||
|
|
||||||
// Third pass. Rows are positioned at 4n + 2.
|
// Third pass. Rows are positioned at 4n + 2.
|
||||||
|
|
||||||
|
|
@ -574,13 +574,13 @@ TEST_F(ImageDeinterlacingFilter,
|
||||||
// previous passes when seeking to the next output row (rows 4 and 5).
|
// previous passes when seeking to the next output row (rows 4 and 5).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 2, 7, 4), 2, 2);
|
OrientedIntRect(0, 2, 7, 4), 2, 2);
|
||||||
|
|
||||||
// Output row 6. The invalid rect is the entire image because this is
|
// Output row 6. The invalid rect is the entire image because this is
|
||||||
// the end of the third pass.
|
// the end of the third pass.
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 0, 7, 7), 6, 6);
|
OrientedIntRect(0, 0, 7, 7), 6, 6);
|
||||||
|
|
||||||
// Fourth pass. Rows are positioned at 2n + 1.
|
// Fourth pass. Rows are positioned at 2n + 1.
|
||||||
|
|
||||||
|
|
@ -589,21 +589,21 @@ TEST_F(ImageDeinterlacingFilter,
|
||||||
// previous passes when seeking to the next output row (row 2).
|
// previous passes when seeking to the next output row (row 2).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 1, 7, 2), 1, 1);
|
OrientedIntRect(0, 1, 7, 2), 1, 1);
|
||||||
|
|
||||||
// Output row 3. The invalid rect contains the Haeberli rows for this
|
// Output row 3. The invalid rect contains the Haeberli rows for this
|
||||||
// output row (just row 3) as well as the rows that we copy from
|
// output row (just row 3) as well as the rows that we copy from
|
||||||
// previous passes when seeking to the next output row (row 4).
|
// previous passes when seeking to the next output row (row 4).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Red(),
|
||||||
WriteState::NEED_MORE_DATA,
|
WriteState::NEED_MORE_DATA,
|
||||||
IntRect(0, 3, 7, 2), 3, 3);
|
OrientedIntRect(0, 3, 7, 2), 3, 3);
|
||||||
|
|
||||||
// Output row 5. The invalid rect contains the Haeberli rows for this
|
// Output row 5. The invalid rect contains the Haeberli rows for this
|
||||||
// output row (just row 5) as well as the rows that we copy from
|
// output row (just row 5) as well as the rows that we copy from
|
||||||
// previous passes when seeking to the next output row (row 6).
|
// previous passes when seeking to the next output row (row 6).
|
||||||
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
WriteRowAndCheckInterlacerOutput(aDecoder, aFilter, BGRAColor::Green(),
|
||||||
WriteState::FINISHED,
|
WriteState::FINISHED,
|
||||||
IntRect(0, 5, 7, 2), 5, 5);
|
OrientedIntRect(0, 5, 7, 2), 5, 5);
|
||||||
|
|
||||||
// Assert that we're in the expected final state.
|
// Assert that we're in the expected final state.
|
||||||
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
EXPECT_TRUE(aFilter->IsSurfaceFinished());
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ static void CheckMetadata(const ImageTestCase& aTestCase,
|
||||||
// Check that we got the expected metadata.
|
// Check that we got the expected metadata.
|
||||||
EXPECT_TRUE(metadataProgress & FLAG_SIZE_AVAILABLE);
|
EXPECT_TRUE(metadataProgress & FLAG_SIZE_AVAILABLE);
|
||||||
|
|
||||||
IntSize metadataSize = decoder->Size();
|
OrientedIntSize metadataSize = decoder->Size();
|
||||||
EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
|
EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
|
||||||
if (aBMPWithinICO == BMPWithinICO::YES) {
|
if (aBMPWithinICO == BMPWithinICO::YES) {
|
||||||
// Half the data is considered to be part of the AND mask if embedded
|
// Half the data is considered to be part of the AND mask if embedded
|
||||||
|
|
@ -120,7 +120,7 @@ static void CheckMetadata(const ImageTestCase& aTestCase,
|
||||||
EXPECT_EQ(fullProgress, metadataProgress | fullProgress);
|
EXPECT_EQ(fullProgress, metadataProgress | fullProgress);
|
||||||
|
|
||||||
// The full decoder and the metadata decoder should agree on the image's size.
|
// The full decoder and the metadata decoder should agree on the image's size.
|
||||||
IntSize fullSize = decoder->Size();
|
OrientedIntSize fullSize = decoder->Size();
|
||||||
EXPECT_EQ(metadataSize.width, fullSize.width);
|
EXPECT_EQ(metadataSize.width, fullSize.width);
|
||||||
EXPECT_EQ(metadataSize.height, fullSize.height);
|
EXPECT_EQ(metadataSize.height, fullSize.height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ void CheckSurfacePipeMethodResults(SurfacePipe* aPipe, image::Decoder* aDecoder,
|
||||||
EXPECT_TRUE(aPipe->IsSurfaceFinished());
|
EXPECT_TRUE(aPipe->IsSurfaceFinished());
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aPipe->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aPipe->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
// Check the generated image.
|
// Check the generated image.
|
||||||
CheckGeneratedImage(aDecoder, aRect);
|
CheckGeneratedImage(aDecoder, aRect);
|
||||||
|
|
@ -71,8 +71,8 @@ void CheckSurfacePipeMethodResults(SurfacePipe* aPipe, image::Decoder* aDecoder,
|
||||||
EXPECT_TRUE(aPipe->IsSurfaceFinished());
|
EXPECT_TRUE(aPipe->IsSurfaceFinished());
|
||||||
invalidRect = aPipe->TakeInvalidRect();
|
invalidRect = aPipe->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
aPipe->ResetToFirstRow();
|
aPipe->ResetToFirstRow();
|
||||||
EXPECT_FALSE(aPipe->IsSurfaceFinished());
|
EXPECT_FALSE(aPipe->IsSurfaceFinished());
|
||||||
|
|
|
||||||
|
|
@ -222,63 +222,63 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsEarlyExit)
|
||||||
|
|
||||||
TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRow)
|
TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRow)
|
||||||
{
|
{
|
||||||
WithSurfaceSink<Orient::NORMAL>(
|
WithSurfaceSink<Orient::NORMAL>([](image::Decoder* aDecoder,
|
||||||
[](image::Decoder* aDecoder, SurfaceSink* aSink) {
|
SurfaceSink* aSink) {
|
||||||
// Write the first 99 rows of our 100x100 surface and verify that even
|
// Write the first 99 rows of our 100x100 surface and verify that even
|
||||||
// though our lambda will yield pixels forever, only one row is written
|
// though our lambda will yield pixels forever, only one row is written
|
||||||
// per call to WritePixelsToRow().
|
// per call to WritePixelsToRow().
|
||||||
for (int row = 0; row < 99; ++row) {
|
for (int row = 0; row < 99; ++row) {
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
|
WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
|
||||||
++count;
|
++count;
|
||||||
return AsVariant(BGRAColor::Green().AsPixel());
|
return AsVariant(BGRAColor::Green().AsPixel());
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
|
|
||||||
EXPECT_EQ(100u, count);
|
|
||||||
EXPECT_FALSE(aSink->IsSurfaceFinished());
|
|
||||||
|
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
|
||||||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
|
|
||||||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
|
|
||||||
|
|
||||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, row + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the final line, which should finish the surface.
|
|
||||||
uint32_t count = 0;
|
|
||||||
WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
|
|
||||||
++count;
|
|
||||||
return AsVariant(BGRAColor::Green().AsPixel());
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_EQ(WriteState::FINISHED, result);
|
|
||||||
EXPECT_EQ(100u, count);
|
|
||||||
|
|
||||||
// Note that the final invalid rect we expect here is only the last row;
|
|
||||||
// that's because we called TakeInvalidRect() repeatedly in the loop
|
|
||||||
// above.
|
|
||||||
AssertCorrectPipelineFinalState(aSink, IntRect(0, 99, 100, 1),
|
|
||||||
IntRect(0, 99, 100, 1));
|
|
||||||
|
|
||||||
// Check that the generated image is correct.
|
|
||||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
|
|
||||||
|
|
||||||
// Attempt to write more and make sure that nothing gets written.
|
|
||||||
count = 0;
|
|
||||||
result = aSink->WritePixelsToRow<uint32_t>([&] {
|
|
||||||
count++;
|
|
||||||
return AsVariant(BGRAColor::Red().AsPixel());
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_EQ(WriteState::FINISHED, result);
|
|
||||||
EXPECT_EQ(0u, count);
|
|
||||||
EXPECT_TRUE(aSink->IsSurfaceFinished());
|
|
||||||
|
|
||||||
// Check that the generated image is still correct.
|
|
||||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
|
||||||
|
EXPECT_EQ(100u, count);
|
||||||
|
EXPECT_FALSE(aSink->IsSurfaceFinished());
|
||||||
|
|
||||||
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
|
EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
|
||||||
|
EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
|
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, row + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the final line, which should finish the surface.
|
||||||
|
uint32_t count = 0;
|
||||||
|
WriteState result = aSink->WritePixelsToRow<uint32_t>([&] {
|
||||||
|
++count;
|
||||||
|
return AsVariant(BGRAColor::Green().AsPixel());
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(WriteState::FINISHED, result);
|
||||||
|
EXPECT_EQ(100u, count);
|
||||||
|
|
||||||
|
// Note that the final invalid rect we expect here is only the last row;
|
||||||
|
// that's because we called TakeInvalidRect() repeatedly in the loop
|
||||||
|
// above.
|
||||||
|
AssertCorrectPipelineFinalState(aSink, IntRect(0, 99, 100, 1),
|
||||||
|
IntRect(0, 99, 100, 1));
|
||||||
|
|
||||||
|
// Check that the generated image is correct.
|
||||||
|
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
|
||||||
|
|
||||||
|
// Attempt to write more and make sure that nothing gets written.
|
||||||
|
count = 0;
|
||||||
|
result = aSink->WritePixelsToRow<uint32_t>([&] {
|
||||||
|
count++;
|
||||||
|
return AsVariant(BGRAColor::Red().AsPixel());
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(WriteState::FINISHED, result);
|
||||||
|
EXPECT_EQ(0u, count);
|
||||||
|
EXPECT_TRUE(aSink->IsSurfaceFinished());
|
||||||
|
|
||||||
|
// Check that the generated image is still correct.
|
||||||
|
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 100));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRowEarlyExit)
|
TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRowEarlyExit)
|
||||||
|
|
@ -673,8 +673,8 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelBlocksPartialRow)
|
||||||
|
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, row + 1));
|
CheckGeneratedImage(aDecoder, IntRect(20, 0, 60, row + 1));
|
||||||
}
|
}
|
||||||
|
|
@ -794,8 +794,8 @@ TEST(ImageSurfaceSink, SurfaceSinkInvalidRect)
|
||||||
// Assert that we have the right invalid rect.
|
// Assert that we have the right invalid rect.
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 1), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 1), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 0, 100, 1), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 0, 100, 1), invalidRect->mOutputSpaceRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -815,8 +815,8 @@ TEST(ImageSurfaceSink, SurfaceSinkInvalidRect)
|
||||||
// Assert that we have the right invalid rect.
|
// Assert that we have the right invalid rect.
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 1, 100, 8), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 1, 100, 8), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 1, 100, 8), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 1, 100, 8), invalidRect->mOutputSpaceRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -857,8 +857,8 @@ TEST(ImageSurfaceSink, SurfaceSinkInvalidRect)
|
||||||
// left and right halves of this row now that we've completed it.
|
// left and right halves of this row now that we've completed it.
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 9, 100, 1), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 9, 100, 1), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 9, 100, 1), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 9, 100, 1), invalidRect->mOutputSpaceRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -887,8 +887,8 @@ TEST(ImageSurfaceSink, SurfaceSinkInvalidRect)
|
||||||
// Assert that we have the right invalid rect.
|
// Assert that we have the right invalid rect.
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 10, 100, 90), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 10, 100, 90), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 10, 100, 90), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 10, 100, 90), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
// Check that the generated image is correct.
|
// Check that the generated image is correct.
|
||||||
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
||||||
|
|
@ -948,8 +948,8 @@ TEST(ImageSurfaceSink, SurfaceSinkFlipVertically)
|
||||||
// *bottom* (since we're flipping vertically) 25 rows of the image.
|
// *bottom* (since we're flipping vertically) 25 rows of the image.
|
||||||
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
|
||||||
EXPECT_TRUE(invalidRect.isSome());
|
EXPECT_TRUE(invalidRect.isSome());
|
||||||
EXPECT_EQ(IntRect(0, 75, 100, 25), invalidRect->mInputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 75, 100, 25), invalidRect->mInputSpaceRect);
|
||||||
EXPECT_EQ(IntRect(0, 75, 100, 25), invalidRect->mOutputSpaceRect);
|
EXPECT_EQ(OrientedIntRect(0, 75, 100, 25), invalidRect->mOutputSpaceRect);
|
||||||
|
|
||||||
// Check that the generated image is correct.
|
// Check that the generated image is correct.
|
||||||
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue