Bug 1292505 (Part 1a) - Replace Decoder::SetTargetSize() with Decoder::SetOutputSize(). r=edwin

This commit is contained in:
Seth Fowler 2016-08-05 04:17:58 -07:00
Родитель 9ba6432be7
Коммит f2c6e25053
2 изменённых файлов: 71 добавлений и 62 удалений

Просмотреть файл

@ -57,6 +57,7 @@ Decoder::Decoder(RasterImage* aImage)
, mSurfaceFlags(DefaultSurfaceFlags())
, mInitialized(false)
, mMetadataDecode(false)
, mHaveExplicitOutputSize(false)
, mInFrame(false)
, mFinishedNewFrame(false)
, mReachedTerminalState(false)
@ -94,6 +95,9 @@ Decoder::Init()
// All decoders must have a SourceBufferIterator.
MOZ_ASSERT(mIterator);
// Metadata decoders must not set an output size.
MOZ_ASSERT_IF(mMetadataDecode, !mHaveExplicitOutputSize);
// It doesn't make sense to decode anything but the first frame if we can't
// store anything in the SurfaceCache, since only the last frame we decode
// will be retrievable.
@ -227,24 +231,18 @@ Decoder::CompleteDecode()
}
}
nsresult
Decoder::SetTargetSize(const nsIntSize& aSize)
void
Decoder::SetOutputSize(const gfx::IntSize& aSize)
{
// Make sure the size is reasonable.
if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
return NS_ERROR_FAILURE;
}
// Create a downscaler that we'll filter our output through.
mDownscaler.emplace(aSize);
return NS_OK;
mOutputSize = Some(aSize);
mHaveExplicitOutputSize = true;
}
Maybe<IntSize>
Decoder::GetTargetSize()
Maybe<gfx::IntSize>
Decoder::ExplicitOutputSize() const
{
return mDownscaler ? Some(mDownscaler->TargetSize()) : Nothing();
MOZ_ASSERT_IF(mHaveExplicitOutputSize, mOutputSize);
return mHaveExplicitOutputSize ? mOutputSize : Nothing();
}
Maybe<uint32_t>
@ -257,12 +255,12 @@ Decoder::TakeCompleteFrameCount()
nsresult
Decoder::AllocateFrame(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
const gfx::IntSize& aOutputSize,
const gfx::IntRect& aFrameRect,
gfx::SurfaceFormat aFormat,
uint8_t aPaletteDepth)
{
mCurrentFrame = AllocateFrameInternal(aFrameNum, aTargetSize, aFrameRect,
mCurrentFrame = AllocateFrameInternal(aFrameNum, aOutputSize, aFrameRect,
aFormat, aPaletteDepth,
mCurrentFrame.get());
@ -288,8 +286,8 @@ Decoder::AllocateFrame(uint32_t aFrameNum,
RawAccessFrameRef
Decoder::AllocateFrameInternal(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
const gfx::IntSize& aOutputSize,
const gfx::IntRect& aFrameRect,
SurfaceFormat aFormat,
uint8_t aPaletteDepth,
imgFrame* aPreviousFrame)
@ -303,7 +301,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
return RawAccessFrameRef();
}
if (aTargetSize.width <= 0 || aTargetSize.height <= 0 ||
if (aOutputSize.width <= 0 || aOutputSize.height <= 0 ||
aFrameRect.width <= 0 || aFrameRect.height <= 0) {
NS_WARNING("Trying to add frame with zero or negative size");
return RawAccessFrameRef();
@ -318,7 +316,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
NotNull<RefPtr<imgFrame>> frame = WrapNotNull(new imgFrame());
bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
if (NS_FAILED(frame->InitForDecoder(aTargetSize, aFrameRect, aFormat,
if (NS_FAILED(frame->InitForDecoder(aOutputSize, aFrameRect, aFormat,
aPaletteDepth, nonPremult))) {
NS_WARNING("imgFrame::Init should succeed");
return RawAccessFrameRef();
@ -335,7 +333,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
WrapNotNull(new SimpleSurfaceProvider(frame));
InsertOutcome outcome =
SurfaceCache::Insert(provider, ImageKey(mImage.get()),
RasterSurfaceKey(aTargetSize,
RasterSurfaceKey(aOutputSize,
mSurfaceFlags,
aFrameNum));
if (outcome == InsertOutcome::FAILURE) {
@ -399,13 +397,28 @@ Decoder::PostSize(int32_t aWidth,
int32_t aHeight,
Orientation aOrientation /* = Orientation()*/)
{
// Validate
// Validate.
MOZ_ASSERT(aWidth >= 0, "Width can't be negative!");
MOZ_ASSERT(aHeight >= 0, "Height can't be negative!");
// Tell the image
// Set our intrinsic size.
mImageMetadata.SetSize(aWidth, aHeight, aOrientation);
// Set our output size if it's not already set.
if (!mOutputSize) {
mOutputSize = Some(IntSize(aWidth, aHeight));
}
MOZ_ASSERT(mOutputSize->width <= aWidth && mOutputSize->height <= aHeight,
"Output size will result in upscaling");
// Create a downscaler if we need to downscale. This is used by legacy
// decoders that haven't been converted to use SurfacePipe yet.
// XXX(seth): Obviously, we'll remove this once all decoders use SurfacePipe.
if (mOutputSize->width < aWidth || mOutputSize->height < aHeight) {
mDownscaler.emplace(*mOutputSize);
}
// Record this notification.
mProgress |= FLAG_SIZE_AVAILABLE;
}
@ -458,8 +471,8 @@ Decoder::PostFrameStop(Opacity aFrameOpacity
}
void
Decoder::PostInvalidation(const nsIntRect& aRect,
const Maybe<nsIntRect>& aRectAtTargetSize
Decoder::PostInvalidation(const gfx::IntRect& aRect,
const Maybe<gfx::IntRect>& aRectAtOutputSize
/* = Nothing() */)
{
// We should be mid-frame
@ -470,7 +483,7 @@ Decoder::PostInvalidation(const nsIntRect& aRect,
// or we're past the first frame.
if (ShouldSendPartialInvalidations() && mFrameCount == 1) {
mInvalidRect.UnionRect(mInvalidRect, aRect);
mCurrentFrame->ImageUpdated(aRectAtTargetSize.valueOr(aRect));
mCurrentFrame->ImageUpdated(aRectAtOutputSize.valueOr(aRect));
}
}

Просмотреть файл

@ -113,28 +113,35 @@ public:
bool IsMetadataDecode() const { return mMetadataDecode; }
/**
* If this decoder supports downscale-during-decode, sets the target size that
* this image should be decoded to.
* Sets the output size of this decoder. If this is smaller than the intrinsic
* size of the image, we'll downscale it while decoding. For memory usage
* reasons, upscaling is forbidden and will trigger assertions in debug
* builds.
*
* If the provided size is unacceptable, an error is returned.
* Not calling SetOutputSize() means that we should just decode at the
* intrinsic size, whatever it is.
*
* Returning NS_OK from this method is a promise that the decoder will decode
* the image to the requested target size unless it encounters an error.
* If SetOutputSize() was called, ExplicitOutputSize() can be used to
* determine the value that was passed to it.
*
* This must be called before Init() is called.
*/
nsresult SetTargetSize(const gfx::IntSize& aSize);
void SetOutputSize(const gfx::IntSize& aSize);
/**
* If this decoder supports downscale-during-decode and is configured to
* downscale, returns the target size that the output size will be decoded to.
* Otherwise, returns Nothing().
* @return the output size of this decoder. If this is smaller than the
* intrinsic size, then the image will be downscaled during the decoding
* process.
*
* Note that virtually all callers don't care whether a decoder is configured
* to downscale; they just want to know what the decoder's output size is.
* Such callers should use OutputSize() instead.
* Illegal to call if HasSize() returns false.
*/
Maybe<gfx::IntSize> GetTargetSize();
gfx::IntSize OutputSize() const { MOZ_ASSERT(HasSize()); return *mOutputSize; }
/**
* @return either the size passed to SetOutputSize() or Nothing(), indicating
* that SetOutputSize() was not explicitly called.
*/
Maybe<gfx::IntSize> ExplicitOutputSize() const;
/**
* Set the requested sample size for this decoder. Used to implement the
@ -284,19 +291,6 @@ public:
return gfx::IntRect(gfx::IntPoint(), Size());
}
/**
* @return the output size of this decoder. If this is different than the
* intrinsic size, then the image will be downscaled during the decoding
* process.
*
* Illegal to call if HasSize() returns false.
*/
gfx::IntSize OutputSize() const
{
return mDownscaler ? mDownscaler->TargetSize()
: Size();
}
/**
* @return an IntRect which covers the entire area of this image at its size
* after scaling - that is, at its output size.
@ -405,13 +399,13 @@ protected:
*
* @param aRect The invalidation rect in the coordinate system of the unscaled
* image (that is, the image at its intrinsic size).
* @param aRectAtTargetSize If not Nothing(), the invalidation rect in the
* @param aRectAtOutputSize If not Nothing(), the invalidation rect in the
* coordinate system of the scaled image (that is,
* the image at our target decoding size). This must
* the image at our output size). This must
* be supplied if we're downscaling during decode.
*/
void PostInvalidation(const nsIntRect& aRect,
const Maybe<nsIntRect>& aRectAtTargetSize = Nothing());
void PostInvalidation(const gfx::IntRect& aRect,
const Maybe<gfx::IntRect>& aRectAtOutputSize = Nothing());
// 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
@ -432,8 +426,8 @@ protected:
* If a non-paletted frame is desired, pass 0 for aPaletteDepth.
*/
nsresult AllocateFrame(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
const gfx::IntSize& aOutputSize,
const gfx::IntRect& aFrameRect,
gfx::SurfaceFormat aFormat,
uint8_t aPaletteDepth = 0);
@ -460,8 +454,8 @@ private:
}
RawAccessFrameRef AllocateFrameInternal(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
const gfx::IntSize& aOutputSize,
const gfx::IntRect& aFrameRect,
gfx::SurfaceFormat aFormat,
uint8_t aPaletteDepth,
imgFrame* aPreviousFrame);
@ -479,7 +473,8 @@ private:
Maybe<SourceBufferIterator> mIterator;
RawAccessFrameRef mCurrentFrame;
ImageMetadata mImageMetadata;
nsIntRect mInvalidRect; // Tracks an invalidation region in the current frame.
gfx::IntRect mInvalidRect; // Tracks an invalidation region in the current frame.
Maybe<gfx::IntSize> mOutputSize; // The size of our output surface.
Progress mProgress;
uint32_t mFrameCount; // Number of frames, including anything in-progress
@ -495,6 +490,7 @@ private:
bool mInitialized : 1;
bool mMetadataDecode : 1;
bool mHaveExplicitOutputSize : 1;
bool mInFrame : 1;
bool mFinishedNewFrame : 1; // True if PostFrameStop() has been called since
// the last call to TakeCompleteFrameCount().